From 21193c2fbf34027fd204b1715537bcfc3f933994 Mon Sep 17 00:00:00 2001 From: Yi Date: Sat, 14 Sep 2024 17:09:25 +0800 Subject: [PATCH 001/346] update the plugins page --- web/app/(commonLayout)/plugins/Container.tsx | 94 ++++++++++++++++++ .../plugins/InstallPluginDropdown.tsx | 67 +++++++++++++ web/app/(commonLayout)/plugins/page.tsx | 13 +++ web/app/components/base/badge/index.css | 28 ++++++ web/app/components/base/badge/index.tsx | 81 +++++++++++++++ .../base/icons/assets/vender/other/group.svg | 8 ++ .../assets/vender/solid/files/file-zip.svg | 6 ++ .../assets/vender/solid/general/github.svg | 5 + .../base/icons/src/vender/other/Group.json | 66 +++++++++++++ .../base/icons/src/vender/other/Group.tsx | 16 +++ .../base/icons/src/vender/other/index.ts | 1 + .../icons/src/vender/solid/files/FileZip.json | 47 +++++++++ .../icons/src/vender/solid/files/FileZip.tsx | 16 +++ .../icons/src/vender/solid/files/index.ts | 1 + .../src/vender/solid/general/Github.json | 36 +++++++ .../icons/src/vender/solid/general/Github.tsx | 16 +++ .../icons/src/vender/solid/general/index.ts | 1 + web/app/components/base/tab-slider/index.tsx | 99 +++++++++++-------- web/app/components/header/index.tsx | 19 +++- .../components/header/plugins-nav/index.tsx | 30 ++++++ web/i18n/en-US/marketplace.ts | 5 + web/service/plugins.ts | 0 22 files changed, 609 insertions(+), 46 deletions(-) create mode 100644 web/app/(commonLayout)/plugins/Container.tsx create mode 100644 web/app/(commonLayout)/plugins/InstallPluginDropdown.tsx create mode 100644 web/app/(commonLayout)/plugins/page.tsx create mode 100644 web/app/components/base/badge/index.css create mode 100644 web/app/components/base/badge/index.tsx create mode 100644 web/app/components/base/icons/assets/vender/other/group.svg create mode 100644 web/app/components/base/icons/assets/vender/solid/files/file-zip.svg create mode 100644 web/app/components/base/icons/assets/vender/solid/general/github.svg create mode 100644 web/app/components/base/icons/src/vender/other/Group.json create mode 100644 web/app/components/base/icons/src/vender/other/Group.tsx create mode 100644 web/app/components/base/icons/src/vender/solid/files/FileZip.json create mode 100644 web/app/components/base/icons/src/vender/solid/files/FileZip.tsx create mode 100644 web/app/components/base/icons/src/vender/solid/general/Github.json create mode 100644 web/app/components/base/icons/src/vender/solid/general/Github.tsx create mode 100644 web/app/components/header/plugins-nav/index.tsx create mode 100644 web/i18n/en-US/marketplace.ts create mode 100644 web/service/plugins.ts diff --git a/web/app/(commonLayout)/plugins/Container.tsx b/web/app/(commonLayout)/plugins/Container.tsx new file mode 100644 index 0000000000..bee44b7215 --- /dev/null +++ b/web/app/(commonLayout)/plugins/Container.tsx @@ -0,0 +1,94 @@ +'use client' + +import { useMemo, useRef } from 'react' +import { useTranslation } from 'react-i18next' +import { + RiArrowRightUpLine, + RiBugLine, + RiDragDropLine, + RiEqualizer2Line, +} from '@remixicon/react' +import InstallPluginDropdown from './InstallPluginDropdown' +import { useTabSearchParams } from '@/hooks/use-tab-searchparams' +import Button from '@/app/components/base/button' +import TabSlider from '@/app/components/base/tab-slider' +import Tooltip from '@/app/components/base/tooltip' + +const Container = () => { + const { t } = useTranslation() + + const options = useMemo(() => { + return [ + { value: 'plugins', text: t('common.menus.plugins') }, + { value: 'discover', text: 'Discover in Marketplace' }, + ] + }, [t]) + + const [activeTab, setActiveTab] = useTabSearchParams({ + defaultTab: 'plugins', + }) + + const containerRef = useRef(null) + + return ( +
+
+
+
+ setActiveTab(newActiveTab)} + options={options} + /> +
+
+ + +
+ Debugging +
+ View docs + +
+
+
+
+ Port +
+
+ + } + popupClassName='flex flex-col items-start w-[256px] px-4 py-3.5 gap-1 border border-components-panel-border + rounded-xl bg-components-tooltip-bg shadows-shadow-lg' + asChild={false} + position='bottom' + > + +
+ +
+
+
+
+
+
+ {/* Content for active tab will go here */} +
+
+
+ + Drop plugin package here to install +
+
+ ) +} + +export default Container diff --git a/web/app/(commonLayout)/plugins/InstallPluginDropdown.tsx b/web/app/(commonLayout)/plugins/InstallPluginDropdown.tsx new file mode 100644 index 0000000000..35b1089bae --- /dev/null +++ b/web/app/(commonLayout)/plugins/InstallPluginDropdown.tsx @@ -0,0 +1,67 @@ +'use client' + +import { useEffect, useRef, useState } from 'react' +import { RiAddLine, RiArrowDownSLine } from '@remixicon/react' +import Button from '@/app/components/base/button' +import { MagicBox } from '@/app/components/base/icons/src/vender/solid/mediaAndDevices' +import { FileZip } from '@/app/components/base/icons/src/vender/solid/files' +import { Github } from '@/app/components/base/icons/src/vender/solid/general' + +const InstallPluginDropdown = () => { + const [isMenuOpen, setIsMenuOpen] = useState(false) + const menuRef = useRef(null) + + useEffect(() => { + const handleClickOutside = (event: MouseEvent) => { + if (menuRef.current && !menuRef.current.contains(event.target as Node)) + setIsMenuOpen(false) + } + + document.addEventListener('mousedown', handleClickOutside) + return () => { + document.removeEventListener('mousedown', handleClickOutside) + } + }, []) + + return ( +
+ + {isMenuOpen && ( +
+ + Install Form + + {[ + { icon: MagicBox, text: 'Marketplace', action: 'marketplace' }, + { icon: Github, text: 'GitHub', action: 'github' }, + { icon: FileZip, text: 'Local Package File', action: 'local' }, + ].map(({ icon: Icon, text, action }) => ( +
{ + console.log(action) + setIsMenuOpen(false) + }} + > + + {text} +
+ ))} +
+ )} +
+ ) +} + +export default InstallPluginDropdown diff --git a/web/app/(commonLayout)/plugins/page.tsx b/web/app/(commonLayout)/plugins/page.tsx new file mode 100644 index 0000000000..c50b3ad9a2 --- /dev/null +++ b/web/app/(commonLayout)/plugins/page.tsx @@ -0,0 +1,13 @@ +import Container from './Container' + +const PluginList = async () => { + return ( + + ) +} + +export const metadata = { + title: 'Plugins - Dify', +} + +export default PluginList diff --git a/web/app/components/base/badge/index.css b/web/app/components/base/badge/index.css new file mode 100644 index 0000000000..99db573c9c --- /dev/null +++ b/web/app/components/base/badge/index.css @@ -0,0 +1,28 @@ +@tailwind components; + +@layer components { + .badge { + @apply inline-flex justify-center items-center text-text-tertiary border border-divider-deep + } + + .badge-l { + @apply rounded-md gap-1 min-w-6 + } + + /* m is for the regular button */ + .badge-m { + @apply rounded-md gap-[3px] min-w-5 + } + + .badge-s { + @apply rounded-[5px] gap-0.5 min-w-[18px] + } + + .badge.badge-warning { + @apply text-text-warning border border-text-warning + } + + .badge.badge-accent { + @apply text-text-accent-secondary border border-text-accent-secondary + } +} \ No newline at end of file diff --git a/web/app/components/base/badge/index.tsx b/web/app/components/base/badge/index.tsx new file mode 100644 index 0000000000..88ba026e14 --- /dev/null +++ b/web/app/components/base/badge/index.tsx @@ -0,0 +1,81 @@ +import type { CSSProperties, ReactNode } from 'react' +import React from 'react' +import { type VariantProps, cva } from 'class-variance-authority' +import classNames from '@/utils/classnames' +import './index.css' + +enum BadgeState { + Warning = 'warning', + Accent = 'accent', + Default = '', +} + +const BadgeVariants = cva( + 'badge', + { + variants: { + size: { + s: 'badge-s', + m: 'badge-m', + l: 'badge-l', + }, + }, + defaultVariants: { + size: 'm', + }, + }, +) + +type BadgeProps = { + size?: 's' | 'm' | 'l' + iconOnly?: boolean + uppercase?: boolean + state?: BadgeState + styleCss?: CSSProperties + children?: ReactNode +} & React.HTMLAttributes & VariantProps + +function getBadgeState(state: BadgeState) { + switch (state) { + case BadgeState.Warning: + return 'badge-warning' + case BadgeState.Accent: + return 'badge-accent' + default: + return '' + } +} + +const Badge: React.FC = ({ + className, + size, + state = BadgeState.Default, + iconOnly = false, + uppercase = false, + styleCss, + children, + ...props +}) => { + return ( +
+ {children} +
+ ) +} +Badge.displayName = 'Badge' + +export default Badge +export { Badge, BadgeState, BadgeVariants } diff --git a/web/app/components/base/icons/assets/vender/other/group.svg b/web/app/components/base/icons/assets/vender/other/group.svg new file mode 100644 index 0000000000..90f1e6b89e --- /dev/null +++ b/web/app/components/base/icons/assets/vender/other/group.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/web/app/components/base/icons/assets/vender/solid/files/file-zip.svg b/web/app/components/base/icons/assets/vender/solid/files/file-zip.svg new file mode 100644 index 0000000000..213606ae49 --- /dev/null +++ b/web/app/components/base/icons/assets/vender/solid/files/file-zip.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/web/app/components/base/icons/assets/vender/solid/general/github.svg b/web/app/components/base/icons/assets/vender/solid/general/github.svg new file mode 100644 index 0000000000..c7b203ddb2 --- /dev/null +++ b/web/app/components/base/icons/assets/vender/solid/general/github.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/web/app/components/base/icons/src/vender/other/Group.json b/web/app/components/base/icons/src/vender/other/Group.json new file mode 100644 index 0000000000..078febbc80 --- /dev/null +++ b/web/app/components/base/icons/src/vender/other/Group.json @@ -0,0 +1,66 @@ +{ + "icon": { + "type": "element", + "isRootNode": true, + "name": "svg", + "attributes": { + "width": "14", + "height": "16", + "viewBox": "0 0 14 16", + "fill": "none", + "xmlns": "http://www.w3.org/2000/svg" + }, + "children": [ + { + "type": "element", + "name": "g", + "attributes": { + "id": "Group" + }, + "children": [ + { + "type": "element", + "name": "path", + "attributes": { + "id": "Vector", + "d": "M5.6475 8.0115L0.333496 5.05884V11.3335C0.333491 11.4524 0.365258 11.569 0.425506 11.6715C0.485754 11.7739 0.572294 11.8584 0.676163 11.9162L6.3335 15.0588V9.17684C6.33344 8.93907 6.26981 8.70565 6.14919 8.50075C6.02857 8.29586 5.85536 8.12694 5.6475 8.0115Z", + "fill": "currentColor" + }, + "children": [] + }, + { + "type": "element", + "name": "path", + "attributes": { + "id": "Vector_2", + "d": "M7.66699 9.17684V15.0588L13.3243 11.9162C13.4282 11.8584 13.5147 11.7739 13.575 11.6715C13.6352 11.569 13.667 11.4524 13.667 11.3335V5.05884L8.35299 8.0115C8.14513 8.12694 7.97192 8.29586 7.8513 8.50075C7.73068 8.70565 7.66705 8.93907 7.66699 9.17684Z", + "fill": "currentColor" + }, + "children": [] + }, + { + "type": "element", + "name": "path", + "attributes": { + "id": "Vector_3", + "d": "M10.1913 2.34351C9.804 3.33351 8.588 4.00017 7 4.00017C5.412 4.00017 4.196 3.33351 3.80867 2.34351L1 3.90417L6.35267 6.87817C6.5507 6.98815 6.77348 7.04586 7 7.04586C7.22652 7.04586 7.4493 6.98815 7.64733 6.87817L13 3.90417L10.1913 2.34351Z", + "fill": "currentColor" + }, + "children": [] + }, + { + "type": "element", + "name": "path", + "attributes": { + "id": "Vector_4", + "d": "M7 2.66675C8.10457 2.66675 9 2.21903 9 1.66675C9 1.11446 8.10457 0.666748 7 0.666748C5.89543 0.666748 5 1.11446 5 1.66675C5 2.21903 5.89543 2.66675 7 2.66675Z", + "fill": "currentColor" + }, + "children": [] + } + ] + } + ] + }, + "name": "Group" +} \ No newline at end of file diff --git a/web/app/components/base/icons/src/vender/other/Group.tsx b/web/app/components/base/icons/src/vender/other/Group.tsx new file mode 100644 index 0000000000..ba9d130f80 --- /dev/null +++ b/web/app/components/base/icons/src/vender/other/Group.tsx @@ -0,0 +1,16 @@ +// GENERATE BY script +// DON NOT EDIT IT MANUALLY + +import * as React from 'react' +import data from './Group.json' +import IconBase from '@/app/components/base/icons/IconBase' +import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase' + +const Icon = React.forwardRef, Omit>(( + props, + ref, +) => ) + +Icon.displayName = 'Group' + +export default Icon diff --git a/web/app/components/base/icons/src/vender/other/index.ts b/web/app/components/base/icons/src/vender/other/index.ts index db6fd9e3f1..0b722bd492 100644 --- a/web/app/components/base/icons/src/vender/other/index.ts +++ b/web/app/components/base/icons/src/vender/other/index.ts @@ -1 +1,2 @@ export { default as Generator } from './Generator' +export { default as Group } from './Group' diff --git a/web/app/components/base/icons/src/vender/solid/files/FileZip.json b/web/app/components/base/icons/src/vender/solid/files/FileZip.json new file mode 100644 index 0000000000..11fe823916 --- /dev/null +++ b/web/app/components/base/icons/src/vender/solid/files/FileZip.json @@ -0,0 +1,47 @@ +{ + "icon": { + "type": "element", + "isRootNode": true, + "name": "svg", + "attributes": { + "width": "16", + "height": "16", + "viewBox": "0 0 16 16", + "fill": "none", + "xmlns": "http://www.w3.org/2000/svg" + }, + "children": [ + { + "type": "element", + "name": "g", + "attributes": { + "id": "Icon" + }, + "children": [ + { + "type": "element", + "name": "path", + "attributes": { + "id": "Vector", + "d": "M3.99999 1.33325H7.99999V5.33325C7.99999 6.06963 8.59692 6.66659 9.33332 6.66659H13.3333V13.3333C13.3333 14.0697 12.7364 14.6666 12 14.6666H6.66666V13.3333H7.99999V11.9999H6.66666V10.6666H7.99999V9.33325H6.66666V7.99992H5.33332V9.33325H6.66666V10.6666H5.33332V11.9999H6.66666V13.3333H5.33332V14.6666H3.99999C3.26361 14.6666 2.66666 14.0697 2.66666 13.3333V2.66659C2.66666 1.93021 3.26361 1.33325 3.99999 1.33325Z", + "fill": "currentColor" + }, + "children": [] + }, + { + "type": "element", + "name": "path", + "attributes": { + "id": "Vector_2", + "opacity": "0.5", + "d": "M12.9428 4.99993C13.0415 5.09868 13.1232 5.21133 13.1859 5.33327H9.33334V1.48071C9.45528 1.54338 9.56794 1.62504 9.66668 1.72379L12.9428 4.99993Z", + "fill": "currentColor" + }, + "children": [] + } + ] + } + ] + }, + "name": "FileZip" +} \ No newline at end of file diff --git a/web/app/components/base/icons/src/vender/solid/files/FileZip.tsx b/web/app/components/base/icons/src/vender/solid/files/FileZip.tsx new file mode 100644 index 0000000000..675fa0ac98 --- /dev/null +++ b/web/app/components/base/icons/src/vender/solid/files/FileZip.tsx @@ -0,0 +1,16 @@ +// GENERATE BY script +// DON NOT EDIT IT MANUALLY + +import * as React from 'react' +import data from './FileZip.json' +import IconBase from '@/app/components/base/icons/IconBase' +import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase' + +const Icon = React.forwardRef, Omit>(( + props, + ref, +) => ) + +Icon.displayName = 'FileZip' + +export default Icon diff --git a/web/app/components/base/icons/src/vender/solid/files/index.ts b/web/app/components/base/icons/src/vender/solid/files/index.ts index 31feeb5309..fa93cd68dc 100644 --- a/web/app/components/base/icons/src/vender/solid/files/index.ts +++ b/web/app/components/base/icons/src/vender/solid/files/index.ts @@ -1,3 +1,4 @@ export { default as File05 } from './File05' export { default as FileSearch02 } from './FileSearch02' +export { default as FileZip } from './FileZip' export { default as Folder } from './Folder' diff --git a/web/app/components/base/icons/src/vender/solid/general/Github.json b/web/app/components/base/icons/src/vender/solid/general/Github.json new file mode 100644 index 0000000000..46e694215b --- /dev/null +++ b/web/app/components/base/icons/src/vender/solid/general/Github.json @@ -0,0 +1,36 @@ +{ + "icon": { + "type": "element", + "isRootNode": true, + "name": "svg", + "attributes": { + "width": "16", + "height": "16", + "viewBox": "0 0 16 16", + "fill": "none", + "xmlns": "http://www.w3.org/2000/svg" + }, + "children": [ + { + "type": "element", + "name": "g", + "attributes": { + "id": "Icon" + }, + "children": [ + { + "type": "element", + "name": "path", + "attributes": { + "id": "Vector", + "d": "M8 1C4.1325 1 1 4.1325 1 8C1 11.0975 3.00375 13.7137 5.78625 14.6413C6.13625 14.7025 6.2675 14.4925 6.2675 14.3088C6.2675 14.1425 6.25875 13.5913 6.25875 13.005C4.5 13.3288 4.045 12.5763 3.905 12.1825C3.82625 11.9812 3.485 11.36 3.1875 11.1937C2.9425 11.0625 2.5925 10.7387 3.17875 10.73C3.73 10.7212 4.12375 11.2375 4.255 11.4475C4.885 12.5062 5.89125 12.2088 6.29375 12.025C6.355 11.57 6.53875 11.2638 6.74 11.0887C5.1825 10.9137 3.555 10.31 3.555 7.6325C3.555 6.87125 3.82625 6.24125 4.2725 5.75125C4.2025 5.57625 3.9575 4.85875 4.3425 3.89625C4.3425 3.89625 4.92875 3.7125 6.2675 4.61375C6.8275 4.45625 7.4225 4.3775 8.0175 4.3775C8.6125 4.3775 9.2075 4.45625 9.7675 4.61375C11.1063 3.70375 11.6925 3.89625 11.6925 3.89625C12.0775 4.85875 11.8325 5.57625 11.7625 5.75125C12.2087 6.24125 12.48 6.8625 12.48 7.6325C12.48 10.3187 10.8438 10.9137 9.28625 11.0887C9.54 11.3075 9.75875 11.7275 9.75875 12.3837C9.75875 13.32 9.75 14.0725 9.75 14.3088C9.75 14.4925 9.88125 14.7113 10.2312 14.6413C11.6209 14.1721 12.8284 13.279 13.6839 12.0877C14.5393 10.8963 14.9996 9.46668 15 8C15 4.1325 11.8675 1 8 1Z", + "fill": "currentColor" + }, + "children": [] + } + ] + } + ] + }, + "name": "Github" +} \ No newline at end of file diff --git a/web/app/components/base/icons/src/vender/solid/general/Github.tsx b/web/app/components/base/icons/src/vender/solid/general/Github.tsx new file mode 100644 index 0000000000..416743fc71 --- /dev/null +++ b/web/app/components/base/icons/src/vender/solid/general/Github.tsx @@ -0,0 +1,16 @@ +// GENERATE BY script +// DON NOT EDIT IT MANUALLY + +import * as React from 'react' +import data from './Github.json' +import IconBase from '@/app/components/base/icons/IconBase' +import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase' + +const Icon = React.forwardRef, Omit>(( + props, + ref, +) => ) + +Icon.displayName = 'Github' + +export default Icon diff --git a/web/app/components/base/icons/src/vender/solid/general/index.ts b/web/app/components/base/icons/src/vender/solid/general/index.ts index 9d2492e287..52647905ab 100644 --- a/web/app/components/base/icons/src/vender/solid/general/index.ts +++ b/web/app/components/base/icons/src/vender/solid/general/index.ts @@ -5,6 +5,7 @@ export { default as Download02 } from './Download02' export { default as Edit03 } from './Edit03' export { default as Edit04 } from './Edit04' export { default as Eye } from './Eye' +export { default as Github } from './Github' export { default as MessageClockCircle } from './MessageClockCircle' export { default as PlusCircle } from './PlusCircle' export { default as QuestionTriangle } from './QuestionTriangle' diff --git a/web/app/components/base/tab-slider/index.tsx b/web/app/components/base/tab-slider/index.tsx index 03296a9dee..f8e06935da 100644 --- a/web/app/components/base/tab-slider/index.tsx +++ b/web/app/components/base/tab-slider/index.tsx @@ -1,64 +1,81 @@ import type { FC } from 'react' +import { useEffect, useState } from 'react' import cn from '@/utils/classnames' - +import Badge, { BadgeState } from '@/app/components/base/badge/index' type Option = { value: string text: string } + type TabSliderProps = { className?: string - itemWidth?: number value: string onChange: (v: string) => void options: Option[] } + const TabSlider: FC = ({ className, - itemWidth = 118, value, onChange, options, }) => { - const currentIndex = options.findIndex(option => option.value === value) - const current = options[currentIndex] + const [activeIndex, setActiveIndex] = useState(options.findIndex(option => option.value === value)) + const [sliderStyle, setSliderStyle] = useState({}) + + const updateSliderStyle = (index: number) => { + const tabElement = document.getElementById(`tab-${index}`) + if (tabElement) { + const { offsetLeft, offsetWidth } = tabElement + setSliderStyle({ + transform: `translateX(${offsetLeft}px)`, + width: `${offsetWidth}px`, + }) + } + } + + useEffect(() => { + const newIndex = options.findIndex(option => option.value === value) + setActiveIndex(newIndex) + updateSliderStyle(newIndex) + }, [value, options]) return ( -
- { - options.map((option, index) => ( -
onChange(option.value)} - > - {option.text} -
- )) - } - { - current && ( -
- {current.text} -
- ) - } +
+
+ {options.map((option, index) => ( +
{ + if (index !== activeIndex) { + onChange(option.value) + updateSliderStyle(index) + } + }} + > + {option.text} + {option.value === 'plugins' + && + 6 + + } +
+ ))}
) } diff --git a/web/app/components/header/index.tsx b/web/app/components/header/index.tsx index 2b020b81e7..035cc6fd1e 100644 --- a/web/app/components/header/index.tsx +++ b/web/app/components/header/index.tsx @@ -9,6 +9,7 @@ import AccountDropdown from './account-dropdown' import AppNav from './app-nav' import DatasetNav from './dataset-nav' import EnvNav from './env-nav' +import PluginsNav from './plugins-nav' import ExploreNav from './explore-nav' import ToolsNav from './tools-nav' import GithubStar from './github-star' @@ -59,6 +60,11 @@ const Header = () => { + {enableBilling && ( +
+ +
+ )} }
@@ -67,6 +73,11 @@ const Header = () => { + {enableBilling && ( +
+ +
+ )}
)} @@ -80,11 +91,9 @@ const Header = () => { )}
- {enableBilling && ( -
- -
- )} +
+ +
diff --git a/web/app/components/header/plugins-nav/index.tsx b/web/app/components/header/plugins-nav/index.tsx new file mode 100644 index 0000000000..c2ad9398f4 --- /dev/null +++ b/web/app/components/header/plugins-nav/index.tsx @@ -0,0 +1,30 @@ +'use client' + +import { useTranslation } from 'react-i18next' +import Link from 'next/link' +import classNames from '@/utils/classnames' +import { Group } from '@/app/components/base/icons/src/vender/other' +type PluginsNavProps = { + className?: string +} + +const PluginsNav = ({ + className, +}: PluginsNavProps) => { + const { t } = useTranslation() + + return ( + +
+
+ +
+ {t('common.menus.plugins')} +
+ + ) +} + +export default PluginsNav diff --git a/web/i18n/en-US/marketplace.ts b/web/i18n/en-US/marketplace.ts new file mode 100644 index 0000000000..144fa07cb4 --- /dev/null +++ b/web/i18n/en-US/marketplace.ts @@ -0,0 +1,5 @@ +const translation = { + +} + +export default translation diff --git a/web/service/plugins.ts b/web/service/plugins.ts new file mode 100644 index 0000000000..e69de29bb2 From d7d7281c93acc2dbc2457c7e086f1e835acd3067 Mon Sep 17 00:00:00 2001 From: Yi Date: Mon, 16 Sep 2024 18:58:39 +0800 Subject: [PATCH 002/346] feat: plugin homepage --- web/app/(commonLayout)/plugins/Container.tsx | 29 +++++-- .../plugins/InstallPluginDropdown.tsx | 3 +- .../plugins/plugin-setting/modal.tsx | 81 +++++++++++++++++++ web/context/modal-context.tsx | 14 ++++ 4 files changed, 121 insertions(+), 6 deletions(-) create mode 100644 web/app/components/plugins/plugin-setting/modal.tsx diff --git a/web/app/(commonLayout)/plugins/Container.tsx b/web/app/(commonLayout)/plugins/Container.tsx index bee44b7215..fde3f0335c 100644 --- a/web/app/(commonLayout)/plugins/Container.tsx +++ b/web/app/(commonLayout)/plugins/Container.tsx @@ -5,17 +5,21 @@ import { useTranslation } from 'react-i18next' import { RiArrowRightUpLine, RiBugLine, + RiClipboardLine, RiDragDropLine, RiEqualizer2Line, } from '@remixicon/react' import InstallPluginDropdown from './InstallPluginDropdown' import { useTabSearchParams } from '@/hooks/use-tab-searchparams' +import { useModalContext } from '@/context/modal-context' import Button from '@/app/components/base/button' import TabSlider from '@/app/components/base/tab-slider' +import ActionButton from '@/app/components/base/action-button' import Tooltip from '@/app/components/base/tooltip' const Container = () => { const { t } = useTranslation() + const { setShowPluginSettingModal } = useModalContext() const options = useMemo(() => { return [ @@ -56,14 +60,24 @@ const Container = () => {
-
- Port -
+ {['Port', 'Key'].map((label, index) => ( +
+ {label} +
+ + {index === 0 ? 'cloud.dify,ai:2048' : 'A1B2C3D4E5F6G7H8'} + + + + +
+
+ ))}
} popupClassName='flex flex-col items-start w-[256px] px-4 py-3.5 gap-1 border border-components-panel-border - rounded-xl bg-components-tooltip-bg shadows-shadow-lg' + rounded-xl bg-components-tooltip-bg shadows-shadow-lg z-50' asChild={false} position='bottom' > @@ -71,7 +85,12 @@ const Container = () => { - diff --git a/web/app/(commonLayout)/plugins/InstallPluginDropdown.tsx b/web/app/(commonLayout)/plugins/InstallPluginDropdown.tsx index 35b1089bae..c94ddfe75b 100644 --- a/web/app/(commonLayout)/plugins/InstallPluginDropdown.tsx +++ b/web/app/(commonLayout)/plugins/InstallPluginDropdown.tsx @@ -6,6 +6,7 @@ import Button from '@/app/components/base/button' import { MagicBox } from '@/app/components/base/icons/src/vender/solid/mediaAndDevices' import { FileZip } from '@/app/components/base/icons/src/vender/solid/files' import { Github } from '@/app/components/base/icons/src/vender/solid/general' +import cn from '@/utils/classnames' const InstallPluginDropdown = () => { const [isMenuOpen, setIsMenuOpen] = useState(false) @@ -26,7 +27,7 @@ const InstallPluginDropdown = () => { return (
+ +
+ + + ) +} + +export default React.memo(PluginSettingModal) diff --git a/web/context/modal-context.tsx b/web/context/modal-context.tsx index 3547c45aac..db52cb6b27 100644 --- a/web/context/modal-context.tsx +++ b/web/context/modal-context.tsx @@ -5,6 +5,7 @@ import { useCallback, useState } from 'react' import { createContext, useContext, useContextSelector } from 'use-context-selector' import { useRouter, useSearchParams } from 'next/navigation' import AccountSetting from '@/app/components/header/account-setting' +import PluginSettingModal from '@/app/components/plugins/plugin-setting/modal' import ApiBasedExtensionModal from '@/app/components/header/account-setting/api-based-extension-page/modal' import ModerationSettingModal from '@/app/components/app/configuration/toolbox/moderation/moderation-setting-modal' import ExternalDataToolModal from '@/app/components/app/configuration/tools/external-data-tool-modal' @@ -46,6 +47,7 @@ export type LoadBalancingEntryModalType = ModelModalType & { } export type ModalContextState = { setShowAccountSettingModal: Dispatch | null>> + setShowPluginSettingModal: () => void setShowApiBasedExtensionModal: Dispatch | null>> setShowModerationSettingModal: Dispatch | null>> setShowExternalDataToolModal: Dispatch | null>> @@ -57,6 +59,7 @@ export type ModalContextState = { } const ModalContext = createContext({ setShowAccountSettingModal: () => { }, + setShowPluginSettingModal: () => { }, setShowApiBasedExtensionModal: () => { }, setShowModerationSettingModal: () => { }, setShowExternalDataToolModal: () => { }, @@ -92,6 +95,7 @@ export const ModalContextProvider = ({ const router = useRouter() const [showPricingModal, setShowPricingModal] = useState(searchParams.get('show-pricing') === '1') const [showAnnotationFullModal, setShowAnnotationFullModal] = useState(false) + const [showPluginSettingModal, setShowPluginSettingModal] = useState(false) const handleCancelAccountSettingModal = () => { setShowAccountSettingModal(null) if (showAccountSettingModal?.onCancelCallback) @@ -167,6 +171,7 @@ export const ModalContextProvider = ({ return ( setShowPluginSettingModal(true), setShowApiBasedExtensionModal, setShowModerationSettingModal, setShowExternalDataToolModal, @@ -187,6 +192,15 @@ export const ModalContextProvider = ({ ) } + { + !!showPluginSettingModal && ( + setShowPluginSettingModal(false)} + /> + ) + } + { !!showApiBasedExtensionModal && ( Date: Wed, 18 Sep 2024 18:32:33 +0800 Subject: [PATCH 003/346] update page header --- web/app/(commonLayout)/plugins/Container.tsx | 14 +++-- web/app/components/base/logo/logo-site.tsx | 12 +--- .../billing/header-billing-btn/index.tsx | 24 ++++++-- .../header/account-dropdown/index.tsx | 5 -- .../workplace-selector/index.tsx | 52 ++++++++---------- web/app/components/header/index.tsx | 33 ++++++----- web/app/components/header/nav/index.tsx | 2 +- .../plugins/plugin-setting/style.module.css | 7 +++ web/i18n/en-US/marketplace.ts | 7 ++- web/i18n/zh-Hans/marketplace.ts | 10 ++++ web/public/logo/logo.png | Bin 0 -> 6249 bytes 11 files changed, 97 insertions(+), 69 deletions(-) create mode 100644 web/app/components/plugins/plugin-setting/style.module.css create mode 100644 web/i18n/zh-Hans/marketplace.ts create mode 100644 web/public/logo/logo.png diff --git a/web/app/(commonLayout)/plugins/Container.tsx b/web/app/(commonLayout)/plugins/Container.tsx index fde3f0335c..5fee5354a2 100644 --- a/web/app/(commonLayout)/plugins/Container.tsx +++ b/web/app/(commonLayout)/plugins/Container.tsx @@ -35,8 +35,11 @@ const Container = () => { const containerRef = useRef(null) return ( -
+
@@ -96,12 +99,15 @@ const Container = () => {
-
+
- {/* Content for active tab will go here */} + {/* Filter goes here */}
+
+ {/* Plugin cards go here */} +
Drop plugin package here to install diff --git a/web/app/components/base/logo/logo-site.tsx b/web/app/components/base/logo/logo-site.tsx index a399ff3301..4b0e026afd 100644 --- a/web/app/components/base/logo/logo-site.tsx +++ b/web/app/components/base/logo/logo-site.tsx @@ -1,7 +1,6 @@ 'use client' import type { FC } from 'react' import classNames from '@/utils/classnames' -import { useSelector } from '@/context/app-context' type LogoSiteProps = { className?: string @@ -10,17 +9,10 @@ type LogoSiteProps = { const LogoSite: FC = ({ className, }) => { - const { theme } = useSelector((s) => { - return { - theme: s.theme, - } - }) - - const src = theme === 'light' ? '/logo/logo-site.png' : `/logo/logo-site-${theme}.png` return ( logo ) diff --git a/web/app/components/billing/header-billing-btn/index.tsx b/web/app/components/billing/header-billing-btn/index.tsx index a8415524fd..a5bc310d9b 100644 --- a/web/app/components/billing/header-billing-btn/index.tsx +++ b/web/app/components/billing/header-billing-btn/index.tsx @@ -7,11 +7,13 @@ import cn from '@/utils/classnames' import { useProviderContext } from '@/context/provider-context' type Props = { - onClick: () => void + onClick?: () => void + isDisplayOnly?: boolean } const HeaderBillingBtn: FC = ({ onClick, + isDisplayOnly = false, }) => { const { plan, enableBilling, isFetchedPlan } = useProviderContext() const { @@ -25,9 +27,9 @@ const HeaderBillingBtn: FC = ({ })() const classNames = (() => { if (type === Plan.professional) - return 'border-[#E0F2FE] hover:border-[#B9E6FE] bg-[#E0F2FE] text-[#026AA2]' + return `border-[#E0F2FE] ${!isDisplayOnly ? 'hover:border-[#B9E6FE]' : ''} bg-[#E0F2FE] text-[#026AA2]` if (type === Plan.team) - return 'border-[#E0EAFF] hover:border-[#C7D7FE] bg-[#E0EAFF] text-[#3538CD]' + return `border-[#E0EAFF] ${!isDisplayOnly ? 'hover:border-[#C7D7FE]' : ''} bg-[#E0EAFF] text-[#3538CD]` return '' })() @@ -35,10 +37,22 @@ const HeaderBillingBtn: FC = ({ return null if (type === Plan.sandbox) - return + return + + const handleClick = () => { + if (!isDisplayOnly && onClick) + onClick() + } return ( -
+
{name}
) diff --git a/web/app/components/header/account-dropdown/index.tsx b/web/app/components/header/account-dropdown/index.tsx index 03157ed7cb..4c42374ffd 100644 --- a/web/app/components/header/account-dropdown/index.tsx +++ b/web/app/components/header/account-dropdown/index.tsx @@ -9,7 +9,6 @@ import { Menu, Transition } from '@headlessui/react' import Indicator from '../indicator' import AccountAbout from '../account-about' import { mailToSupport } from '../utils/util' -import WorkplaceSelector from './workplace-selector' import classNames from '@/utils/classnames' import I18n from '@/context/i18n' import Avatar from '@/app/components/base/avatar' @@ -101,10 +100,6 @@ export default function AppSelector({ isMobile }: IAppSelector) {
-
-
{t('common.userProfile.workspace')}
- -
setShowAccountSettingModal({ payload: 'account' })}> diff --git a/web/app/components/header/account-dropdown/workplace-selector/index.tsx b/web/app/components/header/account-dropdown/workplace-selector/index.tsx index 801f0b3d52..b32cb13227 100644 --- a/web/app/components/header/account-dropdown/workplace-selector/index.tsx +++ b/web/app/components/header/account-dropdown/workplace-selector/index.tsx @@ -2,33 +2,20 @@ import { Fragment } from 'react' import { useContext } from 'use-context-selector' import { useTranslation } from 'react-i18next' import { Menu, Transition } from '@headlessui/react' -import s from './index.module.css' +import { RiArrowDownSLine } from '@remixicon/react' import cn from '@/utils/classnames' import { switchWorkspace } from '@/service/common' import { useWorkspacesContext } from '@/context/workspace-context' -import { ChevronRight } from '@/app/components/base/icons/src/vender/line/arrows' -import { Check } from '@/app/components/base/icons/src/vender/line/general' +import HeaderBillingBtn from '@/app/components/billing/header-billing-btn' +import { useProviderContext } from '@/context/provider-context' import { ToastContext } from '@/app/components/base/toast' -const itemClassName = ` - flex items-center px-3 py-2 h-10 cursor-pointer -` -const itemIconClassName = ` - shrink-0 mr-2 flex items-center justify-center w-6 h-6 bg-[#EFF4FF] rounded-md text-xs font-medium text-primary-600 -` -const itemNameClassName = ` - grow mr-2 text-sm text-gray-700 text-left -` -const itemCheckClassName = ` - shrink-0 w-4 h-4 text-primary-600 -` - const WorkplaceSelector = () => { const { t } = useTranslation() const { notify } = useContext(ToastContext) const { workspaces } = useWorkspacesContext() + const { enableBilling } = useProviderContext() const currentWorkspace = workspaces.find(v => v.current) - const handleSwitchWorkspace = async (tenant_id: string) => { try { if (currentWorkspace?.id === tenant_id) @@ -49,13 +36,13 @@ const WorkplaceSelector = () => { <> -
{currentWorkspace?.name[0].toLocaleUpperCase()}
-
{currentWorkspace?.name}
- +
{currentWorkspace?.name[0].toLocaleUpperCase()}
+
{currentWorkspace?.name}
+
{ -
+
+
+ {t('common.userProfile.workspace')} +
{ workspaces.map(workspace => ( -
handleSwitchWorkspace(workspace.id)}> -
{workspace.name[0].toLocaleUpperCase()}
-
{workspace.name}
- {workspace.current && } +
handleSwitchWorkspace(workspace.id)}> +
{workspace.name[0].toLocaleUpperCase()}
+
{workspace.name}
+ {enableBilling && ( +
+ +
+ )}
)) } diff --git a/web/app/components/header/index.tsx b/web/app/components/header/index.tsx index 035cc6fd1e..8f41dee938 100644 --- a/web/app/components/header/index.tsx +++ b/web/app/components/header/index.tsx @@ -16,6 +16,7 @@ import GithubStar from './github-star' import { WorkspaceProvider } from '@/context/workspace-context' import { useAppContext } from '@/context/app-context' import LogoSite from '@/app/components/base/logo/logo-site' +import WorkplaceSelector from '@/app/components/header/account-dropdown/workplace-selector' import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints' import { useProviderContext } from '@/context/provider-context' import { useModalContext } from '@/context/modal-context' @@ -48,7 +49,7 @@ const Header = () => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [selectedSegment]) return ( -
+
{isMobile &&
{ >
} - {!isMobile && <> - + {!isMobile + &&
+ - {enableBilling && ( -
- -
- )} - - } +
/
+
+ + + + {enableBilling && ( +
+ +
+ )} +
+
+ }
{isMobile && (
+
/
{enableBilling && (
@@ -94,9 +103,7 @@ const Header = () => {
- - - +
{(isMobile && isShowNavMenu) && (
diff --git a/web/app/components/header/nav/index.tsx b/web/app/components/header/nav/index.tsx index bfb4324320..de98593ddd 100644 --- a/web/app/components/header/nav/index.tsx +++ b/web/app/components/header/nav/index.tsx @@ -68,7 +68,7 @@ const Nav = ({ { curNav && isActivated && ( <> -
/
+
/
Jb&5UhoO1A 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 T*BNv-00000NkvXXu0mjf=atdo literal 0 HcmV?d00001 From bbca7088328cf167af283b481dee93b34a16cc8b Mon Sep 17 00:00:00 2001 From: StyleZhang Date: Tue, 24 Sep 2024 11:18:34 +0800 Subject: [PATCH 004/346] add marketplace card --- web/app/components/plugins/card.tsx | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 web/app/components/plugins/card.tsx diff --git a/web/app/components/plugins/card.tsx b/web/app/components/plugins/card.tsx new file mode 100644 index 0000000000..b7710a2ba5 --- /dev/null +++ b/web/app/components/plugins/card.tsx @@ -0,0 +1,24 @@ +const Card = () => { + return ( +
+
+
+
+
+ Notion Page Search +
+
+ Notion +
/
+ notion-page-search +
+
+
+
+ Search Notion pages and open visited ones faster. No admin access required. +
+
+ ) +} + +export default Card From cb4875a3a79f8c43791c8bfb3f66bc3c9fbfb190 Mon Sep 17 00:00:00 2001 From: Joel Date: Thu, 26 Sep 2024 15:06:36 +0800 Subject: [PATCH 005/346] chore: split the common tailwind config --- web/tailwind-common-config.ts | 97 +++++++++++++++++++++++++++++++++++ web/tailwind.config.js | 94 +-------------------------------- 2 files changed, 99 insertions(+), 92 deletions(-) create mode 100644 web/tailwind-common-config.ts diff --git a/web/tailwind-common-config.ts b/web/tailwind-common-config.ts new file mode 100644 index 0000000000..07721b3e48 --- /dev/null +++ b/web/tailwind-common-config.ts @@ -0,0 +1,97 @@ +import tailwindThemeVarDefine from './themes/tailwind-theme-var-define' + +const config = { + theme: { + typography: require('./typography'), + extend: { + colors: { + gray: { + 25: '#fcfcfd', + 50: '#f9fafb', + 100: '#f2f4f7', + 200: '#eaecf0', + 300: '#d0d5dd', + 400: '#98a2b3', + 500: '#667085', + 700: '#475467', + 600: '#344054', + 800: '#1d2939', + 900: '#101828', + }, + primary: { + 25: '#f5f8ff', + 50: '#eff4ff', + 100: '#d1e0ff', + 200: '#b2ccff', + 300: '#84adff', + 400: '#528bff', + 500: '#2970ff', + 600: '#155eef', + 700: '#004eeb', + 800: '#0040c1', + 900: '#00359e', + }, + blue: { + 500: '#E1EFFE', + }, + green: { + 50: '#F3FAF7', + 100: '#DEF7EC', + 800: '#03543F', + + }, + yellow: { + 100: '#FDF6B2', + 800: '#723B13', + }, + purple: { + 50: '#F6F5FF', + 200: '#DCD7FE', + }, + indigo: { + 25: '#F5F8FF', + 50: '#EEF4FF', + 100: '#E0EAFF', + 300: '#A4BCFD', + 400: '#8098F9', + 600: '#444CE7', + 800: '#2D31A6', + }, + ...tailwindThemeVarDefine, + }, + screens: { + mobile: '100px', + // => @media (min-width: 100px) { ... } + tablet: '640px', // 391 + // => @media (min-width: 600px) { ... } + pc: '769px', + // => @media (min-width: 769px) { ... } + }, + boxShadow: { + 'xs': '0px 1px 2px 0px rgba(16, 24, 40, 0.05)', + 'sm': '0px 1px 2px 0px rgba(16, 24, 40, 0.06), 0px 1px 3px 0px rgba(16, 24, 40, 0.10)', + 'md': '0px 2px 4px -2px rgba(16, 24, 40, 0.06), 0px 4px 8px -2px rgba(16, 24, 40, 0.10)', + 'lg': '0px 4px 6px -2px rgba(16, 24, 40, 0.03), 0px 12px 16px -4px rgba(16, 24, 40, 0.08)', + 'xl': '0px 8px 8px -4px rgba(16, 24, 40, 0.03), 0px 20px 24px -4px rgba(16, 24, 40, 0.08)', + '2xl': '0px 24px 48px -12px rgba(16, 24, 40, 0.18)', + '3xl': '0px 32px 64px -12px rgba(16, 24, 40, 0.14)', + }, + opacity: { + 2: '0.02', + 8: '0.08', + }, + fontSize: { + '2xs': '0.625rem', + }, + }, + }, + plugins: [ + require('@tailwindcss/typography'), + ], + // https://github.com/tailwindlabs/tailwindcss/discussions/5969 + corePlugins: { + preflight: false, + }, +} + +export default config diff --git a/web/tailwind.config.js b/web/tailwind.config.js index ad62e74fa6..f92c1f7aee 100644 --- a/web/tailwind.config.js +++ b/web/tailwind.config.js @@ -1,100 +1,10 @@ /** @type {import('tailwindcss').Config} */ -import tailwindThemeVarDefine from './themes/tailwind-theme-var-define' +import commonConfig from './tailwind.common.config'; module.exports = { content: [ './app/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}', './context/**/*.{js,ts,jsx,tsx}', ], - theme: { - typography: require('./typography'), - extend: { - colors: { - gray: { - 25: '#fcfcfd', - 50: '#f9fafb', - 100: '#f2f4f7', - 200: '#eaecf0', - 300: '#d0d5dd', - 400: '#98a2b3', - 500: '#667085', - 700: '#475467', - 600: '#344054', - 800: '#1d2939', - 900: '#101828', - }, - primary: { - 25: '#f5f8ff', - 50: '#eff4ff', - 100: '#d1e0ff', - 200: '#b2ccff', - 300: '#84adff', - 400: '#528bff', - 500: '#2970ff', - 600: '#155eef', - 700: '#004eeb', - 800: '#0040c1', - 900: '#00359e', - }, - blue: { - 500: '#E1EFFE', - }, - green: { - 50: '#F3FAF7', - 100: '#DEF7EC', - 800: '#03543F', - - }, - yellow: { - 100: '#FDF6B2', - 800: '#723B13', - }, - purple: { - 50: '#F6F5FF', - 200: '#DCD7FE', - }, - indigo: { - 25: '#F5F8FF', - 50: '#EEF4FF', - 100: '#E0EAFF', - 300: '#A4BCFD', - 400: '#8098F9', - 600: '#444CE7', - 800: '#2D31A6', - }, - ...tailwindThemeVarDefine, - }, - screens: { - mobile: '100px', - // => @media (min-width: 100px) { ... } - tablet: '640px', // 391 - // => @media (min-width: 600px) { ... } - pc: '769px', - // => @media (min-width: 769px) { ... } - }, - boxShadow: { - 'xs': '0px 1px 2px 0px rgba(16, 24, 40, 0.05)', - 'sm': '0px 1px 2px 0px rgba(16, 24, 40, 0.06), 0px 1px 3px 0px rgba(16, 24, 40, 0.10)', - 'md': '0px 2px 4px -2px rgba(16, 24, 40, 0.06), 0px 4px 8px -2px rgba(16, 24, 40, 0.10)', - 'lg': '0px 4px 6px -2px rgba(16, 24, 40, 0.03), 0px 12px 16px -4px rgba(16, 24, 40, 0.08)', - 'xl': '0px 8px 8px -4px rgba(16, 24, 40, 0.03), 0px 20px 24px -4px rgba(16, 24, 40, 0.08)', - '2xl': '0px 24px 48px -12px rgba(16, 24, 40, 0.18)', - '3xl': '0px 32px 64px -12px rgba(16, 24, 40, 0.14)', - }, - opacity: { - 2: '0.02', - 8: '0.08', - }, - fontSize: { - '2xs': '0.625rem', - }, - }, - }, - plugins: [ - require('@tailwindcss/typography'), - ], - // https://github.com/tailwindlabs/tailwindcss/discussions/5969 - corePlugins: { - preflight: false, - }, + ...commonConfig, } From cef1010cb535d95fa14b1a94359620546b4c1a74 Mon Sep 17 00:00:00 2001 From: JzoNg Date: Tue, 24 Sep 2024 13:32:08 +0800 Subject: [PATCH 006/346] style update --- .../components/header/account-setting/index.module.css | 8 -------- web/app/components/header/account-setting/index.tsx | 3 +-- 2 files changed, 1 insertion(+), 10 deletions(-) delete mode 100644 web/app/components/header/account-setting/index.module.css diff --git a/web/app/components/header/account-setting/index.module.css b/web/app/components/header/account-setting/index.module.css deleted file mode 100644 index bb855e1c86..0000000000 --- a/web/app/components/header/account-setting/index.module.css +++ /dev/null @@ -1,8 +0,0 @@ -.modal { - max-width: 1024px !important; - border-radius: 12px !important; - margin-top: 60px; - margin-bottom: 60px; - padding: 0 !important; - overflow-y: auto; -} \ No newline at end of file diff --git a/web/app/components/header/account-setting/index.tsx b/web/app/components/header/account-setting/index.tsx index 253b9f1b4c..c8f757de28 100644 --- a/web/app/components/header/account-setting/index.tsx +++ b/web/app/components/header/account-setting/index.tsx @@ -28,7 +28,6 @@ import LanguagePage from './language-page' import ApiBasedExtensionPage from './api-based-extension-page' import DataSourcePage from './data-source-page' import ModelProviderPage from './model-provider-page' -import s from './index.module.css' import cn from '@/utils/classnames' import BillingPage from '@/app/components/billing/billing-page' import CustomPage from '@/app/components/custom/custom-page' @@ -166,7 +165,7 @@ export default function AccountSetting({ { }} - className={s.modal} + className='my-[60px] p-0 max-w-[1024px] rounded-xl overflow-y-auto' wrapperClassName='pt-[60px]' >
From f9c48e9ea906d5bd47e4c2d9306222851875cff9 Mon Sep 17 00:00:00 2001 From: Joel Date: Sun, 29 Sep 2024 18:27:26 +0800 Subject: [PATCH 007/346] fix: eslint to find top dir --- web/.eslintrc.json | 3 ++- web/app/(commonLayout)/plugins/page.tsx | 11 ++++++++++- web/app/components/plugins/list-item-for-test.tsx | 15 +++++++++++++++ web/tailwind.config.js | 8 +++++--- 4 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 web/app/components/plugins/list-item-for-test.tsx diff --git a/web/.eslintrc.json b/web/.eslintrc.json index 53308105b6..5194d73c63 100644 --- a/web/.eslintrc.json +++ b/web/.eslintrc.json @@ -1,4 +1,5 @@ { + "root": true, "extends": [ "next", "@antfu" @@ -27,4 +28,4 @@ "react-hooks/exhaustive-deps": "warn", "react/display-name": "warn" } -} +} \ No newline at end of file diff --git a/web/app/(commonLayout)/plugins/page.tsx b/web/app/(commonLayout)/plugins/page.tsx index c50b3ad9a2..e7a5f1d022 100644 --- a/web/app/(commonLayout)/plugins/page.tsx +++ b/web/app/(commonLayout)/plugins/page.tsx @@ -1,8 +1,17 @@ import Container from './Container' +import ListItem from '@/app/components/plugins/list-item-for-test' const PluginList = async () => { + const mockList = ['Plugin 1', 'Plugin 2', 'Plugin 3'] return ( - + <> + +
+ {mockList.map(item => ( + + ))} +
+ ) } diff --git a/web/app/components/plugins/list-item-for-test.tsx b/web/app/components/plugins/list-item-for-test.tsx new file mode 100644 index 0000000000..a0b7101f02 --- /dev/null +++ b/web/app/components/plugins/list-item-for-test.tsx @@ -0,0 +1,15 @@ +import React from 'react' + +type ListItemProps = { + text: string +} + +const ListItem: React.FC = ({ text }) => { + return ( +
+

{text}

+
+ ) +} + +export default ListItem diff --git a/web/tailwind.config.js b/web/tailwind.config.js index f92c1f7aee..a9959e7b76 100644 --- a/web/tailwind.config.js +++ b/web/tailwind.config.js @@ -1,6 +1,6 @@ -/** @type {import('tailwindcss').Config} */ -import commonConfig from './tailwind.common.config'; -module.exports = { +// import type { Config } from 'tailwindcss' +import commonConfig from './tailwind-common-config' +const config = { content: [ './app/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}', @@ -8,3 +8,5 @@ module.exports = { ], ...commonConfig, } + +export default config From 36f8b5711d1c812c8ee3a216df6350141bf8f010 Mon Sep 17 00:00:00 2001 From: Joel Date: Mon, 30 Sep 2024 15:29:53 +0800 Subject: [PATCH 008/346] feat: plugin types --- web/app/components/plugins/types.ts | 47 +++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 web/app/components/plugins/types.ts diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts new file mode 100644 index 0000000000..f01eab6357 --- /dev/null +++ b/web/app/components/plugins/types.ts @@ -0,0 +1,47 @@ +export enum PluginType { + plugin = 'plugin', + model = 'model', + extension = 'Extension', +} + +export type Endpoint = { + 'api_key': { + 'default': null + 'helper': null + 'label': { + 'en_US': string + 'zh_Hans': string + } + 'name': '' + 'options': null + 'placeholder': { + 'en_US': string + 'zh_Hans': string + } + 'required': true + 'scope': null + 'type': string + 'url': null + } +} + +export type Plugin = { + 'type': PluginType + 'org': string + 'name': string + 'latest_version': string + 'icon': string + 'label': { + 'en_US': string + 'zh_Hans': string + } + 'brief': { + 'en_US': string + 'zh_Hans': string + } + // Repo readme.md content + 'introduction': string + 'repository': string + 'category': string + 'endpoint': Endpoint +} From cd03795f2c98833cf07f4704f655b21cea882883 Mon Sep 17 00:00:00 2001 From: Joel Date: Tue, 8 Oct 2024 15:44:52 +0800 Subject: [PATCH 009/346] chore: add endpoint types --- web/app/components/plugins/types.ts | 28 ++++++---------------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts index f01eab6357..47eb6331c0 100644 --- a/web/app/components/plugins/types.ts +++ b/web/app/components/plugins/types.ts @@ -1,30 +1,11 @@ +import type { CredentialFormSchemaBase } from '../header/account-setting/model-provider-page/declarations' + export enum PluginType { plugin = 'plugin', model = 'model', extension = 'Extension', } -export type Endpoint = { - 'api_key': { - 'default': null - 'helper': null - 'label': { - 'en_US': string - 'zh_Hans': string - } - 'name': '' - 'options': null - 'placeholder': { - 'en_US': string - 'zh_Hans': string - } - 'required': true - 'scope': null - 'type': string - 'url': null - } -} - export type Plugin = { 'type': PluginType 'org': string @@ -43,5 +24,8 @@ export type Plugin = { 'introduction': string 'repository': string 'category': string - 'endpoint': Endpoint + 'install_count': number + 'endpoint': { + settings: CredentialFormSchemaBase[] + } } From 58a913b09d55445e6a290a2aaaef14056ae87cb7 Mon Sep 17 00:00:00 2001 From: StyleZhang Date: Tue, 8 Oct 2024 17:57:46 +0800 Subject: [PATCH 010/346] marketplace --- .../components/plugins/marketplace/index.tsx | 35 +++++ .../plugins/marketplace/search-box/index.tsx | 50 +++++++ .../marketplace/search-box/tags-filter.tsx | 135 ++++++++++++++++++ 3 files changed, 220 insertions(+) create mode 100644 web/app/components/plugins/marketplace/index.tsx create mode 100644 web/app/components/plugins/marketplace/search-box/index.tsx create mode 100644 web/app/components/plugins/marketplace/search-box/tags-filter.tsx diff --git a/web/app/components/plugins/marketplace/index.tsx b/web/app/components/plugins/marketplace/index.tsx new file mode 100644 index 0000000000..f35f455618 --- /dev/null +++ b/web/app/components/plugins/marketplace/index.tsx @@ -0,0 +1,35 @@ +import SearchBox from './search-box' + +const Marketplace = () => { + return ( +
+

+ Empower your AI development +

+

+ Discover + + models + + , + + tools + + , + + extensions + + and + + bundles + + in Dify Marketplace +

+
+ {}} /> +
+
+ ) +} + +export default Marketplace diff --git a/web/app/components/plugins/marketplace/search-box/index.tsx b/web/app/components/plugins/marketplace/search-box/index.tsx new file mode 100644 index 0000000000..e29256b555 --- /dev/null +++ b/web/app/components/plugins/marketplace/search-box/index.tsx @@ -0,0 +1,50 @@ +'use client' +import { + useCallback, + useState, +} from 'react' +import { RiCloseLine } from '@remixicon/react' +import TagsFilter from './tags-filter' +import ActionButton from '@/app/components/base/action-button' + +type SearchBoxProps = { + onChange: (searchText: string, tags: string[]) => void +} +const SearchBox = ({ + onChange, +}: SearchBoxProps) => { + const [searchText, setSearchText] = useState('') + const [selectedTags, setSelectedTags] = useState([]) + + const handleTagsChange = useCallback((tags: string[]) => { + setSelectedTags(tags) + onChange(searchText, tags) + }, [searchText, onChange]) + + return ( +
+ +
+
+
+ { + setSearchText(e.target.value) + onChange(e.target.value, selectedTags) + }} + /> + setSearchText('')}> + + +
+
+
+ ) +} + +export default SearchBox diff --git a/web/app/components/plugins/marketplace/search-box/tags-filter.tsx b/web/app/components/plugins/marketplace/search-box/tags-filter.tsx new file mode 100644 index 0000000000..1615478af6 --- /dev/null +++ b/web/app/components/plugins/marketplace/search-box/tags-filter.tsx @@ -0,0 +1,135 @@ +'use client' + +import { useState } from 'react' +import { + RiArrowDownSLine, + RiCloseCircleFill, + RiFilter3Line, + RiSearchLine, +} from '@remixicon/react' +import { + PortalToFollowElem, + PortalToFollowElemContent, + PortalToFollowElemTrigger, +} from '@/app/components/base/portal-to-follow-elem' +import Checkbox from '@/app/components/base/checkbox' +import cn from '@/utils/classnames' + +type TagsFilterProps = { + value: string[] + onChange: (tags: string[]) => void +} +const TagsFilter = ({ + value, + onChange, +}: TagsFilterProps) => { + const [open, setOpen] = useState(false) + const [searchText, setSearchText] = useState('') + const options = [ + { + value: 'search', + text: 'Search', + }, + { + value: 'image', + text: 'Image', + }, + ] + const filteredOptions = options.filter(option => option.text.toLowerCase().includes(searchText.toLowerCase())) + const handleCheck = (id: string) => { + if (value.includes(id)) + onChange(value.filter(tag => tag !== id)) + else + onChange([...value, id]) + } + const selectedTagsLength = value.length + + return ( + + setOpen(v => !v)}> +
+
+ +
+
+ { + !selectedTagsLength && 'All Tags' + } + { + !!selectedTagsLength && value.slice(0, 2).join(',') + } + { + selectedTagsLength > 2 && ( +
+ +{selectedTagsLength - 2} +
+ ) + } +
+ { + !!selectedTagsLength && ( + onChange([])} + /> + ) + } + { + !selectedTagsLength && ( + + ) + } +
+
+ +
+
+
+ + setSearchText(e.target.value)} + /> +
+
+
+ { + filteredOptions.map(option => ( +
+ handleCheck(option.value)} + /> +
+ {option.text} +
+
+ )) + } +
+
+
+
+ ) +} + +export default TagsFilter From 7a43f48c95d56850ff90acf5bb3c7f174c15c066 Mon Sep 17 00:00:00 2001 From: Joel Date: Wed, 9 Oct 2024 11:35:07 +0800 Subject: [PATCH 011/346] chore: add test page --- web/app/(commonLayout)/plugins/page.tsx | 7 ------- web/app/(commonLayout)/plugins/test/card/page.tsx | 14 ++++++++++++++ web/app/components/plugins/list-item-for-test.tsx | 15 --------------- 3 files changed, 14 insertions(+), 22 deletions(-) create mode 100644 web/app/(commonLayout)/plugins/test/card/page.tsx delete mode 100644 web/app/components/plugins/list-item-for-test.tsx diff --git a/web/app/(commonLayout)/plugins/page.tsx b/web/app/(commonLayout)/plugins/page.tsx index e7a5f1d022..5c22853fcd 100644 --- a/web/app/(commonLayout)/plugins/page.tsx +++ b/web/app/(commonLayout)/plugins/page.tsx @@ -1,16 +1,9 @@ import Container from './Container' -import ListItem from '@/app/components/plugins/list-item-for-test' const PluginList = async () => { - const mockList = ['Plugin 1', 'Plugin 2', 'Plugin 3'] return ( <> -
- {mockList.map(item => ( - - ))} -
) } diff --git a/web/app/(commonLayout)/plugins/test/card/page.tsx b/web/app/(commonLayout)/plugins/test/card/page.tsx new file mode 100644 index 0000000000..4c849c41ef --- /dev/null +++ b/web/app/(commonLayout)/plugins/test/card/page.tsx @@ -0,0 +1,14 @@ +import Card from '@/app/components/plugins/card' +const PluginList = async () => { + return ( + <> + + + ) +} + +export const metadata = { + title: 'Plugins - Card', +} + +export default PluginList diff --git a/web/app/components/plugins/list-item-for-test.tsx b/web/app/components/plugins/list-item-for-test.tsx deleted file mode 100644 index a0b7101f02..0000000000 --- a/web/app/components/plugins/list-item-for-test.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import React from 'react' - -type ListItemProps = { - text: string -} - -const ListItem: React.FC = ({ text }) => { - return ( -
-

{text}

-
- ) -} - -export default ListItem From 43f87c0b864c5f8983672fb8a0b0d5697ee014e3 Mon Sep 17 00:00:00 2001 From: Yi Date: Wed, 9 Oct 2024 12:53:43 +0800 Subject: [PATCH 012/346] make the drop plugin only appears when the user selects "plugins" --- web/app/(commonLayout)/plugins/Container.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/web/app/(commonLayout)/plugins/Container.tsx b/web/app/(commonLayout)/plugins/Container.tsx index 5fee5354a2..58d996e7de 100644 --- a/web/app/(commonLayout)/plugins/Container.tsx +++ b/web/app/(commonLayout)/plugins/Container.tsx @@ -29,7 +29,7 @@ const Container = () => { }, [t]) const [activeTab, setActiveTab] = useTabSearchParams({ - defaultTab: 'plugins', + defaultTab: options[0].value, }) const containerRef = useRef(null) @@ -45,7 +45,7 @@ const Container = () => {
setActiveTab(newActiveTab)} + onChange={setActiveTab} options={options} />
@@ -108,10 +108,10 @@ const Container = () => {
{/* Plugin cards go here */}
-
+ {activeTab === 'plugins' &&
Drop plugin package here to install -
+
}
) } From b5edc64b2ab718ebbd6251b74fb117e87753067b Mon Sep 17 00:00:00 2001 From: StyleZhang Date: Wed, 9 Oct 2024 15:06:09 +0800 Subject: [PATCH 013/346] plugin type switch --- web/app/(commonLayout)/plugins/Container.tsx | 38 +++++++---- .../components/plugins/marketplace/index.tsx | 54 ++++++++------- .../marketplace/plugin-type-switch.tsx | 67 +++++++++++++++++++ .../plugins/marketplace/search-box/index.tsx | 10 ++- 4 files changed, 128 insertions(+), 41 deletions(-) create mode 100644 web/app/components/plugins/marketplace/plugin-type-switch.tsx diff --git a/web/app/(commonLayout)/plugins/Container.tsx b/web/app/(commonLayout)/plugins/Container.tsx index 58d996e7de..7adf0405b3 100644 --- a/web/app/(commonLayout)/plugins/Container.tsx +++ b/web/app/(commonLayout)/plugins/Container.tsx @@ -16,6 +16,7 @@ import Button from '@/app/components/base/button' import TabSlider from '@/app/components/base/tab-slider' import ActionButton from '@/app/components/base/action-button' import Tooltip from '@/app/components/base/tooltip' +import Marketplace from '@/app/components/plugins/marketplace' const Container = () => { const { t } = useTranslation() @@ -99,19 +100,30 @@ const Container = () => {
-
-
-
- {/* Filter goes here */} -
-
-
- {/* Plugin cards go here */} -
- {activeTab === 'plugins' &&
- - Drop plugin package here to install -
} + { + activeTab === 'plugins' && ( + <> +
+
+
+ {/* Filter goes here */} +
+
+
+ {/* Plugin cards go here */} +
+
+ + Drop plugin package here to install +
+ + ) + } + { + activeTab === 'discover' && ( + + ) + }
) } diff --git a/web/app/components/plugins/marketplace/index.tsx b/web/app/components/plugins/marketplace/index.tsx index f35f455618..a9a45159a8 100644 --- a/web/app/components/plugins/marketplace/index.tsx +++ b/web/app/components/plugins/marketplace/index.tsx @@ -1,32 +1,36 @@ import SearchBox from './search-box' +import PluginTypeSwitch from './plugin-type-switch' const Marketplace = () => { return ( -
-

- Empower your AI development -

-

- Discover - - models - - , - - tools - - , - - extensions - - and - - bundles - - in Dify Marketplace -

-
- {}} /> +
+
+

+ Empower your AI development +

+

+ Discover + + models + + , + + tools + + , + + extensions + + and + + bundles + + in Dify Marketplace +

+
+ {}} /> +
+ {}} />
) diff --git a/web/app/components/plugins/marketplace/plugin-type-switch.tsx b/web/app/components/plugins/marketplace/plugin-type-switch.tsx new file mode 100644 index 0000000000..3793e463f7 --- /dev/null +++ b/web/app/components/plugins/marketplace/plugin-type-switch.tsx @@ -0,0 +1,67 @@ +import { useState } from 'react' +import { + RiHammerLine, + RiPuzzle2Line, +} from '@remixicon/react' +import cn from '@/utils/classnames' + +type PluginTypeSwitchProps = { + onChange: (type: string) => void +} +const options = [ + { + value: 'all', + text: 'All', + icon: null, + }, + { + value: 'models', + text: 'Models', + icon: null, + }, + { + value: 'tools', + text: 'Tools', + icon: , + }, + { + value: 'extensions', + text: 'Extensions', + icon: , + }, + { + value: 'bundles', + text: 'Bundles', + icon: null, + }, +] +const PluginTypeSwitch = ({ + onChange, +}: PluginTypeSwitchProps) => { + const [activeType, setActiveType] = useState('all') + + return ( +
+ { + options.map(option => ( +
{ + setActiveType(option.value) + onChange(option.value) + }} + > + {option.icon} + {option.text} +
+ )) + } +
+ ) +} + +export default PluginTypeSwitch diff --git a/web/app/components/plugins/marketplace/search-box/index.tsx b/web/app/components/plugins/marketplace/search-box/index.tsx index e29256b555..1addb4cdd5 100644 --- a/web/app/components/plugins/marketplace/search-box/index.tsx +++ b/web/app/components/plugins/marketplace/search-box/index.tsx @@ -38,9 +38,13 @@ const SearchBox = ({ onChange(e.target.value, selectedTags) }} /> - setSearchText('')}> - - + { + searchText && ( + setSearchText('')}> + + + ) + }
From 67acd174ac7068e1864794663a03a2159ccffec0 Mon Sep 17 00:00:00 2001 From: Yi Date: Wed, 9 Oct 2024 15:55:33 +0800 Subject: [PATCH 014/346] add different styles to plugins and discover --- web/app/(commonLayout)/plugins/Container.tsx | 7 +++++-- web/app/components/plugins/marketplace/index.tsx | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/web/app/(commonLayout)/plugins/Container.tsx b/web/app/(commonLayout)/plugins/Container.tsx index 7adf0405b3..f6d9c9a700 100644 --- a/web/app/(commonLayout)/plugins/Container.tsx +++ b/web/app/(commonLayout)/plugins/Container.tsx @@ -17,6 +17,7 @@ import TabSlider from '@/app/components/base/tab-slider' import ActionButton from '@/app/components/base/action-button' import Tooltip from '@/app/components/base/tooltip' import Marketplace from '@/app/components/plugins/marketplace' +import cn from '@/utils/classnames' const Container = () => { const { t } = useTranslation() @@ -38,8 +39,10 @@ const Container = () => { return (
diff --git a/web/app/components/plugins/marketplace/index.tsx b/web/app/components/plugins/marketplace/index.tsx index a9a45159a8..740d1e35b7 100644 --- a/web/app/components/plugins/marketplace/index.tsx +++ b/web/app/components/plugins/marketplace/index.tsx @@ -3,8 +3,8 @@ import PluginTypeSwitch from './plugin-type-switch' const Marketplace = () => { return ( -
-
+
+

Empower your AI development

From 36800eeaba3084ccd76856e1233c91d4366375f7 Mon Sep 17 00:00:00 2001 From: Joel Date: Wed, 9 Oct 2024 17:50:23 +0800 Subject: [PATCH 015/346] feat: base card component --- .../(commonLayout)/plugins/test/card/page.tsx | 10 +- .../assets/vender/plugin/left-corner.svg | 3 + .../files/{Unknown.json => Unknow.json} | 2 +- .../public/files/{Unknown.tsx => Unknow.tsx} | 4 +- .../base/icons/src/public/files/index.ts | 2 +- .../icons/src/vender/plugin/LeftCorner.json | 27 ++++ .../CuteRobot.tsx => plugin/LeftCorner.tsx} | 4 +- .../base/icons/src/vender/plugin/index.ts | 1 + .../{CuteRobot.json => CuteRobote.json} | 2 +- .../vender/solid/communication/CuteRobote.tsx | 16 ++ .../src/vender/solid/communication/index.ts | 2 +- web/app/components/plugins/card-mock.ts | 49 ++++++ web/app/components/plugins/card.tsx | 144 ++++++++++++++++-- web/app/components/plugins/types.ts | 15 +- 14 files changed, 247 insertions(+), 34 deletions(-) create mode 100644 web/app/components/base/icons/assets/vender/plugin/left-corner.svg rename web/app/components/base/icons/src/public/files/{Unknown.json => Unknow.json} (99%) rename web/app/components/base/icons/src/public/files/{Unknown.tsx => Unknow.tsx} (87%) create mode 100644 web/app/components/base/icons/src/vender/plugin/LeftCorner.json rename web/app/components/base/icons/src/vender/{solid/communication/CuteRobot.tsx => plugin/LeftCorner.tsx} (86%) create mode 100644 web/app/components/base/icons/src/vender/plugin/index.ts rename web/app/components/base/icons/src/vender/solid/communication/{CuteRobot.json => CuteRobote.json} (98%) create mode 100644 web/app/components/base/icons/src/vender/solid/communication/CuteRobote.tsx create mode 100644 web/app/components/plugins/card-mock.ts diff --git a/web/app/(commonLayout)/plugins/test/card/page.tsx b/web/app/(commonLayout)/plugins/test/card/page.tsx index 4c849c41ef..ac85164412 100644 --- a/web/app/(commonLayout)/plugins/test/card/page.tsx +++ b/web/app/(commonLayout)/plugins/test/card/page.tsx @@ -1,8 +1,16 @@ import Card from '@/app/components/plugins/card' +import { extensionDallE, modelGPT4, toolNotion } from '@/app/components/plugins/card-mock' + const PluginList = async () => { return ( <> - +
+ + + + + +
) } diff --git a/web/app/components/base/icons/assets/vender/plugin/left-corner.svg b/web/app/components/base/icons/assets/vender/plugin/left-corner.svg new file mode 100644 index 0000000000..9b360e4be7 --- /dev/null +++ b/web/app/components/base/icons/assets/vender/plugin/left-corner.svg @@ -0,0 +1,3 @@ + + + diff --git a/web/app/components/base/icons/src/public/files/Unknown.json b/web/app/components/base/icons/src/public/files/Unknow.json similarity index 99% rename from web/app/components/base/icons/src/public/files/Unknown.json rename to web/app/components/base/icons/src/public/files/Unknow.json index c39df990d0..33067fa96f 100644 --- a/web/app/components/base/icons/src/public/files/Unknown.json +++ b/web/app/components/base/icons/src/public/files/Unknow.json @@ -195,5 +195,5 @@ } ] }, - "name": "Unknown" + "name": "Unknow" } \ No newline at end of file diff --git a/web/app/components/base/icons/src/public/files/Unknown.tsx b/web/app/components/base/icons/src/public/files/Unknow.tsx similarity index 87% rename from web/app/components/base/icons/src/public/files/Unknown.tsx rename to web/app/components/base/icons/src/public/files/Unknow.tsx index de909ed65e..ce84d344bf 100644 --- a/web/app/components/base/icons/src/public/files/Unknown.tsx +++ b/web/app/components/base/icons/src/public/files/Unknow.tsx @@ -2,7 +2,7 @@ // DON NOT EDIT IT MANUALLY import * as React from 'react' -import data from './Unknown.json' +import data from './Unknow.json' import IconBase from '@/app/components/base/icons/IconBase' import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase' @@ -11,6 +11,6 @@ const Icon = React.forwardRef, Omit ) -Icon.displayName = 'Unknown' +Icon.displayName = 'Unknow' export default Icon diff --git a/web/app/components/base/icons/src/public/files/index.ts b/web/app/components/base/icons/src/public/files/index.ts index f38c28cbdb..2814c4ae39 100644 --- a/web/app/components/base/icons/src/public/files/index.ts +++ b/web/app/components/base/icons/src/public/files/index.ts @@ -6,6 +6,6 @@ export { default as Json } from './Json' export { default as Md } from './Md' export { default as Pdf } from './Pdf' export { default as Txt } from './Txt' -export { default as Unknown } from './Unknown' +export { default as Unknow } from './Unknow' export { default as Xlsx } from './Xlsx' export { default as Yaml } from './Yaml' diff --git a/web/app/components/base/icons/src/vender/plugin/LeftCorner.json b/web/app/components/base/icons/src/vender/plugin/LeftCorner.json new file mode 100644 index 0000000000..d4cd0cd0ec --- /dev/null +++ b/web/app/components/base/icons/src/vender/plugin/LeftCorner.json @@ -0,0 +1,27 @@ +{ + "icon": { + "type": "element", + "isRootNode": true, + "name": "svg", + "attributes": { + "width": "13", + "height": "20", + "viewBox": "0 0 13 20", + "fill": "none", + "xmlns": "http://www.w3.org/2000/svg" + }, + "children": [ + { + "type": "element", + "name": "path", + "attributes": { + "id": "Shape", + "d": "M0 0H13V20C9.98017 20 7.26458 18.1615 6.14305 15.3576L0 0Z", + "fill": "currentColor" + }, + "children": [] + } + ] + }, + "name": "LeftCorner" +} \ No newline at end of file diff --git a/web/app/components/base/icons/src/vender/solid/communication/CuteRobot.tsx b/web/app/components/base/icons/src/vender/plugin/LeftCorner.tsx similarity index 86% rename from web/app/components/base/icons/src/vender/solid/communication/CuteRobot.tsx rename to web/app/components/base/icons/src/vender/plugin/LeftCorner.tsx index 49994048b7..dd215b9bf7 100644 --- a/web/app/components/base/icons/src/vender/solid/communication/CuteRobot.tsx +++ b/web/app/components/base/icons/src/vender/plugin/LeftCorner.tsx @@ -2,7 +2,7 @@ // DON NOT EDIT IT MANUALLY import * as React from 'react' -import data from './CuteRobot.json' +import data from './LeftCorner.json' import IconBase from '@/app/components/base/icons/IconBase' import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase' @@ -11,6 +11,6 @@ const Icon = React.forwardRef, Omit ) -Icon.displayName = 'CuteRobot' +Icon.displayName = 'LeftCorner' export default Icon diff --git a/web/app/components/base/icons/src/vender/plugin/index.ts b/web/app/components/base/icons/src/vender/plugin/index.ts new file mode 100644 index 0000000000..6d219fce21 --- /dev/null +++ b/web/app/components/base/icons/src/vender/plugin/index.ts @@ -0,0 +1 @@ +export { default as LeftCorner } from './LeftCorner' diff --git a/web/app/components/base/icons/src/vender/solid/communication/CuteRobot.json b/web/app/components/base/icons/src/vender/solid/communication/CuteRobote.json similarity index 98% rename from web/app/components/base/icons/src/vender/solid/communication/CuteRobot.json rename to web/app/components/base/icons/src/vender/solid/communication/CuteRobote.json index 5b36575f56..389d044a9b 100644 --- a/web/app/components/base/icons/src/vender/solid/communication/CuteRobot.json +++ b/web/app/components/base/icons/src/vender/solid/communication/CuteRobote.json @@ -34,5 +34,5 @@ } ] }, - "name": "CuteRobot" + "name": "CuteRobote" } \ No newline at end of file diff --git a/web/app/components/base/icons/src/vender/solid/communication/CuteRobote.tsx b/web/app/components/base/icons/src/vender/solid/communication/CuteRobote.tsx new file mode 100644 index 0000000000..d416fb5b66 --- /dev/null +++ b/web/app/components/base/icons/src/vender/solid/communication/CuteRobote.tsx @@ -0,0 +1,16 @@ +// GENERATE BY script +// DON NOT EDIT IT MANUALLY + +import * as React from 'react' +import data from './CuteRobote.json' +import IconBase from '@/app/components/base/icons/IconBase' +import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase' + +const Icon = React.forwardRef, Omit>(( + props, + ref, +) => ) + +Icon.displayName = 'CuteRobote' + +export default Icon diff --git a/web/app/components/base/icons/src/vender/solid/communication/index.ts b/web/app/components/base/icons/src/vender/solid/communication/index.ts index 673de27463..854953c116 100644 --- a/web/app/components/base/icons/src/vender/solid/communication/index.ts +++ b/web/app/components/base/icons/src/vender/solid/communication/index.ts @@ -1,6 +1,6 @@ export { default as AiText } from './AiText' export { default as ChatBot } from './ChatBot' -export { default as CuteRobot } from './CuteRobot' +export { default as CuteRobote } from './CuteRobote' export { default as EditList } from './EditList' export { default as MessageDotsCircle } from './MessageDotsCircle' export { default as MessageFast } from './MessageFast' diff --git a/web/app/components/plugins/card-mock.ts b/web/app/components/plugins/card-mock.ts new file mode 100644 index 0000000000..f054afb855 --- /dev/null +++ b/web/app/components/plugins/card-mock.ts @@ -0,0 +1,49 @@ +import { PluginType } from './types' + +export const toolNotion = { + type: PluginType.tool, + org: 'Notion', + name: 'notion page search', + latest_version: '1.0.0', + icon: 'https://via.placeholder.com/150', + label: { + 'en-US': 'Notion Page Search', + 'zh-Hans': 'Notion 页面搜索', + }, + brief: { + 'en-US': 'Description: Search Notion pages and open visited ones faster. No admin access required.', + 'zh-Hans': '搜索 Notion 页面并更快地打开已访问的页面。无需管理员访问权限。', + }, +} + +export const extensionDallE = { + type: PluginType.extension, + org: 'OpenAI', + name: 'DALL-E', + latest_version: '1.0.0', + icon: 'https://via.placeholder.com/150', + label: { + 'en-US': 'DALL-E', + 'zh-Hans': 'DALL-E', + }, + brief: { + 'en-US': 'Description: A simple plugin to use OpenAI DALL-E model.', + 'zh-Hans': '一个使用 OpenAI DALL-E 模型的简单插件。', + }, +} + +export const modelGPT4 = { + type: PluginType.model, + org: 'OpenAI', + name: 'GPT-4', + latest_version: '1.0.0', + icon: 'https://via.placeholder.com/150', + label: { + 'en-US': 'GPT-4', + 'zh-Hans': 'GPT-4', + }, + brief: { + 'en-US': 'Description: A simple plugin to use OpenAI GPT-4 model.', + 'zh-Hans': '一个使用 OpenAI GPT-4 模型的简单插件。', + }, +} diff --git a/web/app/components/plugins/card.tsx b/web/app/components/plugins/card.tsx index b7710a2ba5..30885961ea 100644 --- a/web/app/components/plugins/card.tsx +++ b/web/app/components/plugins/card.tsx @@ -1,22 +1,136 @@ -const Card = () => { +import React, { useMemo } from 'react' +import { RiVerifiedBadgeLine } from '@remixicon/react' +import type { FC } from 'react' +import { LeftCorner } from '../base/icons/src/vender/plugin' +import type { Plugin } from './types' +import { getLocaleOnServer } from '@/i18n/server' +import cn from '@/utils/classnames' + +export const CornerMark = ({ text }: { text: string }) => { return ( -
-
-
-
-
- Notion Page Search -
-
- Notion -
/
- notion-page-search +
+ +
{text}
+
+ ) +} + +export const Icon = ({ + className, + src, + installed = false, +}: { + className?: string + src: string + installed?: boolean +}) => { + return ( +
+
+ ) +} + +export const Title = ({ + title, +}: { + title: string +}) => { + return ( +
+ {title} +
+ ) +} + +export const OrgInfo = ({ + className, + orgName, + packageName, +}: { + className?: string + orgName: string + packageName: string +}) => { + return
+ {orgName} + / + {packageName} +
+} + +type DescriptionProps = { + className?: string + text: string + descriptionLineRows: number +} + +const Description: FC = ({ + className, + text, + descriptionLineRows, +}) => { + const lineClassName = useMemo(() => { + if (descriptionLineRows === 1) + return 'truncate' + else if (descriptionLineRows === 2) + return 'line-clamp-2' + else + return 'line-clamp-3' + }, [descriptionLineRows]) + return ( +
+ {text} +
+ ) +} + +type Props = { + className?: string + payload: Plugin + installed?: boolean + descriptionLineRows?: number + footer?: React.ReactNode +} + +const Card = ({ + className, + payload, + installed, + descriptionLineRows = 2, + footer, +}: Props) => { + const locale = getLocaleOnServer() + + const { type, name, org, label } = payload + return ( +
+ + {/* Header */} +
+ +
+
+ + <RiVerifiedBadgeLine className="shrink-0 ml-0.5 w-4 h-4 text-text-accent" /> </div> + <OrgInfo + className="mt-0.5" + orgName={org} + packageName={name} + /> </div> </div> - <div className='px-4 pt-1 pb-2 system-xs-regular text-text-tertiary'> - Search Notion pages and open visited ones faster. No admin access required. - </div> + <Description + className="mt-3" + text={payload.brief[locale]} + descriptionLineRows={descriptionLineRows} + /> + {footer && <div>{footer}</div>} </div> ) } diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts index 47eb6331c0..f9b1add725 100644 --- a/web/app/components/plugins/types.ts +++ b/web/app/components/plugins/types.ts @@ -1,9 +1,10 @@ import type { CredentialFormSchemaBase } from '../header/account-setting/model-provider-page/declarations' +import type { Locale } from '@/i18n' export enum PluginType { - plugin = 'plugin', + tool = 'tool', model = 'model', - extension = 'Extension', + extension = 'extension', } export type Plugin = { @@ -12,14 +13,8 @@ export type Plugin = { 'name': string 'latest_version': string 'icon': string - 'label': { - 'en_US': string - 'zh_Hans': string - } - 'brief': { - 'en_US': string - 'zh_Hans': string - } + 'label': Record<Locale, string> + 'brief': Record<Locale, string> // Repo readme.md content 'introduction': string 'repository': string From 6b29860788c742e53c40b2e394ee130fcbba1c8f Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Wed, 9 Oct 2024 18:12:14 +0800 Subject: [PATCH 016/346] feat: add installed --- .../(commonLayout)/plugins/test/card/page.tsx | 35 ++++++++++++++----- web/app/components/plugins/card-mock.ts | 4 +-- web/app/components/plugins/card.tsx | 11 ++++-- 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/web/app/(commonLayout)/plugins/test/card/page.tsx b/web/app/(commonLayout)/plugins/test/card/page.tsx index ac85164412..952660feea 100644 --- a/web/app/(commonLayout)/plugins/test/card/page.tsx +++ b/web/app/(commonLayout)/plugins/test/card/page.tsx @@ -3,15 +3,34 @@ import { extensionDallE, modelGPT4, toolNotion } from '@/app/components/plugins/ const PluginList = async () => { return ( - <> - <div className='mx-3 grid grid-cols-4 gap-3'> - <Card payload={toolNotion as any} /> - <Card payload={extensionDallE as any} /> - <Card payload={modelGPT4 as any} /> - <Card payload={toolNotion as any} /> - <Card payload={toolNotion as any} /> + <div className='pb-3 bg-white'> + <div className='mx-3 '> + <h2 className='my-3'>Dify Plugin list</h2> + <div className='grid grid-cols-4 gap-3'> + <Card payload={toolNotion as any} /> + <Card payload={extensionDallE as any} /> + <Card payload={modelGPT4 as any} /> + <Card payload={toolNotion as any} /> + <Card payload={toolNotion as any} /> + </div> + + <h2 className='my-3'>Install Plugin / Package under bundle</h2> + <div className='w-[512px] rounded-2xl bg-background-section-burn p-2'> + <Card + payload={toolNotion as any} + descriptionLineRows={1} + /> + </div> + <h3 className='my-1'>Installed</h3> + <div className='w-[512px] rounded-2xl bg-background-section-burn p-2'> + <Card + payload={toolNotion as any} + descriptionLineRows={1} + installed + /> + </div> </div> - </> + </div> ) } diff --git a/web/app/components/plugins/card-mock.ts b/web/app/components/plugins/card-mock.ts index f054afb855..27f7fd5386 100644 --- a/web/app/components/plugins/card-mock.ts +++ b/web/app/components/plugins/card-mock.ts @@ -11,8 +11,8 @@ export const toolNotion = { 'zh-Hans': 'Notion 页面搜索', }, brief: { - 'en-US': 'Description: Search Notion pages and open visited ones faster. No admin access required.', - 'zh-Hans': '搜索 Notion 页面并更快地打开已访问的页面。无需管理员访问权限。', + 'en-US': 'Description: Search Notion pages and open visited ones faster. No admin access required.More and more info...More and more info...More and more info...', + 'zh-Hans': '搜索 Notion 页面并更快地打开已访问的页面。无需管理员访问权限。More and more info...More and more info...More and more info...', }, } diff --git a/web/app/components/plugins/card.tsx b/web/app/components/plugins/card.tsx index 30885961ea..291b7b1a84 100644 --- a/web/app/components/plugins/card.tsx +++ b/web/app/components/plugins/card.tsx @@ -1,5 +1,5 @@ import React, { useMemo } from 'react' -import { RiVerifiedBadgeLine } from '@remixicon/react' +import { RiCheckLine, RiVerifiedBadgeLine } from '@remixicon/react' import type { FC } from 'react' import { LeftCorner } from '../base/icons/src/vender/plugin' import type { Plugin } from './types' @@ -31,6 +31,13 @@ export const Icon = ({ backgroundImage: `url(${src})`, }} > + {installed + && <div className='p-0.5 absolute bottom-[-4px] right-[-4px] w-3 h-3 rounded-full bg-white '> + <div className='h-full rounded-full bg-state-success-solid'> + <RiCheckLine className='w-full h-full text-text-primary-on-surface' /> + </div> + </div> + } </div> ) } @@ -108,7 +115,7 @@ const Card = ({ const { type, name, org, label } = payload return ( - <div className={cn('relative p-4 pb-3 border-[0.5px] border-components-panel-border bg-components-panel-on-panel-item-bg hover-bg-components-panel-on-panel-item-bg rounded-xl shadow-xs')}> + <div className={cn('relative p-4 pb-3 border-[0.5px] border-components-panel-border bg-components-panel-on-panel-item-bg hover-bg-components-panel-on-panel-item-bg rounded-xl shadow-xs', className)}> <CornerMark text={type} /> {/* Header */} <div className="flex"> From fa43d4202f9dcc602d4fc57acfc816bfd903d7f7 Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Wed, 9 Oct 2024 18:36:15 +0800 Subject: [PATCH 017/346] feat: plugin item --- .../(commonLayout)/plugins/test/card/page.tsx | 23 +++++-- web/app/components/plugins/card-more-info.tsx | 3 + web/app/components/plugins/card.tsx | 2 +- web/app/components/plugins/plugin-item.tsx | 62 +++++++++++++++++++ 4 files changed, 83 insertions(+), 7 deletions(-) create mode 100644 web/app/components/plugins/card-more-info.tsx create mode 100644 web/app/components/plugins/plugin-item.tsx diff --git a/web/app/(commonLayout)/plugins/test/card/page.tsx b/web/app/(commonLayout)/plugins/test/card/page.tsx index 952660feea..facff918bc 100644 --- a/web/app/(commonLayout)/plugins/test/card/page.tsx +++ b/web/app/(commonLayout)/plugins/test/card/page.tsx @@ -1,17 +1,18 @@ import Card from '@/app/components/plugins/card' import { extensionDallE, modelGPT4, toolNotion } from '@/app/components/plugins/card-mock' +import PluginItem from '@/app/components/plugins/plugin-item' const PluginList = async () => { return ( <div className='pb-3 bg-white'> <div className='mx-3 '> <h2 className='my-3'>Dify Plugin list</h2> - <div className='grid grid-cols-4 gap-3'> - <Card payload={toolNotion as any} /> - <Card payload={extensionDallE as any} /> - <Card payload={modelGPT4 as any} /> - <Card payload={toolNotion as any} /> - <Card payload={toolNotion as any} /> + <div className='grid grid-cols-2 gap-3'> + <PluginItem payload={toolNotion as any} /> + <PluginItem payload={extensionDallE as any} /> + <PluginItem payload={modelGPT4 as any} /> + <PluginItem payload={toolNotion as any} /> + <PluginItem payload={toolNotion as any} /> </div> <h2 className='my-3'>Install Plugin / Package under bundle</h2> @@ -29,6 +30,16 @@ const PluginList = async () => { installed /> </div> + + <div className='my-3 h-[px] bg-gray-50'></div> + <h2 className='my-3'>Marketplace Plugin list</h2> + <div className='grid grid-cols-4 gap-3'> + <Card payload={toolNotion as any} /> + <Card payload={extensionDallE as any} /> + <Card payload={modelGPT4 as any} /> + <Card payload={toolNotion as any} /> + <Card payload={toolNotion as any} /> + </div> </div> </div> ) diff --git a/web/app/components/plugins/card-more-info.tsx b/web/app/components/plugins/card-more-info.tsx new file mode 100644 index 0000000000..b808cecd96 --- /dev/null +++ b/web/app/components/plugins/card-more-info.tsx @@ -0,0 +1,3 @@ +const CardMoreInfo = () => { + +} diff --git a/web/app/components/plugins/card.tsx b/web/app/components/plugins/card.tsx index 291b7b1a84..c3897e22c6 100644 --- a/web/app/components/plugins/card.tsx +++ b/web/app/components/plugins/card.tsx @@ -76,7 +76,7 @@ type DescriptionProps = { descriptionLineRows: number } -const Description: FC<DescriptionProps> = ({ +export const Description: FC<DescriptionProps> = ({ className, text, descriptionLineRows, diff --git a/web/app/components/plugins/plugin-item.tsx b/web/app/components/plugins/plugin-item.tsx new file mode 100644 index 0000000000..d685517ba4 --- /dev/null +++ b/web/app/components/plugins/plugin-item.tsx @@ -0,0 +1,62 @@ +import type { FC } from 'react' +import React from 'react' +import { RiArrowRightUpLine, RiVerifiedBadgeLine } from '@remixicon/react' +import { Github } from '../base/icons/src/public/common' +import type { Plugin } from './types' +import { CornerMark, Description, Icon, OrgInfo, Title } from '@/app/components/plugins/card' +import cn from '@/utils/classnames' +import { getLocaleOnServer } from '@/i18n/server' + +type Props = { + className?: string + payload: Plugin +} + +const PluginItem: FC<Props> = ({ + className, + payload, +}) => { + const locale = getLocaleOnServer() + const { type, name, org, label } = payload + + return ( + <div className='p-1 bg-background-section-burn rounded-xl'> + <div className={cn('relative p-4 pb-3 border-[0.5px] border-components-panel-border bg-components-panel-on-panel-item-bg hover-bg-components-panel-on-panel-item-bg rounded-xl shadow-xs', className)}> + <CornerMark text={type} /> + {/* Header */} + <div className="flex"> + <Icon src={payload.icon} /> + <div className="ml-3 grow"> + <div className="flex items-center h-5"> + <Title title={label[locale]} /> + <RiVerifiedBadgeLine className="shrink-0 ml-0.5 w-4 h-4 text-text-accent" /> + </div> + <Description text={payload.brief[locale]} descriptionLineRows={1}></Description> + </div> + </div> + </div> + <div className='mt-1.5 mb-1 flex justify-between items-center h-4'> + <div className='flex items-center'> + <OrgInfo + className="mt-0.5" + orgName={org} + packageName={name} + /> + <div className='mx-2 text-text-quaternary system-xs-regular'>·</div> + <div className='text-text-tertiary system-xs-regular'>2 sets of endpoints enabled</div> + </div> + + <div className='flex items-center'> + <div className='mr-1 text-text-tertiary system-2xs-medium-uppercase'>From</div> + <div className='flex items-center space-x-0.5 text-text-secondary'> + <Github className='ml-1 w-3 h-3' /> + <div className='system-2xs-semibold-uppercase'>GitHub</div> + <RiArrowRightUpLine className='w-3 h-3' /> + </div> + </div> + </div> + </div> + ) +} + +export default PluginItem From 1d74e693ea0e76a8e2b8730aa6aa13a7d7d6d32a Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Thu, 10 Oct 2024 10:22:18 +0800 Subject: [PATCH 018/346] chore: fix imge name --- .../solid/communication/{cute-robote.svg => cute-robot.svg} | 0 .../solid/communication/{CuteRobote.json => CuteRobot.json} | 2 +- .../solid/communication/{CuteRobote.tsx => CuteRobot.tsx} | 4 ++-- .../base/icons/src/vender/solid/communication/index.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename web/app/components/base/icons/assets/vender/solid/communication/{cute-robote.svg => cute-robot.svg} (100%) rename web/app/components/base/icons/src/vender/solid/communication/{CuteRobote.json => CuteRobot.json} (98%) rename web/app/components/base/icons/src/vender/solid/communication/{CuteRobote.tsx => CuteRobot.tsx} (86%) diff --git a/web/app/components/base/icons/assets/vender/solid/communication/cute-robote.svg b/web/app/components/base/icons/assets/vender/solid/communication/cute-robot.svg similarity index 100% rename from web/app/components/base/icons/assets/vender/solid/communication/cute-robote.svg rename to web/app/components/base/icons/assets/vender/solid/communication/cute-robot.svg diff --git a/web/app/components/base/icons/src/vender/solid/communication/CuteRobote.json b/web/app/components/base/icons/src/vender/solid/communication/CuteRobot.json similarity index 98% rename from web/app/components/base/icons/src/vender/solid/communication/CuteRobote.json rename to web/app/components/base/icons/src/vender/solid/communication/CuteRobot.json index 389d044a9b..5b36575f56 100644 --- a/web/app/components/base/icons/src/vender/solid/communication/CuteRobote.json +++ b/web/app/components/base/icons/src/vender/solid/communication/CuteRobot.json @@ -34,5 +34,5 @@ } ] }, - "name": "CuteRobote" + "name": "CuteRobot" } \ No newline at end of file diff --git a/web/app/components/base/icons/src/vender/solid/communication/CuteRobote.tsx b/web/app/components/base/icons/src/vender/solid/communication/CuteRobot.tsx similarity index 86% rename from web/app/components/base/icons/src/vender/solid/communication/CuteRobote.tsx rename to web/app/components/base/icons/src/vender/solid/communication/CuteRobot.tsx index d416fb5b66..49994048b7 100644 --- a/web/app/components/base/icons/src/vender/solid/communication/CuteRobote.tsx +++ b/web/app/components/base/icons/src/vender/solid/communication/CuteRobot.tsx @@ -2,7 +2,7 @@ // DON NOT EDIT IT MANUALLY import * as React from 'react' -import data from './CuteRobote.json' +import data from './CuteRobot.json' import IconBase from '@/app/components/base/icons/IconBase' import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase' @@ -11,6 +11,6 @@ const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseP ref, ) => <IconBase {...props} ref={ref} data={data as IconData} />) -Icon.displayName = 'CuteRobote' +Icon.displayName = 'CuteRobot' export default Icon diff --git a/web/app/components/base/icons/src/vender/solid/communication/index.ts b/web/app/components/base/icons/src/vender/solid/communication/index.ts index 854953c116..673de27463 100644 --- a/web/app/components/base/icons/src/vender/solid/communication/index.ts +++ b/web/app/components/base/icons/src/vender/solid/communication/index.ts @@ -1,6 +1,6 @@ export { default as AiText } from './AiText' export { default as ChatBot } from './ChatBot' -export { default as CuteRobote } from './CuteRobote' +export { default as CuteRobot } from './CuteRobot' export { default as EditList } from './EditList' export { default as MessageDotsCircle } from './MessageDotsCircle' export { default as MessageFast } from './MessageFast' From ab868ac979eea280a67793d17ea1573c945a75b3 Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Thu, 10 Oct 2024 10:25:25 +0800 Subject: [PATCH 019/346] fix: error igm --- .../icons/assets/public/files/{unknow.svg => unknown.svg} | 0 .../base/icons/src/public/files/{Unknow.json => Unknown.json} | 2 +- .../base/icons/src/public/files/{Unknow.tsx => Unknown.tsx} | 4 ++-- web/app/components/base/icons/src/public/files/index.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename web/app/components/base/icons/assets/public/files/{unknow.svg => unknown.svg} (100%) rename web/app/components/base/icons/src/public/files/{Unknow.json => Unknown.json} (99%) rename web/app/components/base/icons/src/public/files/{Unknow.tsx => Unknown.tsx} (87%) diff --git a/web/app/components/base/icons/assets/public/files/unknow.svg b/web/app/components/base/icons/assets/public/files/unknown.svg similarity index 100% rename from web/app/components/base/icons/assets/public/files/unknow.svg rename to web/app/components/base/icons/assets/public/files/unknown.svg diff --git a/web/app/components/base/icons/src/public/files/Unknow.json b/web/app/components/base/icons/src/public/files/Unknown.json similarity index 99% rename from web/app/components/base/icons/src/public/files/Unknow.json rename to web/app/components/base/icons/src/public/files/Unknown.json index 33067fa96f..c39df990d0 100644 --- a/web/app/components/base/icons/src/public/files/Unknow.json +++ b/web/app/components/base/icons/src/public/files/Unknown.json @@ -195,5 +195,5 @@ } ] }, - "name": "Unknow" + "name": "Unknown" } \ No newline at end of file diff --git a/web/app/components/base/icons/src/public/files/Unknow.tsx b/web/app/components/base/icons/src/public/files/Unknown.tsx similarity index 87% rename from web/app/components/base/icons/src/public/files/Unknow.tsx rename to web/app/components/base/icons/src/public/files/Unknown.tsx index ce84d344bf..de909ed65e 100644 --- a/web/app/components/base/icons/src/public/files/Unknow.tsx +++ b/web/app/components/base/icons/src/public/files/Unknown.tsx @@ -2,7 +2,7 @@ // DON NOT EDIT IT MANUALLY import * as React from 'react' -import data from './Unknow.json' +import data from './Unknown.json' import IconBase from '@/app/components/base/icons/IconBase' import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase' @@ -11,6 +11,6 @@ const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseP ref, ) => <IconBase {...props} ref={ref} data={data as IconData} />) -Icon.displayName = 'Unknow' +Icon.displayName = 'Unknown' export default Icon diff --git a/web/app/components/base/icons/src/public/files/index.ts b/web/app/components/base/icons/src/public/files/index.ts index 2814c4ae39..f38c28cbdb 100644 --- a/web/app/components/base/icons/src/public/files/index.ts +++ b/web/app/components/base/icons/src/public/files/index.ts @@ -6,6 +6,6 @@ export { default as Json } from './Json' export { default as Md } from './Md' export { default as Pdf } from './Pdf' export { default as Txt } from './Txt' -export { default as Unknow } from './Unknow' +export { default as Unknown } from './Unknown' export { default as Xlsx } from './Xlsx' export { default as Yaml } from './Yaml' From 6d62840aff8559626dcc7ca40fa59ccd36125996 Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Thu, 10 Oct 2024 10:40:26 +0800 Subject: [PATCH 020/346] chore: split card component --- .../(commonLayout)/plugins/test/card/page.tsx | 2 +- web/app/components/plugins/card.tsx | 145 ------------------ .../plugins/card/base/corner-mark.tsx | 12 ++ .../plugins/card/base/description.tsx | 31 ++++ web/app/components/plugins/card/base/icon.tsx | 31 ++++ .../components/plugins/card/base/org-info.tsx | 19 +++ .../components/plugins/card/base/title.tsx | 13 ++ .../plugins/{ => card}/card-mock.ts | 2 +- .../plugins/{ => card}/card-more-info.tsx | 0 web/app/components/plugins/card/index.tsx | 58 +++++++ web/app/components/plugins/plugin-item.tsx | 7 +- 11 files changed, 172 insertions(+), 148 deletions(-) delete mode 100644 web/app/components/plugins/card.tsx create mode 100644 web/app/components/plugins/card/base/corner-mark.tsx create mode 100644 web/app/components/plugins/card/base/description.tsx create mode 100644 web/app/components/plugins/card/base/icon.tsx create mode 100644 web/app/components/plugins/card/base/org-info.tsx create mode 100644 web/app/components/plugins/card/base/title.tsx rename web/app/components/plugins/{ => card}/card-mock.ts (97%) rename web/app/components/plugins/{ => card}/card-more-info.tsx (100%) create mode 100644 web/app/components/plugins/card/index.tsx diff --git a/web/app/(commonLayout)/plugins/test/card/page.tsx b/web/app/(commonLayout)/plugins/test/card/page.tsx index facff918bc..a916606dfc 100644 --- a/web/app/(commonLayout)/plugins/test/card/page.tsx +++ b/web/app/(commonLayout)/plugins/test/card/page.tsx @@ -1,5 +1,5 @@ import Card from '@/app/components/plugins/card' -import { extensionDallE, modelGPT4, toolNotion } from '@/app/components/plugins/card-mock' +import { extensionDallE, modelGPT4, toolNotion } from '@/app/components/plugins/card/card-mock' import PluginItem from '@/app/components/plugins/plugin-item' const PluginList = async () => { diff --git a/web/app/components/plugins/card.tsx b/web/app/components/plugins/card.tsx deleted file mode 100644 index c3897e22c6..0000000000 --- a/web/app/components/plugins/card.tsx +++ /dev/null @@ -1,145 +0,0 @@ -import React, { useMemo } from 'react' -import { RiCheckLine, RiVerifiedBadgeLine } from '@remixicon/react' -import type { FC } from 'react' -import { LeftCorner } from '../base/icons/src/vender/plugin' -import type { Plugin } from './types' -import { getLocaleOnServer } from '@/i18n/server' -import cn from '@/utils/classnames' - -export const CornerMark = ({ text }: { text: string }) => { - return ( - <div className='absolute top-0 right-0 flex pl-[13px] '> - <LeftCorner className="text-background-section" /> - <div className="h-5 leading-5 rounded-tr-xl pr-2 bg-background-section text-text-tertiary system-2xs-medium-uppercase">{text}</div> - </div> - ) -} - -export const Icon = ({ - className, - src, - installed = false, -}: { - className?: string - src: string - installed?: boolean -}) => { - return ( - <div - className={cn('shrink-0 relative w-10 h-10 rounded-md bg-center bg-no-repeat bg-contain', className)} - style={{ - backgroundImage: `url(${src})`, - }} - > - {installed - && <div className='p-0.5 absolute bottom-[-4px] right-[-4px] w-3 h-3 rounded-full bg-white '> - <div className='h-full rounded-full bg-state-success-solid'> - <RiCheckLine className='w-full h-full text-text-primary-on-surface' /> - </div> - </div> - } - </div> - ) -} - -export const Title = ({ - title, -}: { - title: string -}) => { - return ( - <div className='max-w-[150px] truncate text-text-secondary system-md-semibold'> - {title} - </div> - ) -} - -export const OrgInfo = ({ - className, - orgName, - packageName, -}: { - className?: string - orgName: string - packageName: string -}) => { - return <div className={cn('flex items-center h-4 space-x-0.5', className)}> - <span className="shrink-0 text-text-tertiary system-xs-regular">{orgName}</span> - <span className='shrink-0 text-text-quaternary system-xs-regular'>/</span> - <span className="shrink-0 w-0 grow truncate text-text-tertiary system-xs-regular">{packageName}</span> - </div> -} - -type DescriptionProps = { - className?: string - text: string - descriptionLineRows: number -} - -export const Description: FC<DescriptionProps> = ({ - className, - text, - descriptionLineRows, -}) => { - const lineClassName = useMemo(() => { - if (descriptionLineRows === 1) - return 'truncate' - else if (descriptionLineRows === 2) - return 'line-clamp-2' - else - return 'line-clamp-3' - }, [descriptionLineRows]) - return ( - <div className={cn('text-text-tertiary system-xs-regular', lineClassName, className)}> - {text} - </div> - ) -} - -type Props = { - className?: string - payload: Plugin - installed?: boolean - descriptionLineRows?: number - footer?: React.ReactNode -} - -const Card = ({ - className, - payload, - installed, - descriptionLineRows = 2, - footer, -}: Props) => { - const locale = getLocaleOnServer() - - const { type, name, org, label } = payload - return ( - <div className={cn('relative p-4 pb-3 border-[0.5px] border-components-panel-border bg-components-panel-on-panel-item-bg hover-bg-components-panel-on-panel-item-bg rounded-xl shadow-xs', className)}> - <CornerMark text={type} /> - {/* Header */} - <div className="flex"> - <Icon src={payload.icon} installed={installed} /> - <div className="ml-3 grow"> - <div className="flex items-center h-5"> - <Title title={label[locale]} /> - <RiVerifiedBadgeLine className="shrink-0 ml-0.5 w-4 h-4 text-text-accent" /> - </div> - <OrgInfo - className="mt-0.5" - orgName={org} - packageName={name} - /> - </div> - </div> - <Description - className="mt-3" - text={payload.brief[locale]} - descriptionLineRows={descriptionLineRows} - /> - {footer && <div>{footer}</div>} - </div> - ) -} - -export default Card diff --git a/web/app/components/plugins/card/base/corner-mark.tsx b/web/app/components/plugins/card/base/corner-mark.tsx new file mode 100644 index 0000000000..cdb9eb5417 --- /dev/null +++ b/web/app/components/plugins/card/base/corner-mark.tsx @@ -0,0 +1,12 @@ +import { LeftCorner } from '../../../base/icons/src/vender/plugin' + +const CornerMark = ({ text }: { text: string }) => { + return ( + <div className='absolute top-0 right-0 flex pl-[13px] '> + <LeftCorner className="text-background-section" /> + <div className="h-5 leading-5 rounded-tr-xl pr-2 bg-background-section text-text-tertiary system-2xs-medium-uppercase">{text}</div> + </div> + ) +} + +export default CornerMark diff --git a/web/app/components/plugins/card/base/description.tsx b/web/app/components/plugins/card/base/description.tsx new file mode 100644 index 0000000000..678e7b651e --- /dev/null +++ b/web/app/components/plugins/card/base/description.tsx @@ -0,0 +1,31 @@ +import type { FC } from 'react' +import React, { useMemo } from 'react' +import cn from '@/utils/classnames' + +type Props = { + className?: string + text: string + descriptionLineRows: number +} + +const Description: FC<Props> = ({ + className, + text, + descriptionLineRows, +}) => { + const lineClassName = useMemo(() => { + if (descriptionLineRows === 1) + return 'truncate' + else if (descriptionLineRows === 2) + return 'line-clamp-2' + else + return 'line-clamp-3' + }, [descriptionLineRows]) + return ( + <div className={cn('text-text-tertiary system-xs-regular', lineClassName, className)}> + {text} + </div> + ) +} + +export default Description diff --git a/web/app/components/plugins/card/base/icon.tsx b/web/app/components/plugins/card/base/icon.tsx new file mode 100644 index 0000000000..60be58007f --- /dev/null +++ b/web/app/components/plugins/card/base/icon.tsx @@ -0,0 +1,31 @@ +import { RiCheckLine } from '@remixicon/react' +import cn from '@/utils/classnames' + +const Icon = ({ + className, + src, + installed = false, +}: { + className?: string + src: string + installed?: boolean +}) => { + return ( + <div + className={cn('shrink-0 relative w-10 h-10 rounded-md bg-center bg-no-repeat bg-contain', className)} + style={{ + backgroundImage: `url(${src})`, + }} + > + {installed + && <div className='p-0.5 absolute bottom-[-4px] right-[-4px] w-3 h-3 rounded-full bg-white '> + <div className='h-full rounded-full bg-state-success-solid'> + <RiCheckLine className='w-full h-full text-text-primary-on-surface' /> + </div> + </div> + } + </div> + ) +} + +export default Icon diff --git a/web/app/components/plugins/card/base/org-info.tsx b/web/app/components/plugins/card/base/org-info.tsx new file mode 100644 index 0000000000..972b871375 --- /dev/null +++ b/web/app/components/plugins/card/base/org-info.tsx @@ -0,0 +1,19 @@ +import cn from '@/utils/classnames' + +const OrgInfo = ({ + className, + orgName, + packageName, +}: { + className?: string + orgName: string + packageName: string +}) => { + return <div className={cn('flex items-center h-4 space-x-0.5', className)}> + <span className="shrink-0 text-text-tertiary system-xs-regular">{orgName}</span> + <span className='shrink-0 text-text-quaternary system-xs-regular'>/</span> + <span className="shrink-0 w-0 grow truncate text-text-tertiary system-xs-regular">{packageName}</span> + </div> +} + +export default OrgInfo diff --git a/web/app/components/plugins/card/base/title.tsx b/web/app/components/plugins/card/base/title.tsx new file mode 100644 index 0000000000..bfdcd7fc2b --- /dev/null +++ b/web/app/components/plugins/card/base/title.tsx @@ -0,0 +1,13 @@ +const Title = ({ + title, +}: { + title: string +}) => { + return ( + <div className='max-w-[150px] truncate text-text-secondary system-md-semibold'> + {title} + </div> + ) +} + +export default Title diff --git a/web/app/components/plugins/card-mock.ts b/web/app/components/plugins/card/card-mock.ts similarity index 97% rename from web/app/components/plugins/card-mock.ts rename to web/app/components/plugins/card/card-mock.ts index 27f7fd5386..a3e75a3573 100644 --- a/web/app/components/plugins/card-mock.ts +++ b/web/app/components/plugins/card/card-mock.ts @@ -1,4 +1,4 @@ -import { PluginType } from './types' +import { PluginType } from '../types' export const toolNotion = { type: PluginType.tool, diff --git a/web/app/components/plugins/card-more-info.tsx b/web/app/components/plugins/card/card-more-info.tsx similarity index 100% rename from web/app/components/plugins/card-more-info.tsx rename to web/app/components/plugins/card/card-more-info.tsx diff --git a/web/app/components/plugins/card/index.tsx b/web/app/components/plugins/card/index.tsx new file mode 100644 index 0000000000..1cec64491e --- /dev/null +++ b/web/app/components/plugins/card/index.tsx @@ -0,0 +1,58 @@ +import React from 'react' +import { RiVerifiedBadgeLine } from '@remixicon/react' +import type { Plugin } from '../types' +import CornerMark from './base/corner-mark' +import Icon from './base/icon' +import Title from './base/title' +import OrgInfo from './base/org-info' +import Description from './base/description' +import cn from '@/utils/classnames' +import { getLocaleOnServer } from '@/i18n/server' + +type Props = { + className?: string + payload: Plugin + installed?: boolean + descriptionLineRows?: number + footer?: React.ReactNode +} + +const Card = ({ + className, + payload, + installed, + descriptionLineRows = 2, + footer, +}: Props) => { + const locale = getLocaleOnServer() + + const { type, name, org, label } = payload + return ( + <div className={cn('relative p-4 pb-3 border-[0.5px] border-components-panel-border bg-components-panel-on-panel-item-bg hover-bg-components-panel-on-panel-item-bg rounded-xl shadow-xs', className)}> + <CornerMark text={type} /> + {/* Header */} + <div className="flex"> + <Icon src={payload.icon} installed={installed} /> + <div className="ml-3 grow"> + <div className="flex items-center h-5"> + <Title title={label[locale]} /> + <RiVerifiedBadgeLine className="shrink-0 ml-0.5 w-4 h-4 text-text-accent" /> + </div> + <OrgInfo + className="mt-0.5" + orgName={org} + packageName={name} + /> + </div> + </div> + <Description + className="mt-3" + text={payload.brief[locale]} + descriptionLineRows={descriptionLineRows} + /> + {footer && <div>{footer}</div>} + </div> + ) +} + +export default Card diff --git a/web/app/components/plugins/plugin-item.tsx b/web/app/components/plugins/plugin-item.tsx index d685517ba4..c2d09cfa73 100644 --- a/web/app/components/plugins/plugin-item.tsx +++ b/web/app/components/plugins/plugin-item.tsx @@ -3,7 +3,12 @@ import React from 'react' import { RiArrowRightUpLine, RiVerifiedBadgeLine } from '@remixicon/react' import { Github } from '../base/icons/src/public/common' import type { Plugin } from './types' -import { CornerMark, Description, Icon, OrgInfo, Title } from '@/app/components/plugins/card' +import CornerMark from './card/base/corner-mark' +import Description from './card/base/description' +import Icon from './card/base/icon' +import OrgInfo from './card/base/org-info' +import Title from './card/base/title' + import cn from '@/utils/classnames' import { getLocaleOnServer } from '@/i18n/server' From 19f568496033e19420c703b65a0d91c6091d1cbf Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Thu, 10 Oct 2024 11:29:11 +0800 Subject: [PATCH 021/346] feat: add label and fix some ui problem --- .../(commonLayout)/plugins/test/card/page.tsx | 1 + web/app/components/base/badge.tsx | 8 +++++++- .../components/plugins/card/base/org-info.tsx | 17 ++++++++++------- web/app/components/plugins/card/card-mock.ts | 7 +++++-- web/app/components/plugins/card/index.tsx | 8 +++++++- web/app/components/plugins/plugin-item.tsx | 15 +++++++++++---- web/app/components/plugins/types.ts | 1 + 7 files changed, 42 insertions(+), 15 deletions(-) diff --git a/web/app/(commonLayout)/plugins/test/card/page.tsx b/web/app/(commonLayout)/plugins/test/card/page.tsx index a916606dfc..2a2add60c6 100644 --- a/web/app/(commonLayout)/plugins/test/card/page.tsx +++ b/web/app/(commonLayout)/plugins/test/card/page.tsx @@ -20,6 +20,7 @@ const PluginList = async () => { <Card payload={toolNotion as any} descriptionLineRows={1} + showVersion /> </div> <h3 className='my-1'>Installed</h3> diff --git a/web/app/components/base/badge.tsx b/web/app/components/base/badge.tsx index c3300a1e67..c520fe02c9 100644 --- a/web/app/components/base/badge.tsx +++ b/web/app/components/base/badge.tsx @@ -5,22 +5,28 @@ type BadgeProps = { className?: string text: string uppercase?: boolean + hasRedCornerMark?: boolean } const Badge = ({ className, text, uppercase = true, + hasRedCornerMark, }: BadgeProps) => { return ( <div className={cn( - 'inline-flex items-center px-[5px] h-5 rounded-[5px] border border-divider-deep leading-3 text-text-tertiary', + 'relative inline-flex items-center px-[5px] h-5 rounded-[5px] border border-divider-deep leading-3 text-text-tertiary', uppercase ? 'system-2xs-medium-uppercase' : 'system-xs-medium', className, )} > {text} + {hasRedCornerMark && ( + <div className='absolute top-[-2px] right-[-2px] w-1.5 h-1.5 border border-components-badge-status-light-error-border-inner bg-components-badge-status-light-error-bg rounded-[2px] shadow-sm'> + </div> + )} </div> ) } diff --git a/web/app/components/plugins/card/base/org-info.tsx b/web/app/components/plugins/card/base/org-info.tsx index 972b871375..65cfb1cb68 100644 --- a/web/app/components/plugins/card/base/org-info.tsx +++ b/web/app/components/plugins/card/base/org-info.tsx @@ -1,18 +1,21 @@ import cn from '@/utils/classnames' +type Props = { + className?: string + orgName: string + packageName: string + packageNameClassName?: string +} const OrgInfo = ({ className, orgName, packageName, -}: { - className?: string - orgName: string - packageName: string -}) => { + packageNameClassName, +}: Props) => { return <div className={cn('flex items-center h-4 space-x-0.5', className)}> - <span className="shrink-0 text-text-tertiary system-xs-regular">{orgName}</span> + <span className='shrink-0 text-text-tertiary system-xs-regular'>{orgName}</span> <span className='shrink-0 text-text-quaternary system-xs-regular'>/</span> - <span className="shrink-0 w-0 grow truncate text-text-tertiary system-xs-regular">{packageName}</span> + <span className={cn('shrink-0 w-0 grow truncate text-text-tertiary system-xs-regular', packageNameClassName)}>{packageName}</span> </div> } diff --git a/web/app/components/plugins/card/card-mock.ts b/web/app/components/plugins/card/card-mock.ts index a3e75a3573..6718c50740 100644 --- a/web/app/components/plugins/card/card-mock.ts +++ b/web/app/components/plugins/card/card-mock.ts @@ -4,7 +4,8 @@ export const toolNotion = { type: PluginType.tool, org: 'Notion', name: 'notion page search', - latest_version: '1.0.0', + version: '1.2.0', + latest_version: '1.3.0', icon: 'https://via.placeholder.com/150', label: { 'en-US': 'Notion Page Search', @@ -20,7 +21,8 @@ export const extensionDallE = { type: PluginType.extension, org: 'OpenAI', name: 'DALL-E', - latest_version: '1.0.0', + version: '1.1.0', + latest_version: '1.2.0', icon: 'https://via.placeholder.com/150', label: { 'en-US': 'DALL-E', @@ -36,6 +38,7 @@ export const modelGPT4 = { type: PluginType.model, org: 'OpenAI', name: 'GPT-4', + version: '1.0.0', latest_version: '1.0.0', icon: 'https://via.placeholder.com/150', label: { diff --git a/web/app/components/plugins/card/index.tsx b/web/app/components/plugins/card/index.tsx index 1cec64491e..64fe273ef3 100644 --- a/web/app/components/plugins/card/index.tsx +++ b/web/app/components/plugins/card/index.tsx @@ -1,6 +1,7 @@ import React from 'react' import { RiVerifiedBadgeLine } from '@remixicon/react' import type { Plugin } from '../types' +import Badge from '../../base/badge' import CornerMark from './base/corner-mark' import Icon from './base/icon' import Title from './base/title' @@ -12,6 +13,7 @@ import { getLocaleOnServer } from '@/i18n/server' type Props = { className?: string payload: Plugin + showVersion?: boolean installed?: boolean descriptionLineRows?: number footer?: React.ReactNode @@ -20,13 +22,14 @@ type Props = { const Card = ({ className, payload, + showVersion, installed, descriptionLineRows = 2, footer, }: Props) => { const locale = getLocaleOnServer() - const { type, name, org, label } = payload + return ( <div className={cn('relative p-4 pb-3 border-[0.5px] border-components-panel-border bg-components-panel-on-panel-item-bg hover-bg-components-panel-on-panel-item-bg rounded-xl shadow-xs', className)}> <CornerMark text={type} /> @@ -37,6 +40,9 @@ const Card = ({ <div className="flex items-center h-5"> <Title title={label[locale]} /> <RiVerifiedBadgeLine className="shrink-0 ml-0.5 w-4 h-4 text-text-accent" /> + { + showVersion && <Badge className='ml-1' text={payload.latest_version} /> + } </div> <OrgInfo className="mt-0.5" diff --git a/web/app/components/plugins/plugin-item.tsx b/web/app/components/plugins/plugin-item.tsx index c2d09cfa73..6625a7f850 100644 --- a/web/app/components/plugins/plugin-item.tsx +++ b/web/app/components/plugins/plugin-item.tsx @@ -1,7 +1,8 @@ import type { FC } from 'react' import React from 'react' -import { RiArrowRightUpLine, RiVerifiedBadgeLine } from '@remixicon/react' +import { RiArrowRightUpLine, RiLoginCircleLine, RiVerifiedBadgeLine } from '@remixicon/react' import { Github } from '../base/icons/src/public/common' +import Badge from '../base/badge' import type { Plugin } from './types' import CornerMark from './card/base/corner-mark' import Description from './card/base/description' @@ -23,6 +24,7 @@ const PluginItem: FC<Props> = ({ }) => { const locale = getLocaleOnServer() const { type, name, org, label } = payload + const hasNewVersion = payload.latest_version !== payload.version return ( <div className='p-1 bg-background-section-burn rounded-xl'> @@ -31,24 +33,29 @@ const PluginItem: FC<Props> = ({ {/* Header */} <div className="flex"> <Icon src={payload.icon} /> - <div className="ml-3 grow"> + <div className="ml-3 w-0 grow"> <div className="flex items-center h-5"> <Title title={label[locale]} /> <RiVerifiedBadgeLine className="shrink-0 ml-0.5 w-4 h-4 text-text-accent" /> + <Badge className='ml-1' text={payload.version} hasRedCornerMark={hasNewVersion} /> </div> <Description text={payload.brief[locale]} descriptionLineRows={1}></Description> </div> </div> </div> - <div className='mt-1.5 mb-1 flex justify-between items-center h-4'> + <div className='mt-1.5 mb-1 flex justify-between items-center h-4 px-3'> <div className='flex items-center'> <OrgInfo className="mt-0.5" orgName={org} packageName={name} + packageNameClassName='w-auto max-w-[150px]' /> <div className='mx-2 text-text-quaternary system-xs-regular'>·</div> - <div className='text-text-tertiary system-xs-regular'>2 sets of endpoints enabled</div> + <div className='flex text-text-tertiary system-xs-regular space-x-1'> + <RiLoginCircleLine className='w-4 h-4' /> + <span>2 sets of endpoints enabled</span> + </div> </div> <div className='flex items-center'> diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts index f9b1add725..3b8fdd12f2 100644 --- a/web/app/components/plugins/types.ts +++ b/web/app/components/plugins/types.ts @@ -11,6 +11,7 @@ export type Plugin = { 'type': PluginType 'org': string 'name': string + 'version': string 'latest_version': string 'icon': string 'label': Record<Locale, string> From 946068967becea234bb5df10ab237457ecc5e44f Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Thu, 10 Oct 2024 17:47:04 +0800 Subject: [PATCH 022/346] feat: finish card components --- .../plugins/test/card/actions.ts | 9 +++ .../(commonLayout)/plugins/test/card/page.tsx | 34 +++++++---- .../plugins/card/base/description.tsx | 6 +- .../plugins/card/base/download-count.tsx | 19 +++++++ web/app/components/plugins/card/card-mock.ts | 2 + .../plugins/card/card-more-info.tsx | 31 +++++++++- .../components/plugins/install-model-item.tsx | 56 +++++++++++++++++++ .../components/plugins/plugin-item/action.tsx | 50 +++++++++++++++++ .../index.tsx} | 41 +++++++++----- web/i18n/de-DE/plugin.ts | 4 ++ web/i18n/en-US/plugin.ts | 6 ++ web/i18n/es-ES/plugin.ts | 4 ++ web/i18n/fa-IR/plugin.ts | 4 ++ web/i18n/fr-FR/plugin.ts | 4 ++ web/i18n/hi-IN/plugin.ts | 4 ++ web/i18n/i18next-config.ts | 1 + web/i18n/it-IT/plugin.ts | 4 ++ web/i18n/ja-JP/plugin.ts | 4 ++ web/i18n/ko-KR/plugin.ts | 4 ++ web/i18n/pl-PL/plugin.ts | 4 ++ web/i18n/pt-BR/plugin.ts | 4 ++ web/i18n/ro-RO/plugin.ts | 4 ++ web/i18n/ru-RU/plugin.ts | 4 ++ web/i18n/tr-TR/plugin.ts | 4 ++ web/i18n/uk-UA/plugin.ts | 4 ++ web/i18n/vi-VN/plugin.ts | 4 ++ web/i18n/zh-Hans/plugin.ts | 6 ++ web/i18n/zh-Hant/plugin.ts | 4 ++ 28 files changed, 297 insertions(+), 28 deletions(-) create mode 100644 web/app/(commonLayout)/plugins/test/card/actions.ts create mode 100644 web/app/components/plugins/card/base/download-count.tsx create mode 100644 web/app/components/plugins/install-model-item.tsx create mode 100644 web/app/components/plugins/plugin-item/action.tsx rename web/app/components/plugins/{plugin-item.tsx => plugin-item/index.tsx} (64%) create mode 100644 web/i18n/de-DE/plugin.ts create mode 100644 web/i18n/en-US/plugin.ts create mode 100644 web/i18n/es-ES/plugin.ts create mode 100644 web/i18n/fa-IR/plugin.ts create mode 100644 web/i18n/fr-FR/plugin.ts create mode 100644 web/i18n/hi-IN/plugin.ts create mode 100644 web/i18n/it-IT/plugin.ts create mode 100644 web/i18n/ja-JP/plugin.ts create mode 100644 web/i18n/ko-KR/plugin.ts create mode 100644 web/i18n/pl-PL/plugin.ts create mode 100644 web/i18n/pt-BR/plugin.ts create mode 100644 web/i18n/ro-RO/plugin.ts create mode 100644 web/i18n/ru-RU/plugin.ts create mode 100644 web/i18n/tr-TR/plugin.ts create mode 100644 web/i18n/uk-UA/plugin.ts create mode 100644 web/i18n/vi-VN/plugin.ts create mode 100644 web/i18n/zh-Hans/plugin.ts create mode 100644 web/i18n/zh-Hant/plugin.ts diff --git a/web/app/(commonLayout)/plugins/test/card/actions.ts b/web/app/(commonLayout)/plugins/test/card/actions.ts new file mode 100644 index 0000000000..42c335ea87 --- /dev/null +++ b/web/app/(commonLayout)/plugins/test/card/actions.ts @@ -0,0 +1,9 @@ +'use server' + +import { revalidatePath } from 'next/cache' + +// Server Actions +export async function handleDelete() { + // revalidatePath only invalidates the cache when the included path is next visited. + revalidatePath('/') +} diff --git a/web/app/(commonLayout)/plugins/test/card/page.tsx b/web/app/(commonLayout)/plugins/test/card/page.tsx index 2a2add60c6..88357c2d33 100644 --- a/web/app/(commonLayout)/plugins/test/card/page.tsx +++ b/web/app/(commonLayout)/plugins/test/card/page.tsx @@ -1,18 +1,21 @@ +import { handleDelete } from './actions' import Card from '@/app/components/plugins/card' import { extensionDallE, modelGPT4, toolNotion } from '@/app/components/plugins/card/card-mock' import PluginItem from '@/app/components/plugins/plugin-item' +import CardMoreInfo from '@/app/components/plugins/card/card-more-info' +import InstallModelItem from '@/app/components/plugins/install-model-item' const PluginList = async () => { + const pluginList = [toolNotion, extensionDallE, modelGPT4, toolNotion, toolNotion] + return ( <div className='pb-3 bg-white'> <div className='mx-3 '> <h2 className='my-3'>Dify Plugin list</h2> <div className='grid grid-cols-2 gap-3'> - <PluginItem payload={toolNotion as any} /> - <PluginItem payload={extensionDallE as any} /> - <PluginItem payload={modelGPT4 as any} /> - <PluginItem payload={toolNotion as any} /> - <PluginItem payload={toolNotion as any} /> + {pluginList.map((plugin, index) => ( + <PluginItem key={index} payload={plugin as any} onDelete={handleDelete} /> + ))} </div> <h2 className='my-3'>Install Plugin / Package under bundle</h2> @@ -32,14 +35,25 @@ const PluginList = async () => { /> </div> + <h3 className='my-1'>Install model provide</h3> + <div className='grid grid-cols-2 gap-3'> + {pluginList.map((plugin, index) => ( + <InstallModelItem key={index} payload={plugin as any} /> + ))} + </div> + <div className='my-3 h-[px] bg-gray-50'></div> <h2 className='my-3'>Marketplace Plugin list</h2> <div className='grid grid-cols-4 gap-3'> - <Card payload={toolNotion as any} /> - <Card payload={extensionDallE as any} /> - <Card payload={modelGPT4 as any} /> - <Card payload={toolNotion as any} /> - <Card payload={toolNotion as any} /> + {pluginList.map((plugin, index) => ( + <Card + key={index} + payload={plugin as any} + footer={ + <CardMoreInfo downloadCount={index % 2 === 0 ? 1234 : 6} tags={index % 2 === 0 ? ['Search', 'Productivity'] : []} /> + } + /> + ))} </div> </div> </div> diff --git a/web/app/components/plugins/card/base/description.tsx b/web/app/components/plugins/card/base/description.tsx index 678e7b651e..247a55c628 100644 --- a/web/app/components/plugins/card/base/description.tsx +++ b/web/app/components/plugins/card/base/description.tsx @@ -15,11 +15,11 @@ const Description: FC<Props> = ({ }) => { const lineClassName = useMemo(() => { if (descriptionLineRows === 1) - return 'truncate' + return 'h-4 truncate' else if (descriptionLineRows === 2) - return 'line-clamp-2' + return 'h-8 line-clamp-2' else - return 'line-clamp-3' + return 'h-12 line-clamp-3' }, [descriptionLineRows]) return ( <div className={cn('text-text-tertiary system-xs-regular', lineClassName, className)}> diff --git a/web/app/components/plugins/card/base/download-count.tsx b/web/app/components/plugins/card/base/download-count.tsx new file mode 100644 index 0000000000..0c28e6970e --- /dev/null +++ b/web/app/components/plugins/card/base/download-count.tsx @@ -0,0 +1,19 @@ +import { RiInstallLine } from '@remixicon/react' +import { formatNumber } from '@/utils/format' + +type Props = { + downloadCount: number +} + +const DownloadCount = ({ + downloadCount, +}: Props) => { + return ( + <div className="flex items-center space-x-1 text-text-tertiary"> + <RiInstallLine className="shrink-0 w-3 h-3" /> + <div className="system-xs-regular">{formatNumber(downloadCount)}</div> + </div> + ) +} + +export default DownloadCount diff --git a/web/app/components/plugins/card/card-mock.ts b/web/app/components/plugins/card/card-mock.ts index 6718c50740..d411288db7 100644 --- a/web/app/components/plugins/card/card-mock.ts +++ b/web/app/components/plugins/card/card-mock.ts @@ -23,6 +23,7 @@ export const extensionDallE = { name: 'DALL-E', version: '1.1.0', latest_version: '1.2.0', + install_count: 1234, icon: 'https://via.placeholder.com/150', label: { 'en-US': 'DALL-E', @@ -40,6 +41,7 @@ export const modelGPT4 = { name: 'GPT-4', version: '1.0.0', latest_version: '1.0.0', + install_count: 99999, icon: 'https://via.placeholder.com/150', label: { 'en-US': 'GPT-4', diff --git a/web/app/components/plugins/card/card-more-info.tsx b/web/app/components/plugins/card/card-more-info.tsx index b808cecd96..8c9d324c35 100644 --- a/web/app/components/plugins/card/card-more-info.tsx +++ b/web/app/components/plugins/card/card-more-info.tsx @@ -1,3 +1,32 @@ -const CardMoreInfo = () => { +import DownloadCount from './base/download-count' +type Props = { + downloadCount: number + tags: string[] } + +const CardMoreInfo = ({ + downloadCount, + tags, +}: Props) => { + return ( + <div className="flex items-center h-5"> + <DownloadCount downloadCount={downloadCount} /> + {tags && tags.length > 0 && ( + <> + <div className="mx-2 text-text-quaternary system-xs-regular">·</div> + <div className="flex space-x-2"> + {tags.map(tag => ( + <div key={tag} className="flex space-x-1 system-xs-regular"> + <span className="text-text-quaternary">#</span> + <span className="text-text-tertiary">{tag}</span> + </div> + ))} + </div> + </> + )} + </div> + ) +} + +export default CardMoreInfo diff --git a/web/app/components/plugins/install-model-item.tsx b/web/app/components/plugins/install-model-item.tsx new file mode 100644 index 0000000000..906f9cee94 --- /dev/null +++ b/web/app/components/plugins/install-model-item.tsx @@ -0,0 +1,56 @@ +import type { FC } from 'react' +import React from 'react' +import { RiVerifiedBadgeLine } from '@remixicon/react' +import Badge from '../base/badge' +import type { Plugin } from './types' +import Description from './card/base/description' +import Icon from './card/base/icon' +import Title from './card/base/title' +import DownloadCount from './card/base/download-count' +import { getLocaleOnServer } from '@/i18n/server' +import cn from '@/utils/classnames' + +type Props = { + className?: string + payload: Plugin +} + +const PluginItem: FC<Props> = async ({ + className, + payload, +}) => { + const locale = getLocaleOnServer() + const { org, label } = payload + + return ( + <div className='p-1 bg-background-section-burn rounded-xl'> + <div className={cn('relative p-4 pb-3 border-[0.5px] border-components-panel-border bg-components-panel-on-panel-item-bg hover-bg-components-panel-on-panel-item-bg rounded-xl shadow-xs', className)}> + {/* Header */} + <div className="flex"> + <Icon src={payload.icon} /> + <div className="ml-3 w-0 grow"> + <div className="flex items-center h-5"> + <Title title={label[locale]} /> + <RiVerifiedBadgeLine className="shrink-0 ml-0.5 w-4 h-4 text-text-accent" /> + </div> + <div className='mb-1 flex justify-between items-center h-4'> + <div className='flex items-center'> + <div className='text-text-tertiary system/xs-regular'>{org}</div> + <div className='mx-2 text-text-quaternary system-xs-regular'>·</div> + <DownloadCount downloadCount={payload.install_count || 0} /> + </div> + </div> + </div> + </div> + <Description className='mt-3' text={payload.brief[locale]} descriptionLineRows={2}></Description> + <div className='mt-3 flex space-x-0.5'> + {['LLM', 'text embedding', 'speech2text'].map(tag => ( + <Badge key={tag} text={tag} /> + ))} + </div> + </div> + </div> + ) +} + +export default PluginItem diff --git a/web/app/components/plugins/plugin-item/action.tsx b/web/app/components/plugins/plugin-item/action.tsx new file mode 100644 index 0000000000..86198b9d70 --- /dev/null +++ b/web/app/components/plugins/plugin-item/action.tsx @@ -0,0 +1,50 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import { useRouter } from 'next/navigation' +import { RiDeleteBinLine, RiInformation2Line, RiLoopLeftLine } from '@remixicon/react' + +type Props = { + pluginId: string + isShowFetchNewVersion: boolean + isShowInfo: boolean + isShowDelete: boolean + onDelete: () => void +} + +const Action: FC<Props> = ({ + isShowFetchNewVersion, + isShowInfo, + isShowDelete, + onDelete, +}) => { + const router = useRouter() + + const handleFetchNewVersion = () => { } + const handleShowInfo = () => { + router.refresh() // refresh the page ... + } + // const handleDelete = () => { } + return ( + <div className='flex space-x-1'> + {isShowFetchNewVersion + && <div className='p-0.5 cursor-pointer' onClick={handleFetchNewVersion}> + <RiLoopLeftLine className='w-5 h-5 text-text-tertiary' /> + </div> + } + { + isShowInfo + && <div className='p-0.5 cursor-pointer' onClick={handleShowInfo}> + <RiInformation2Line className='w-5 h-5 text-text-tertiary' /> + </div> + } + { + isShowDelete + && <div className='p-0.5 cursor-pointer' onClick={onDelete}> + <RiDeleteBinLine className='w-5 h-5 text-text-tertiary' /> + </div> + } + </div> + ) +} +export default React.memo(Action) diff --git a/web/app/components/plugins/plugin-item.tsx b/web/app/components/plugins/plugin-item/index.tsx similarity index 64% rename from web/app/components/plugins/plugin-item.tsx rename to web/app/components/plugins/plugin-item/index.tsx index 6625a7f850..65c68ddf18 100644 --- a/web/app/components/plugins/plugin-item.tsx +++ b/web/app/components/plugins/plugin-item/index.tsx @@ -1,28 +1,32 @@ import type { FC } from 'react' import React from 'react' import { RiArrowRightUpLine, RiLoginCircleLine, RiVerifiedBadgeLine } from '@remixicon/react' -import { Github } from '../base/icons/src/public/common' -import Badge from '../base/badge' -import type { Plugin } from './types' -import CornerMark from './card/base/corner-mark' -import Description from './card/base/description' -import Icon from './card/base/icon' -import OrgInfo from './card/base/org-info' -import Title from './card/base/title' - +import { Github } from '../../base/icons/src/public/common' +import Badge from '../../base/badge' +import type { Plugin } from '../types' +import CornerMark from '../card/base/corner-mark' +import Description from '../card/base/description' +import Icon from '../card/base/icon' +import OrgInfo from '../card/base/org-info' +import Title from '../card/base/title' +import Action from './action' +import { getLocaleOnServer, useTranslation as translate } from '@/i18n/server' import cn from '@/utils/classnames' -import { getLocaleOnServer } from '@/i18n/server' type Props = { className?: string payload: Plugin + onDelete: () => void } -const PluginItem: FC<Props> = ({ +const PluginItem: FC<Props> = async ({ className, payload, + onDelete, }) => { const locale = getLocaleOnServer() + const { t: pluginI8n } = await translate(locale, 'plugin') + const { type, name, org, label } = payload const hasNewVersion = payload.latest_version !== payload.version @@ -39,7 +43,16 @@ const PluginItem: FC<Props> = ({ <RiVerifiedBadgeLine className="shrink-0 ml-0.5 w-4 h-4 text-text-accent" /> <Badge className='ml-1' text={payload.version} hasRedCornerMark={hasNewVersion} /> </div> - <Description text={payload.brief[locale]} descriptionLineRows={1}></Description> + <div className='flex items-center justify-between'> + <Description text={payload.brief[locale]} descriptionLineRows={1}></Description> + <Action + pluginId='xxx' + isShowFetchNewVersion={hasNewVersion} + isShowInfo + isShowDelete + onDelete={onDelete} + /> + </div> </div> </div> </div> @@ -54,12 +67,12 @@ const PluginItem: FC<Props> = ({ <div className='mx-2 text-text-quaternary system-xs-regular'>·</div> <div className='flex text-text-tertiary system-xs-regular space-x-1'> <RiLoginCircleLine className='w-4 h-4' /> - <span>2 sets of endpoints enabled</span> + <span>{pluginI8n('endpointsEnabled', { num: 2 })}</span> </div> </div> <div className='flex items-center'> - <div className='mr-1 text-text-tertiary system-2xs-medium-uppercase'>From</div> + <a href='' target='_blank' className='mr-1 text-text-tertiary system-2xs-medium-uppercase'>{pluginI8n('from')}</a> <div className='flex items-center space-x-0.5 text-text-secondary'> <Github className='ml-1 w-3 h-3' /> <div className='system-2xs-semibold-uppercase'>GitHub</div> diff --git a/web/i18n/de-DE/plugin.ts b/web/i18n/de-DE/plugin.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/de-DE/plugin.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/en-US/plugin.ts b/web/i18n/en-US/plugin.ts new file mode 100644 index 0000000000..55acb354ab --- /dev/null +++ b/web/i18n/en-US/plugin.ts @@ -0,0 +1,6 @@ +const translation = { + from: 'From', + endpointsEnabled: '{{num}} sets of endpoints enabled', +} + +export default translation diff --git a/web/i18n/es-ES/plugin.ts b/web/i18n/es-ES/plugin.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/es-ES/plugin.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/fa-IR/plugin.ts b/web/i18n/fa-IR/plugin.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/fa-IR/plugin.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/fr-FR/plugin.ts b/web/i18n/fr-FR/plugin.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/fr-FR/plugin.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/hi-IN/plugin.ts b/web/i18n/hi-IN/plugin.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/hi-IN/plugin.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/i18next-config.ts b/web/i18n/i18next-config.ts index 661475ea21..be8b4c46e1 100644 --- a/web/i18n/i18next-config.ts +++ b/web/i18n/i18next-config.ts @@ -28,6 +28,7 @@ const loadLangResources = (lang: string) => ({ tools: require(`./${lang}/tools`).default, workflow: require(`./${lang}/workflow`).default, runLog: require(`./${lang}/run-log`).default, + plugin: require(`./${lang}/plugin`).default, }, }) diff --git a/web/i18n/it-IT/plugin.ts b/web/i18n/it-IT/plugin.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/it-IT/plugin.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/ja-JP/plugin.ts b/web/i18n/ja-JP/plugin.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/ja-JP/plugin.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/ko-KR/plugin.ts b/web/i18n/ko-KR/plugin.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/ko-KR/plugin.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/pl-PL/plugin.ts b/web/i18n/pl-PL/plugin.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/pl-PL/plugin.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/pt-BR/plugin.ts b/web/i18n/pt-BR/plugin.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/pt-BR/plugin.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/ro-RO/plugin.ts b/web/i18n/ro-RO/plugin.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/ro-RO/plugin.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/ru-RU/plugin.ts b/web/i18n/ru-RU/plugin.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/ru-RU/plugin.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/tr-TR/plugin.ts b/web/i18n/tr-TR/plugin.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/tr-TR/plugin.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/uk-UA/plugin.ts b/web/i18n/uk-UA/plugin.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/uk-UA/plugin.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/vi-VN/plugin.ts b/web/i18n/vi-VN/plugin.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/vi-VN/plugin.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/zh-Hans/plugin.ts b/web/i18n/zh-Hans/plugin.ts new file mode 100644 index 0000000000..e540d590f6 --- /dev/null +++ b/web/i18n/zh-Hans/plugin.ts @@ -0,0 +1,6 @@ +const translation = { + from: '来自', + endpointsEnabled: '{{num}} 组端点已启用', +} + +export default translation diff --git a/web/i18n/zh-Hant/plugin.ts b/web/i18n/zh-Hant/plugin.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/zh-Hant/plugin.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation From 8257c7bf021514140aadd5896262ce1f73688d1a Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Thu, 10 Oct 2024 17:49:23 +0800 Subject: [PATCH 023/346] chore: remove useless data --- web/app/(commonLayout)/plugins/test/card/page.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/app/(commonLayout)/plugins/test/card/page.tsx b/web/app/(commonLayout)/plugins/test/card/page.tsx index 88357c2d33..bd1169cd91 100644 --- a/web/app/(commonLayout)/plugins/test/card/page.tsx +++ b/web/app/(commonLayout)/plugins/test/card/page.tsx @@ -6,7 +6,7 @@ import CardMoreInfo from '@/app/components/plugins/card/card-more-info' import InstallModelItem from '@/app/components/plugins/install-model-item' const PluginList = async () => { - const pluginList = [toolNotion, extensionDallE, modelGPT4, toolNotion, toolNotion] + const pluginList = [toolNotion, extensionDallE, modelGPT4] return ( <div className='pb-3 bg-white'> From 6d7588f23636a57cdd744feead91de2d9fc989cd Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Thu, 10 Oct 2024 17:53:13 +0800 Subject: [PATCH 024/346] chore: fix ui --- web/app/components/plugins/plugin-item/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/app/components/plugins/plugin-item/index.tsx b/web/app/components/plugins/plugin-item/index.tsx index 65c68ddf18..424d5ef4bc 100644 --- a/web/app/components/plugins/plugin-item/index.tsx +++ b/web/app/components/plugins/plugin-item/index.tsx @@ -56,7 +56,7 @@ const PluginItem: FC<Props> = async ({ </div> </div> </div> - <div className='mt-1.5 mb-1 flex justify-between items-center h-4 px-3'> + <div className='mt-1.5 mb-1 flex justify-between items-center h-4 px-4'> <div className='flex items-center'> <OrgInfo className="mt-0.5" From c990bc61dbaf6ac9f7bfdf144b51089d23a3a9b3 Mon Sep 17 00:00:00 2001 From: Yi <yxiaoisme@gmail.com> Date: Fri, 11 Oct 2024 12:39:27 +0800 Subject: [PATCH 025/346] feat: install plugins (partial) --- web/app/(commonLayout)/plugins/Container.tsx | 2 +- .../plugins/InstallPluginDropdown.tsx | 39 ++++- web/app/components/plugins/card/index.tsx | 17 +- .../install-from-github/index.tsx | 145 ++++++++++++++++++ .../install-from-local-package/index.tsx | 55 +++++++ .../install-from-marketplace/index.tsx | 66 ++++++++ .../plugins/install-plugin/uploader.tsx | 97 ++++++++++++ 7 files changed, 414 insertions(+), 7 deletions(-) create mode 100644 web/app/components/plugins/install-plugin/install-from-github/index.tsx create mode 100644 web/app/components/plugins/install-plugin/install-from-local-package/index.tsx create mode 100644 web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx create mode 100644 web/app/components/plugins/install-plugin/uploader.tsx diff --git a/web/app/(commonLayout)/plugins/Container.tsx b/web/app/(commonLayout)/plugins/Container.tsx index f6d9c9a700..3e8642c947 100644 --- a/web/app/(commonLayout)/plugins/Container.tsx +++ b/web/app/(commonLayout)/plugins/Container.tsx @@ -26,7 +26,7 @@ const Container = () => { const options = useMemo(() => { return [ { value: 'plugins', text: t('common.menus.plugins') }, - { value: 'discover', text: 'Discover in Marketplace' }, + { value: 'discover', text: 'Explore Marketplace' }, ] }, [t]) diff --git a/web/app/(commonLayout)/plugins/InstallPluginDropdown.tsx b/web/app/(commonLayout)/plugins/InstallPluginDropdown.tsx index c94ddfe75b..111f977289 100644 --- a/web/app/(commonLayout)/plugins/InstallPluginDropdown.tsx +++ b/web/app/(commonLayout)/plugins/InstallPluginDropdown.tsx @@ -6,12 +6,27 @@ import Button from '@/app/components/base/button' import { MagicBox } from '@/app/components/base/icons/src/vender/solid/mediaAndDevices' import { FileZip } from '@/app/components/base/icons/src/vender/solid/files' import { Github } from '@/app/components/base/icons/src/vender/solid/general' +import InstallFromMarketplace from '@/app/components/plugins/install-plugin/install-from-marketplace' +import InstallFromGitHub from '@/app/components/plugins/install-plugin/install-from-github' +import InstallFromLocalPackage from '@/app/components/plugins/install-plugin/install-from-local-package' import cn from '@/utils/classnames' const InstallPluginDropdown = () => { + const fileInputRef = useRef<HTMLInputElement>(null) const [isMenuOpen, setIsMenuOpen] = useState(false) + const [selectedAction, setSelectedAction] = useState<string | null>(null) + const [selectedFile, setSelectedFile] = useState<File | null>(null) const menuRef = useRef<HTMLDivElement>(null) + const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => { + const file = event.target.files?.[0] + if (file) { + setSelectedFile(file) + setSelectedAction('local') + setIsMenuOpen(false) + } + } + useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if (menuRef.current && !menuRef.current.contains(event.target as Node)) @@ -42,6 +57,13 @@ const InstallPluginDropdown = () => { system-xs-medium-uppercase'> Install Form </span> + <input + type='file' + ref={fileInputRef} + style={{ display: 'none' }} + onChange={handleFileChange} + accept='.difypkg' + /> {[ { icon: MagicBox, text: 'Marketplace', action: 'marketplace' }, { icon: Github, text: 'GitHub', action: 'github' }, @@ -51,8 +73,13 @@ const InstallPluginDropdown = () => { key={action} className='flex items-center w-full px-2 py-1.5 gap-1 rounded-lg hover:bg-state-base-hover cursor-pointer' onClick={() => { - console.log(action) - setIsMenuOpen(false) + if (action === 'local') { + fileInputRef.current?.click() + } + else { + setSelectedAction(action) + setIsMenuOpen(false) + } }} > <Icon className="w-4 h-4 text-text-tertiary" /> @@ -61,6 +88,14 @@ const InstallPluginDropdown = () => { ))} </div> )} + {selectedAction === 'marketplace' && <InstallFromMarketplace onClose={() => setSelectedAction(null)} />} + {selectedAction === 'github' && <InstallFromGitHub onClose={() => setSelectedAction(null)}/>} + {selectedAction === 'local' && selectedFile + && (<InstallFromLocalPackage + file={selectedFile} + onClose={() => setSelectedAction(null)}/> + ) + } </div> ) } diff --git a/web/app/components/plugins/card/index.tsx b/web/app/components/plugins/card/index.tsx index 64fe273ef3..f0a6666450 100644 --- a/web/app/components/plugins/card/index.tsx +++ b/web/app/components/plugins/card/index.tsx @@ -3,12 +3,12 @@ import { RiVerifiedBadgeLine } from '@remixicon/react' import type { Plugin } from '../types' import Badge from '../../base/badge' import CornerMark from './base/corner-mark' -import Icon from './base/icon' import Title from './base/title' import OrgInfo from './base/org-info' import Description from './base/description' import cn from '@/utils/classnames' -import { getLocaleOnServer } from '@/i18n/server' +// import { getLocaleOnServer } from '@/i18n/server' +import type { Locale } from '@/i18n' type Props = { className?: string @@ -17,6 +17,8 @@ type Props = { installed?: boolean descriptionLineRows?: number footer?: React.ReactNode + clientLocale?: Locale + serverLocale?: Locale } const Card = ({ @@ -26,8 +28,10 @@ const Card = ({ installed, descriptionLineRows = 2, footer, + clientLocale, + serverLocale, }: Props) => { - const locale = getLocaleOnServer() + const locale = clientLocale || serverLocale || 'en' const { type, name, org, label } = payload return ( @@ -35,7 +39,7 @@ const Card = ({ <CornerMark text={type} /> {/* Header */} <div className="flex"> - <Icon src={payload.icon} installed={installed} /> + {/* <Icon src={payload.icon} installed={installed} /> */} <div className="ml-3 grow"> <div className="flex items-center h-5"> <Title title={label[locale]} /> @@ -62,3 +66,8 @@ const Card = ({ } export default Card + +// export function ServerCard(props: Omit<Props, 'serverLocale'>) { +// const serverLocale = getLocaleOnServer() +// return <Card {...props} serverLocale={serverLocale} /> +// } diff --git a/web/app/components/plugins/install-plugin/install-from-github/index.tsx b/web/app/components/plugins/install-plugin/install-from-github/index.tsx new file mode 100644 index 0000000000..8f7aebebcc --- /dev/null +++ b/web/app/components/plugins/install-plugin/install-from-github/index.tsx @@ -0,0 +1,145 @@ +'use client' + +import React, { useState } from 'react' +import Modal from '@/app/components/base/modal' +import Button from '@/app/components/base/button' +import type { Item } from '@/app/components/base/select' +import { PortalSelect } from '@/app/components/base/select' + +type InstallFromGitHubProps = { + onClose: () => void +} + +type InstallStep = 'url' | 'version' | 'package' + +const InstallFromGitHub: React.FC<InstallFromGitHubProps> = ({ onClose }) => { + const [step, setStep] = useState<InstallStep>('url') + const [repoUrl, setRepoUrl] = useState('') + const [selectedVersion, setSelectedVersion] = useState('') + const [selectedPackage, setSelectedPackage] = useState('') + + // Mock data - replace with actual data fetched from the backend + const versions: Item[] = [ + { value: '1.0.1', name: '1.0.1' }, + { value: '1.2.0', name: '1.2.0' }, + { value: '1.2.1', name: '1.2.1' }, + { value: '1.3.2', name: '1.3.2' }, + ] + const packages: Item[] = [ + { value: 'package1', name: 'Package 1' }, + { value: 'package2', name: 'Package 2' }, + { value: 'package3', name: 'Package 3' }, + ] + + const handleNext = () => { + switch (step) { + case 'url': + // TODO: Validate URL and fetch versions + setStep('version') + break + case 'version': + // TODO: Validate version and fetch packages + setStep('package') + break + case 'package': + // TODO: Handle final submission + break + } + } + + return ( + <Modal + isShow={true} + onClose={onClose} + className='flex min-w-[480px] p-0 flex-col items-start rounded-2xl border-[0.5px] + border-components-panel-border bg-components-panel-bg shadows-shadow-xl' + closable + > + <div className='flex pt-6 pl-6 pb-3 pr-14 items-start gap-2 self-stretch'> + <div className='flex flex-col items-start gap-1 flex-grow'> + <div className='self-stretch text-text-primary title-2xl-semi-bold'> + Install plugin from GitHub + </div> + <div className='self-stretch text-text-tertiary system-xs-regular'> + Please make sure that you only install plugins from a trusted source. + </div> + </div> + </div> + <div className='flex px-6 py-3 flex-col justify-center items-start gap-4 self-stretch'> + {step === 'url' && ( + <> + <label + htmlFor='repoUrl' + className='flex flex-col justify-center items-start self-stretch text-text-secondary' + > + <span className='system-sm-semibold'>GitHub repository</span> + </label> + <input + type='url' + id='repoUrl' + name='repoUrl' + value={repoUrl} + onChange={e => setRepoUrl(e.target.value)} // TODO: needs to verify the url + className='flex items-center self-stretch rounded-lg border border-components-input-border-active + bg-components-input-bg-active shadows-shadow-xs p-2 gap-[2px] flex-grow overflow-hidden + text-components-input-text-filled text-ellipsis system-sm-regular' + placeholder='Please enter GitHub repo URL' + /> + </> + )} + {step === 'version' && ( + <> + <label + htmlFor='version' + className='flex flex-col justify-center items-start self-stretch text-text-secondary' + > + <span className='system-sm-semibold'>Select version</span> + </label> + <PortalSelect + value={selectedVersion} + onSelect={item => setSelectedVersion(item.value as string)} + items={versions} + placeholder="Please select a version" + popupClassName='w-[432px] z-[1001]' + /> + </> + )} + {step === 'package' && ( + <> + <label + htmlFor='package' + className='flex flex-col justify-center items-start self-stretch text-text-secondary' + > + <span className='system-sm-semibold'>Select package</span> + </label> + <PortalSelect + value={selectedPackage} + onSelect={item => setSelectedPackage(item.value as string)} + items={packages} + placeholder="Please select a package" + popupClassName='w-[432px] z-[1001]' + /> + </> + )} + </div> + <div className='flex p-6 pt-5 justify-end items-center gap-2 self-stretch'> + <Button + variant='secondary' + className='min-w-[72px]' + onClick={onClose} + > + Cancel + </Button> + <Button + variant='primary' + className='min-w-[72px]' + onClick={handleNext} + > + {step === 'package' ? 'Install' : 'Next'} + </Button> + </div> + </Modal> + ) +} + +export default InstallFromGitHub diff --git a/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx b/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx new file mode 100644 index 0000000000..c8863faf79 --- /dev/null +++ b/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx @@ -0,0 +1,55 @@ +'use client' + +import React from 'react' +import { RiLoader2Line } from '@remixicon/react' +import Modal from '@/app/components/base/modal' +import Button from '@/app/components/base/button' + +type InstallFromLocalPackageProps = { + file: File + onClose: () => void +} + +const InstallFromLocalPackage: React.FC<InstallFromLocalPackageProps> = ({ onClose }) => { + return ( + <Modal + isShow={true} + onClose={onClose} + className='flex min-w-[560px] p-0 flex-col items-start rounded-2xl border-[0.5px] + border-components-panel-border bg-components-panel-bg shadows-shadow-xl' + closable + > + <div className='flex pt-6 pl-6 pb-3 pr-14 items-start gap-2 self-stretch'> + <div className='self-stretch text-text-primary title-2xl-semi-bold'> + Install plugin + </div> + </div> + <div className='flex flex-col px-6 py-3 justify-center items-start gap-4 self-stretch'> + <div className='flex items-center gap-1 self-stretch'> + <RiLoader2Line className='text-text-accent w-4 h-4' /> + <div className='text-text-secondary system-md-regular'> + Uploading notion-sync.difypkg ... + </div> + </div> + </div> + <div className='flex p-6 pt-5 justify-end items-center gap-2 self-stretch'> + <Button + variant='secondary' + className='min-w-[72px]' + onClick={onClose} + > + Cancel + </Button> + <Button + variant='primary' + className='min-w-[72px]' + disabled + > + Install + </Button> + </div> + </Modal> + ) +} + +export default InstallFromLocalPackage diff --git a/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx b/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx new file mode 100644 index 0000000000..dd80fcce55 --- /dev/null +++ b/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx @@ -0,0 +1,66 @@ +'use client' + +import React from 'react' +import { useContext } from 'use-context-selector' +import Card from '../../card' +import { extensionDallE, modelGPT4, toolNotion } from '../../card/card-mock' +import Modal from '@/app/components/base/modal' +import Button from '@/app/components/base/button' +import I18n from '@/context/i18n' + +type InstallFromMarketplaceProps = { + onClose: () => void +} + +const InstallFromMarketplace: React.FC<InstallFromMarketplaceProps> = ({ onClose }) => { + const { locale } = useContext(I18n) + + // Mock a plugin list + const plugins = [toolNotion, extensionDallE, modelGPT4] + + return ( + <Modal + isShow={true} + onClose={onClose} + className='flex min-w-[560px] flex-col items-start p-0 rounded-2xl border-[0.5px] + border-components-panel-border bg-components-panel-bg shadows-shadow-xl' + closable + > + <div className='flex pt-6 pl-6 pb-3 pr-14 items-start gap-2 self-stretch'> + <div className='self-stretch text-text-primary title-2xl-semi-bold'>Install plugin</div> + </div> + <div className='flex px-6 py-3 flex-col justify-center items-start gap-4 self-stretch'> + <div className='flex flex-col items-start gap-2 self-stretch'> + <div className='text-text-secondary system-md-regular'>About to install the following plugin</div> + </div> + <div className='flex p-2 items-start content-start gap-1 self-stretch flex-wrap + rounded-2xl bg-background-section-burn'> + {plugins.map((plugin, index) => ( + <Card + key={index} + payload={plugin as any} + clientLocale={locale} + /> + ))} + </div> + </div> + <div className='flex p-6 pt-5 justify-end items-center gap-2 self-stretch'> + <Button + variant='secondary' + className='min-w-[72px]' + onClick={onClose} + > + Cancel + </Button> + <Button + variant='primary' + className='min-w-[72px]' + > + Install + </Button> + </div> + </Modal> + ) +} + +export default InstallFromMarketplace diff --git a/web/app/components/plugins/install-plugin/uploader.tsx b/web/app/components/plugins/install-plugin/uploader.tsx new file mode 100644 index 0000000000..8e66ed21dd --- /dev/null +++ b/web/app/components/plugins/install-plugin/uploader.tsx @@ -0,0 +1,97 @@ +'use client' +import type { FC } from 'react' +import React, { useEffect, useRef, useState } from 'react' +import { useContext } from 'use-context-selector' +import { ToastContext } from '@/app/components/base/toast' + +export type Props = { + file: File | undefined + updateFile: (file?: File) => void + className?: string +} + +const Uploader: FC<Props> = ({ + file, + updateFile, + className, +}) => { + const { notify } = useContext(ToastContext) + const [dragging, setDragging] = useState(false) + const dropRef = useRef<HTMLDivElement>(null) + const dragRef = useRef<HTMLDivElement>(null) + const fileUploader = useRef<HTMLInputElement>(null) + + const handleDragEnter = (e: DragEvent) => { + e.preventDefault() + e.stopPropagation() + e.target !== dragRef.current && setDragging(true) + } + + const handleDragOver = (e: DragEvent) => { + e.preventDefault() + e.stopPropagation() + } + + const handleDragLeave = (e: DragEvent) => { + e.preventDefault() + e.stopPropagation() + e.target === dragRef.current && setDragging(false) + } + + const handleDrop = (e: DragEvent) => { + e.preventDefault() + e.stopPropagation() + setDragging(false) + if (!e.dataTransfer) + return + const files = [...e.dataTransfer.files] + if (files.length > 1) { + // notify({ type: 'error', message: }) + } + updateFile(files[0]) + } + + const selectHandle = () => { + + } + + const fileChangeHandle = (e: React.ChangeEvent<HTMLInputElement>) => { + const currentFile = e.target.files?.[0] + updateFile(currentFile) + } + + useEffect(() => { + dropRef.current?.addEventListener('dragenter', handleDragEnter) + dropRef.current?.addEventListener('dragover', handleDragOver) + dropRef.current?.addEventListener('dragleave', handleDragLeave) + dropRef.current?.addEventListener('drop', handleDrop) + return () => { + dropRef.current?.removeEventListener('dragenter', handleDragEnter) + dropRef.current?.removeEventListener('dragover', handleDragOver) + dropRef.current?.removeEventListener('dragleave', handleDragLeave) + dropRef.current?.removeEventListener('drop', handleDrop) + } + }, []) + + return ( + <> + <input + ref={fileUploader} + style={{ display: 'none' }} + type="file" + id="fileUploader" + accept='.difypkg' + onChange={fileChangeHandle} + /> + {dragging && ( + <div + ref={dragRef} + className='flex w-full h-full p-2 items-start gap-2 absolute left-1 bottom-[3px] + rounded-2xl border-2 border-dashed bg-components-dropzone-bg-accent'> + </div> + )} + </> + ) +} + +export default React.memo(Uploader) From aa8b525b482fc7f09aaa07a35539f7f3c642f9ef Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Fri, 11 Oct 2024 14:10:24 +0800 Subject: [PATCH 026/346] fix: icon tsx to router problem --- .../components/plugins/card/base/{icon.tsx => card-icon.tsx} | 0 web/app/components/plugins/card/index.tsx | 3 ++- web/app/components/plugins/install-model-item.tsx | 2 +- web/app/components/plugins/plugin-item/index.tsx | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) rename web/app/components/plugins/card/base/{icon.tsx => card-icon.tsx} (100%) diff --git a/web/app/components/plugins/card/base/icon.tsx b/web/app/components/plugins/card/base/card-icon.tsx similarity index 100% rename from web/app/components/plugins/card/base/icon.tsx rename to web/app/components/plugins/card/base/card-icon.tsx diff --git a/web/app/components/plugins/card/index.tsx b/web/app/components/plugins/card/index.tsx index f0a6666450..0936541b88 100644 --- a/web/app/components/plugins/card/index.tsx +++ b/web/app/components/plugins/card/index.tsx @@ -2,6 +2,7 @@ import React from 'react' import { RiVerifiedBadgeLine } from '@remixicon/react' import type { Plugin } from '../types' import Badge from '../../base/badge' +import Icon from '../card/base/card-icon' import CornerMark from './base/corner-mark' import Title from './base/title' import OrgInfo from './base/org-info' @@ -39,7 +40,7 @@ const Card = ({ <CornerMark text={type} /> {/* Header */} <div className="flex"> - {/* <Icon src={payload.icon} installed={installed} /> */} + <Icon src={payload.icon} installed={installed} /> <div className="ml-3 grow"> <div className="flex items-center h-5"> <Title title={label[locale]} /> diff --git a/web/app/components/plugins/install-model-item.tsx b/web/app/components/plugins/install-model-item.tsx index 906f9cee94..05d8426566 100644 --- a/web/app/components/plugins/install-model-item.tsx +++ b/web/app/components/plugins/install-model-item.tsx @@ -4,7 +4,7 @@ import { RiVerifiedBadgeLine } from '@remixicon/react' import Badge from '../base/badge' import type { Plugin } from './types' import Description from './card/base/description' -import Icon from './card/base/icon' +import Icon from './card/base/card-icon' import Title from './card/base/title' import DownloadCount from './card/base/download-count' import { getLocaleOnServer } from '@/i18n/server' diff --git a/web/app/components/plugins/plugin-item/index.tsx b/web/app/components/plugins/plugin-item/index.tsx index 424d5ef4bc..3c07383274 100644 --- a/web/app/components/plugins/plugin-item/index.tsx +++ b/web/app/components/plugins/plugin-item/index.tsx @@ -6,7 +6,7 @@ import Badge from '../../base/badge' import type { Plugin } from '../types' import CornerMark from '../card/base/corner-mark' import Description from '../card/base/description' -import Icon from '../card/base/icon' +import Icon from '../card/base/card-icon' import OrgInfo from '../card/base/org-info' import Title from '../card/base/title' import Action from './action' From 88dbf639e074e252e3da43e370197cc5e34b0041 Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Fri, 11 Oct 2024 14:24:43 +0800 Subject: [PATCH 027/346] chore: enchance locale props --- web/app/(commonLayout)/plugins/test/card/page.tsx | 6 ++++++ web/app/components/plugins/card/index.tsx | 7 ++----- .../install-plugin/install-from-marketplace/index.tsx | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/web/app/(commonLayout)/plugins/test/card/page.tsx b/web/app/(commonLayout)/plugins/test/card/page.tsx index bd1169cd91..e7ba6849bb 100644 --- a/web/app/(commonLayout)/plugins/test/card/page.tsx +++ b/web/app/(commonLayout)/plugins/test/card/page.tsx @@ -4,8 +4,11 @@ import { extensionDallE, modelGPT4, toolNotion } from '@/app/components/plugins/ import PluginItem from '@/app/components/plugins/plugin-item' import CardMoreInfo from '@/app/components/plugins/card/card-more-info' import InstallModelItem from '@/app/components/plugins/install-model-item' +import { getLocaleOnServer } from '@/i18n/server' const PluginList = async () => { + const locale = getLocaleOnServer() + const pluginList = [toolNotion, extensionDallE, modelGPT4] return ( @@ -22,6 +25,7 @@ const PluginList = async () => { <div className='w-[512px] rounded-2xl bg-background-section-burn p-2'> <Card payload={toolNotion as any} + locale={locale} descriptionLineRows={1} showVersion /> @@ -30,6 +34,7 @@ const PluginList = async () => { <div className='w-[512px] rounded-2xl bg-background-section-burn p-2'> <Card payload={toolNotion as any} + locale={locale} descriptionLineRows={1} installed /> @@ -49,6 +54,7 @@ const PluginList = async () => { <Card key={index} payload={plugin as any} + locale={locale} footer={ <CardMoreInfo downloadCount={index % 2 === 0 ? 1234 : 6} tags={index % 2 === 0 ? ['Search', 'Productivity'] : []} /> } diff --git a/web/app/components/plugins/card/index.tsx b/web/app/components/plugins/card/index.tsx index 0936541b88..b67c68c7e4 100644 --- a/web/app/components/plugins/card/index.tsx +++ b/web/app/components/plugins/card/index.tsx @@ -8,17 +8,16 @@ import Title from './base/title' import OrgInfo from './base/org-info' import Description from './base/description' import cn from '@/utils/classnames' -// import { getLocaleOnServer } from '@/i18n/server' import type { Locale } from '@/i18n' type Props = { className?: string payload: Plugin + locale: Locale // The component is used in both client and server side, so we can't get the locale from both side(getLocaleOnServer and useContext) showVersion?: boolean installed?: boolean descriptionLineRows?: number footer?: React.ReactNode - clientLocale?: Locale serverLocale?: Locale } @@ -29,10 +28,8 @@ const Card = ({ installed, descriptionLineRows = 2, footer, - clientLocale, - serverLocale, + locale, }: Props) => { - const locale = clientLocale || serverLocale || 'en' const { type, name, org, label } = payload return ( diff --git a/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx b/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx index dd80fcce55..36e813bf68 100644 --- a/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx +++ b/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx @@ -39,7 +39,7 @@ const InstallFromMarketplace: React.FC<InstallFromMarketplaceProps> = ({ onClose <Card key={index} payload={plugin as any} - clientLocale={locale} + locale={locale} /> ))} </div> From b358ed3a5ba1a31e62b23b63639d42bf9a9139cb Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Fri, 11 Oct 2024 14:31:14 +0800 Subject: [PATCH 028/346] fix: init workflow image crash --- web/app/components/workflow/index.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/web/app/components/workflow/index.tsx b/web/app/components/workflow/index.tsx index cdccd60a3b..938ae679c3 100644 --- a/web/app/components/workflow/index.tsx +++ b/web/app/components/workflow/index.tsx @@ -405,9 +405,9 @@ const WorkflowWrap = memo(() => { const initialFeatures: FeaturesData = { file: { image: { - enabled: !!features.file_upload?.image.enabled, - number_limits: features.file_upload?.image.number_limits || 3, - transfer_methods: features.file_upload?.image.transfer_methods || ['local_file', 'remote_url'], + enabled: !!features.file_upload?.image?.enabled, + number_limits: features.file_upload?.image?.number_limits || 3, + transfer_methods: features.file_upload?.image?.transfer_methods || ['local_file', 'remote_url'], }, }, opening: { From f111e605c427fd8ee2483af05b269b267384679c Mon Sep 17 00:00:00 2001 From: StyleZhang <jasonapring2015@outlook.com> Date: Fri, 11 Oct 2024 15:26:53 +0800 Subject: [PATCH 029/346] marketplace --- web/app/(commonLayout)/plugins/Container.tsx | 2 +- .../components/plugins/marketplace/index.tsx | 41 ++------- .../components/plugins/marketplace/list.tsx | 90 +++++++++++++++++++ .../marketplace/marketplace-wrapper.tsx | 12 +++ .../plugins/marketplace/marketplace.tsx | 41 +++++++++ .../marketplace/plugin-type-switch.tsx | 2 + .../plugins/marketplace/search-box/index.tsx | 1 + .../marketplace/search-box/tags-filter.tsx | 16 ++-- 8 files changed, 161 insertions(+), 44 deletions(-) create mode 100644 web/app/components/plugins/marketplace/list.tsx create mode 100644 web/app/components/plugins/marketplace/marketplace-wrapper.tsx create mode 100644 web/app/components/plugins/marketplace/marketplace.tsx diff --git a/web/app/(commonLayout)/plugins/Container.tsx b/web/app/(commonLayout)/plugins/Container.tsx index 3e8642c947..1c03b08d37 100644 --- a/web/app/(commonLayout)/plugins/Container.tsx +++ b/web/app/(commonLayout)/plugins/Container.tsx @@ -44,7 +44,7 @@ const Container = () => { : 'bg-background-body', )} > - <div className='flex min-h-[60px] px-12 pt-4 pb-2 items-center self-stretch gap-1'> + <div className='sticky top-0 flex min-h-[60px] px-12 pt-4 pb-2 items-center self-stretch gap-1'> <div className='flex justify-between items-center w-full'> <div className='flex-1'> <TabSlider diff --git a/web/app/components/plugins/marketplace/index.tsx b/web/app/components/plugins/marketplace/index.tsx index 740d1e35b7..8e0cb16452 100644 --- a/web/app/components/plugins/marketplace/index.tsx +++ b/web/app/components/plugins/marketplace/index.tsx @@ -1,39 +1,12 @@ -import SearchBox from './search-box' -import PluginTypeSwitch from './plugin-type-switch' +import MarketplaceWrapper from './marketplace-wrapper' +import Marketplace from './marketplace' -const Marketplace = () => { +const MarketplacePage = () => { return ( - <div className='w-full'> - <div className='py-10'> - <h1 className='mb-2 text-center title-4xl-semibold text-text-primary'> - Empower your AI development - </h1> - <h2 className='flex justify-center items-center mb-4 text-center body-md-regular text-text-tertiary'> - Discover - <span className="relative ml-1 body-md-medium text-text-secondary after:content-[''] after:absolute after:left-0 after:bottom-[1.5px] after:w-full after:h-2 after:bg-text-text-selected"> - models - </span> - , - <span className="relative ml-1 body-md-medium text-text-secondary after:content-[''] after:absolute after:left-0 after:bottom-[1.5px] after:w-full after:h-2 after:bg-text-text-selected"> - tools - </span> - , - <span className="relative ml-1 mr-1 body-md-medium text-text-secondary after:content-[''] after:absolute after:left-0 after:bottom-[1.5px] after:w-full after:h-2 after:bg-text-text-selected"> - extensions - </span> - and - <span className="relative ml-1 mr-1 body-md-medium text-text-secondary after:content-[''] after:absolute after:left-0 after:bottom-[1.5px] after:w-full after:h-2 after:bg-text-text-selected"> - bundles - </span> - in Dify Marketplace - </h2> - <div className='flex items-center justify-center mb-4'> - <SearchBox onChange={() => {}} /> - </div> - <PluginTypeSwitch onChange={() => {}} /> - </div> - </div> + <MarketplaceWrapper> + <Marketplace /> + </MarketplaceWrapper> ) } -export default Marketplace +export default MarketplacePage diff --git a/web/app/components/plugins/marketplace/list.tsx b/web/app/components/plugins/marketplace/list.tsx new file mode 100644 index 0000000000..a42e6e3edb --- /dev/null +++ b/web/app/components/plugins/marketplace/list.tsx @@ -0,0 +1,90 @@ +import Card from '@/app/components/plugins/card' +import CardMoreInfo from '@/app/components/plugins/card/card-more-info' +import { toolNotion } from '@/app/components/plugins/card/card-mock' + +const List = () => { + return ( + <div className='px-12 py-2 bg-background-default-subtle'> + <div className='py-3'> + <div className='title-xl-semi-bold text-text-primary'>Featured</div> + <div className='system-xs-regular text-text-tertiary'>Our top picks to get you started</div> + <div className='grid grid-cols-4 gap-3 mt-2'> + <Card + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + </div> + </div> + <div className='py-3'> + <div className='title-xl-semi-bold text-text-primary'>Popular</div> + <div className='system-xs-regular text-text-tertiary'>Explore the library and discover the incredible work of our community</div> + <div className='grid grid-cols-4 gap-3 mt-2'> + <Card + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + </div> + </div> + </div> + ) +} + +export default List diff --git a/web/app/components/plugins/marketplace/marketplace-wrapper.tsx b/web/app/components/plugins/marketplace/marketplace-wrapper.tsx new file mode 100644 index 0000000000..6c78d73c39 --- /dev/null +++ b/web/app/components/plugins/marketplace/marketplace-wrapper.tsx @@ -0,0 +1,12 @@ +'use client' + +type WrapperProps = { + children: React.ReactNode +} +const MarketplaceWrapper = ({ + children, +}: WrapperProps) => { + return children +} + +export default MarketplaceWrapper diff --git a/web/app/components/plugins/marketplace/marketplace.tsx b/web/app/components/plugins/marketplace/marketplace.tsx new file mode 100644 index 0000000000..bc40e6c245 --- /dev/null +++ b/web/app/components/plugins/marketplace/marketplace.tsx @@ -0,0 +1,41 @@ +import SearchBox from './search-box' +import PluginTypeSwitch from './plugin-type-switch' +import List from './list' + +const Marketplace = () => { + return ( + <div className='w-full'> + <div className='py-10'> + <h1 className='mb-2 text-center title-4xl-semi-bold text-text-primary'> + Empower your AI development + </h1> + <h2 className='flex justify-center items-center mb-4 text-center body-md-regular text-text-tertiary'> + Discover + <span className="relative ml-1 body-md-medium text-text-secondary after:content-[''] after:absolute after:left-0 after:bottom-[1.5px] after:w-full after:h-2 after:bg-text-text-selected"> + models + </span> + , + <span className="relative ml-1 body-md-medium text-text-secondary after:content-[''] after:absolute after:left-0 after:bottom-[1.5px] after:w-full after:h-2 after:bg-text-text-selected"> + tools + </span> + , + <span className="relative ml-1 mr-1 body-md-medium text-text-secondary after:content-[''] after:absolute after:left-0 after:bottom-[1.5px] after:w-full after:h-2 after:bg-text-text-selected"> + extensions + </span> + and + <span className="relative ml-1 mr-1 body-md-medium text-text-secondary after:content-[''] after:absolute after:left-0 after:bottom-[1.5px] after:w-full after:h-2 after:bg-text-text-selected"> + bundles + </span> + in Dify Marketplace + </h2> + <div className='flex items-center justify-center mb-4'> + <SearchBox onChange={() => {}} /> + </div> + <PluginTypeSwitch onChange={() => {}} /> + </div> + <List /> + </div> + ) +} + +export default Marketplace diff --git a/web/app/components/plugins/marketplace/plugin-type-switch.tsx b/web/app/components/plugins/marketplace/plugin-type-switch.tsx index 3793e463f7..607bd362a6 100644 --- a/web/app/components/plugins/marketplace/plugin-type-switch.tsx +++ b/web/app/components/plugins/marketplace/plugin-type-switch.tsx @@ -1,3 +1,5 @@ +'use client' + import { useState } from 'react' import { RiHammerLine, diff --git a/web/app/components/plugins/marketplace/search-box/index.tsx b/web/app/components/plugins/marketplace/search-box/index.tsx index 1addb4cdd5..627f387aef 100644 --- a/web/app/components/plugins/marketplace/search-box/index.tsx +++ b/web/app/components/plugins/marketplace/search-box/index.tsx @@ -1,4 +1,5 @@ 'use client' + import { useCallback, useState, diff --git a/web/app/components/plugins/marketplace/search-box/tags-filter.tsx b/web/app/components/plugins/marketplace/search-box/tags-filter.tsx index 1615478af6..83c1ba2872 100644 --- a/web/app/components/plugins/marketplace/search-box/tags-filter.tsx +++ b/web/app/components/plugins/marketplace/search-box/tags-filter.tsx @@ -5,7 +5,6 @@ import { RiArrowDownSLine, RiCloseCircleFill, RiFilter3Line, - RiSearchLine, } from '@remixicon/react' import { PortalToFollowElem, @@ -14,6 +13,7 @@ import { } from '@/app/components/base/portal-to-follow-elem' import Checkbox from '@/app/components/base/checkbox' import cn from '@/utils/classnames' +import Input from '@/app/components/base/input' type TagsFilterProps = { value: string[] @@ -98,14 +98,12 @@ const TagsFilter = ({ <PortalToFollowElemContent> <div className='w-[240px] border-[0.5px] border-components-panel-border bg-components-panel-bg-blur rounded-xl shadow-lg'> <div className='p-2 pb-1'> - <div className='flex items-center p-2'> - <RiSearchLine className='mr-0.5 w-4 h-4 text-text-placeholder' /> - <input - className='px-1 system-sm-regular outline-none appearance-none' - value={searchText} - onChange={e => setSearchText(e.target.value)} - /> - </div> + <Input + showLeftIcon + value={searchText} + onChange={e => setSearchText(e.target.value)} + placeholder='Search tags' + /> </div> <div className='p-1 max-h-[448px] overflow-y-auto'> { From 76f6b8d104f2f828a904636c3b7ec581fb066e1c Mon Sep 17 00:00:00 2001 From: StyleZhang <jasonapring2015@outlook.com> Date: Fri, 11 Oct 2024 16:15:24 +0800 Subject: [PATCH 030/346] marketplace --- web/app/(commonLayout)/plugins/Container.tsx | 37 ++++++---------- web/app/(commonLayout)/plugins/page.tsx | 11 +++-- .../(commonLayout)/plugins/plugins-panel.tsx | 25 +++++++++++ .../components/plugins/marketplace/index.tsx | 43 ++++++++++++++++--- .../components/plugins/marketplace/list.tsx | 14 ++++++ .../marketplace/marketplace-wrapper.tsx | 12 ------ .../plugins/marketplace/marketplace.tsx | 41 ------------------ .../marketplace/plugin-type-switch.tsx | 4 +- .../plugins/marketplace/search-box/index.tsx | 6 +-- 9 files changed, 99 insertions(+), 94 deletions(-) create mode 100644 web/app/(commonLayout)/plugins/plugins-panel.tsx delete mode 100644 web/app/components/plugins/marketplace/marketplace-wrapper.tsx delete mode 100644 web/app/components/plugins/marketplace/marketplace.tsx diff --git a/web/app/(commonLayout)/plugins/Container.tsx b/web/app/(commonLayout)/plugins/Container.tsx index 1c03b08d37..f3de74cfab 100644 --- a/web/app/(commonLayout)/plugins/Container.tsx +++ b/web/app/(commonLayout)/plugins/Container.tsx @@ -6,7 +6,6 @@ import { RiArrowRightUpLine, RiBugLine, RiClipboardLine, - RiDragDropLine, RiEqualizer2Line, } from '@remixicon/react' import InstallPluginDropdown from './InstallPluginDropdown' @@ -16,12 +15,18 @@ import Button from '@/app/components/base/button' import TabSlider from '@/app/components/base/tab-slider' import ActionButton from '@/app/components/base/action-button' import Tooltip from '@/app/components/base/tooltip' -import Marketplace from '@/app/components/plugins/marketplace' import cn from '@/utils/classnames' -const Container = () => { +type ContainerWrapperProps = { + plugins: React.ReactNode + marketplace: React.ReactNode +} +const ContainerWrapper = ({ + plugins, + marketplace, +}: ContainerWrapperProps) => { const { t } = useTranslation() - const { setShowPluginSettingModal } = useModalContext() + const { setShowPluginSettingModal } = useModalContext() as any const options = useMemo(() => { return [ @@ -104,31 +109,13 @@ const Container = () => { </div> </div> { - activeTab === 'plugins' && ( - <> - <div className='flex flex-col pt-1 pb-3 px-12 justify-center items-start gap-3 self-stretch'> - <div className='h-px self-stretch bg-divider-subtle'></div> - <div className='flex items-center gap-2 self-stretch'> - {/* Filter goes here */} - </div> - </div> - <div className='flex px-12 items-start content-start gap-2 flex-grow self-stretch flex-wrap'> - {/* Plugin cards go here */} - </div> - <div className='flex items-center justify-center py-4 gap-2 text-text-quaternary'> - <RiDragDropLine className='w-4 h-4' /> - <span className='system-xs-regular'>Drop plugin package here to install</span> - </div> - </> - ) + activeTab === 'plugins' && plugins } { - activeTab === 'discover' && ( - <Marketplace /> - ) + activeTab === 'discover' && marketplace } </div> ) } -export default Container +export default ContainerWrapper diff --git a/web/app/(commonLayout)/plugins/page.tsx b/web/app/(commonLayout)/plugins/page.tsx index 5c22853fcd..830efd7159 100644 --- a/web/app/(commonLayout)/plugins/page.tsx +++ b/web/app/(commonLayout)/plugins/page.tsx @@ -1,10 +1,13 @@ -import Container from './Container' +import PluginsPanel from './plugins-panel' +import Container from './container' +import Marketplace from '@/app/components/plugins/marketplace' const PluginList = async () => { return ( - <> - <Container /> - </> + <Container + plugins={<PluginsPanel />} + marketplace={<Marketplace />} + /> ) } diff --git a/web/app/(commonLayout)/plugins/plugins-panel.tsx b/web/app/(commonLayout)/plugins/plugins-panel.tsx new file mode 100644 index 0000000000..227630f7d8 --- /dev/null +++ b/web/app/(commonLayout)/plugins/plugins-panel.tsx @@ -0,0 +1,25 @@ +'use client' + +import { RiDragDropLine } from '@remixicon/react' + +const PluginsPanel = () => { + return ( + <> + <div className='flex flex-col pt-1 pb-3 px-12 justify-center items-start gap-3 self-stretch'> + <div className='h-px self-stretch bg-divider-subtle'></div> + <div className='flex items-center gap-2 self-stretch'> + {/* Filter goes here */} + </div> + </div> + <div className='flex px-12 items-start content-start gap-2 flex-grow self-stretch flex-wrap'> + {/* Plugin cards go here */} + </div> + <div className='flex items-center justify-center py-4 gap-2 text-text-quaternary'> + <RiDragDropLine className='w-4 h-4' /> + <span className='system-xs-regular'>Drop plugin package here to install</span> + </div> + </> + ) +} + +export default PluginsPanel diff --git a/web/app/components/plugins/marketplace/index.tsx b/web/app/components/plugins/marketplace/index.tsx index 8e0cb16452..b07db8e920 100644 --- a/web/app/components/plugins/marketplace/index.tsx +++ b/web/app/components/plugins/marketplace/index.tsx @@ -1,12 +1,41 @@ -import MarketplaceWrapper from './marketplace-wrapper' -import Marketplace from './marketplace' +import SearchBox from './search-box' +import PluginTypeSwitch from './plugin-type-switch' +import List from './list' -const MarketplacePage = () => { +const Marketplace = () => { return ( - <MarketplaceWrapper> - <Marketplace /> - </MarketplaceWrapper> + <div className='w-full'> + <div className='py-10'> + <h1 className='mb-2 text-center title-4xl-semi-bold text-text-primary'> + Empower your AI development + </h1> + <h2 className='flex justify-center items-center mb-4 text-center body-md-regular text-text-tertiary'> + Discover + <span className="relative ml-1 body-md-medium text-text-secondary after:content-[''] after:absolute after:left-0 after:bottom-[1.5px] after:w-full after:h-2 after:bg-text-text-selected"> + models + </span> + , + <span className="relative ml-1 body-md-medium text-text-secondary after:content-[''] after:absolute after:left-0 after:bottom-[1.5px] after:w-full after:h-2 after:bg-text-text-selected"> + tools + </span> + , + <span className="relative ml-1 mr-1 body-md-medium text-text-secondary after:content-[''] after:absolute after:left-0 after:bottom-[1.5px] after:w-full after:h-2 after:bg-text-text-selected"> + extensions + </span> + and + <span className="relative ml-1 mr-1 body-md-medium text-text-secondary after:content-[''] after:absolute after:left-0 after:bottom-[1.5px] after:w-full after:h-2 after:bg-text-text-selected"> + bundles + </span> + in Dify Marketplace + </h2> + <div className='flex items-center justify-center mb-4'> + <SearchBox /> + </div> + <PluginTypeSwitch /> + </div> + <List /> + </div> ) } -export default MarketplacePage +export default Marketplace diff --git a/web/app/components/plugins/marketplace/list.tsx b/web/app/components/plugins/marketplace/list.tsx index a42e6e3edb..d9365fa54a 100644 --- a/web/app/components/plugins/marketplace/list.tsx +++ b/web/app/components/plugins/marketplace/list.tsx @@ -1,8 +1,11 @@ import Card from '@/app/components/plugins/card' import CardMoreInfo from '@/app/components/plugins/card/card-more-info' import { toolNotion } from '@/app/components/plugins/card/card-mock' +import { getLocaleOnServer } from '@/i18n/server' const List = () => { + const locale = getLocaleOnServer() + return ( <div className='px-12 py-2 bg-background-default-subtle'> <div className='py-3'> @@ -10,30 +13,35 @@ const List = () => { <div className='system-xs-regular text-text-tertiary'>Our top picks to get you started</div> <div className='grid grid-cols-4 gap-3 mt-2'> <Card + locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card + locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card + locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card + locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card + locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> @@ -46,36 +54,42 @@ const List = () => { <div className='system-xs-regular text-text-tertiary'>Explore the library and discover the incredible work of our community</div> <div className='grid grid-cols-4 gap-3 mt-2'> <Card + locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card + locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card + locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card + locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card + locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card + locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> diff --git a/web/app/components/plugins/marketplace/marketplace-wrapper.tsx b/web/app/components/plugins/marketplace/marketplace-wrapper.tsx deleted file mode 100644 index 6c78d73c39..0000000000 --- a/web/app/components/plugins/marketplace/marketplace-wrapper.tsx +++ /dev/null @@ -1,12 +0,0 @@ -'use client' - -type WrapperProps = { - children: React.ReactNode -} -const MarketplaceWrapper = ({ - children, -}: WrapperProps) => { - return children -} - -export default MarketplaceWrapper diff --git a/web/app/components/plugins/marketplace/marketplace.tsx b/web/app/components/plugins/marketplace/marketplace.tsx deleted file mode 100644 index bc40e6c245..0000000000 --- a/web/app/components/plugins/marketplace/marketplace.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import SearchBox from './search-box' -import PluginTypeSwitch from './plugin-type-switch' -import List from './list' - -const Marketplace = () => { - return ( - <div className='w-full'> - <div className='py-10'> - <h1 className='mb-2 text-center title-4xl-semi-bold text-text-primary'> - Empower your AI development - </h1> - <h2 className='flex justify-center items-center mb-4 text-center body-md-regular text-text-tertiary'> - Discover - <span className="relative ml-1 body-md-medium text-text-secondary after:content-[''] after:absolute after:left-0 after:bottom-[1.5px] after:w-full after:h-2 after:bg-text-text-selected"> - models - </span> - , - <span className="relative ml-1 body-md-medium text-text-secondary after:content-[''] after:absolute after:left-0 after:bottom-[1.5px] after:w-full after:h-2 after:bg-text-text-selected"> - tools - </span> - , - <span className="relative ml-1 mr-1 body-md-medium text-text-secondary after:content-[''] after:absolute after:left-0 after:bottom-[1.5px] after:w-full after:h-2 after:bg-text-text-selected"> - extensions - </span> - and - <span className="relative ml-1 mr-1 body-md-medium text-text-secondary after:content-[''] after:absolute after:left-0 after:bottom-[1.5px] after:w-full after:h-2 after:bg-text-text-selected"> - bundles - </span> - in Dify Marketplace - </h2> - <div className='flex items-center justify-center mb-4'> - <SearchBox onChange={() => {}} /> - </div> - <PluginTypeSwitch onChange={() => {}} /> - </div> - <List /> - </div> - ) -} - -export default Marketplace diff --git a/web/app/components/plugins/marketplace/plugin-type-switch.tsx b/web/app/components/plugins/marketplace/plugin-type-switch.tsx index 607bd362a6..9c9d73cdb7 100644 --- a/web/app/components/plugins/marketplace/plugin-type-switch.tsx +++ b/web/app/components/plugins/marketplace/plugin-type-switch.tsx @@ -8,7 +8,7 @@ import { import cn from '@/utils/classnames' type PluginTypeSwitchProps = { - onChange: (type: string) => void + onChange?: (type: string) => void } const options = [ { @@ -54,7 +54,7 @@ const PluginTypeSwitch = ({ )} onClick={() => { setActiveType(option.value) - onChange(option.value) + onChange?.(option.value) }} > {option.icon} diff --git a/web/app/components/plugins/marketplace/search-box/index.tsx b/web/app/components/plugins/marketplace/search-box/index.tsx index 627f387aef..cb01f0ad10 100644 --- a/web/app/components/plugins/marketplace/search-box/index.tsx +++ b/web/app/components/plugins/marketplace/search-box/index.tsx @@ -9,7 +9,7 @@ import TagsFilter from './tags-filter' import ActionButton from '@/app/components/base/action-button' type SearchBoxProps = { - onChange: (searchText: string, tags: string[]) => void + onChange?: (searchText: string, tags: string[]) => void } const SearchBox = ({ onChange, @@ -19,7 +19,7 @@ const SearchBox = ({ const handleTagsChange = useCallback((tags: string[]) => { setSelectedTags(tags) - onChange(searchText, tags) + onChange?.(searchText, tags) }, [searchText, onChange]) return ( @@ -36,7 +36,7 @@ const SearchBox = ({ value={searchText} onChange={(e) => { setSearchText(e.target.value) - onChange(e.target.value, selectedTags) + onChange?.(e.target.value, selectedTags) }} /> { From 902de72cc080628eb768426bf359f9bde0e6c3d0 Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Thu, 10 Oct 2024 12:58:28 +0800 Subject: [PATCH 031/346] new style of settings --- .../header/account-dropdown/index.tsx | 2 +- .../header/account-setting/index.tsx | 61 ++++++++++--------- .../header/account-setting/menu-dialog.tsx | 46 ++++++++++++++ web/i18n/en-US/common.ts | 1 + web/i18n/zh-Hans/common.ts | 1 + 5 files changed, 81 insertions(+), 30 deletions(-) create mode 100644 web/app/components/header/account-setting/menu-dialog.tsx diff --git a/web/app/components/header/account-dropdown/index.tsx b/web/app/components/header/account-dropdown/index.tsx index 4c42374ffd..c29e0f159b 100644 --- a/web/app/components/header/account-dropdown/index.tsx +++ b/web/app/components/header/account-dropdown/index.tsx @@ -102,7 +102,7 @@ export default function AppSelector({ isMobile }: IAppSelector) { </Menu.Item> <div className="px-1 py-1"> <Menu.Item> - <div className={itemClassName} onClick={() => setShowAccountSettingModal({ payload: 'account' })}> + <div className={itemClassName} onClick={() => setShowAccountSettingModal({ payload: 'provider' })}> <div>{t('common.userProfile.settings')}</div> </div> </Menu.Item> diff --git a/web/app/components/header/account-setting/index.tsx b/web/app/components/header/account-setting/index.tsx index c8f757de28..d56f231a55 100644 --- a/web/app/components/header/account-setting/index.tsx +++ b/web/app/components/header/account-setting/index.tsx @@ -6,8 +6,8 @@ import { RiAccountCircleLine, RiApps2AddFill, RiApps2AddLine, - RiBox3Fill, - RiBox3Line, + RiBrainFill, + RiBrainLine, RiCloseLine, RiColorFilterFill, RiColorFilterLine, @@ -31,17 +31,14 @@ import ModelProviderPage from './model-provider-page' import cn from '@/utils/classnames' import BillingPage from '@/app/components/billing/billing-page' import CustomPage from '@/app/components/custom/custom-page' -import Modal from '@/app/components/base/modal' import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints' import { useProviderContext } from '@/context/provider-context' import { useAppContext } from '@/context/app-context' +import MenuDialog from '@/app/components/header/account-setting/menu-dialog' +import Input from '@/app/components/base/input' const iconClassName = ` - w-4 h-4 ml-3 mr-2 -` - -const scrolledClassName = ` - border-b shadow-xs bg-white/[.98] + w-5 h-5 mr-2 ` type IAccountSettingProps = { @@ -59,7 +56,7 @@ type GroupItem = { export default function AccountSetting({ onCancel, - activeTab = 'account', + activeTab = 'provider', }: IAccountSettingProps) { const [activeMenu, setActiveMenu] = useState(activeTab) const { t } = useTranslation() @@ -73,8 +70,8 @@ export default function AccountSetting({ { key: 'provider', name: t('common.settings.provider'), - icon: <RiBox3Line className={iconClassName} />, - activeIcon: <RiBox3Fill className={iconClassName} />, + icon: <RiBrainLine className={iconClassName} />, + activeIcon: <RiBrainFill className={iconClassName} />, }, { key: 'members', @@ -122,7 +119,7 @@ export default function AccountSetting({ }, { key: 'account-group', - name: t('common.settings.accountGroup'), + name: t('common.settings.generalGroup'), items: [ { key: 'account', @@ -161,32 +158,31 @@ export default function AccountSetting({ const activeItem = [...menuItems[0].items, ...menuItems[1].items].find(item => item.key === activeMenu) + const [searchValue, setSearchValue] = useState<string>('') + return ( - <Modal - isShow + <MenuDialog + show onClose={() => { }} - className='my-[60px] p-0 max-w-[1024px] rounded-xl overflow-y-auto' - wrapperClassName='pt-[60px]' > - <div className='flex'> - <div className='w-[44px] sm:w-[200px] px-[1px] py-4 sm:p-4 border border-gray-100 shrink-0 sm:shrink-1 flex flex-col items-center sm:items-start'> - <div className='mb-8 ml-0 sm:ml-2 text-sm sm:text-base font-medium leading-6 text-gray-900'>{t('common.userProfile.settings')}</div> + <div className='mx-auto max-w-[1048px] h-[100vh] flex'> + <div className='w-[44px] sm:w-[224px] pl-4 pr-6 border-r border-divider-burn flex flex-col'> + <div className='mt-6 mb-8 px-3 py-2 text-text-primary title-2xl-semi-bold'>{t('common.userProfile.settings')}</div> <div className='w-full'> { menuItems.map(menuItem => ( - <div key={menuItem.key} className='mb-4'> + <div key={menuItem.key} className='mb-2'> {!isCurrentWorkspaceDatasetOperator && ( - <div className='px-2 mb-[6px] text-[10px] sm:text-xs font-medium text-gray-500'>{menuItem.name}</div> + <div className='py-2 pl-3 pb-1 mb-0.5 text-text-tertiary system-xs-medium-uppercase'>{menuItem.name}</div> )} <div> { menuItem.items.map(item => ( <div key={item.key} - className={` - flex items-center h-[37px] mb-[2px] text-sm cursor-pointer rounded-lg - ${activeMenu === item.key ? 'font-semibold text-primary-600 bg-primary-50' : 'font-light text-gray-700'} - `} + className={cn( + 'flex items-center mb-0.5 p-1 pl-3 h-[37px] text-sm cursor-pointer rounded-lg', + activeMenu === item.key ? 'bg-state-base-active text-components-menu-item-text-active system-sm-semibold' : 'text-components-menu-item-text system-sm-medium')} title={item.name} onClick={() => setActiveMenu(item.key)} > @@ -201,15 +197,22 @@ export default function AccountSetting({ } </div> </div> - <div ref={scrollRef} className='relative w-[824px] h-[720px] pb-4 overflow-y-auto'> - <div className={cn('sticky top-0 px-6 py-4 flex items-center h-14 mb-4 bg-white text-base font-medium text-gray-900 z-20', scrolled && scrolledClassName)}> - <div className='shrink-0'>{activeItem?.name}</div> + <div ref={scrollRef} className='relative w-[824px] pb-4 bg-components-panel-bg overflow-y-auto'> + <div className={cn('sticky top-0 px-8 py-[26px] flex items-center bg-components-panel-bg z-20', scrolled && 'border-b shadow-xs')}> + <div className='shrink-0 text-text-primary title-2xl-semi-bold'>{activeItem?.name}</div> { activeItem?.description && ( <div className='shrink-0 ml-2 text-xs text-gray-600'>{activeItem?.description}</div> ) } <div className='grow flex justify-end'> + <Input + showLeftIcon + wrapperClassName='!w-[200px]' + className='!h-8 !text-[13px]' + onChange={e => setSearchValue(e.target.value)} + value={searchValue} + /> <div className='flex items-center justify-center -mr-4 w-6 h-6 cursor-pointer' onClick={onCancel}> <RiCloseLine className='w-4 h-4 text-gray-400' /> </div> @@ -228,6 +231,6 @@ export default function AccountSetting({ </div> </div> </div> - </Modal> + </MenuDialog> ) } diff --git a/web/app/components/header/account-setting/menu-dialog.tsx b/web/app/components/header/account-setting/menu-dialog.tsx new file mode 100644 index 0000000000..2f13311d0d --- /dev/null +++ b/web/app/components/header/account-setting/menu-dialog.tsx @@ -0,0 +1,46 @@ +import { Fragment, useCallback } from 'react' +import type { ReactNode } from 'react' +import { Dialog, Transition } from '@headlessui/react' +import cn from '@/utils/classnames' + +type DialogProps = { + className?: string + children: ReactNode + show: boolean + onClose?: () => void +} + +const MenuDialog = ({ + className, + children, + show, + onClose, +}: DialogProps) => { + const close = useCallback(() => onClose?.(), [onClose]) + return ( + <Transition appear show={show} as={Fragment}> + <Dialog as="div" className="relative z-40" onClose={close}> + <div className="fixed inset-0"> + <div className="flex flex-col items-center justify-center min-h-full"> + <Transition.Child + as={Fragment} + enter="ease-out duration-300" + enterFrom="opacity-0 scale-95" + enterTo="opacity-100 scale-100" + leave="ease-in duration-200" + leaveFrom="opacity-100 scale-100" + leaveTo="opacity-0 scale-95" + > + <Dialog.Panel className={cn('grow relative w-full h-full p-0 overflow-hidden text-left align-middle transition-all transform bg-background-sidenav-bg backdrop-blur-md', className)}> + <div className='absolute right-0 top-0 h-full w-1/2 bg-components-panel-bg'/> + {children} + </Dialog.Panel> + </Transition.Child> + </div> + </div> + </Dialog> + </Transition > + ) +} + +export default MenuDialog diff --git a/web/i18n/en-US/common.ts b/web/i18n/en-US/common.ts index 23e301485a..483c4788e6 100644 --- a/web/i18n/en-US/common.ts +++ b/web/i18n/en-US/common.ts @@ -142,6 +142,7 @@ const translation = { settings: { accountGroup: 'ACCOUNT', workplaceGroup: 'WORKSPACE', + generalGroup: 'GENERAL', account: 'My account', members: 'Members', billing: 'Billing', diff --git a/web/i18n/zh-Hans/common.ts b/web/i18n/zh-Hans/common.ts index 7947d32f25..7d906ed0b4 100644 --- a/web/i18n/zh-Hans/common.ts +++ b/web/i18n/zh-Hans/common.ts @@ -142,6 +142,7 @@ const translation = { settings: { accountGroup: '账户', workplaceGroup: '工作空间', + generalGroup: '通用', account: '我的账户', members: '成员', billing: '账单', From 49856d8d174672172752d17dfbbe36762e2b3b96 Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Thu, 10 Oct 2024 16:01:07 +0800 Subject: [PATCH 032/346] setting content header & close button --- .../header/account-setting/index.tsx | 6 +--- .../header/account-setting/menu-dialog.tsx | 30 +++++++++++++++++-- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/web/app/components/header/account-setting/index.tsx b/web/app/components/header/account-setting/index.tsx index d56f231a55..02895b0255 100644 --- a/web/app/components/header/account-setting/index.tsx +++ b/web/app/components/header/account-setting/index.tsx @@ -8,7 +8,6 @@ import { RiApps2AddLine, RiBrainFill, RiBrainLine, - RiCloseLine, RiColorFilterFill, RiColorFilterLine, RiDatabase2Fill, @@ -163,7 +162,7 @@ export default function AccountSetting({ return ( <MenuDialog show - onClose={() => { }} + onClose={onCancel} > <div className='mx-auto max-w-[1048px] h-[100vh] flex'> <div className='w-[44px] sm:w-[224px] pl-4 pr-6 border-r border-divider-burn flex flex-col'> @@ -213,9 +212,6 @@ export default function AccountSetting({ onChange={e => setSearchValue(e.target.value)} value={searchValue} /> - <div className='flex items-center justify-center -mr-4 w-6 h-6 cursor-pointer' onClick={onCancel}> - <RiCloseLine className='w-4 h-4 text-gray-400' /> - </div> </div> </div> <div className='px-4 sm:px-8 pt-2'> diff --git a/web/app/components/header/account-setting/menu-dialog.tsx b/web/app/components/header/account-setting/menu-dialog.tsx index 2f13311d0d..19639488da 100644 --- a/web/app/components/header/account-setting/menu-dialog.tsx +++ b/web/app/components/header/account-setting/menu-dialog.tsx @@ -1,6 +1,8 @@ -import { Fragment, useCallback } from 'react' +import { Fragment, useCallback, useEffect } from 'react' import type { ReactNode } from 'react' +import { RiCloseLine } from '@remixicon/react' import { Dialog, Transition } from '@headlessui/react' +import Button from '@/app/components/base/button' import cn from '@/utils/classnames' type DialogProps = { @@ -17,9 +19,22 @@ const MenuDialog = ({ onClose, }: DialogProps) => { const close = useCallback(() => onClose?.(), [onClose]) + + useEffect(() => { + const handleKeyDown = (event: KeyboardEvent) => { + if (event.key === 'Escape') + close() + } + + document.addEventListener('keydown', handleKeyDown) + return () => { + document.removeEventListener('keydown', handleKeyDown) + } + }, [close]) + return ( <Transition appear show={show} as={Fragment}> - <Dialog as="div" className="relative z-40" onClose={close}> + <Dialog as="div" className="relative z-40" onClose={() => {}}> <div className="fixed inset-0"> <div className="flex flex-col items-center justify-center min-h-full"> <Transition.Child @@ -33,6 +48,17 @@ const MenuDialog = ({ > <Dialog.Panel className={cn('grow relative w-full h-full p-0 overflow-hidden text-left align-middle transition-all transform bg-background-sidenav-bg backdrop-blur-md', className)}> <div className='absolute right-0 top-0 h-full w-1/2 bg-components-panel-bg'/> + <div className='absolute top-6 right-6 flex flex-col items-center'> + <Button + variant='tertiary' + size='large' + className='px-2' + onClick={close} + > + <RiCloseLine className='w-5 h-5' /> + </Button> + <div className='mt-1 text-text-tertiary system-2xs-medium-uppercase'>ESC</div> + </div> {children} </Dialog.Panel> </Transition.Child> From d68ca56b3aaafbb4b126783f5839d66f6ed956ee Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Fri, 11 Oct 2024 12:26:53 +0800 Subject: [PATCH 033/346] system default model --- .../header/account-setting/index.tsx | 2 +- .../model-provider-page/index.tsx | 43 +++++++++++-------- .../system-model-selector/index.tsx | 17 ++++---- web/i18n/en-US/common.ts | 2 +- web/i18n/zh-Hans/common.ts | 2 +- 5 files changed, 36 insertions(+), 30 deletions(-) diff --git a/web/app/components/header/account-setting/index.tsx b/web/app/components/header/account-setting/index.tsx index 02895b0255..33b4a0f68a 100644 --- a/web/app/components/header/account-setting/index.tsx +++ b/web/app/components/header/account-setting/index.tsx @@ -197,7 +197,7 @@ export default function AccountSetting({ </div> </div> <div ref={scrollRef} className='relative w-[824px] pb-4 bg-components-panel-bg overflow-y-auto'> - <div className={cn('sticky top-0 px-8 py-[26px] flex items-center bg-components-panel-bg z-20', scrolled && 'border-b shadow-xs')}> + <div className={cn('sticky top-0 mx-8 pt-[27px] pb-2 mb-[18px] flex items-center bg-components-panel-bg z-20', scrolled && 'border-b')}> <div className='shrink-0 text-text-primary title-2xl-semi-bold'>{activeItem?.name}</div> { activeItem?.description && ( diff --git a/web/app/components/header/account-setting/model-provider-page/index.tsx b/web/app/components/header/account-setting/model-provider-page/index.tsx index a8a5a0cf42..8862b0029b 100644 --- a/web/app/components/header/account-setting/model-provider-page/index.tsx +++ b/web/app/components/header/account-setting/model-provider-page/index.tsx @@ -1,5 +1,6 @@ import { useMemo } from 'react' import { useTranslation } from 'react-i18next' +import { RiAlertFill } from '@remixicon/react' import SystemModelSelector from './system-model-selector' import ProviderAddedCard, { UPDATE_MODEL_PROVIDER_CUSTOM_MODEL_LIST } from './provider-added-card' import ProviderCard from './provider-card' @@ -17,10 +18,10 @@ import { useUpdateModelList, useUpdateModelProviders, } from './hooks' -import { AlertTriangle } from '@/app/components/base/icons/src/vender/solid/alertsAndFeedback' import { useProviderContext } from '@/context/provider-context' import { useModalContextSelector } from '@/context/modal-context' import { useEventEmitterContextContext } from '@/context/event-emitter' +import cn from '@/utils/classnames' const ModelProviderPage = () => { const { t } = useTranslation() @@ -90,24 +91,28 @@ const ModelProviderPage = () => { return ( <div className='relative pt-1 -mt-2'> - <div className={`flex items-center justify-between mb-2 h-8 ${defaultModelNotConfigured && 'px-3 bg-[#FFFAEB] rounded-lg border border-[#FEF0C7]'}`}> - { - defaultModelNotConfigured - ? ( - <div className='flex items-center text-xs font-medium text-gray-700'> - <AlertTriangle className='mr-1 w-3 h-3 text-[#F79009]' /> - {t('common.modelProvider.notConfigured')} - </div> - ) - : <div className='text-sm font-medium text-gray-800'>{t('common.modelProvider.models')}</div> - } - <SystemModelSelector - textGenerationDefaultModel={textGenerationDefaultModel} - embeddingsDefaultModel={embeddingsDefaultModel} - rerankDefaultModel={rerankDefaultModel} - speech2textDefaultModel={speech2textDefaultModel} - ttsDefaultModel={ttsDefaultModel} - /> + <div className={cn('flex items-center mb-2')}> + <div className='grow text-text-primary system-md-semibold'>{t('common.modelProvider.models')}</div> + <div className={cn( + 'shrink-0 relative flex items-center justify-end gap-2 p-0.5 rounded-lg border border-transparent', + defaultModelNotConfigured && 'pl-2 bg-components-panel-bg-blur border-components-panel-border shadow-xs', + )}> + {defaultModelNotConfigured && <div className='absolute top-0 bottom-0 right-0 left-0 opacity-40' style={{ background: 'linear-gradient(92deg, rgba(247, 144, 9, 0.25) 0%, rgba(255, 255, 255, 0.00) 100%)' }}/>} + {defaultModelNotConfigured && ( + <div className='flex items-center gap-1 text-text-primary system-xs-medium'> + <RiAlertFill className='w-4 h-4 text-text-warning-secondary' /> + {t('common.modelProvider.notConfigured')} + </div> + )} + <SystemModelSelector + notConfigured={defaultModelNotConfigured} + textGenerationDefaultModel={textGenerationDefaultModel} + embeddingsDefaultModel={embeddingsDefaultModel} + rerankDefaultModel={rerankDefaultModel} + speech2textDefaultModel={speech2textDefaultModel} + ttsDefaultModel={ttsDefaultModel} + /> + </div> </div> { !!configuredProviders?.length && ( diff --git a/web/app/components/header/account-setting/model-provider-page/system-model-selector/index.tsx b/web/app/components/header/account-setting/model-provider-page/system-model-selector/index.tsx index 1574785898..846738d4ae 100644 --- a/web/app/components/header/account-setting/model-provider-page/system-model-selector/index.tsx +++ b/web/app/components/header/account-setting/model-provider-page/system-model-selector/index.tsx @@ -1,6 +1,7 @@ import type { FC } from 'react' import { useState } from 'react' import { useTranslation } from 'react-i18next' +import { RiEqualizer2Line } from '@remixicon/react' import ModelSelector from '../model-selector' import { useModelList, @@ -13,7 +14,6 @@ import type { } from '../declarations' import { ModelTypeEnum } from '../declarations' import Tooltip from '@/app/components/base/tooltip' -import { Settings01 } from '@/app/components/base/icons/src/vender/line/general' import { PortalToFollowElem, PortalToFollowElemContent, @@ -31,6 +31,7 @@ type SystemModelSelectorProps = { rerankDefaultModel: DefaultModelResponse | undefined speech2textDefaultModel: DefaultModelResponse | undefined ttsDefaultModel: DefaultModelResponse | undefined + notConfigured: boolean } const SystemModel: FC<SystemModelSelectorProps> = ({ textGenerationDefaultModel, @@ -38,6 +39,7 @@ const SystemModel: FC<SystemModelSelectorProps> = ({ rerankDefaultModel, speech2textDefaultModel, ttsDefaultModel, + notConfigured, }) => { const { t } = useTranslation() const { notify } = useToastContext() @@ -128,14 +130,13 @@ const SystemModel: FC<SystemModelSelectorProps> = ({ }} > <PortalToFollowElemTrigger onClick={() => setOpen(v => !v)}> - <div className={` - flex items-center px-2 h-6 text-xs text-gray-700 cursor-pointer bg-white rounded-md border-[0.5px] border-gray-200 shadow-xs - hover:bg-gray-100 hover:shadow-none - ${open && 'bg-gray-100 shadow-none'} - `}> - <Settings01 className='mr-1 w-3 h-3 text-gray-500' /> + <Button + variant={notConfigured ? 'primary' : 'secondary'} + size='small' + > + <RiEqualizer2Line className='mr-1 w-3.5 h-3.5' /> {t('common.modelProvider.systemModelSettings')} - </div> + </Button> </PortalToFollowElemTrigger> <PortalToFollowElemContent className='z-50'> <div className='pt-4 w-[360px] rounded-xl border-[0.5px] border-black/5 bg-white shadow-xl'> diff --git a/web/i18n/en-US/common.ts b/web/i18n/en-US/common.ts index 483c4788e6..3bdeb7cec9 100644 --- a/web/i18n/en-US/common.ts +++ b/web/i18n/en-US/common.ts @@ -276,7 +276,7 @@ const translation = { }, }, modelProvider: { - notConfigured: 'The system model has not yet been fully configured, and some functions may be unavailable.', + notConfigured: 'The system model has not yet been fully configured', systemModelSettings: 'System Model Settings', systemModelSettingsLink: 'Why is it necessary to set up a system model?', selectModel: 'Select your model', diff --git a/web/i18n/zh-Hans/common.ts b/web/i18n/zh-Hans/common.ts index 7d906ed0b4..f80afe8fca 100644 --- a/web/i18n/zh-Hans/common.ts +++ b/web/i18n/zh-Hans/common.ts @@ -276,7 +276,7 @@ const translation = { }, }, modelProvider: { - notConfigured: '系统模型尚未完全配置,部分功能可能无法使用。', + notConfigured: '系统模型尚未完全配置', systemModelSettings: '系统模型设置', systemModelSettingsLink: '为什么需要设置系统模型?', selectModel: '选择您的模型', From d1452d4af4ec2d41e90f7f3db68ae81bfdc4e280 Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Fri, 11 Oct 2024 13:04:57 +0800 Subject: [PATCH 034/346] no provider installed --- .../model-provider-page/index.tsx | 48 +++++++++++-------- web/i18n/en-US/common.ts | 6 +++ web/i18n/zh-Hans/common.ts | 6 +++ 3 files changed, 40 insertions(+), 20 deletions(-) diff --git a/web/app/components/header/account-setting/model-provider-page/index.tsx b/web/app/components/header/account-setting/model-provider-page/index.tsx index 8862b0029b..744e8b8daa 100644 --- a/web/app/components/header/account-setting/model-provider-page/index.tsx +++ b/web/app/components/header/account-setting/model-provider-page/index.tsx @@ -1,6 +1,6 @@ import { useMemo } from 'react' import { useTranslation } from 'react-i18next' -import { RiAlertFill } from '@remixicon/react' +import { RiAlertFill, RiBrainLine } from '@remixicon/react' import SystemModelSelector from './system-model-selector' import ProviderAddedCard, { UPDATE_MODEL_PROVIDER_CUSTOM_MODEL_LIST } from './provider-added-card' import ProviderCard from './provider-card' @@ -58,25 +58,25 @@ const ModelProviderPage = () => { const handleOpenModal = ( provider: ModelProvider, - configurateMethod: ConfigurationMethodEnum, + configurationMethod: ConfigurationMethodEnum, CustomConfigurationModelFixedFields?: CustomConfigurationModelFixedFields, ) => { setShowModelModal({ payload: { currentProvider: provider, - currentConfigurationMethod: configurateMethod, + currentConfigurationMethod: configurationMethod, currentCustomConfigurationModelFixedFields: CustomConfigurationModelFixedFields, }, onSaveCallback: () => { updateModelProviders() - if (configurateMethod === ConfigurationMethodEnum.predefinedModel) { + if (configurationMethod === ConfigurationMethodEnum.predefinedModel) { provider.supported_model_types.forEach((type) => { updateModelList(type) }) } - if (configurateMethod === ConfigurationMethodEnum.customizableModel && provider.custom_configuration.status === CustomConfigurationStatusEnum.active) { + if (configurationMethod === ConfigurationMethodEnum.customizableModel && provider.custom_configuration.status === CustomConfigurationStatusEnum.active) { eventEmitter?.emit({ type: UPDATE_MODEL_PROVIDER_CUSTOM_MODEL_LIST, payload: provider.provider, @@ -114,21 +114,29 @@ const ModelProviderPage = () => { /> </div> </div> - { - !!configuredProviders?.length && ( - <div className='pb-3'> - { - configuredProviders?.map(provider => ( - <ProviderAddedCard - key={provider.provider} - provider={provider} - onOpenModal={(configurateMethod: ConfigurationMethodEnum, currentCustomConfigurationModelFixedFields?: CustomConfigurationModelFixedFields) => handleOpenModal(provider, configurateMethod, currentCustomConfigurationModelFixedFields)} - /> - )) - } + {!configuredProviders?.length && ( + <div className='mb-2 p-4 rounded-[10px]' style={{ background: 'linear-gradient(90deg, rgba(200, 206, 218, 0.20) 0%, rgba(200, 206, 218, 0.04) 100%)' }}> + <div className='w-10 h-10 flex items-center justify-center rounded-[10px] border-[0.5px] border-components-card-border bg-components-card-bg shadow-lg backdrop-blur'> + <RiBrainLine className='w-5 h-5 text-text-primary' /> </div> - ) - } + <div className='mt-2 text-text-secondary system-sm-medium'>{t('common.modelProvider.emptyProviderTitle')}</div> + <div className='mt-1 text-text-tertiary system-xs-regular'>{t('common.modelProvider.emptyProviderTip')}</div> + </div> + )} + {!!configuredProviders?.length && ( + <div className='pb-3'> + {configuredProviders?.map(provider => ( + <ProviderAddedCard + key={provider.provider} + provider={provider} + onOpenModal={(configurationMethod: ConfigurationMethodEnum, currentCustomConfigurationModelFixedFields?: CustomConfigurationModelFixedFields) => handleOpenModal(provider, configurationMethod, currentCustomConfigurationModelFixedFields)} + /> + ))} + </div> + )} + <div className='flex items-center mb-2 pt-2'>{t('common.modelProvider.configureRequired')}</div> + <div className='flex items-center mb-2 pt-2'>{t('common.modelProvider.installProvider')}</div> + <div className='flex items-center mb-2 pt-2'>{t('common.modelProvider.discoverMore')}</div> { !!notConfiguredProviders?.length && ( <> @@ -142,7 +150,7 @@ const ModelProviderPage = () => { <ProviderCard key={provider.provider} provider={provider} - onOpenModal={(configurateMethod: ConfigurationMethodEnum) => handleOpenModal(provider, configurateMethod)} + onOpenModal={(configurationMethod: ConfigurationMethodEnum) => handleOpenModal(provider, configurationMethod)} /> )) } diff --git a/web/i18n/en-US/common.ts b/web/i18n/en-US/common.ts index 3bdeb7cec9..11db6f7359 100644 --- a/web/i18n/en-US/common.ts +++ b/web/i18n/en-US/common.ts @@ -374,6 +374,12 @@ const translation = { loadBalancingLeastKeyWarning: 'To enable load balancing at least 2 keys must be enabled.', loadBalancingInfo: 'By default, load balancing uses the Round-robin strategy. If rate limiting is triggered, a 1-minute cooldown period will be applied.', upgradeForLoadBalancing: 'Upgrade your plan to enable Load Balancing.', + configureRequired: 'Configure required', + configureTip: 'Set up api-key or add model to use', + installProvider: 'Install model providers', + discoverMore: 'Discover more in', + emptyProviderTitle: 'Model provider not set up', + emptyProviderTip: 'Please install a model provider first.', }, dataSource: { add: 'Add a data source', diff --git a/web/i18n/zh-Hans/common.ts b/web/i18n/zh-Hans/common.ts index f80afe8fca..17edc3a958 100644 --- a/web/i18n/zh-Hans/common.ts +++ b/web/i18n/zh-Hans/common.ts @@ -374,6 +374,12 @@ const translation = { loadBalancingInfo: '默认情况下,负载平衡使用 Round-robin 策略。如果触发速率限制,将应用 1 分钟的冷却时间', upgradeForLoadBalancing: '升级以解锁负载均衡功能', apiKey: 'API 密钥', + configureRequired: '尚未配置', + configureTip: '请配置 API 密钥,添加模型。', + installProvider: '安装模型供应商', + discoverMore: '发现更多就在', + emptyProviderTitle: '尚未安装模型供应商', + emptyProviderTip: '请安装模型供应商。', }, dataSource: { add: '添加数据源', From 4cc6dfa2329d4babf38e4f3d8091d556d304068b Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Fri, 11 Oct 2024 13:55:09 +0800 Subject: [PATCH 035/346] new style of provider card --- .../header/account-setting/model-provider-page/index.tsx | 2 +- .../provider-added-card/credential-panel.tsx | 6 +++--- .../model-provider-page/provider-added-card/index.tsx | 9 +++++---- .../provider-added-card/model-list.tsx | 9 ++++++--- 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/web/app/components/header/account-setting/model-provider-page/index.tsx b/web/app/components/header/account-setting/model-provider-page/index.tsx index 744e8b8daa..84916fb05a 100644 --- a/web/app/components/header/account-setting/model-provider-page/index.tsx +++ b/web/app/components/header/account-setting/model-provider-page/index.tsx @@ -124,7 +124,7 @@ const ModelProviderPage = () => { </div> )} {!!configuredProviders?.length && ( - <div className='pb-3'> + <div className='relative'> {configuredProviders?.map(provider => ( <ProviderAddedCard key={provider.provider} diff --git a/web/app/components/header/account-setting/model-provider-page/provider-added-card/credential-panel.tsx b/web/app/components/header/account-setting/model-provider-page/provider-added-card/credential-panel.tsx index f141e0018c..e7f865f198 100644 --- a/web/app/components/header/account-setting/model-provider-page/provider-added-card/credential-panel.tsx +++ b/web/app/components/header/account-setting/model-provider-page/provider-added-card/credential-panel.tsx @@ -1,5 +1,6 @@ import type { FC } from 'react' import { useTranslation } from 'react-i18next' +import { RiEqualizer2Line } from '@remixicon/react' import type { ModelProvider } from '../declarations' import { ConfigurationMethodEnum, @@ -14,7 +15,6 @@ import PrioritySelector from './priority-selector' import PriorityUseTip from './priority-use-tip' import { UPDATE_MODEL_PROVIDER_CUSTOM_MODEL_LIST } from './index' import Indicator from '@/app/components/header/indicator' -import { Settings01 } from '@/app/components/base/icons/src/vender/line/general' import Button from '@/app/components/base/button' import { changeModelProviderPriority } from '@/service/common' import { useToastContext } from '@/app/components/base/toast' @@ -69,7 +69,7 @@ const CredentialPanel: FC<CredentialPanelProps> = ({ <div className='shrink-0 relative ml-1 p-1 w-[112px] rounded-lg bg-white/[0.3] border-[0.5px] border-black/5'> <div className='flex items-center justify-between mb-1 pt-1 pl-2 pr-[7px] h-5 text-xs font-medium text-gray-500'> API-KEY - <Indicator color={isCustomConfigured ? 'green' : 'gray'} /> + <Indicator color={isCustomConfigured ? 'green' : 'red'} /> </div> <div className='flex items-center gap-0.5'> <Button @@ -77,7 +77,7 @@ const CredentialPanel: FC<CredentialPanelProps> = ({ size='small' onClick={onSetup} > - <Settings01 className='mr-1 w-3 h-3' /> + <RiEqualizer2Line className='mr-1 w-3.5 h-3.5' /> {t('common.operation.setup')} </Button> { diff --git a/web/app/components/header/account-setting/model-provider-page/provider-added-card/index.tsx b/web/app/components/header/account-setting/model-provider-page/provider-added-card/index.tsx index 5e73b36c42..9cb3899235 100644 --- a/web/app/components/header/account-setting/model-provider-page/provider-added-card/index.tsx +++ b/web/app/components/header/account-setting/model-provider-page/provider-added-card/index.tsx @@ -2,6 +2,7 @@ import type { FC } from 'react' import { useState } from 'react' import { useTranslation } from 'react-i18next' import { + RiArrowRightSLine, RiLoader2Line, } from '@remixicon/react' import type { @@ -21,7 +22,6 @@ import CredentialPanel from './credential-panel' import QuotaPanel from './quota-panel' import ModelList from './model-list' import AddModelButton from './add-model-button' -import { ChevronDownDouble } from '@/app/components/base/icons/src/vender/line/arrows' import { fetchModelProviderModelList } from '@/service/common' import { useEventEmitterContextContext } from '@/context/event-emitter' import { IS_CE_EDITION } from '@/config' @@ -116,23 +116,24 @@ const ProviderAddedCard: FC<ProviderAddedCardProps> = ({ { collapsed && ( <div className='group flex items-center justify-between pl-2 py-1.5 pr-[11px] border-t border-t-black/5 bg-white/30 text-xs font-medium text-gray-500'> - <div className='group-hover:hidden pl-1 pr-1.5 h-6 leading-6'> + <div className='group-hover:hidden flex items-center pl-1 pr-1.5 h-6 leading-6'> { hasModelList ? t('common.modelProvider.modelsNum', { num: modelList.length }) : t('common.modelProvider.showModels') } + {!loading && <RiArrowRightSLine className='w-4 h-4' />} </div> <div className='hidden group-hover:flex items-center pl-1 pr-1.5 h-6 rounded-lg hover:bg-white cursor-pointer' onClick={handleOpenModelList} > - <ChevronDownDouble className='mr-0.5 w-3 h-3' /> { hasModelList ? t('common.modelProvider.showModelsNum', { num: modelList.length }) : t('common.modelProvider.showModels') } + {!loading && <RiArrowRightSLine className='w-4 h-4' />} { loading && ( <RiLoader2Line className='ml-0.5 animate-spin w-3 h-3' /> @@ -143,7 +144,7 @@ const ProviderAddedCard: FC<ProviderAddedCardProps> = ({ configurationMethods.includes(ConfigurationMethodEnum.customizableModel) && isCurrentWorkspaceManager && ( <AddModelButton onClick={() => onOpenModal(ConfigurationMethodEnum.customizableModel)} - className='hidden group-hover:flex group-hover:text-primary-600' + className='flex' /> ) } diff --git a/web/app/components/header/account-setting/model-provider-page/provider-added-card/model-list.tsx b/web/app/components/header/account-setting/model-provider-page/provider-added-card/model-list.tsx index e321d4076d..709560b419 100644 --- a/web/app/components/header/account-setting/model-provider-page/provider-added-card/model-list.tsx +++ b/web/app/components/header/account-setting/model-provider-page/provider-added-card/model-list.tsx @@ -1,6 +1,9 @@ import type { FC } from 'react' import { useCallback } from 'react' import { useTranslation } from 'react-i18next' +import { + RiArrowRightSLine, +} from '@remixicon/react' import type { CustomConfigurationModelFixedFields, ModelItem, @@ -12,7 +15,6 @@ import { // import Tab from './tab' import AddModelButton from './add-model-button' import ModelListItem from './model-list-item' -import { ChevronDownDouble } from '@/app/components/base/icons/src/vender/line/arrows' import { useModalContextSelector } from '@/context/modal-context' import { useAppContext } from '@/context/app-context' @@ -53,13 +55,14 @@ const ModelList: FC<ModelListProps> = ({ <span className='group shrink-0 flex items-center mr-2'> <span className='group-hover:hidden pl-1 pr-1.5 h-6 leading-6 text-xs font-medium text-gray-500'> {t('common.modelProvider.modelsNum', { num: models.length })} + <RiArrowRightSLine className='mr-0.5 w-4 h-4 rotate-90' /> </span> <span className='hidden group-hover:inline-flex items-center pl-1 pr-1.5 h-6 text-xs font-medium text-gray-500 bg-gray-50 cursor-pointer rounded-lg' onClick={() => onCollapse()} > - <ChevronDownDouble className='mr-0.5 w-3 h-3 rotate-180' /> - {t('common.modelProvider.collapse')} + {t('common.modelProvider.modelsNum', { num: models.length })} + <RiArrowRightSLine className='mr-0.5 w-4 h-4 rotate-90' /> </span> </span> {/* { From 495dec143c6314af0a0e0d87a52bdf0b55cd77c5 Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Fri, 11 Oct 2024 15:14:13 +0800 Subject: [PATCH 036/346] unconfigured provider --- .../model-provider-page/index.tsx | 39 +++++------ .../provider-added-card/index.tsx | 64 +++++++++++-------- .../provider-added-card/model-list.tsx | 2 +- 3 files changed, 56 insertions(+), 49 deletions(-) diff --git a/web/app/components/header/account-setting/model-provider-page/index.tsx b/web/app/components/header/account-setting/model-provider-page/index.tsx index 84916fb05a..8dc6513c05 100644 --- a/web/app/components/header/account-setting/model-provider-page/index.tsx +++ b/web/app/components/header/account-setting/model-provider-page/index.tsx @@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next' import { RiAlertFill, RiBrainLine } from '@remixicon/react' import SystemModelSelector from './system-model-selector' import ProviderAddedCard, { UPDATE_MODEL_PROVIDER_CUSTOM_MODEL_LIST } from './provider-added-card' -import ProviderCard from './provider-card' +// import ProviderCard from './provider-card' import type { CustomConfigurationModelFixedFields, ModelProvider, @@ -134,30 +134,23 @@ const ModelProviderPage = () => { ))} </div> )} - <div className='flex items-center mb-2 pt-2'>{t('common.modelProvider.configureRequired')}</div> + {!!notConfiguredProviders?.length && ( + <> + <div className='flex items-center mb-2 pt-2 text-text-primary system-md-semibold'>{t('common.modelProvider.configureRequired')}</div> + <div className='relative'> + {notConfiguredProviders?.map(provider => ( + <ProviderAddedCard + notConfigured + key={provider.provider} + provider={provider} + onOpenModal={(configurationMethod: ConfigurationMethodEnum, currentCustomConfigurationModelFixedFields?: CustomConfigurationModelFixedFields) => handleOpenModal(provider, configurationMethod, currentCustomConfigurationModelFixedFields)} + /> + ))} + </div> + </> + )} <div className='flex items-center mb-2 pt-2'>{t('common.modelProvider.installProvider')}</div> <div className='flex items-center mb-2 pt-2'>{t('common.modelProvider.discoverMore')}</div> - { - !!notConfiguredProviders?.length && ( - <> - <div className='flex items-center mb-2 text-xs font-semibold text-gray-500'> - + {t('common.modelProvider.addMoreModelProvider')} - <span className='grow ml-3 h-[1px] bg-gradient-to-r from-[#f3f4f6]' /> - </div> - <div className='grid grid-cols-3 gap-2'> - { - notConfiguredProviders?.map(provider => ( - <ProviderCard - key={provider.provider} - provider={provider} - onOpenModal={(configurationMethod: ConfigurationMethodEnum) => handleOpenModal(provider, configurationMethod)} - /> - )) - } - </div> - </> - ) - } </div> ) } diff --git a/web/app/components/header/account-setting/model-provider-page/provider-added-card/index.tsx b/web/app/components/header/account-setting/model-provider-page/provider-added-card/index.tsx index 9cb3899235..46ef6add24 100644 --- a/web/app/components/header/account-setting/model-provider-page/provider-added-card/index.tsx +++ b/web/app/components/header/account-setting/model-provider-page/provider-added-card/index.tsx @@ -3,6 +3,7 @@ import { useState } from 'react' import { useTranslation } from 'react-i18next' import { RiArrowRightSLine, + RiInformation2Fill, RiLoader2Line, } from '@remixicon/react' import type { @@ -29,10 +30,12 @@ import { useAppContext } from '@/context/app-context' export const UPDATE_MODEL_PROVIDER_CUSTOM_MODEL_LIST = 'UPDATE_MODEL_PROVIDER_CUSTOM_MODEL_LIST' type ProviderAddedCardProps = { + notConfigured?: boolean provider: ModelProvider onOpenModal: (configurationMethod: ConfigurationMethodEnum, currentCustomConfigurationModelFixedFields?: CustomConfigurationModelFixedFields) => void } const ProviderAddedCard: FC<ProviderAddedCardProps> = ({ + notConfigured, provider, onOpenModal, }) => { @@ -47,6 +50,7 @@ const ProviderAddedCard: FC<ProviderAddedCardProps> = ({ const hasModelList = fetched && !!modelList.length const { isCurrentWorkspaceManager } = useAppContext() const showQuota = systemConfig.enabled && [...MODEL_PROVIDER_QUOTA_GET_PAID].includes(provider.provider) && !IS_CE_EDITION + const showCredential = configurationMethods.includes(ConfigurationMethodEnum.predefinedModel) && isCurrentWorkspaceManager const getModelList = async (providerName: string) => { if (loading) @@ -105,7 +109,7 @@ const ProviderAddedCard: FC<ProviderAddedCardProps> = ({ ) } { - configurationMethods.includes(ConfigurationMethodEnum.predefinedModel) && isCurrentWorkspaceManager && ( + showCredential && ( <CredentialPanel onSetup={() => onOpenModal(ConfigurationMethodEnum.predefinedModel)} provider={provider} @@ -116,30 +120,40 @@ const ProviderAddedCard: FC<ProviderAddedCardProps> = ({ { collapsed && ( <div className='group flex items-center justify-between pl-2 py-1.5 pr-[11px] border-t border-t-black/5 bg-white/30 text-xs font-medium text-gray-500'> - <div className='group-hover:hidden flex items-center pl-1 pr-1.5 h-6 leading-6'> - { - hasModelList - ? t('common.modelProvider.modelsNum', { num: modelList.length }) - : t('common.modelProvider.showModels') - } - {!loading && <RiArrowRightSLine className='w-4 h-4' />} - </div> - <div - className='hidden group-hover:flex items-center pl-1 pr-1.5 h-6 rounded-lg hover:bg-white cursor-pointer' - onClick={handleOpenModelList} - > - { - hasModelList - ? t('common.modelProvider.showModelsNum', { num: modelList.length }) - : t('common.modelProvider.showModels') - } - {!loading && <RiArrowRightSLine className='w-4 h-4' />} - { - loading && ( - <RiLoader2Line className='ml-0.5 animate-spin w-3 h-3' /> - ) - } - </div> + {(showQuota || !notConfigured) && ( + <> + <div className='group-hover:hidden flex items-center pl-1 pr-1.5 h-6 leading-6'> + { + hasModelList + ? t('common.modelProvider.modelsNum', { num: modelList.length }) + : t('common.modelProvider.showModels') + } + {!loading && <RiArrowRightSLine className='w-4 h-4' />} + </div> + <div + className='hidden group-hover:flex items-center pl-1 pr-1.5 h-6 rounded-lg hover:bg-white cursor-pointer' + onClick={handleOpenModelList} + > + { + hasModelList + ? t('common.modelProvider.showModelsNum', { num: modelList.length }) + : t('common.modelProvider.showModels') + } + {!loading && <RiArrowRightSLine className='w-4 h-4' />} + { + loading && ( + <RiLoader2Line className='ml-0.5 animate-spin w-3 h-3' /> + ) + } + </div> + </> + )} + {!showQuota && notConfigured && ( + <div className='flex items-center pl-1 pr-1.5 h-6'> + <RiInformation2Fill className='mr-1 w-4 h-4 text-text-accent' /> + <span>{t('common.modelProvider.configureTip')}</span> + </div> + )} { configurationMethods.includes(ConfigurationMethodEnum.customizableModel) && isCurrentWorkspaceManager && ( <AddModelButton diff --git a/web/app/components/header/account-setting/model-provider-page/provider-added-card/model-list.tsx b/web/app/components/header/account-setting/model-provider-page/provider-added-card/model-list.tsx index 709560b419..5e70a0def1 100644 --- a/web/app/components/header/account-setting/model-provider-page/provider-added-card/model-list.tsx +++ b/web/app/components/header/account-setting/model-provider-page/provider-added-card/model-list.tsx @@ -53,7 +53,7 @@ const ModelList: FC<ModelListProps> = ({ <div className='py-1 bg-white rounded-lg'> <div className='flex items-center pl-1 pr-[3px]'> <span className='group shrink-0 flex items-center mr-2'> - <span className='group-hover:hidden pl-1 pr-1.5 h-6 leading-6 text-xs font-medium text-gray-500'> + <span className='group-hover:hidden inline-flex pl-1 pr-1.5 h-6 leading-6 text-xs font-medium text-gray-500'> {t('common.modelProvider.modelsNum', { num: models.length })} <RiArrowRightSLine className='mr-0.5 w-4 h-4 rotate-90' /> </span> From e7dc16fd08d09966c2fd191bbe28a2d51413f2fe Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Fri, 11 Oct 2024 16:21:03 +0800 Subject: [PATCH 037/346] provider card --- .../(commonLayout)/plugins/test/card/page.tsx | 2 +- .../model-provider-page/index.tsx | 49 ++++++++++-- .../components/plugins/install-model-item.tsx | 7 +- web/app/components/plugins/provider-card.tsx | 74 +++++++++++++++++++ web/i18n/en-US/common.ts | 2 +- 5 files changed, 124 insertions(+), 10 deletions(-) create mode 100644 web/app/components/plugins/provider-card.tsx diff --git a/web/app/(commonLayout)/plugins/test/card/page.tsx b/web/app/(commonLayout)/plugins/test/card/page.tsx index e7ba6849bb..0b76e183f9 100644 --- a/web/app/(commonLayout)/plugins/test/card/page.tsx +++ b/web/app/(commonLayout)/plugins/test/card/page.tsx @@ -43,7 +43,7 @@ const PluginList = async () => { <h3 className='my-1'>Install model provide</h3> <div className='grid grid-cols-2 gap-3'> {pluginList.map((plugin, index) => ( - <InstallModelItem key={index} payload={plugin as any} /> + <InstallModelItem key={index} locale={locale} payload={plugin as any} /> ))} </div> diff --git a/web/app/components/header/account-setting/model-provider-page/index.tsx b/web/app/components/header/account-setting/model-provider-page/index.tsx index 8dc6513c05..5f0ac829c1 100644 --- a/web/app/components/header/account-setting/model-provider-page/index.tsx +++ b/web/app/components/header/account-setting/model-provider-page/index.tsx @@ -1,6 +1,13 @@ -import { useMemo } from 'react' +import { useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' -import { RiAlertFill, RiBrainLine } from '@remixicon/react' +import Link from 'next/link' +import { + RiAlertFill, + RiArrowDownSLine, + RiArrowRightUpLine, + RiBrainLine, +} from '@remixicon/react' +import { useContext } from 'use-context-selector' import SystemModelSelector from './system-model-selector' import ProviderAddedCard, { UPDATE_MODEL_PROVIDER_CUSTOM_MODEL_LIST } from './provider-added-card' // import ProviderCard from './provider-card' @@ -18,11 +25,16 @@ import { useUpdateModelList, useUpdateModelProviders, } from './hooks' +import Divider from '@/app/components/base/divider' +import ProviderCard from '@/app/components/plugins/provider-card' +import I18n from '@/context/i18n' import { useProviderContext } from '@/context/provider-context' import { useModalContextSelector } from '@/context/modal-context' import { useEventEmitterContextContext } from '@/context/event-emitter' import cn from '@/utils/classnames' +import { extensionDallE, modelGPT4, toolNotion } from '@/app/components/plugins/card/card-mock' + const ModelProviderPage = () => { const { t } = useTranslation() const { eventEmitter } = useEventEmitterContextContext() @@ -89,6 +101,12 @@ const ModelProviderPage = () => { }) } + const [collapse, setCollapse] = useState(false) + const { locale } = useContext(I18n) + + // TODO #Plugin list API# + const pluginList = [toolNotion, extensionDallE, modelGPT4] + return ( <div className='relative pt-1 -mt-2'> <div className={cn('flex items-center mb-2')}> @@ -134,7 +152,7 @@ const ModelProviderPage = () => { ))} </div> )} - {!!notConfiguredProviders?.length && ( + {false && !!notConfiguredProviders?.length && ( <> <div className='flex items-center mb-2 pt-2 text-text-primary system-md-semibold'>{t('common.modelProvider.configureRequired')}</div> <div className='relative'> @@ -149,8 +167,29 @@ const ModelProviderPage = () => { </div> </> )} - <div className='flex items-center mb-2 pt-2'>{t('common.modelProvider.installProvider')}</div> - <div className='flex items-center mb-2 pt-2'>{t('common.modelProvider.discoverMore')}</div> + <div className='mb-2'> + <Divider className='!mt-4 h-px' /> + <div className='flex items-center justify-between'> + <div className='flex items-center gap-1 text-text-primary system-md-semibold cursor-pointer' onClick={() => setCollapse(!collapse)}> + <RiArrowDownSLine className={cn('w-4 h-4', collapse && '-rotate-90')} /> + {t('common.modelProvider.installProvider')} + </div> + <div className='flex items-center mb-2 pt-2'> + <span className='pr-1 text-text-tertiary system-sm-regular'>{t('common.modelProvider.discoverMore')}</span> + <Link target="_blank" href="/plugins" className='inline-flex items-center system-sm-medium text-text-accent'> + Dify Marketplace + <RiArrowRightUpLine className='w-4 h-4' /> + </Link> + </div> + </div> + {!collapse && ( + <div className='grid grid-cols-2 gap-2'> + {pluginList.map((plugin, index) => ( + <ProviderCard key={index} locale={locale} payload={plugin as any} /> + ))} + </div> + )} + </div> </div> ) } diff --git a/web/app/components/plugins/install-model-item.tsx b/web/app/components/plugins/install-model-item.tsx index 05d8426566..57a00ce1ef 100644 --- a/web/app/components/plugins/install-model-item.tsx +++ b/web/app/components/plugins/install-model-item.tsx @@ -1,5 +1,5 @@ -import type { FC } from 'react' import React from 'react' +import type { FC } from 'react' import { RiVerifiedBadgeLine } from '@remixicon/react' import Badge from '../base/badge' import type { Plugin } from './types' @@ -7,19 +7,20 @@ import Description from './card/base/description' import Icon from './card/base/card-icon' import Title from './card/base/title' import DownloadCount from './card/base/download-count' -import { getLocaleOnServer } from '@/i18n/server' +import type { Locale } from '@/i18n' import cn from '@/utils/classnames' type Props = { className?: string + locale: Locale // The component is used in both client and server side, so we can't get the locale from both side(getLocaleOnServer and useContext) payload: Plugin } const PluginItem: FC<Props> = async ({ className, + locale, payload, }) => { - const locale = getLocaleOnServer() const { org, label } = payload return ( diff --git a/web/app/components/plugins/provider-card.tsx b/web/app/components/plugins/provider-card.tsx new file mode 100644 index 0000000000..4892d9da29 --- /dev/null +++ b/web/app/components/plugins/provider-card.tsx @@ -0,0 +1,74 @@ +import React from 'react' +import type { FC } from 'react' +import { RiArrowRightUpLine, RiVerifiedBadgeLine } from '@remixicon/react' +import Badge from '../base/badge' +import type { Plugin } from './types' +import Description from './card/base/description' +import Icon from './card/base/card-icon' +import Title from './card/base/title' +import DownloadCount from './card/base/download-count' +import Button from '@/app/components/base/button' +import type { Locale } from '@/i18n' +import cn from '@/utils/classnames' + +type Props = { + className?: string + locale: Locale // The component is used in both client and server side, so we can't get the locale from both side(getLocaleOnServer and useContext) + payload: Plugin +} + +const ProviderCard: FC<Props> = ({ + className, + locale, + payload, +}) => { + const { org, label } = payload + + return ( + <div className={cn('group relative p-4 pb-3 border-[0.5px] border-components-panel-border bg-components-panel-on-panel-item-bg hover-bg-components-panel-on-panel-item-bg rounded-xl shadow-xs', className)}> + {/* Header */} + <div className="flex"> + <Icon src={payload.icon} /> + <div className="ml-3 w-0 grow"> + <div className="flex items-center h-5"> + <Title title={label[locale]} /> + <RiVerifiedBadgeLine className="shrink-0 ml-0.5 w-4 h-4 text-text-accent" /> + </div> + <div className='mb-1 flex justify-between items-center h-4'> + <div className='flex items-center'> + <div className='text-text-tertiary system-xs-regular'>{org}</div> + <div className='mx-2 text-text-quaternary system-xs-regular'>·</div> + <DownloadCount downloadCount={payload.install_count || 0} /> + </div> + </div> + </div> + </div> + <Description className='mt-3' text={payload.brief[locale]} descriptionLineRows={2}></Description> + <div className='mt-3 flex space-x-0.5'> + {['LLM', 'text embedding', 'speech2text'].map(tag => ( + <Badge key={tag} text={tag} /> + ))} + </div> + <div + className='hidden group-hover:flex items-center gap-2 absolute bottom-0 left-0 right-0 p-4 pt-8' + style={{ background: 'linear-gradient(0deg, #F9FAFB 60.27%, rgba(249, 250, 251, 0.00) 100%)' }} + > + <Button + className='flex-grow' + variant='primary' + > + Install + </Button> + <Button + className='flex-grow' + variant='secondary' + > + Details + <RiArrowRightUpLine className='w-4 h-4' /> + </Button> + </div> + </div> + ) +} + +export default ProviderCard diff --git a/web/i18n/en-US/common.ts b/web/i18n/en-US/common.ts index 11db6f7359..963a9d6a59 100644 --- a/web/i18n/en-US/common.ts +++ b/web/i18n/en-US/common.ts @@ -377,7 +377,7 @@ const translation = { configureRequired: 'Configure required', configureTip: 'Set up api-key or add model to use', installProvider: 'Install model providers', - discoverMore: 'Discover more in', + discoverMore: 'Discover more in ', emptyProviderTitle: 'Model provider not set up', emptyProviderTip: 'Please install a model provider first.', }, From 95777d23e0de99d3f50e597ee6c148515aac293d Mon Sep 17 00:00:00 2001 From: Yi <yxiaoisme@gmail.com> Date: Fri, 11 Oct 2024 16:27:31 +0800 Subject: [PATCH 038/346] fix: naming styles --- web/app/(commonLayout)/plugins/{Container.tsx => C.tsx} | 2 +- .../{InstallPluginDropdown.tsx => Install-plugin-dropdown.tsx} | 0 web/app/(commonLayout)/plugins/page.tsx | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename web/app/(commonLayout)/plugins/{Container.tsx => C.tsx} (98%) rename web/app/(commonLayout)/plugins/{InstallPluginDropdown.tsx => Install-plugin-dropdown.tsx} (100%) diff --git a/web/app/(commonLayout)/plugins/Container.tsx b/web/app/(commonLayout)/plugins/C.tsx similarity index 98% rename from web/app/(commonLayout)/plugins/Container.tsx rename to web/app/(commonLayout)/plugins/C.tsx index f3de74cfab..8c97f3b4bf 100644 --- a/web/app/(commonLayout)/plugins/Container.tsx +++ b/web/app/(commonLayout)/plugins/C.tsx @@ -8,7 +8,7 @@ import { RiClipboardLine, RiEqualizer2Line, } from '@remixicon/react' -import InstallPluginDropdown from './InstallPluginDropdown' +import InstallPluginDropdown from './Install-plugin-dropdown' import { useTabSearchParams } from '@/hooks/use-tab-searchparams' import { useModalContext } from '@/context/modal-context' import Button from '@/app/components/base/button' diff --git a/web/app/(commonLayout)/plugins/InstallPluginDropdown.tsx b/web/app/(commonLayout)/plugins/Install-plugin-dropdown.tsx similarity index 100% rename from web/app/(commonLayout)/plugins/InstallPluginDropdown.tsx rename to web/app/(commonLayout)/plugins/Install-plugin-dropdown.tsx diff --git a/web/app/(commonLayout)/plugins/page.tsx b/web/app/(commonLayout)/plugins/page.tsx index 830efd7159..d83773ebf2 100644 --- a/web/app/(commonLayout)/plugins/page.tsx +++ b/web/app/(commonLayout)/plugins/page.tsx @@ -1,5 +1,5 @@ import PluginsPanel from './plugins-panel' -import Container from './container' +import Container from './C' import Marketplace from '@/app/components/plugins/marketplace' const PluginList = async () => { From c6377f6e388003fb280fc74b2fa72869e277b653 Mon Sep 17 00:00:00 2001 From: Yi <yxiaoisme@gmail.com> Date: Fri, 11 Oct 2024 16:29:07 +0800 Subject: [PATCH 039/346] fix: naming styles --- web/app/(commonLayout)/plugins/{C.tsx => container.tsx} | 0 web/app/(commonLayout)/plugins/page.tsx | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename web/app/(commonLayout)/plugins/{C.tsx => container.tsx} (100%) diff --git a/web/app/(commonLayout)/plugins/C.tsx b/web/app/(commonLayout)/plugins/container.tsx similarity index 100% rename from web/app/(commonLayout)/plugins/C.tsx rename to web/app/(commonLayout)/plugins/container.tsx diff --git a/web/app/(commonLayout)/plugins/page.tsx b/web/app/(commonLayout)/plugins/page.tsx index d83773ebf2..830efd7159 100644 --- a/web/app/(commonLayout)/plugins/page.tsx +++ b/web/app/(commonLayout)/plugins/page.tsx @@ -1,5 +1,5 @@ import PluginsPanel from './plugins-panel' -import Container from './C' +import Container from './container' import Marketplace from '@/app/components/plugins/marketplace' const PluginList = async () => { From c08f98218cec5b188defbd93116b88426bed0a1d Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Fri, 11 Oct 2024 17:13:28 +0800 Subject: [PATCH 040/346] hide search in other pages --- .../header/account-setting/index.tsx | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/web/app/components/header/account-setting/index.tsx b/web/app/components/header/account-setting/index.tsx index 33b4a0f68a..652ba38322 100644 --- a/web/app/components/header/account-setting/index.tsx +++ b/web/app/components/header/account-setting/index.tsx @@ -204,15 +204,17 @@ export default function AccountSetting({ <div className='shrink-0 ml-2 text-xs text-gray-600'>{activeItem?.description}</div> ) } - <div className='grow flex justify-end'> - <Input - showLeftIcon - wrapperClassName='!w-[200px]' - className='!h-8 !text-[13px]' - onChange={e => setSearchValue(e.target.value)} - value={searchValue} - /> - </div> + {activeItem?.key === 'provider' && ( + <div className='grow flex justify-end'> + <Input + showLeftIcon + wrapperClassName='!w-[200px]' + className='!h-8 !text-[13px]' + onChange={e => setSearchValue(e.target.value)} + value={searchValue} + /> + </div> + )} </div> <div className='px-4 sm:px-8 pt-2'> {activeMenu === 'account' && <AccountPage />} From 1fcb902715a6a3e9c2073174973242b6fc3b479d Mon Sep 17 00:00:00 2001 From: Yi <yxiaoisme@gmail.com> Date: Fri, 11 Oct 2024 17:25:33 +0800 Subject: [PATCH 041/346] feat: add cards to "install from marketplace" --- web/app/components/plugins/card/index.tsx | 14 ++--- .../install-from-marketplace/index.tsx | 53 ++++++++++++++++--- 2 files changed, 50 insertions(+), 17 deletions(-) diff --git a/web/app/components/plugins/card/index.tsx b/web/app/components/plugins/card/index.tsx index b67c68c7e4..9b00284fd4 100644 --- a/web/app/components/plugins/card/index.tsx +++ b/web/app/components/plugins/card/index.tsx @@ -1,7 +1,6 @@ import React from 'react' import { RiVerifiedBadgeLine } from '@remixicon/react' import type { Plugin } from '../types' -import Badge from '../../base/badge' import Icon from '../card/base/card-icon' import CornerMark from './base/corner-mark' import Title from './base/title' @@ -14,7 +13,7 @@ type Props = { className?: string payload: Plugin locale: Locale // The component is used in both client and server side, so we can't get the locale from both side(getLocaleOnServer and useContext) - showVersion?: boolean + titleLeft?: React.ReactNode installed?: boolean descriptionLineRows?: number footer?: React.ReactNode @@ -24,7 +23,7 @@ type Props = { const Card = ({ className, payload, - showVersion, + titleLeft, installed, descriptionLineRows = 2, footer, @@ -42,9 +41,7 @@ const Card = ({ <div className="flex items-center h-5"> <Title title={label[locale]} /> <RiVerifiedBadgeLine className="shrink-0 ml-0.5 w-4 h-4 text-text-accent" /> - { - showVersion && <Badge className='ml-1' text={payload.latest_version} /> - } + {titleLeft} {/* This can be version badge */} </div> <OrgInfo className="mt-0.5" @@ -64,8 +61,3 @@ const Card = ({ } export default Card - -// export function ServerCard(props: Omit<Props, 'serverLocale'>) { -// const serverLocale = getLocaleOnServer() -// return <Card {...props} serverLocale={serverLocale} /> -// } diff --git a/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx b/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx index 36e813bf68..524588132f 100644 --- a/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx +++ b/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx @@ -1,11 +1,14 @@ 'use client' -import React from 'react' +import React, { useState } from 'react' import { useContext } from 'use-context-selector' +import { RiInformation2Line } from '@remixicon/react' import Card from '../../card' import { extensionDallE, modelGPT4, toolNotion } from '../../card/card-mock' import Modal from '@/app/components/base/modal' import Button from '@/app/components/base/button' +import Checkbox from '@/app/components/base/checkbox' +import Badge, { BadgeState } from '@/app/components/base/badge/index' import I18n from '@/context/i18n' type InstallFromMarketplaceProps = { @@ -17,6 +20,7 @@ const InstallFromMarketplace: React.FC<InstallFromMarketplaceProps> = ({ onClose // Mock a plugin list const plugins = [toolNotion, extensionDallE, modelGPT4] + const [selectedPlugins, setSelectedPlugins] = useState<Set<number>>(new Set()) return ( <Modal @@ -35,12 +39,49 @@ const InstallFromMarketplace: React.FC<InstallFromMarketplaceProps> = ({ onClose </div> <div className='flex p-2 items-start content-start gap-1 self-stretch flex-wrap rounded-2xl bg-background-section-burn'> - {plugins.map((plugin, index) => ( - <Card - key={index} - payload={plugin as any} + {plugins.length === 1 + && <Card + payload={plugins[0] as any} locale={locale} - /> + className='w-full' + > + </Card> + } + {plugins.length > 1 && plugins.map((plugin, index) => ( + <div className='flex pl-1 items-center gap-2 flex-grow' key={index}> + <Checkbox + checked={selectedPlugins.has(index)} + onCheck={() => { + const newSelectedPlugins = new Set(selectedPlugins) + if (newSelectedPlugins.has(index)) + newSelectedPlugins.delete(index) + else + newSelectedPlugins.add(index) + + setSelectedPlugins(newSelectedPlugins) + }} + /> + <Card + key={index} + payload={plugin as any} + locale={locale} + className='w-full' + titleLeft={plugin.version === plugin.latest_version + ? <Badge className='mx-1' size="s" state={BadgeState.Default}>{plugin.version}</Badge> + : <> + <Badge + className='mx-1' + size="s" + state={BadgeState.Warning}>{`${plugin.version} -> ${plugin.latest_version}`} + </Badge> + <div className='flex px-0.5 justify-center items-center gap-0.5'> + <div className='text-text-warning system-xs-medium'>Used in 3 apps</div> + <RiInformation2Line className='w-4 h-4 text-text-tertiary' /> + </div> + </> + } + /> + </div> ))} </div> </div> From e2c33fc40f20c8fd20e85fb8b0f72f361e9ecf6c Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Fri, 11 Oct 2024 18:05:36 +0800 Subject: [PATCH 042/346] fix: plugin item i18n --- .../(commonLayout)/plugins/test/card/page.tsx | 17 ++++++++++----- .../plugins/test/card/test-client-plugin.tsx | 21 +++++++++++++++++++ .../components/plugins/plugin-item/index.tsx | 17 +++++++++------ 3 files changed, 44 insertions(+), 11 deletions(-) create mode 100644 web/app/(commonLayout)/plugins/test/card/test-client-plugin.tsx diff --git a/web/app/(commonLayout)/plugins/test/card/page.tsx b/web/app/(commonLayout)/plugins/test/card/page.tsx index 0b76e183f9..83643873e3 100644 --- a/web/app/(commonLayout)/plugins/test/card/page.tsx +++ b/web/app/(commonLayout)/plugins/test/card/page.tsx @@ -1,25 +1,32 @@ import { handleDelete } from './actions' +import TestClientPlugin from './test-client-plugin' import Card from '@/app/components/plugins/card' import { extensionDallE, modelGPT4, toolNotion } from '@/app/components/plugins/card/card-mock' import PluginItem from '@/app/components/plugins/plugin-item' import CardMoreInfo from '@/app/components/plugins/card/card-more-info' import InstallModelItem from '@/app/components/plugins/install-model-item' -import { getLocaleOnServer } from '@/i18n/server' - +import { getLocaleOnServer, useTranslation as translate } from '@/i18n/server' const PluginList = async () => { const locale = getLocaleOnServer() - const pluginList = [toolNotion, extensionDallE, modelGPT4] - + const { t: pluginI8n } = await translate(locale, 'plugin') return ( <div className='pb-3 bg-white'> <div className='mx-3 '> <h2 className='my-3'>Dify Plugin list</h2> <div className='grid grid-cols-2 gap-3'> {pluginList.map((plugin, index) => ( - <PluginItem key={index} payload={plugin as any} onDelete={handleDelete} /> + <PluginItem + key={index} + payload={plugin as any} + onDelete={handleDelete} + pluginI8n={pluginI8n} + locale={locale} + /> ))} </div> + <h2>Client plugin item</h2> + <TestClientPlugin /> <h2 className='my-3'>Install Plugin / Package under bundle</h2> <div className='w-[512px] rounded-2xl bg-background-section-burn p-2'> diff --git a/web/app/(commonLayout)/plugins/test/card/test-client-plugin.tsx b/web/app/(commonLayout)/plugins/test/card/test-client-plugin.tsx new file mode 100644 index 0000000000..8187428d9c --- /dev/null +++ b/web/app/(commonLayout)/plugins/test/card/test-client-plugin.tsx @@ -0,0 +1,21 @@ +'use client' +import React from 'react' +import { useTranslation } from 'react-i18next' +import { useContext } from 'use-context-selector' +import { extensionDallE } from '@/app/components/plugins/card/card-mock' +import PluginItem from '@/app/components/plugins/plugin-item' +import I18n from '@/context/i18n' + +const TestClientPlugin = () => { + const { locale } = useContext(I18n) + const { t } = useTranslation() + return ( + <PluginItem + payload={extensionDallE as any} + onDelete={() => { }} + pluginI8n={t} + locale={locale} + /> + ) +} +export default React.memo(TestClientPlugin) diff --git a/web/app/components/plugins/plugin-item/index.tsx b/web/app/components/plugins/plugin-item/index.tsx index 3c07383274..d4f4159af5 100644 --- a/web/app/components/plugins/plugin-item/index.tsx +++ b/web/app/components/plugins/plugin-item/index.tsx @@ -10,22 +10,27 @@ import Icon from '../card/base/card-icon' import OrgInfo from '../card/base/org-info' import Title from '../card/base/title' import Action from './action' -import { getLocaleOnServer, useTranslation as translate } from '@/i18n/server' import cn from '@/utils/classnames' +import type { Locale } from '@/i18n' type Props = { className?: string payload: Plugin + locale: Locale onDelete: () => void + pluginI8n: any + isClient?: boolean } -const PluginItem: FC<Props> = async ({ +const PluginItem: FC<Props> = ({ className, payload, onDelete, + locale, + pluginI8n, + isClient, }) => { - const locale = getLocaleOnServer() - const { t: pluginI8n } = await translate(locale, 'plugin') + const t = (key: string, param?: object) => pluginI8n(`${isClient ? 'plugin.' : ''}${key}`, param) const { type, name, org, label } = payload const hasNewVersion = payload.latest_version !== payload.version @@ -67,12 +72,12 @@ const PluginItem: FC<Props> = async ({ <div className='mx-2 text-text-quaternary system-xs-regular'>·</div> <div className='flex text-text-tertiary system-xs-regular space-x-1'> <RiLoginCircleLine className='w-4 h-4' /> - <span>{pluginI8n('endpointsEnabled', { num: 2 })}</span> + <span>{t('endpointsEnabled', { num: 2 })}</span> </div> </div> <div className='flex items-center'> - <a href='' target='_blank' className='mr-1 text-text-tertiary system-2xs-medium-uppercase'>{pluginI8n('from')}</a> + <a href='' target='_blank' className='mr-1 text-text-tertiary system-2xs-medium-uppercase'>{t('from')}</a> <div className='flex items-center space-x-0.5 text-text-secondary'> <Github className='ml-1 w-3 h-3' /> <div className='system-2xs-semibold-uppercase'>GitHub</div> From dec4bf6b9815476d830d25039e51fb1377d8ba22 Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Fri, 11 Oct 2024 18:06:23 +0800 Subject: [PATCH 043/346] fix: install modal item server --- web/app/components/plugins/install-model-item.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/app/components/plugins/install-model-item.tsx b/web/app/components/plugins/install-model-item.tsx index 57a00ce1ef..a053cd7671 100644 --- a/web/app/components/plugins/install-model-item.tsx +++ b/web/app/components/plugins/install-model-item.tsx @@ -16,7 +16,7 @@ type Props = { payload: Plugin } -const PluginItem: FC<Props> = async ({ +const PluginItem: FC<Props> = ({ className, locale, payload, From 8dd941e3d25cffd716c3424a7ea1c033ab6cb617 Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Fri, 11 Oct 2024 18:18:32 +0800 Subject: [PATCH 044/346] chore: instal plug add tag --- web/app/(commonLayout)/plugins/test/card/page.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/web/app/(commonLayout)/plugins/test/card/page.tsx b/web/app/(commonLayout)/plugins/test/card/page.tsx index 83643873e3..f0a77f24c1 100644 --- a/web/app/(commonLayout)/plugins/test/card/page.tsx +++ b/web/app/(commonLayout)/plugins/test/card/page.tsx @@ -6,6 +6,7 @@ import PluginItem from '@/app/components/plugins/plugin-item' import CardMoreInfo from '@/app/components/plugins/card/card-more-info' import InstallModelItem from '@/app/components/plugins/install-model-item' import { getLocaleOnServer, useTranslation as translate } from '@/i18n/server' +import Badge from '@/app/components/base/badge' const PluginList = async () => { const locale = getLocaleOnServer() const pluginList = [toolNotion, extensionDallE, modelGPT4] @@ -34,7 +35,9 @@ const PluginList = async () => { payload={toolNotion as any} locale={locale} descriptionLineRows={1} - showVersion + titleLeft={ + <Badge className='ml-1' text={toolNotion.version} /> + } /> </div> <h3 className='my-1'>Installed</h3> From 27ae74af504f2c6155facf74d5ccc1da52572334 Mon Sep 17 00:00:00 2001 From: StyleZhang <jasonapring2015@outlook.com> Date: Sat, 12 Oct 2024 11:03:00 +0800 Subject: [PATCH 045/346] hook --- .../components/plugins/marketplace/hooks.ts | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 web/app/components/plugins/marketplace/hooks.ts diff --git a/web/app/components/plugins/marketplace/hooks.ts b/web/app/components/plugins/marketplace/hooks.ts new file mode 100644 index 0000000000..3846bbac2f --- /dev/null +++ b/web/app/components/plugins/marketplace/hooks.ts @@ -0,0 +1,20 @@ +import { useEffect } from 'react' + +export const useScrollIntersection = ( + rootRef: React.RefObject<HTMLDivElement>, + anchorRef: React.RefObject<HTMLDivElement>, + callback: (isIntersecting: boolean) => void, +) => { + useEffect(() => { + let observer: IntersectionObserver | undefined + if (rootRef.current && anchorRef.current) { + observer = new IntersectionObserver((entries) => { + callback(entries[0].isIntersecting) + }, { + root: rootRef.current, + }) + observer.observe(anchorRef.current) + } + return () => observer?.disconnect() + }, [rootRef, anchorRef, callback]) +} From 466f61d04493c0cb87aeb50a553027e06ad936a2 Mon Sep 17 00:00:00 2001 From: StyleZhang <jasonapring2015@outlook.com> Date: Sat, 12 Oct 2024 11:05:03 +0800 Subject: [PATCH 046/346] relocate file --- web/app/(commonLayout)/plugins/page.tsx | 4 ++-- .../plugins/Install-plugin-dropdown.tsx | 0 web/app/{(commonLayout) => components}/plugins/container.tsx | 0 .../{(commonLayout) => components}/plugins/plugins-panel.tsx | 0 4 files changed, 2 insertions(+), 2 deletions(-) rename web/app/{(commonLayout) => components}/plugins/Install-plugin-dropdown.tsx (100%) rename web/app/{(commonLayout) => components}/plugins/container.tsx (100%) rename web/app/{(commonLayout) => components}/plugins/plugins-panel.tsx (100%) diff --git a/web/app/(commonLayout)/plugins/page.tsx b/web/app/(commonLayout)/plugins/page.tsx index 830efd7159..981319eb4a 100644 --- a/web/app/(commonLayout)/plugins/page.tsx +++ b/web/app/(commonLayout)/plugins/page.tsx @@ -1,5 +1,5 @@ -import PluginsPanel from './plugins-panel' -import Container from './container' +import PluginsPanel from '@/app/components/plugins/plugins-panel' +import Container from '@/app/components/plugins/container' import Marketplace from '@/app/components/plugins/marketplace' const PluginList = async () => { diff --git a/web/app/(commonLayout)/plugins/Install-plugin-dropdown.tsx b/web/app/components/plugins/Install-plugin-dropdown.tsx similarity index 100% rename from web/app/(commonLayout)/plugins/Install-plugin-dropdown.tsx rename to web/app/components/plugins/Install-plugin-dropdown.tsx diff --git a/web/app/(commonLayout)/plugins/container.tsx b/web/app/components/plugins/container.tsx similarity index 100% rename from web/app/(commonLayout)/plugins/container.tsx rename to web/app/components/plugins/container.tsx diff --git a/web/app/(commonLayout)/plugins/plugins-panel.tsx b/web/app/components/plugins/plugins-panel.tsx similarity index 100% rename from web/app/(commonLayout)/plugins/plugins-panel.tsx rename to web/app/components/plugins/plugins-panel.tsx From fcf43ee8459451a5fb5c3288a0e47f5582923d2a Mon Sep 17 00:00:00 2001 From: StyleZhang <jasonapring2015@outlook.com> Date: Sat, 12 Oct 2024 11:33:12 +0800 Subject: [PATCH 047/346] plugin page context --- web/app/(commonLayout)/plugins/page.tsx | 4 +-- .../plugins/plugin-page/context.tsx | 30 +++++++++++++++++++ .../{container.tsx => plugin-page/index.tsx} | 28 ++++++++++++----- .../install-plugin-dropdown.tsx} | 0 4 files changed, 52 insertions(+), 10 deletions(-) create mode 100644 web/app/components/plugins/plugin-page/context.tsx rename web/app/components/plugins/{container.tsx => plugin-page/index.tsx} (87%) rename web/app/components/plugins/{Install-plugin-dropdown.tsx => plugin-page/install-plugin-dropdown.tsx} (100%) diff --git a/web/app/(commonLayout)/plugins/page.tsx b/web/app/(commonLayout)/plugins/page.tsx index 981319eb4a..6220c20aa0 100644 --- a/web/app/(commonLayout)/plugins/page.tsx +++ b/web/app/(commonLayout)/plugins/page.tsx @@ -1,10 +1,10 @@ +import PluginPage from '@/app/components/plugins/plugin-page' import PluginsPanel from '@/app/components/plugins/plugins-panel' -import Container from '@/app/components/plugins/container' import Marketplace from '@/app/components/plugins/marketplace' const PluginList = async () => { return ( - <Container + <PluginPage plugins={<PluginsPanel />} marketplace={<Marketplace />} /> diff --git a/web/app/components/plugins/plugin-page/context.tsx b/web/app/components/plugins/plugin-page/context.tsx new file mode 100644 index 0000000000..94351484b1 --- /dev/null +++ b/web/app/components/plugins/plugin-page/context.tsx @@ -0,0 +1,30 @@ +'use client' + +import type { ReactNode } from 'react' +import { useRef } from 'react' +import { createContext } from 'use-context-selector' + +export type PluginPageContextValue = { + containerRef: React.RefObject<HTMLDivElement> +} + +export const PluginPageContext = createContext<PluginPageContextValue>({ + containerRef: { current: null }, +}) + +type PluginPageContextProviderProps = { + children: ReactNode +} + +export const PluginPageContextProvider = ({ + children, +}: PluginPageContextProviderProps) => { + const containerRef = useRef<HTMLDivElement>(null) + return ( + <PluginPageContext.Provider value={{ + containerRef, + }}> + {children} + </PluginPageContext.Provider> + ) +} diff --git a/web/app/components/plugins/container.tsx b/web/app/components/plugins/plugin-page/index.tsx similarity index 87% rename from web/app/components/plugins/container.tsx rename to web/app/components/plugins/plugin-page/index.tsx index 8c97f3b4bf..fa62a592c7 100644 --- a/web/app/components/plugins/container.tsx +++ b/web/app/components/plugins/plugin-page/index.tsx @@ -1,14 +1,19 @@ 'use client' -import { useMemo, useRef } from 'react' +import { useMemo } from 'react' import { useTranslation } from 'react-i18next' +import { useContextSelector } from 'use-context-selector' import { RiArrowRightUpLine, RiBugLine, RiClipboardLine, RiEqualizer2Line, } from '@remixicon/react' -import InstallPluginDropdown from './Install-plugin-dropdown' +import { + PluginPageContext, + PluginPageContextProvider, +} from './context' +import InstallPluginDropdown from './install-plugin-dropdown' import { useTabSearchParams } from '@/hooks/use-tab-searchparams' import { useModalContext } from '@/context/modal-context' import Button from '@/app/components/base/button' @@ -17,16 +22,17 @@ import ActionButton from '@/app/components/base/action-button' import Tooltip from '@/app/components/base/tooltip' import cn from '@/utils/classnames' -type ContainerWrapperProps = { +export type PluginPageProps = { plugins: React.ReactNode marketplace: React.ReactNode } -const ContainerWrapper = ({ +const PluginPage = ({ plugins, marketplace, -}: ContainerWrapperProps) => { +}: PluginPageProps) => { const { t } = useTranslation() const { setShowPluginSettingModal } = useModalContext() as any + const containerRef = useContextSelector(PluginPageContext, v => v.containerRef) const options = useMemo(() => { return [ @@ -39,8 +45,6 @@ const ContainerWrapper = ({ defaultTab: options[0].value, }) - const containerRef = useRef<HTMLDivElement>(null) - return ( <div ref={containerRef} @@ -118,4 +122,12 @@ const ContainerWrapper = ({ ) } -export default ContainerWrapper +const PluginPageWithContext = (props: PluginPageProps) => { + return ( + <PluginPageContextProvider> + <PluginPage {...props} /> + </PluginPageContextProvider> + ) +} + +export default PluginPageWithContext diff --git a/web/app/components/plugins/Install-plugin-dropdown.tsx b/web/app/components/plugins/plugin-page/install-plugin-dropdown.tsx similarity index 100% rename from web/app/components/plugins/Install-plugin-dropdown.tsx rename to web/app/components/plugins/plugin-page/install-plugin-dropdown.tsx From c75e02b5b2563bb6aeb043dc9eba383225d3ecf6 Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Sat, 12 Oct 2024 09:23:01 +0800 Subject: [PATCH 048/346] update provider card --- .../(commonLayout)/plugins/test/card/page.tsx | 4 +- .../components/plugins/install-model-item.tsx | 57 ------------------- 2 files changed, 2 insertions(+), 59 deletions(-) delete mode 100644 web/app/components/plugins/install-model-item.tsx diff --git a/web/app/(commonLayout)/plugins/test/card/page.tsx b/web/app/(commonLayout)/plugins/test/card/page.tsx index f0a77f24c1..7621404dba 100644 --- a/web/app/(commonLayout)/plugins/test/card/page.tsx +++ b/web/app/(commonLayout)/plugins/test/card/page.tsx @@ -4,7 +4,7 @@ import Card from '@/app/components/plugins/card' import { extensionDallE, modelGPT4, toolNotion } from '@/app/components/plugins/card/card-mock' import PluginItem from '@/app/components/plugins/plugin-item' import CardMoreInfo from '@/app/components/plugins/card/card-more-info' -import InstallModelItem from '@/app/components/plugins/install-model-item' +import ProviderCard from '@/app/components/plugins/provider-card' import { getLocaleOnServer, useTranslation as translate } from '@/i18n/server' import Badge from '@/app/components/base/badge' const PluginList = async () => { @@ -53,7 +53,7 @@ const PluginList = async () => { <h3 className='my-1'>Install model provide</h3> <div className='grid grid-cols-2 gap-3'> {pluginList.map((plugin, index) => ( - <InstallModelItem key={index} locale={locale} payload={plugin as any} /> + <ProviderCard key={index} locale={locale} payload={plugin as any} /> ))} </div> diff --git a/web/app/components/plugins/install-model-item.tsx b/web/app/components/plugins/install-model-item.tsx deleted file mode 100644 index a053cd7671..0000000000 --- a/web/app/components/plugins/install-model-item.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import React from 'react' -import type { FC } from 'react' -import { RiVerifiedBadgeLine } from '@remixicon/react' -import Badge from '../base/badge' -import type { Plugin } from './types' -import Description from './card/base/description' -import Icon from './card/base/card-icon' -import Title from './card/base/title' -import DownloadCount from './card/base/download-count' -import type { Locale } from '@/i18n' -import cn from '@/utils/classnames' - -type Props = { - className?: string - locale: Locale // The component is used in both client and server side, so we can't get the locale from both side(getLocaleOnServer and useContext) - payload: Plugin -} - -const PluginItem: FC<Props> = ({ - className, - locale, - payload, -}) => { - const { org, label } = payload - - return ( - <div className='p-1 bg-background-section-burn rounded-xl'> - <div className={cn('relative p-4 pb-3 border-[0.5px] border-components-panel-border bg-components-panel-on-panel-item-bg hover-bg-components-panel-on-panel-item-bg rounded-xl shadow-xs', className)}> - {/* Header */} - <div className="flex"> - <Icon src={payload.icon} /> - <div className="ml-3 w-0 grow"> - <div className="flex items-center h-5"> - <Title title={label[locale]} /> - <RiVerifiedBadgeLine className="shrink-0 ml-0.5 w-4 h-4 text-text-accent" /> - </div> - <div className='mb-1 flex justify-between items-center h-4'> - <div className='flex items-center'> - <div className='text-text-tertiary system/xs-regular'>{org}</div> - <div className='mx-2 text-text-quaternary system-xs-regular'>·</div> - <DownloadCount downloadCount={payload.install_count || 0} /> - </div> - </div> - </div> - </div> - <Description className='mt-3' text={payload.brief[locale]} descriptionLineRows={2}></Description> - <div className='mt-3 flex space-x-0.5'> - {['LLM', 'text embedding', 'speech2text'].map(tag => ( - <Badge key={tag} text={tag} /> - ))} - </div> - </div> - </div> - ) -} - -export default PluginItem From 060a894bd122b4ce88e082efaa1005c9b05947df Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Sat, 12 Oct 2024 12:35:56 +0800 Subject: [PATCH 049/346] interaction of plugin detail panel --- .../plugins/test/card/actions.ts | 5 + .../(commonLayout)/plugins/test/card/page.tsx | 4 + web/app/components/plugins/card/card-mock.ts | 3 + .../plugins/plugin-detail-panel/index.tsx | 109 ++++++++++++++++++ web/app/components/plugins/provider-card.tsx | 77 +++++++------ web/app/components/plugins/types.ts | 1 + 6 files changed, 162 insertions(+), 37 deletions(-) create mode 100644 web/app/components/plugins/plugin-detail-panel/index.tsx diff --git a/web/app/(commonLayout)/plugins/test/card/actions.ts b/web/app/(commonLayout)/plugins/test/card/actions.ts index 42c335ea87..251d00d272 100644 --- a/web/app/(commonLayout)/plugins/test/card/actions.ts +++ b/web/app/(commonLayout)/plugins/test/card/actions.ts @@ -7,3 +7,8 @@ export async function handleDelete() { // revalidatePath only invalidates the cache when the included path is next visited. revalidatePath('/') } + +export async function fetchPluginDetail(id: string) { + // Fetch plugin detail TODO + return { id } +} diff --git a/web/app/(commonLayout)/plugins/test/card/page.tsx b/web/app/(commonLayout)/plugins/test/card/page.tsx index 7621404dba..81ac3e4ea6 100644 --- a/web/app/(commonLayout)/plugins/test/card/page.tsx +++ b/web/app/(commonLayout)/plugins/test/card/page.tsx @@ -5,6 +5,7 @@ import { extensionDallE, modelGPT4, toolNotion } from '@/app/components/plugins/ import PluginItem from '@/app/components/plugins/plugin-item' import CardMoreInfo from '@/app/components/plugins/card/card-more-info' import ProviderCard from '@/app/components/plugins/provider-card' +import PluginDetailPanel from '@/app/components/plugins/plugin-detail-panel' import { getLocaleOnServer, useTranslation as translate } from '@/i18n/server' import Badge from '@/app/components/base/badge' const PluginList = async () => { @@ -72,6 +73,9 @@ const PluginList = async () => { ))} </div> </div> + <PluginDetailPanel + locale={locale} + /> </div> ) } diff --git a/web/app/components/plugins/card/card-mock.ts b/web/app/components/plugins/card/card-mock.ts index d411288db7..f653e711dd 100644 --- a/web/app/components/plugins/card/card-mock.ts +++ b/web/app/components/plugins/card/card-mock.ts @@ -1,6 +1,7 @@ import { PluginType } from '../types' export const toolNotion = { + id: 'tool-notion', type: PluginType.tool, org: 'Notion', name: 'notion page search', @@ -18,6 +19,7 @@ export const toolNotion = { } export const extensionDallE = { + id: 'extension-dalle', type: PluginType.extension, org: 'OpenAI', name: 'DALL-E', @@ -36,6 +38,7 @@ export const extensionDallE = { } export const modelGPT4 = { + id: 'model-gpt4', type: PluginType.model, org: 'OpenAI', name: 'GPT-4', diff --git a/web/app/components/plugins/plugin-detail-panel/index.tsx b/web/app/components/plugins/plugin-detail-panel/index.tsx new file mode 100644 index 0000000000..14c47f3b01 --- /dev/null +++ b/web/app/components/plugins/plugin-detail-panel/index.tsx @@ -0,0 +1,109 @@ +'use client' +import React, { useEffect, useState } from 'react' +import type { FC } from 'react' +import { usePathname, useRouter, useSearchParams } from 'next/navigation' +import { RiVerifiedBadgeLine } from '@remixicon/react' +import Badge from '../../base/badge' +import type { Plugin } from '../types' +import Description from '../card/base/description' +import Icon from '../card/base/card-icon' +import Title from '../card/base/title' +import DownloadCount from '../card/base/download-count' +import type { Locale } from '@/i18n' +import { fetchPluginDetail } from '@/app/(commonLayout)/plugins/test/card/actions' +import Drawer from '@/app/components/base/drawer' +import Loading from '@/app/components/base/loading' +import cn from '@/utils/classnames' +import { + // extensionDallE, + // modelGPT4, + toolNotion, +} from '@/app/components/plugins/card/card-mock' + +type Props = { + locale: Locale // The component is used in both client and server side, so we can't get the locale from both side(getLocaleOnServer and useContext) +} + +const PluginDetailPanel: FC<Props> = ({ + locale, +}) => { + const searchParams = useSearchParams() + const pluginID = searchParams.get('pluginID') + const router = useRouter() + const pathname = usePathname() + const [loading, setLoading] = useState(true) + const [pluginDetail, setPluginDetail] = useState<Plugin>() + + const getPluginDetail = async (pluginID: string) => { + setLoading(true) + const detail = await fetchPluginDetail(pluginID) + setPluginDetail({ + ...detail, + ...toolNotion, + } as any) + setLoading(false) + } + + const handleClose = () => { + setPluginDetail(undefined) + router.replace(pathname) + } + + useEffect(() => { + if (pluginID) + getPluginDetail(pluginID) + }, [pluginID]) + + if (!pluginID) + return null + + return ( + <Drawer + isOpen={!!pluginDetail} + clickOutsideNotOpen={false} + onClose={handleClose} + footer={null} + mask={false} + positionCenter={false} + panelClassname={cn('mt-[65px] !w-[405px] !max-w-[405px]')} + > + {loading && <Loading type='area' />} + {!loading && pluginDetail && ( + <div + className={cn('w-full flex flex-col bg-white border-[0.5px] border-gray-200 rounded-xl shadow-xl')} + style={{ + height: 'calc(100vh - 65px)', + }} + > + <div className={cn('group relative p-4 pb-3 border-[0.5px] border-components-panel-border bg-components-panel-on-panel-item-bg hover-bg-components-panel-on-panel-item-bg rounded-xl shadow-xs')}> + {/* Header */} + <div className="flex"> + <Icon src={pluginDetail.icon} /> + <div className="ml-3 w-0 grow"> + <div className="flex items-center h-5"> + <Title title={pluginDetail.label[locale]} /> + <RiVerifiedBadgeLine className="shrink-0 ml-0.5 w-4 h-4 text-text-accent" /> + </div> + <div className='mb-1 flex justify-between items-center h-4'> + <div className='flex items-center'> + <div className='text-text-tertiary system-xs-regular'>{pluginDetail.org}</div> + <div className='mx-2 text-text-quaternary system-xs-regular'>·</div> + <DownloadCount downloadCount={pluginDetail.install_count || 0} /> + </div> + </div> + </div> + </div> + <Description className='mt-3' text={pluginDetail.brief[locale]} descriptionLineRows={2}></Description> + <div className='mt-3 flex space-x-0.5'> + {['LLM', 'text embedding', 'speech2text'].map(tag => ( + <Badge key={tag} text={tag} /> + ))} + </div> + </div> + </div> + )} + </Drawer> + ) +} + +export default PluginDetailPanel diff --git a/web/app/components/plugins/provider-card.tsx b/web/app/components/plugins/provider-card.tsx index 4892d9da29..7ee0b55e86 100644 --- a/web/app/components/plugins/provider-card.tsx +++ b/web/app/components/plugins/provider-card.tsx @@ -1,5 +1,6 @@ import React from 'react' import type { FC } from 'react' +import Link from 'next/link' import { RiArrowRightUpLine, RiVerifiedBadgeLine } from '@remixicon/react' import Badge from '../base/badge' import type { Plugin } from './types' @@ -26,47 +27,49 @@ const ProviderCard: FC<Props> = ({ return ( <div className={cn('group relative p-4 pb-3 border-[0.5px] border-components-panel-border bg-components-panel-on-panel-item-bg hover-bg-components-panel-on-panel-item-bg rounded-xl shadow-xs', className)}> - {/* Header */} - <div className="flex"> - <Icon src={payload.icon} /> - <div className="ml-3 w-0 grow"> - <div className="flex items-center h-5"> - <Title title={label[locale]} /> - <RiVerifiedBadgeLine className="shrink-0 ml-0.5 w-4 h-4 text-text-accent" /> - </div> - <div className='mb-1 flex justify-between items-center h-4'> - <div className='flex items-center'> - <div className='text-text-tertiary system-xs-regular'>{org}</div> - <div className='mx-2 text-text-quaternary system-xs-regular'>·</div> - <DownloadCount downloadCount={payload.install_count || 0} /> + <Link href={`/plugins/test/card?pluginID=${payload.id}`}> + {/* Header */} + <div className="flex"> + <Icon src={payload.icon} /> + <div className="ml-3 w-0 grow"> + <div className="flex items-center h-5"> + <Title title={label[locale]} /> + <RiVerifiedBadgeLine className="shrink-0 ml-0.5 w-4 h-4 text-text-accent" /> + </div> + <div className='mb-1 flex justify-between items-center h-4'> + <div className='flex items-center'> + <div className='text-text-tertiary system-xs-regular'>{org}</div> + <div className='mx-2 text-text-quaternary system-xs-regular'>·</div> + <DownloadCount downloadCount={payload.install_count || 0} /> + </div> </div> </div> </div> - </div> - <Description className='mt-3' text={payload.brief[locale]} descriptionLineRows={2}></Description> - <div className='mt-3 flex space-x-0.5'> - {['LLM', 'text embedding', 'speech2text'].map(tag => ( - <Badge key={tag} text={tag} /> - ))} - </div> - <div - className='hidden group-hover:flex items-center gap-2 absolute bottom-0 left-0 right-0 p-4 pt-8' - style={{ background: 'linear-gradient(0deg, #F9FAFB 60.27%, rgba(249, 250, 251, 0.00) 100%)' }} - > - <Button - className='flex-grow' - variant='primary' + <Description className='mt-3' text={payload.brief[locale]} descriptionLineRows={2}></Description> + <div className='mt-3 flex space-x-0.5'> + {['LLM', 'text embedding', 'speech2text'].map(tag => ( + <Badge key={tag} text={tag} /> + ))} + </div> + <div + className='hidden group-hover:flex items-center gap-2 absolute bottom-0 left-0 right-0 p-4 pt-8' + style={{ background: 'linear-gradient(0deg, #F9FAFB 60.27%, rgba(249, 250, 251, 0.00) 100%)' }} > - Install - </Button> - <Button - className='flex-grow' - variant='secondary' - > - Details - <RiArrowRightUpLine className='w-4 h-4' /> - </Button> - </div> + <Button + className='flex-grow' + variant='primary' + > + Install + </Button> + <Button + className='flex-grow' + variant='secondary' + > + Details + <RiArrowRightUpLine className='w-4 h-4' /> + </Button> + </div> + </Link> </div> ) } diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts index 3b8fdd12f2..0c2b467326 100644 --- a/web/app/components/plugins/types.ts +++ b/web/app/components/plugins/types.ts @@ -8,6 +8,7 @@ export enum PluginType { } export type Plugin = { + id: string 'type': PluginType 'org': string 'name': string From c1e0a939b0b37b427c8ad0d75b6458a6f51a6e49 Mon Sep 17 00:00:00 2001 From: StyleZhang <jasonapring2015@outlook.com> Date: Sat, 12 Oct 2024 12:46:29 +0800 Subject: [PATCH 050/346] marketplace --- .../plugins/marketplace/context.tsx | 41 ++++++ .../plugins/marketplace/header-wrapper.tsx | 23 ++++ .../components/plugins/marketplace/header.tsx | 39 ++++++ .../components/plugins/marketplace/hooks.ts | 20 --- .../components/plugins/marketplace/index.tsx | 43 ++---- .../marketplace/intersection-line/hooks.ts | 30 ++++ .../marketplace/intersection-line/index.tsx | 16 +++ .../plugins/marketplace/list-wrapper.tsx | 23 ++++ .../components/plugins/marketplace/list.tsx | 130 +++++++++++++++++- .../plugins/marketplace/search-box/index.tsx | 10 +- 10 files changed, 321 insertions(+), 54 deletions(-) create mode 100644 web/app/components/plugins/marketplace/context.tsx create mode 100644 web/app/components/plugins/marketplace/header-wrapper.tsx create mode 100644 web/app/components/plugins/marketplace/header.tsx delete mode 100644 web/app/components/plugins/marketplace/hooks.ts create mode 100644 web/app/components/plugins/marketplace/intersection-line/hooks.ts create mode 100644 web/app/components/plugins/marketplace/intersection-line/index.tsx create mode 100644 web/app/components/plugins/marketplace/list-wrapper.tsx diff --git a/web/app/components/plugins/marketplace/context.tsx b/web/app/components/plugins/marketplace/context.tsx new file mode 100644 index 0000000000..86eab52006 --- /dev/null +++ b/web/app/components/plugins/marketplace/context.tsx @@ -0,0 +1,41 @@ +'use client' + +import type { ReactNode } from 'react' +import { useState } from 'react' +import { + createContext, + useContextSelector, +} from 'use-context-selector' + +export type MarketplaceContextValue = { + scrollIntersected: boolean + setScrollIntersected: (scrollIntersected: boolean) => void +} + +export const MarketplaceContext = createContext<MarketplaceContextValue>({ + scrollIntersected: false, + setScrollIntersected: () => {}, +}) + +type MarketplaceContextProviderProps = { + children: ReactNode +} + +export function useMarketplaceContext(selector: (value: MarketplaceContextValue) => any) { + return useContextSelector(MarketplaceContext, selector) +} + +export const MarketplaceContextProvider = ({ + children, +}: MarketplaceContextProviderProps) => { + const [scrollIntersected, setScrollIntersected] = useState(false) + + return ( + <MarketplaceContext.Provider value={{ + scrollIntersected, + setScrollIntersected, + }}> + {children} + </MarketplaceContext.Provider> + ) +} diff --git a/web/app/components/plugins/marketplace/header-wrapper.tsx b/web/app/components/plugins/marketplace/header-wrapper.tsx new file mode 100644 index 0000000000..6e18309a5f --- /dev/null +++ b/web/app/components/plugins/marketplace/header-wrapper.tsx @@ -0,0 +1,23 @@ +'use client' + +import type { ReactNode } from 'react' +import cn from '@/utils/classnames' + +type HeaderWrapperProps = { + children: ReactNode +} +const HeaderWrapper = ({ + children, +}: HeaderWrapperProps) => { + return ( + <div + className={cn( + 'py-10', + )} + > + {children} + </div> + ) +} + +export default HeaderWrapper diff --git a/web/app/components/plugins/marketplace/header.tsx b/web/app/components/plugins/marketplace/header.tsx new file mode 100644 index 0000000000..e8f0920287 --- /dev/null +++ b/web/app/components/plugins/marketplace/header.tsx @@ -0,0 +1,39 @@ +import SearchBox from './search-box' +import PluginTypeSwitch from './plugin-type-switch' +import IntersectionLine from './intersection-line' + +const Header = () => { + return ( + <> + <h1 className='mb-2 text-center title-4xl-semi-bold text-text-primary'> + Empower your AI development + </h1> + <h2 className='flex justify-center items-center mb-4 text-center body-md-regular text-text-tertiary'> + Discover + <span className="relative ml-1 body-md-medium text-text-secondary after:content-[''] after:absolute after:left-0 after:bottom-[1.5px] after:w-full after:h-2 after:bg-text-text-selected"> + models + </span> + , + <span className="relative ml-1 body-md-medium text-text-secondary after:content-[''] after:absolute after:left-0 after:bottom-[1.5px] after:w-full after:h-2 after:bg-text-text-selected"> + tools + </span> + , + <span className="relative ml-1 mr-1 body-md-medium text-text-secondary after:content-[''] after:absolute after:left-0 after:bottom-[1.5px] after:w-full after:h-2 after:bg-text-text-selected"> + extensions + </span> + and + <span className="relative ml-1 mr-1 body-md-medium text-text-secondary after:content-[''] after:absolute after:left-0 after:bottom-[1.5px] after:w-full after:h-2 after:bg-text-text-selected"> + bundles + </span> + in Dify Marketplace + </h2> + <IntersectionLine /> + <div className='flex items-center justify-center mb-[15px]'> + <SearchBox /> + </div> + <PluginTypeSwitch /> + </> + ) +} + +export default Header diff --git a/web/app/components/plugins/marketplace/hooks.ts b/web/app/components/plugins/marketplace/hooks.ts deleted file mode 100644 index 3846bbac2f..0000000000 --- a/web/app/components/plugins/marketplace/hooks.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { useEffect } from 'react' - -export const useScrollIntersection = ( - rootRef: React.RefObject<HTMLDivElement>, - anchorRef: React.RefObject<HTMLDivElement>, - callback: (isIntersecting: boolean) => void, -) => { - useEffect(() => { - let observer: IntersectionObserver | undefined - if (rootRef.current && anchorRef.current) { - observer = new IntersectionObserver((entries) => { - callback(entries[0].isIntersecting) - }, { - root: rootRef.current, - }) - observer.observe(anchorRef.current) - } - return () => observer?.disconnect() - }, [rootRef, anchorRef, callback]) -} diff --git a/web/app/components/plugins/marketplace/index.tsx b/web/app/components/plugins/marketplace/index.tsx index b07db8e920..cbf1c870ce 100644 --- a/web/app/components/plugins/marketplace/index.tsx +++ b/web/app/components/plugins/marketplace/index.tsx @@ -1,39 +1,20 @@ -import SearchBox from './search-box' -import PluginTypeSwitch from './plugin-type-switch' +import { MarketplaceContextProvider } from './context' +import HeaderWrapper from './header-wrapper' +import Header from './header' +import ListWrapper from './list-wrapper' import List from './list' const Marketplace = () => { return ( <div className='w-full'> - <div className='py-10'> - <h1 className='mb-2 text-center title-4xl-semi-bold text-text-primary'> - Empower your AI development - </h1> - <h2 className='flex justify-center items-center mb-4 text-center body-md-regular text-text-tertiary'> - Discover - <span className="relative ml-1 body-md-medium text-text-secondary after:content-[''] after:absolute after:left-0 after:bottom-[1.5px] after:w-full after:h-2 after:bg-text-text-selected"> - models - </span> - , - <span className="relative ml-1 body-md-medium text-text-secondary after:content-[''] after:absolute after:left-0 after:bottom-[1.5px] after:w-full after:h-2 after:bg-text-text-selected"> - tools - </span> - , - <span className="relative ml-1 mr-1 body-md-medium text-text-secondary after:content-[''] after:absolute after:left-0 after:bottom-[1.5px] after:w-full after:h-2 after:bg-text-text-selected"> - extensions - </span> - and - <span className="relative ml-1 mr-1 body-md-medium text-text-secondary after:content-[''] after:absolute after:left-0 after:bottom-[1.5px] after:w-full after:h-2 after:bg-text-text-selected"> - bundles - </span> - in Dify Marketplace - </h2> - <div className='flex items-center justify-center mb-4'> - <SearchBox /> - </div> - <PluginTypeSwitch /> - </div> - <List /> + <MarketplaceContextProvider> + <HeaderWrapper> + <Header /> + </HeaderWrapper> + <ListWrapper> + <List /> + </ListWrapper> + </MarketplaceContextProvider> </div> ) } diff --git a/web/app/components/plugins/marketplace/intersection-line/hooks.ts b/web/app/components/plugins/marketplace/intersection-line/hooks.ts new file mode 100644 index 0000000000..ed79daaa5a --- /dev/null +++ b/web/app/components/plugins/marketplace/intersection-line/hooks.ts @@ -0,0 +1,30 @@ +import { useEffect } from 'react' +import { useContextSelector } from 'use-context-selector' +import { PluginPageContext } from '../../plugin-page/context' +import { MarketplaceContext } from '../context' + +export const useScrollIntersection = ( + anchorRef: React.RefObject<HTMLDivElement>, +) => { + const containerRef = useContextSelector(PluginPageContext, v => v.containerRef) + const scrollIntersected = useContextSelector(MarketplaceContext, v => v.scrollIntersected) + const setScrollIntersected = useContextSelector(MarketplaceContext, v => v.setScrollIntersected) + + useEffect(() => { + let observer: IntersectionObserver | undefined + if (containerRef.current && anchorRef.current) { + observer = new IntersectionObserver((entries) => { + console.log(entries, 'entries') + if (entries[0].isIntersecting && !scrollIntersected) + setScrollIntersected(true) + + if (!entries[0].isIntersecting && scrollIntersected) + setScrollIntersected(false) + }, { + root: containerRef.current, + }) + observer.observe(anchorRef.current) + } + return () => observer?.disconnect() + }, [containerRef, anchorRef, scrollIntersected, setScrollIntersected]) +} diff --git a/web/app/components/plugins/marketplace/intersection-line/index.tsx b/web/app/components/plugins/marketplace/intersection-line/index.tsx new file mode 100644 index 0000000000..647247c995 --- /dev/null +++ b/web/app/components/plugins/marketplace/intersection-line/index.tsx @@ -0,0 +1,16 @@ +'use client' + +import { useRef } from 'react' +import { useScrollIntersection } from './hooks' + +const IntersectionLine = () => { + const ref = useRef<HTMLDivElement>(null) + + useScrollIntersection(ref) + + return ( + <div ref={ref} className='h-[1px] bg-transparent'></div> + ) +} + +export default IntersectionLine diff --git a/web/app/components/plugins/marketplace/list-wrapper.tsx b/web/app/components/plugins/marketplace/list-wrapper.tsx new file mode 100644 index 0000000000..6dd58bdcf5 --- /dev/null +++ b/web/app/components/plugins/marketplace/list-wrapper.tsx @@ -0,0 +1,23 @@ +'use client' + +import type { ReactNode } from 'react' +import cn from '@/utils/classnames' + +type ListWrapperProps = { + children: ReactNode +} +const ListWrapper = ({ + children, +}: ListWrapperProps) => { + return ( + <div + className={cn( + 'px-12 py-2 bg-background-default-subtle', + )} + > + {children} + </div> + ) +} + +export default ListWrapper diff --git a/web/app/components/plugins/marketplace/list.tsx b/web/app/components/plugins/marketplace/list.tsx index d9365fa54a..7a8d6daa5d 100644 --- a/web/app/components/plugins/marketplace/list.tsx +++ b/web/app/components/plugins/marketplace/list.tsx @@ -7,7 +7,7 @@ const List = () => { const locale = getLocaleOnServer() return ( - <div className='px-12 py-2 bg-background-default-subtle'> + <> <div className='py-3'> <div className='title-xl-semi-bold text-text-primary'>Featured</div> <div className='system-xs-regular text-text-tertiary'>Our top picks to get you started</div> @@ -95,9 +95,135 @@ const List = () => { <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> </div> </div> - </div> + </> ) } diff --git a/web/app/components/plugins/marketplace/search-box/index.tsx b/web/app/components/plugins/marketplace/search-box/index.tsx index cb01f0ad10..923b16096c 100644 --- a/web/app/components/plugins/marketplace/search-box/index.tsx +++ b/web/app/components/plugins/marketplace/search-box/index.tsx @@ -5,8 +5,10 @@ import { useState, } from 'react' import { RiCloseLine } from '@remixicon/react' +import { useMarketplaceContext } from '../context' import TagsFilter from './tags-filter' import ActionButton from '@/app/components/base/action-button' +import cn from '@/utils/classnames' type SearchBoxProps = { onChange?: (searchText: string, tags: string[]) => void @@ -16,6 +18,7 @@ const SearchBox = ({ }: SearchBoxProps) => { const [searchText, setSearchText] = useState('') const [selectedTags, setSelectedTags] = useState<string[]>([]) + const scrollIntersected = useMarketplaceContext(v => v.scrollIntersected) const handleTagsChange = useCallback((tags: string[]) => { setSelectedTags(tags) @@ -23,7 +26,12 @@ const SearchBox = ({ }, [searchText, onChange]) return ( - <div className='flex items-center p-1.5 w-[640px] h-11 border border-components-chat-input-border bg-components-panel-bg-blur rounded-xl shadow-md'> + <div + className={cn( + 'flex items-center p-1.5 w-[640px] h-11 border border-components-chat-input-border bg-components-panel-bg-blur rounded-xl shadow-md', + !scrollIntersected && 'w-[508px] transition-[width] duration-300', + )} + > <TagsFilter value={selectedTags} onChange={handleTagsChange} From 6d0eef12b18e32021a778bc89dac239d8b0bd6ec Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Sat, 12 Oct 2024 14:30:37 +0800 Subject: [PATCH 051/346] feat: split tools data to out and add demo --- .../plugins/test/tools-picker/page.tsx | 39 +++++++++++++++++++ .../workflow/block-selector/all-tools.tsx | 10 +++-- .../workflow/block-selector/index-bar.tsx | 2 +- .../workflow/block-selector/tabs.tsx | 7 ++++ 4 files changed, 53 insertions(+), 5 deletions(-) create mode 100644 web/app/(commonLayout)/plugins/test/tools-picker/page.tsx diff --git a/web/app/(commonLayout)/plugins/test/tools-picker/page.tsx b/web/app/(commonLayout)/plugins/test/tools-picker/page.tsx new file mode 100644 index 0000000000..e2b9bd9dc8 --- /dev/null +++ b/web/app/(commonLayout)/plugins/test/tools-picker/page.tsx @@ -0,0 +1,39 @@ +'use client' +import { useEffect, useState } from 'react' +import AllTools from '@/app/components/workflow/block-selector/all-tools' +import { + fetchAllBuiltInTools, + fetchAllCustomTools, + fetchAllWorkflowTools, +} from '@/service/tools' +import type { ToolWithProvider } from '@/app/components/workflow/types' + +const ToolsPicker = () => { + const [buildInTools, setBuildInTools] = useState<ToolWithProvider[]>([]) + const [customTools, setCustomTools] = useState<ToolWithProvider[]>([]) + const [workflowTools, setWorkflowTools] = useState<ToolWithProvider[]>([]) + + useEffect(() => { + (async () => { + const buildInTools = await fetchAllBuiltInTools() + const customTools = await fetchAllCustomTools() + const workflowTools = await fetchAllWorkflowTools() + setBuildInTools(buildInTools) + setCustomTools(customTools) + setWorkflowTools(workflowTools) + })() + }) + return ( + <div className="relative mt-5 mx-auto w-[320px] bg-white"> + <AllTools + searchText="" + onSelect={() => { }} + buildInTools={buildInTools} + customTools={customTools} + workflowTools={workflowTools} + /> + </div> + ) +} + +export default ToolsPicker diff --git a/web/app/components/workflow/block-selector/all-tools.tsx b/web/app/components/workflow/block-selector/all-tools.tsx index 8925649226..9ef239ce18 100644 --- a/web/app/components/workflow/block-selector/all-tools.tsx +++ b/web/app/components/workflow/block-selector/all-tools.tsx @@ -6,7 +6,6 @@ import type { OnSelectBlock, ToolWithProvider, } from '../types' -import { useStore } from '../store' import { ToolTypeEnum } from './types' import Tools from './tools' import { useToolTabs } from './hooks' @@ -15,18 +14,21 @@ import { useGetLanguage } from '@/context/i18n' type AllToolsProps = { searchText: string + buildInTools: ToolWithProvider[] + customTools: ToolWithProvider[] + workflowTools: ToolWithProvider[] onSelect: OnSelectBlock } const AllTools = ({ searchText, onSelect, + buildInTools, + workflowTools, + customTools, }: AllToolsProps) => { const language = useGetLanguage() const tabs = useToolTabs() const [activeTab, setActiveTab] = useState(ToolTypeEnum.All) - const buildInTools = useStore(s => s.buildInTools) - const customTools = useStore(s => s.customTools) - const workflowTools = useStore(s => s.workflowTools) const tools = useMemo(() => { let mergedTools: ToolWithProvider[] = [] diff --git a/web/app/components/workflow/block-selector/index-bar.tsx b/web/app/components/workflow/block-selector/index-bar.tsx index 6eab51246d..7432358c9c 100644 --- a/web/app/components/workflow/block-selector/index-bar.tsx +++ b/web/app/components/workflow/block-selector/index-bar.tsx @@ -47,7 +47,7 @@ const IndexBar: FC<IndexBarProps> = ({ letters, itemRefs }) => { element.scrollIntoView({ behavior: 'smooth' }) } return ( - <div className="index-bar fixed right-4 top-36 flex flex-col items-center text-xs font-medium text-gray-500"> + <div className="index-bar absolute right-4 top-36 flex flex-col items-center text-xs font-medium text-gray-500"> {letters.map(letter => ( <div className="hover:text-gray-900 cursor-pointer" key={letter} onClick={() => handleIndexClick(letter)}> {letter} diff --git a/web/app/components/workflow/block-selector/tabs.tsx b/web/app/components/workflow/block-selector/tabs.tsx index 8c410b5641..5d44011465 100644 --- a/web/app/components/workflow/block-selector/tabs.tsx +++ b/web/app/components/workflow/block-selector/tabs.tsx @@ -1,5 +1,6 @@ import type { FC } from 'react' import { memo } from 'react' +import { useStore } from '../store' import type { BlockEnum } from '../types' import { useTabs } from './hooks' import type { ToolDefaultValue } from './types' @@ -25,6 +26,9 @@ const Tabs: FC<TabsProps> = ({ noBlocks, }) => { const tabs = useTabs() + const buildInTools = useStore(s => s.buildInTools) + const customTools = useStore(s => s.customTools) + const workflowTools = useStore(s => s.workflowTools) return ( <div onClick={e => e.stopPropagation()}> @@ -64,6 +68,9 @@ const Tabs: FC<TabsProps> = ({ <AllTools searchText={searchText} onSelect={onSelect} + buildInTools={buildInTools} + customTools={customTools} + workflowTools={workflowTools} /> ) } From 49ee9ca5f147087cd53c75e27e653eeede3a7ddf Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Sat, 12 Oct 2024 16:04:16 +0800 Subject: [PATCH 052/346] feat: tool item support action --- .../workflow/block-selector/tool-item.tsx | 110 ++++++++++++++++++ .../workflow/block-selector/tools.tsx | 47 ++------ 2 files changed, 118 insertions(+), 39 deletions(-) create mode 100644 web/app/components/workflow/block-selector/tool-item.tsx diff --git a/web/app/components/workflow/block-selector/tool-item.tsx b/web/app/components/workflow/block-selector/tool-item.tsx new file mode 100644 index 0000000000..a5e1639392 --- /dev/null +++ b/web/app/components/workflow/block-selector/tool-item.tsx @@ -0,0 +1,110 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import { RiArrowRightSLine } from '@remixicon/react' +import { useBoolean } from 'ahooks' +import BlockIcon from '../block-icon' +import type { ToolWithProvider } from '../types' +import { BlockEnum } from '../types' +import type { ToolDefaultValue } from './types' +import Tooltip from '@/app/components/base/tooltip' +import type { Tool } from '@/app/components/tools/types' +import { useGetLanguage } from '@/context/i18n' + +type Props = { + isToolPlugin: boolean // Tool plugin should choose action + provider: ToolWithProvider + payload: Tool + onSelect: (type: BlockEnum, tool?: ToolDefaultValue) => void +} + +const ToolItem: FC<Props> = ({ + isToolPlugin, + provider, + payload, + onSelect, +}) => { + const language = useGetLanguage() + const [isFold, { + toggle: toggleFold, + }] = useBoolean(true) + + const actions = [ + 'DuckDuckGo AI Search', + 'DuckDuckGo Connect', + ] + + return ( + <Tooltip + key={payload.name} + position='right' + popupClassName='!p-0 !px-3 !py-2.5 !w-[200px] !leading-[18px] !text-xs !text-gray-700 !border-[0.5px] !border-black/5 !rounded-xl !shadow-lg' + popupContent={( + <div> + <BlockIcon + size='md' + className='mb-2' + type={BlockEnum.Tool} + toolIcon={provider.icon} + /> + <div className='mb-1 text-sm leading-5 text-gray-900'>{payload.label[language]}</div> + <div className='text-xs text-gray-700 leading-[18px]'>{payload.description[language]}</div> + </div> + )} + > + <div> + <div + className='flex items-center px-3 w-full h-8 rounded-lg hover:bg-gray-50 cursor-pointer' + onClick={() => { + if (isToolPlugin) { + toggleFold() + return + } + onSelect(BlockEnum.Tool, { + provider_id: provider.id, + provider_type: provider.type, + provider_name: provider.name, + tool_name: payload.name, + tool_label: payload.label[language], + title: payload.label[language], + }) + }} + > + {isToolPlugin && ( + <RiArrowRightSLine className='mr-1 w-4 h-4 text-text-quaternary shrink-0' /> + )} + <BlockIcon + className='mr-2 shrink-0' + type={BlockEnum.Tool} + toolIcon={provider.icon} + /> + <div className='text-sm text-gray-900 flex-1 min-w-0 truncate'>{payload.label[language]}</div> + </div> + {(!isFold && isToolPlugin) && ( + <div> + {actions.map(action => ( + <div + key={action} + className='rounded-lg pl-[37px] hover:bg-state-base-hover cursor-pointer' + onClick={() => { + onSelect(BlockEnum.Tool, { + provider_id: provider.id, + provider_type: provider.type, + provider_name: provider.name, + tool_name: payload.name, + tool_label: payload.label[language], + title: payload.label[language], + }) + }} + > + <div className='h-8 leading-8 border-l-2 border-divider-subtle pl-[19px] truncate text-text-secondary system-sm-medium'>{action}</div> + </div> + ))} + </div> + )} + </div> + + </Tooltip> + ) +} +export default React.memo(ToolItem) diff --git a/web/app/components/workflow/block-selector/tools.tsx b/web/app/components/workflow/block-selector/tools.tsx index a2ae845997..534fe1499d 100644 --- a/web/app/components/workflow/block-selector/tools.tsx +++ b/web/app/components/workflow/block-selector/tools.tsx @@ -4,12 +4,10 @@ import { useRef, } from 'react' import { useTranslation } from 'react-i18next' -import BlockIcon from '../block-icon' -import { BlockEnum } from '../types' -import type { ToolWithProvider } from '../types' +import type { BlockEnum, ToolWithProvider } from '../types' import IndexBar, { groupItems } from './index-bar' import type { ToolDefaultValue } from './types' -import Tooltip from '@/app/components/base/tooltip' +import ToolItem from './tool-item' import Empty from '@/app/components/tools/add-tool-modal/empty' import { useGetLanguage } from '@/context/i18n' @@ -42,42 +40,13 @@ const Blocks = ({ </div> { list.map(tool => ( - <Tooltip + <ToolItem key={tool.name} - position='right' - popupClassName='!p-0 !px-3 !py-2.5 !w-[200px] !leading-[18px] !text-xs !text-gray-700 !border-[0.5px] !border-black/5 !rounded-xl !shadow-lg' - popupContent={( - <div> - <BlockIcon - size='md' - className='mb-2' - type={BlockEnum.Tool} - toolIcon={toolWithProvider.icon} - /> - <div className='mb-1 text-sm leading-5 text-gray-900'>{tool.label[language]}</div> - <div className='text-xs text-gray-700 leading-[18px]'>{tool.description[language]}</div> - </div> - )} - > - <div - className='flex items-center px-3 w-full h-8 rounded-lg hover:bg-gray-50 cursor-pointer' - onClick={() => onSelect(BlockEnum.Tool, { - provider_id: toolWithProvider.id, - provider_type: toolWithProvider.type, - provider_name: toolWithProvider.name, - tool_name: tool.name, - tool_label: tool.label[language], - title: tool.label[language], - })} - > - <BlockIcon - className='mr-2 shrink-0' - type={BlockEnum.Tool} - toolIcon={toolWithProvider.icon} - /> - <div className='text-sm text-gray-900 flex-1 min-w-0 truncate'>{tool.label[language]}</div> - </div> - </Tooltip> + isToolPlugin={toolWithProvider.type === 'builtin'} + provider={toolWithProvider} + payload={tool} + onSelect={onSelect} + /> )) } </div> From ecd2a1be9f3ccabcdab939aaa1da313543472244 Mon Sep 17 00:00:00 2001 From: StyleZhang <jasonapring2015@outlook.com> Date: Sat, 12 Oct 2024 16:34:02 +0800 Subject: [PATCH 053/346] marketplace --- web/app/(commonLayout)/plugins/page.tsx | 2 +- .../plugins/marketplace/context.tsx | 41 ------------------- .../{header.tsx => description/index.tsx} | 15 ++----- .../marketplace/description/wrapper.tsx | 39 ++++++++++++++++++ .../plugins/marketplace/header/index.tsx | 20 +++++++++ .../wrapper.tsx} | 4 ++ .../components/plugins/marketplace/index.tsx | 21 ++++------ .../marketplace/intersection-line/hooks.ts | 21 +++------- .../marketplace/intersection-line/index.tsx | 15 ++++++- .../plugins/marketplace/list-wrapper.tsx | 23 ----------- .../marketplace/{list.tsx => list/index.tsx} | 0 .../plugins/marketplace/list/wrapper.tsx | 39 ++++++++++++++++++ .../plugins/marketplace/search-box/index.tsx | 6 +-- .../marketplace/search-box/wrapper.tsx | 14 +++++++ .../plugins/plugin-page/context.tsx | 30 +++++++++++--- .../components/plugins/plugin-page/index.tsx | 13 ++++-- .../{ => plugin-page}/plugins-panel.tsx | 0 17 files changed, 185 insertions(+), 118 deletions(-) delete mode 100644 web/app/components/plugins/marketplace/context.tsx rename web/app/components/plugins/marketplace/{header.tsx => description/index.tsx} (72%) create mode 100644 web/app/components/plugins/marketplace/description/wrapper.tsx create mode 100644 web/app/components/plugins/marketplace/header/index.tsx rename web/app/components/plugins/marketplace/{header-wrapper.tsx => header/wrapper.tsx} (59%) delete mode 100644 web/app/components/plugins/marketplace/list-wrapper.tsx rename web/app/components/plugins/marketplace/{list.tsx => list/index.tsx} (100%) create mode 100644 web/app/components/plugins/marketplace/list/wrapper.tsx create mode 100644 web/app/components/plugins/marketplace/search-box/wrapper.tsx rename web/app/components/plugins/{ => plugin-page}/plugins-panel.tsx (100%) diff --git a/web/app/(commonLayout)/plugins/page.tsx b/web/app/(commonLayout)/plugins/page.tsx index 6220c20aa0..f28944ebbd 100644 --- a/web/app/(commonLayout)/plugins/page.tsx +++ b/web/app/(commonLayout)/plugins/page.tsx @@ -1,5 +1,5 @@ import PluginPage from '@/app/components/plugins/plugin-page' -import PluginsPanel from '@/app/components/plugins/plugins-panel' +import PluginsPanel from '@/app/components/plugins/plugin-page/plugins-panel' import Marketplace from '@/app/components/plugins/marketplace' const PluginList = async () => { diff --git a/web/app/components/plugins/marketplace/context.tsx b/web/app/components/plugins/marketplace/context.tsx deleted file mode 100644 index 86eab52006..0000000000 --- a/web/app/components/plugins/marketplace/context.tsx +++ /dev/null @@ -1,41 +0,0 @@ -'use client' - -import type { ReactNode } from 'react' -import { useState } from 'react' -import { - createContext, - useContextSelector, -} from 'use-context-selector' - -export type MarketplaceContextValue = { - scrollIntersected: boolean - setScrollIntersected: (scrollIntersected: boolean) => void -} - -export const MarketplaceContext = createContext<MarketplaceContextValue>({ - scrollIntersected: false, - setScrollIntersected: () => {}, -}) - -type MarketplaceContextProviderProps = { - children: ReactNode -} - -export function useMarketplaceContext(selector: (value: MarketplaceContextValue) => any) { - return useContextSelector(MarketplaceContext, selector) -} - -export const MarketplaceContextProvider = ({ - children, -}: MarketplaceContextProviderProps) => { - const [scrollIntersected, setScrollIntersected] = useState(false) - - return ( - <MarketplaceContext.Provider value={{ - scrollIntersected, - setScrollIntersected, - }}> - {children} - </MarketplaceContext.Provider> - ) -} diff --git a/web/app/components/plugins/marketplace/header.tsx b/web/app/components/plugins/marketplace/description/index.tsx similarity index 72% rename from web/app/components/plugins/marketplace/header.tsx rename to web/app/components/plugins/marketplace/description/index.tsx index e8f0920287..754a4b12a9 100644 --- a/web/app/components/plugins/marketplace/header.tsx +++ b/web/app/components/plugins/marketplace/description/index.tsx @@ -1,14 +1,10 @@ -import SearchBox from './search-box' -import PluginTypeSwitch from './plugin-type-switch' -import IntersectionLine from './intersection-line' - -const Header = () => { +const Description = () => { return ( <> <h1 className='mb-2 text-center title-4xl-semi-bold text-text-primary'> Empower your AI development </h1> - <h2 className='flex justify-center items-center mb-4 text-center body-md-regular text-text-tertiary'> + <h2 className='flex justify-center items-center text-center body-md-regular text-text-tertiary'> Discover <span className="relative ml-1 body-md-medium text-text-secondary after:content-[''] after:absolute after:left-0 after:bottom-[1.5px] after:w-full after:h-2 after:bg-text-text-selected"> models @@ -27,13 +23,8 @@ const Header = () => { </span> in Dify Marketplace </h2> - <IntersectionLine /> - <div className='flex items-center justify-center mb-[15px]'> - <SearchBox /> - </div> - <PluginTypeSwitch /> </> ) } -export default Header +export default Description diff --git a/web/app/components/plugins/marketplace/description/wrapper.tsx b/web/app/components/plugins/marketplace/description/wrapper.tsx new file mode 100644 index 0000000000..91dd3a2ba6 --- /dev/null +++ b/web/app/components/plugins/marketplace/description/wrapper.tsx @@ -0,0 +1,39 @@ +'use client' + +import type { ReactNode } from 'react' +import { useCallback } from 'react' +import IntersectionLine from '../intersection-line' +import { usePluginPageContext } from '@/app/components/plugins/plugin-page/context' + +type DescriptionWrapperProps = { + children: ReactNode +} +const DescriptionWrapper = ({ + children, +}: DescriptionWrapperProps) => { + const containerRef = usePluginPageContext(v => v.containerRef) + const scrollDisabled = usePluginPageContext(v => v.scrollDisabled) + const setScrollDisabled = usePluginPageContext(v => v.setScrollDisabled) + + const handleScrollIntersectionChange = useCallback((isIntersecting: boolean) => { + if (!isIntersecting && !scrollDisabled) { + setScrollDisabled(true) + setTimeout(() => { + if (containerRef && containerRef.current) + containerRef.current.scrollTop = 0 + }, 100) + } + }, [containerRef, scrollDisabled, setScrollDisabled]) + + return !scrollDisabled && ( + <> + {children} + <IntersectionLine + containerRef={containerRef} + intersectedCallback={handleScrollIntersectionChange} + /> + </> + ) +} + +export default DescriptionWrapper diff --git a/web/app/components/plugins/marketplace/header/index.tsx b/web/app/components/plugins/marketplace/header/index.tsx new file mode 100644 index 0000000000..3caeea6c7f --- /dev/null +++ b/web/app/components/plugins/marketplace/header/index.tsx @@ -0,0 +1,20 @@ +import Description from '../description' +import DescriptionWrapper from '../description/wrapper' +import SearchBoxWrapper from '../search-box/wrapper' +import PluginTypeSwitch from '../plugin-type-switch' + +const Header = () => { + return ( + <> + <DescriptionWrapper> + <Description /> + </DescriptionWrapper> + <div className='flex items-center justify-center mt-[15px] mb-4'> + <SearchBoxWrapper /> + </div> + <PluginTypeSwitch /> + </> + ) +} + +export default Header diff --git a/web/app/components/plugins/marketplace/header-wrapper.tsx b/web/app/components/plugins/marketplace/header/wrapper.tsx similarity index 59% rename from web/app/components/plugins/marketplace/header-wrapper.tsx rename to web/app/components/plugins/marketplace/header/wrapper.tsx index 6e18309a5f..a0c45bbc1a 100644 --- a/web/app/components/plugins/marketplace/header-wrapper.tsx +++ b/web/app/components/plugins/marketplace/header/wrapper.tsx @@ -1,6 +1,7 @@ 'use client' import type { ReactNode } from 'react' +import { usePluginPageContext } from '@/app/components/plugins/plugin-page/context' import cn from '@/utils/classnames' type HeaderWrapperProps = { @@ -9,10 +10,13 @@ type HeaderWrapperProps = { const HeaderWrapper = ({ children, }: HeaderWrapperProps) => { + const scrollDisabled = usePluginPageContext(v => v.scrollDisabled) + return ( <div className={cn( 'py-10', + scrollDisabled && 'absolute left-1/2 -translate-x-1/2 -top-[100px] pb-3', )} > {children} diff --git a/web/app/components/plugins/marketplace/index.tsx b/web/app/components/plugins/marketplace/index.tsx index cbf1c870ce..5d737db448 100644 --- a/web/app/components/plugins/marketplace/index.tsx +++ b/web/app/components/plugins/marketplace/index.tsx @@ -1,20 +1,17 @@ -import { MarketplaceContextProvider } from './context' -import HeaderWrapper from './header-wrapper' import Header from './header' -import ListWrapper from './list-wrapper' +import HeaderWrapper from './header/wrapper' import List from './list' +import ListWrapper from './list/wrapper' const Marketplace = () => { return ( - <div className='w-full'> - <MarketplaceContextProvider> - <HeaderWrapper> - <Header /> - </HeaderWrapper> - <ListWrapper> - <List /> - </ListWrapper> - </MarketplaceContextProvider> + <div className='grow relative flex flex-col w-full h-0'> + <HeaderWrapper> + <Header /> + </HeaderWrapper> + <ListWrapper> + <List /> + </ListWrapper> </div> ) } diff --git a/web/app/components/plugins/marketplace/intersection-line/hooks.ts b/web/app/components/plugins/marketplace/intersection-line/hooks.ts index ed79daaa5a..a31d196179 100644 --- a/web/app/components/plugins/marketplace/intersection-line/hooks.ts +++ b/web/app/components/plugins/marketplace/intersection-line/hooks.ts @@ -1,30 +1,21 @@ import { useEffect } from 'react' -import { useContextSelector } from 'use-context-selector' -import { PluginPageContext } from '../../plugin-page/context' -import { MarketplaceContext } from '../context' export const useScrollIntersection = ( + containerRef: React.RefObject<HTMLDivElement>, anchorRef: React.RefObject<HTMLDivElement>, + callback: (isIntersecting: boolean) => void, ) => { - const containerRef = useContextSelector(PluginPageContext, v => v.containerRef) - const scrollIntersected = useContextSelector(MarketplaceContext, v => v.scrollIntersected) - const setScrollIntersected = useContextSelector(MarketplaceContext, v => v.setScrollIntersected) - useEffect(() => { let observer: IntersectionObserver | undefined - if (containerRef.current && anchorRef.current) { + if (containerRef?.current && anchorRef.current) { observer = new IntersectionObserver((entries) => { - console.log(entries, 'entries') - if (entries[0].isIntersecting && !scrollIntersected) - setScrollIntersected(true) - - if (!entries[0].isIntersecting && scrollIntersected) - setScrollIntersected(false) + const isIntersecting = entries[0].isIntersecting + callback(isIntersecting) }, { root: containerRef.current, }) observer.observe(anchorRef.current) } return () => observer?.disconnect() - }, [containerRef, anchorRef, scrollIntersected, setScrollIntersected]) + }, [containerRef, anchorRef, callback]) } diff --git a/web/app/components/plugins/marketplace/intersection-line/index.tsx b/web/app/components/plugins/marketplace/intersection-line/index.tsx index 647247c995..3805ec6f13 100644 --- a/web/app/components/plugins/marketplace/intersection-line/index.tsx +++ b/web/app/components/plugins/marketplace/intersection-line/index.tsx @@ -3,10 +3,21 @@ import { useRef } from 'react' import { useScrollIntersection } from './hooks' -const IntersectionLine = () => { +type IntersectionLineProps = { + containerRef: React.RefObject<HTMLDivElement> + intersectedCallback: (isIntersecting: boolean) => void +} +const IntersectionLine = ({ + containerRef, + intersectedCallback, +}: IntersectionLineProps) => { const ref = useRef<HTMLDivElement>(null) - useScrollIntersection(ref) + useScrollIntersection( + containerRef, + ref, + intersectedCallback, + ) return ( <div ref={ref} className='h-[1px] bg-transparent'></div> diff --git a/web/app/components/plugins/marketplace/list-wrapper.tsx b/web/app/components/plugins/marketplace/list-wrapper.tsx deleted file mode 100644 index 6dd58bdcf5..0000000000 --- a/web/app/components/plugins/marketplace/list-wrapper.tsx +++ /dev/null @@ -1,23 +0,0 @@ -'use client' - -import type { ReactNode } from 'react' -import cn from '@/utils/classnames' - -type ListWrapperProps = { - children: ReactNode -} -const ListWrapper = ({ - children, -}: ListWrapperProps) => { - return ( - <div - className={cn( - 'px-12 py-2 bg-background-default-subtle', - )} - > - {children} - </div> - ) -} - -export default ListWrapper diff --git a/web/app/components/plugins/marketplace/list.tsx b/web/app/components/plugins/marketplace/list/index.tsx similarity index 100% rename from web/app/components/plugins/marketplace/list.tsx rename to web/app/components/plugins/marketplace/list/index.tsx diff --git a/web/app/components/plugins/marketplace/list/wrapper.tsx b/web/app/components/plugins/marketplace/list/wrapper.tsx new file mode 100644 index 0000000000..cf040c8d6b --- /dev/null +++ b/web/app/components/plugins/marketplace/list/wrapper.tsx @@ -0,0 +1,39 @@ +'use client' + +import type { ReactNode } from 'react' +import { usePluginPageContext } from '@/app/components/plugins/plugin-page/context' +import cn from '@/utils/classnames' + +type ListWrapperProps = { + children: ReactNode +} +const ListWrapper = ({ + children, +}: ListWrapperProps) => { + const scrollDisabled = usePluginPageContext(v => v.scrollDisabled) + const setScrollDisabled = usePluginPageContext(v => v.setScrollDisabled) + + return ( + <> + { + scrollDisabled && ( + <div className='h-[60px]'></div> + ) + } + <div + className={cn( + 'px-12 py-2 bg-background-default-subtle', + scrollDisabled && 'grow h-0 overflow-y-auto', + )} + onScroll={(e) => { + if ((e.target as HTMLElement).scrollTop <= 0) + setScrollDisabled(false) + }} + > + {children} + </div> + </> + ) +} + +export default ListWrapper diff --git a/web/app/components/plugins/marketplace/search-box/index.tsx b/web/app/components/plugins/marketplace/search-box/index.tsx index 923b16096c..612130bc96 100644 --- a/web/app/components/plugins/marketplace/search-box/index.tsx +++ b/web/app/components/plugins/marketplace/search-box/index.tsx @@ -5,20 +5,20 @@ import { useState, } from 'react' import { RiCloseLine } from '@remixicon/react' -import { useMarketplaceContext } from '../context' import TagsFilter from './tags-filter' import ActionButton from '@/app/components/base/action-button' import cn from '@/utils/classnames' type SearchBoxProps = { onChange?: (searchText: string, tags: string[]) => void + widthShouldChange?: boolean } const SearchBox = ({ onChange, + widthShouldChange, }: SearchBoxProps) => { const [searchText, setSearchText] = useState('') const [selectedTags, setSelectedTags] = useState<string[]>([]) - const scrollIntersected = useMarketplaceContext(v => v.scrollIntersected) const handleTagsChange = useCallback((tags: string[]) => { setSelectedTags(tags) @@ -29,7 +29,7 @@ const SearchBox = ({ <div className={cn( 'flex items-center p-1.5 w-[640px] h-11 border border-components-chat-input-border bg-components-panel-bg-blur rounded-xl shadow-md', - !scrollIntersected && 'w-[508px] transition-[width] duration-300', + widthShouldChange && 'w-[508px] transition-[width] duration-300', )} > <TagsFilter diff --git a/web/app/components/plugins/marketplace/search-box/wrapper.tsx b/web/app/components/plugins/marketplace/search-box/wrapper.tsx new file mode 100644 index 0000000000..df42f3740c --- /dev/null +++ b/web/app/components/plugins/marketplace/search-box/wrapper.tsx @@ -0,0 +1,14 @@ +'use client' + +import SearchBox from '.' +import { usePluginPageContext } from '@/app/components/plugins/plugin-page/context' + +const Wrapper = () => { + const scrollDisabled = usePluginPageContext(v => v.scrollDisabled) + + return ( + <SearchBox widthShouldChange={scrollDisabled} /> + ) +} + +export default Wrapper diff --git a/web/app/components/plugins/plugin-page/context.tsx b/web/app/components/plugins/plugin-page/context.tsx index 94351484b1..57e00d9c5d 100644 --- a/web/app/components/plugins/plugin-page/context.tsx +++ b/web/app/components/plugins/plugin-page/context.tsx @@ -1,29 +1,49 @@ 'use client' import type { ReactNode } from 'react' -import { useRef } from 'react' -import { createContext } from 'use-context-selector' +import { + useRef, + useState, +} from 'react' +import { + createContext, + useContextSelector, +} from 'use-context-selector' export type PluginPageContextValue = { containerRef: React.RefObject<HTMLDivElement> + scrollDisabled: boolean + setScrollDisabled: (scrollDisabled: boolean) => void } export const PluginPageContext = createContext<PluginPageContextValue>({ containerRef: { current: null }, + scrollDisabled: false, + setScrollDisabled: () => {}, }) type PluginPageContextProviderProps = { children: ReactNode } +export function usePluginPageContext(selector: (value: PluginPageContextValue) => any) { + return useContextSelector(PluginPageContext, selector) +} + export const PluginPageContextProvider = ({ children, }: PluginPageContextProviderProps) => { const containerRef = useRef<HTMLDivElement>(null) + const [scrollDisabled, setScrollDisabled] = useState(false) + return ( - <PluginPageContext.Provider value={{ - containerRef, - }}> + <PluginPageContext.Provider + value={{ + containerRef, + scrollDisabled, + setScrollDisabled, + }} + > {children} </PluginPageContext.Provider> ) diff --git a/web/app/components/plugins/plugin-page/index.tsx b/web/app/components/plugins/plugin-page/index.tsx index fa62a592c7..f79e0af275 100644 --- a/web/app/components/plugins/plugin-page/index.tsx +++ b/web/app/components/plugins/plugin-page/index.tsx @@ -2,7 +2,6 @@ import { useMemo } from 'react' import { useTranslation } from 'react-i18next' -import { useContextSelector } from 'use-context-selector' import { RiArrowRightUpLine, RiBugLine, @@ -10,8 +9,8 @@ import { RiEqualizer2Line, } from '@remixicon/react' import { - PluginPageContext, PluginPageContextProvider, + usePluginPageContext, } from './context' import InstallPluginDropdown from './install-plugin-dropdown' import { useTabSearchParams } from '@/hooks/use-tab-searchparams' @@ -32,7 +31,8 @@ const PluginPage = ({ }: PluginPageProps) => { const { t } = useTranslation() const { setShowPluginSettingModal } = useModalContext() as any - const containerRef = useContextSelector(PluginPageContext, v => v.containerRef) + const containerRef = usePluginPageContext(v => v.containerRef) + const scrollDisabled = usePluginPageContext(v => v.scrollDisabled) const options = useMemo(() => { return [ @@ -51,9 +51,14 @@ const PluginPage = ({ className={cn('grow relative flex flex-col overflow-y-auto border-t border-divider-subtle', activeTab === 'plugins' ? 'rounded-t-xl bg-components-panel-bg' : 'bg-background-body', + activeTab === 'discover' && scrollDisabled && 'overflow-hidden', )} > - <div className='sticky top-0 flex min-h-[60px] px-12 pt-4 pb-2 items-center self-stretch gap-1'> + <div + className={cn( + 'sticky top-0 flex min-h-[60px] px-12 pt-4 pb-2 items-center self-stretch gap-1', + )} + > <div className='flex justify-between items-center w-full'> <div className='flex-1'> <TabSlider diff --git a/web/app/components/plugins/plugins-panel.tsx b/web/app/components/plugins/plugin-page/plugins-panel.tsx similarity index 100% rename from web/app/components/plugins/plugins-panel.tsx rename to web/app/components/plugins/plugin-page/plugins-panel.tsx From 99f5fea001bc8693570a15ef7267cdf7297bd16a Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Sat, 12 Oct 2024 14:39:53 +0800 Subject: [PATCH 054/346] plugin detail panel header --- .../assets/vender/plugin/box-sparkle-fill.svg | 9 +++ .../src/vender/plugin/BoxSparkleFill.json | 66 +++++++++++++++++++ .../src/vender/plugin/BoxSparkleFill.tsx | 16 +++++ .../base/icons/src/vender/plugin/index.ts | 1 + .../plugins/plugin-detail-panel/index.tsx | 54 +++++++++------ .../operation-dropdown.tsx | 61 +++++++++++++++++ web/i18n/en-US/plugin.ts | 9 +++ web/i18n/zh-Hans/plugin.ts | 9 +++ 8 files changed, 206 insertions(+), 19 deletions(-) create mode 100644 web/app/components/base/icons/assets/vender/plugin/box-sparkle-fill.svg create mode 100644 web/app/components/base/icons/src/vender/plugin/BoxSparkleFill.json create mode 100644 web/app/components/base/icons/src/vender/plugin/BoxSparkleFill.tsx create mode 100644 web/app/components/plugins/plugin-detail-panel/operation-dropdown.tsx diff --git a/web/app/components/base/icons/assets/vender/plugin/box-sparkle-fill.svg b/web/app/components/base/icons/assets/vender/plugin/box-sparkle-fill.svg new file mode 100644 index 0000000000..3ec651fd94 --- /dev/null +++ b/web/app/components/base/icons/assets/vender/plugin/box-sparkle-fill.svg @@ -0,0 +1,9 @@ +<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg"> +<g id="Icon"> +<path id="Vector" fill-rule="evenodd" clip-rule="evenodd" d="M11.3891 2.41987C11.6635 2.58871 11.749 2.94802 11.5802 3.22239L10.3324 5.25H11.0833C11.4055 5.25 11.6667 5.51117 11.6667 5.83334V11.6667C11.6667 12.311 11.1444 12.8333 10.5 12.8333H3.50001C2.85568 12.8333 2.33334 12.311 2.33334 11.6667V5.83334C2.33334 5.51117 2.59451 5.25 2.91668 5.25H8.96252L10.5865 2.61094C10.7554 2.33657 11.1147 2.25102 11.3891 2.41987ZM5.83334 7.58334C5.51118 7.58334 5.25001 7.84449 5.25001 8.16667C5.25001 8.48884 5.51118 8.75 5.83334 8.75H8.16668C8.48885 8.75 8.75001 8.48884 8.75001 8.16667C8.75001 7.84449 8.48885 7.58334 8.16668 7.58334H5.83334Z" fill="#676F83"/> +<g id="Vector_2" opacity="0.5"> +<path d="M6.91257 1.79347C6.96898 1.76525 7.01477 1.71948 7.043 1.66303L7.32195 1.10508C7.42946 0.890105 7.73623 0.890105 7.84374 1.10508L8.12269 1.66303C8.15093 1.71948 8.19672 1.76525 8.25313 1.79347L8.81108 2.07245C9.0261 2.17994 9.0261 2.48672 8.81108 2.5942L8.25313 2.87318C8.19672 2.9014 8.15093 2.94717 8.12269 3.00362L7.84374 3.56158C7.73623 3.77655 7.42946 3.77655 7.32195 3.56158L7.043 3.00362C7.01477 2.94717 6.96898 2.9014 6.91257 2.87318L6.35461 2.5942C6.13965 2.48672 6.13965 2.17994 6.35461 2.07245L6.91257 1.79347Z" fill="#676F83"/> +<path d="M3.80145 2.7657C3.85789 2.73748 3.90366 2.69171 3.93189 2.63526L4.11364 2.27174C4.22113 2.05677 4.5279 2.05677 4.63539 2.27174L4.81715 2.63526C4.84537 2.6917 4.89114 2.73748 4.94759 2.7657L5.3111 2.94745C5.52607 3.05494 5.52607 3.36172 5.3111 3.4692L4.94759 3.65096C4.89114 3.67919 4.84537 3.72495 4.81715 3.7814L4.63539 4.14491C4.5279 4.35988 4.22113 4.35988 4.11364 4.14491L3.93189 3.7814C3.90366 3.72495 3.85789 3.67919 3.80145 3.65096L3.43793 3.4692C3.22296 3.36172 3.22296 3.05494 3.43793 2.94745L3.80145 2.7657Z" fill="#676F83"/> +</g> +</g> +</svg> diff --git a/web/app/components/base/icons/src/vender/plugin/BoxSparkleFill.json b/web/app/components/base/icons/src/vender/plugin/BoxSparkleFill.json new file mode 100644 index 0000000000..3733f98afd --- /dev/null +++ b/web/app/components/base/icons/src/vender/plugin/BoxSparkleFill.json @@ -0,0 +1,66 @@ +{ + "icon": { + "type": "element", + "isRootNode": true, + "name": "svg", + "attributes": { + "width": "14", + "height": "14", + "viewBox": "0 0 14 14", + "fill": "none", + "xmlns": "http://www.w3.org/2000/svg" + }, + "children": [ + { + "type": "element", + "name": "g", + "attributes": { + "id": "Icon" + }, + "children": [ + { + "type": "element", + "name": "path", + "attributes": { + "id": "Vector", + "fill-rule": "evenodd", + "clip-rule": "evenodd", + "d": "M11.3891 2.41987C11.6635 2.58871 11.749 2.94802 11.5802 3.22239L10.3324 5.25H11.0833C11.4055 5.25 11.6667 5.51117 11.6667 5.83334V11.6667C11.6667 12.311 11.1444 12.8333 10.5 12.8333H3.50001C2.85568 12.8333 2.33334 12.311 2.33334 11.6667V5.83334C2.33334 5.51117 2.59451 5.25 2.91668 5.25H8.96252L10.5865 2.61094C10.7554 2.33657 11.1147 2.25102 11.3891 2.41987ZM5.83334 7.58334C5.51118 7.58334 5.25001 7.84449 5.25001 8.16667C5.25001 8.48884 5.51118 8.75 5.83334 8.75H8.16668C8.48885 8.75 8.75001 8.48884 8.75001 8.16667C8.75001 7.84449 8.48885 7.58334 8.16668 7.58334H5.83334Z", + "fill": "currentColor" + }, + "children": [] + }, + { + "type": "element", + "name": "g", + "attributes": { + "id": "Vector_2", + "opacity": "0.5" + }, + "children": [ + { + "type": "element", + "name": "path", + "attributes": { + "d": "M6.91257 1.79347C6.96898 1.76525 7.01477 1.71948 7.043 1.66303L7.32195 1.10508C7.42946 0.890105 7.73623 0.890105 7.84374 1.10508L8.12269 1.66303C8.15093 1.71948 8.19672 1.76525 8.25313 1.79347L8.81108 2.07245C9.0261 2.17994 9.0261 2.48672 8.81108 2.5942L8.25313 2.87318C8.19672 2.9014 8.15093 2.94717 8.12269 3.00362L7.84374 3.56158C7.73623 3.77655 7.42946 3.77655 7.32195 3.56158L7.043 3.00362C7.01477 2.94717 6.96898 2.9014 6.91257 2.87318L6.35461 2.5942C6.13965 2.48672 6.13965 2.17994 6.35461 2.07245L6.91257 1.79347Z", + "fill": "currentColor" + }, + "children": [] + }, + { + "type": "element", + "name": "path", + "attributes": { + "d": "M3.80145 2.7657C3.85789 2.73748 3.90366 2.69171 3.93189 2.63526L4.11364 2.27174C4.22113 2.05677 4.5279 2.05677 4.63539 2.27174L4.81715 2.63526C4.84537 2.6917 4.89114 2.73748 4.94759 2.7657L5.3111 2.94745C5.52607 3.05494 5.52607 3.36172 5.3111 3.4692L4.94759 3.65096C4.89114 3.67919 4.84537 3.72495 4.81715 3.7814L4.63539 4.14491C4.5279 4.35988 4.22113 4.35988 4.11364 4.14491L3.93189 3.7814C3.90366 3.72495 3.85789 3.67919 3.80145 3.65096L3.43793 3.4692C3.22296 3.36172 3.22296 3.05494 3.43793 2.94745L3.80145 2.7657Z", + "fill": "currentColor" + }, + "children": [] + } + ] + } + ] + } + ] + }, + "name": "BoxSparkleFill" +} \ No newline at end of file diff --git a/web/app/components/base/icons/src/vender/plugin/BoxSparkleFill.tsx b/web/app/components/base/icons/src/vender/plugin/BoxSparkleFill.tsx new file mode 100644 index 0000000000..5b60827fe9 --- /dev/null +++ b/web/app/components/base/icons/src/vender/plugin/BoxSparkleFill.tsx @@ -0,0 +1,16 @@ +// GENERATE BY script +// DON NOT EDIT IT MANUALLY + +import * as React from 'react' +import data from './BoxSparkleFill.json' +import IconBase from '@/app/components/base/icons/IconBase' +import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase' + +const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>(( + props, + ref, +) => <IconBase {...props} ref={ref} data={data as IconData} />) + +Icon.displayName = 'BoxSparkleFill' + +export default Icon diff --git a/web/app/components/base/icons/src/vender/plugin/index.ts b/web/app/components/base/icons/src/vender/plugin/index.ts index 6d219fce21..943c764116 100644 --- a/web/app/components/base/icons/src/vender/plugin/index.ts +++ b/web/app/components/base/icons/src/vender/plugin/index.ts @@ -1 +1,2 @@ +export { default as BoxSparkleFill } from './BoxSparkleFill' export { default as LeftCorner } from './LeftCorner' diff --git a/web/app/components/plugins/plugin-detail-panel/index.tsx b/web/app/components/plugins/plugin-detail-panel/index.tsx index 14c47f3b01..84d2afdd43 100644 --- a/web/app/components/plugins/plugin-detail-panel/index.tsx +++ b/web/app/components/plugins/plugin-detail-panel/index.tsx @@ -1,16 +1,20 @@ 'use client' -import React, { useEffect, useState } from 'react' +import React, { useEffect, useMemo, useState } from 'react' import type { FC } from 'react' +import { useTranslation } from 'react-i18next' import { usePathname, useRouter, useSearchParams } from 'next/navigation' -import { RiVerifiedBadgeLine } from '@remixicon/react' -import Badge from '../../base/badge' +import { RiCloseLine, RiVerifiedBadgeLine } from '@remixicon/react' import type { Plugin } from '../types' +import Badge from '../../base/badge' import Description from '../card/base/description' import Icon from '../card/base/card-icon' import Title from '../card/base/title' -import DownloadCount from '../card/base/download-count' +import OperationDropdown from './operation-dropdown' import type { Locale } from '@/i18n' import { fetchPluginDetail } from '@/app/(commonLayout)/plugins/test/card/actions' +import { BoxSparkleFill } from '@/app/components/base/icons/src/vender/plugin' +import Button from '@/app/components/base/button' +import ActionButton from '@/app/components/base/action-button' import Drawer from '@/app/components/base/drawer' import Loading from '@/app/components/base/loading' import cn from '@/utils/classnames' @@ -27,6 +31,7 @@ type Props = { const PluginDetailPanel: FC<Props> = ({ locale, }) => { + const { t } = useTranslation() const searchParams = useSearchParams() const pluginID = searchParams.get('pluginID') const router = useRouter() @@ -34,6 +39,12 @@ const PluginDetailPanel: FC<Props> = ({ const [loading, setLoading] = useState(true) const [pluginDetail, setPluginDetail] = useState<Plugin>() + const hasNewVersion = useMemo(() => { + if (!pluginDetail) + return false + return pluginDetail.latest_version !== pluginDetail.version + }, [pluginDetail]) + const getPluginDetail = async (pluginID: string) => { setLoading(true) const detail = await fetchPluginDetail(pluginID) @@ -49,6 +60,8 @@ const PluginDetailPanel: FC<Props> = ({ router.replace(pathname) } + const handleUpdate = () => {} + useEffect(() => { if (pluginID) getPluginDetail(pluginID) @@ -65,40 +78,43 @@ const PluginDetailPanel: FC<Props> = ({ footer={null} mask={false} positionCenter={false} - panelClassname={cn('mt-[65px] !w-[405px] !max-w-[405px]')} + panelClassname={cn('mt-[64px] mr-2 mb-2 !w-[420px] !max-w-[420px] !p-0 !bg-components-panel-bg rounded-2xl border-[0.5px] border-components-panel-border shadow-xl')} > {loading && <Loading type='area' />} {!loading && pluginDetail && ( - <div - className={cn('w-full flex flex-col bg-white border-[0.5px] border-gray-200 rounded-xl shadow-xl')} - style={{ - height: 'calc(100vh - 65px)', - }} - > - <div className={cn('group relative p-4 pb-3 border-[0.5px] border-components-panel-border bg-components-panel-on-panel-item-bg hover-bg-components-panel-on-panel-item-bg rounded-xl shadow-xs')}> - {/* Header */} + <div className={cn('w-full flex flex-col')}> + <div className={cn('shrink-0 p-4 pb-3 border-b border-divider-subtle bg-components-panel-bg')}> <div className="flex"> <Icon src={pluginDetail.icon} /> <div className="ml-3 w-0 grow"> <div className="flex items-center h-5"> <Title title={pluginDetail.label[locale]} /> <RiVerifiedBadgeLine className="shrink-0 ml-0.5 w-4 h-4 text-text-accent" /> + <Badge + className='mx-1' + text={pluginDetail.version} + hasRedCornerMark={hasNewVersion} + /> + {hasNewVersion && ( + <Button variant='secondary-accent' size='small' className='!h-5' onClick={handleUpdate}>{t('plugin.detailPanel.operation.update')}</Button> + )} </div> <div className='mb-1 flex justify-between items-center h-4'> <div className='flex items-center'> <div className='text-text-tertiary system-xs-regular'>{pluginDetail.org}</div> <div className='mx-2 text-text-quaternary system-xs-regular'>·</div> - <DownloadCount downloadCount={pluginDetail.install_count || 0} /> + <BoxSparkleFill className='w-3.5 h-3.5 text-text-tertiary' /> </div> </div> </div> + <div className='flex gap-1'> + <OperationDropdown /> + <ActionButton onClick={handleClose}> + <RiCloseLine className='w-4 h-4' /> + </ActionButton> + </div> </div> <Description className='mt-3' text={pluginDetail.brief[locale]} descriptionLineRows={2}></Description> - <div className='mt-3 flex space-x-0.5'> - {['LLM', 'text embedding', 'speech2text'].map(tag => ( - <Badge key={tag} text={tag} /> - ))} - </div> </div> </div> )} diff --git a/web/app/components/plugins/plugin-detail-panel/operation-dropdown.tsx b/web/app/components/plugins/plugin-detail-panel/operation-dropdown.tsx new file mode 100644 index 0000000000..c9be924a65 --- /dev/null +++ b/web/app/components/plugins/plugin-detail-panel/operation-dropdown.tsx @@ -0,0 +1,61 @@ +'use client' +import type { FC } from 'react' +import React, { useCallback, useRef, useState } from 'react' +import { useTranslation } from 'react-i18next' +import { RiArrowRightUpLine, RiMoreFill } from '@remixicon/react' +import ActionButton from '@/app/components/base/action-button' +// import Button from '@/app/components/base/button' +import { + PortalToFollowElem, + PortalToFollowElemContent, + PortalToFollowElemTrigger, +} from '@/app/components/base/portal-to-follow-elem' +import cn from '@/utils/classnames' + +type Props = { +} + +const OperationDropdown: FC<Props> = () => { + const { t } = useTranslation() + const [open, doSetOpen] = useState(false) + const openRef = useRef(open) + const setOpen = useCallback((v: boolean) => { + doSetOpen(v) + openRef.current = v + }, [doSetOpen]) + + const handleTrigger = useCallback(() => { + setOpen(!openRef.current) + }, [setOpen]) + + return ( + <PortalToFollowElem + open={open} + onOpenChange={setOpen} + placement='bottom-end' + offset={{ + mainAxis: -12, + crossAxis: 36, + }} + > + <PortalToFollowElemTrigger onClick={handleTrigger}> + <ActionButton className={cn(open && 'bg-state-base-hover')}> + <RiMoreFill className='w-4 h-4' /> + </ActionButton> + </PortalToFollowElemTrigger> + <PortalToFollowElemContent className='z-50'> + <div className='w-[160px] p-1 bg-components-panel-bg-blur rounded-xl border-[0.5px] border-components-panel-border shadow-lg'> + <div className='px-3 py-1.5 rounded-lg text-text-secondary system-md-regular cursor-pointer hover:bg-state-base-hover'>{t('plugin.detailPanel.operation.info')}</div> + <div className='px-3 py-1.5 rounded-lg text-text-secondary system-md-regular cursor-pointer hover:bg-state-base-hover'>{t('plugin.detailPanel.operation.checkUpdate')}</div> + <div className='flex items-center px-3 py-1.5 rounded-lg text-text-secondary system-md-regular cursor-pointer hover:bg-state-base-hover'> + <div className='grow'>{t('plugin.detailPanel.operation.viewDetail')}</div> + <RiArrowRightUpLine className='shrink-0 w-3.5 h-3.5 text-text-tertiary' /> + </div> + <div className='my-1 h-px bg-divider-subtle'></div> + <div className='px-3 py-1.5 rounded-lg text-text-secondary system-md-regular cursor-pointer hover:bg-state-base-hover'>{t('plugin.detailPanel.operation.remove')}</div> + </div> + </PortalToFollowElemContent> + </PortalToFollowElem> + ) +} +export default React.memo(OperationDropdown) diff --git a/web/i18n/en-US/plugin.ts b/web/i18n/en-US/plugin.ts index 55acb354ab..239c1fc322 100644 --- a/web/i18n/en-US/plugin.ts +++ b/web/i18n/en-US/plugin.ts @@ -1,6 +1,15 @@ const translation = { from: 'From', endpointsEnabled: '{{num}} sets of endpoints enabled', + detailPanel: { + operation: { + update: 'Update', + info: 'Plugin Info', + checkUpdate: 'Check Update', + viewDetail: 'View Detail', + remove: 'Remove', + }, + }, } export default translation diff --git a/web/i18n/zh-Hans/plugin.ts b/web/i18n/zh-Hans/plugin.ts index e540d590f6..e89c5bddef 100644 --- a/web/i18n/zh-Hans/plugin.ts +++ b/web/i18n/zh-Hans/plugin.ts @@ -1,6 +1,15 @@ const translation = { from: '来自', endpointsEnabled: '{{num}} 组端点已启用', + detailPanel: { + operation: { + update: '更新', + info: '插件信息', + checkUpdate: '检查更新', + viewDetail: '查看详情', + remove: '移除', + }, + }, } export default translation From 2fbfc988c40bc396a57e894694f39930dc13355c Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Sat, 12 Oct 2024 16:29:46 +0800 Subject: [PATCH 055/346] plugin panel detail --- .../plugins/test/card/actions.ts | 4 +- .../model-provider-page/index.tsx | 2 +- web/app/components/plugins/card/card-mock.ts | 3 -- .../plugin-detail-panel/action-list.tsx | 11 +++++ .../plugin-detail-panel/endpoint-list.tsx | 11 +++++ .../plugins/plugin-detail-panel/index.tsx | 46 +++++++++++++------ .../plugin-detail-panel/model-list.tsx | 31 +++++++++++++ web/app/components/plugins/provider-card.tsx | 40 ++++++++-------- web/app/components/plugins/types.ts | 1 - web/i18n/en-US/plugin.ts | 3 ++ web/i18n/zh-Hans/plugin.ts | 3 ++ 11 files changed, 116 insertions(+), 39 deletions(-) create mode 100644 web/app/components/plugins/plugin-detail-panel/action-list.tsx create mode 100644 web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx create mode 100644 web/app/components/plugins/plugin-detail-panel/model-list.tsx diff --git a/web/app/(commonLayout)/plugins/test/card/actions.ts b/web/app/(commonLayout)/plugins/test/card/actions.ts index 251d00d272..799d6ee8db 100644 --- a/web/app/(commonLayout)/plugins/test/card/actions.ts +++ b/web/app/(commonLayout)/plugins/test/card/actions.ts @@ -8,7 +8,7 @@ export async function handleDelete() { revalidatePath('/') } -export async function fetchPluginDetail(id: string) { +export async function fetchPluginDetail(org: string, name: string) { // Fetch plugin detail TODO - return { id } + return { org, name } } diff --git a/web/app/components/header/account-setting/model-provider-page/index.tsx b/web/app/components/header/account-setting/model-provider-page/index.tsx index 5f0ac829c1..70965c0b6b 100644 --- a/web/app/components/header/account-setting/model-provider-page/index.tsx +++ b/web/app/components/header/account-setting/model-provider-page/index.tsx @@ -185,7 +185,7 @@ const ModelProviderPage = () => { {!collapse && ( <div className='grid grid-cols-2 gap-2'> {pluginList.map((plugin, index) => ( - <ProviderCard key={index} locale={locale} payload={plugin as any} /> + <ProviderCard key={index} installed={false} locale={locale} payload={plugin as any} /> ))} </div> )} diff --git a/web/app/components/plugins/card/card-mock.ts b/web/app/components/plugins/card/card-mock.ts index f653e711dd..d411288db7 100644 --- a/web/app/components/plugins/card/card-mock.ts +++ b/web/app/components/plugins/card/card-mock.ts @@ -1,7 +1,6 @@ import { PluginType } from '../types' export const toolNotion = { - id: 'tool-notion', type: PluginType.tool, org: 'Notion', name: 'notion page search', @@ -19,7 +18,6 @@ export const toolNotion = { } export const extensionDallE = { - id: 'extension-dalle', type: PluginType.extension, org: 'OpenAI', name: 'DALL-E', @@ -38,7 +36,6 @@ export const extensionDallE = { } export const modelGPT4 = { - id: 'model-gpt4', type: PluginType.model, org: 'OpenAI', name: 'GPT-4', diff --git a/web/app/components/plugins/plugin-detail-panel/action-list.tsx b/web/app/components/plugins/plugin-detail-panel/action-list.tsx new file mode 100644 index 0000000000..f7419406d3 --- /dev/null +++ b/web/app/components/plugins/plugin-detail-panel/action-list.tsx @@ -0,0 +1,11 @@ +import React from 'react' + +const ActionList = () => { + return ( + <div> + <h1>Action List</h1> + </div> + ) +} + +export default ActionList diff --git a/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx b/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx new file mode 100644 index 0000000000..ddfe434e55 --- /dev/null +++ b/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx @@ -0,0 +1,11 @@ +import React from 'react' + +const EndpointList = () => { + return ( + <div> + <h1>Endpoints</h1> + </div> + ) +} + +export default EndpointList diff --git a/web/app/components/plugins/plugin-detail-panel/index.tsx b/web/app/components/plugins/plugin-detail-panel/index.tsx index 84d2afdd43..c953e45098 100644 --- a/web/app/components/plugins/plugin-detail-panel/index.tsx +++ b/web/app/components/plugins/plugin-detail-panel/index.tsx @@ -5,11 +5,15 @@ import { useTranslation } from 'react-i18next' import { usePathname, useRouter, useSearchParams } from 'next/navigation' import { RiCloseLine, RiVerifiedBadgeLine } from '@remixicon/react' import type { Plugin } from '../types' +import { PluginType } from '../types' import Badge from '../../base/badge' import Description from '../card/base/description' import Icon from '../card/base/card-icon' import Title from '../card/base/title' import OperationDropdown from './operation-dropdown' +import EndpointList from './endpoint-list' +import ActionList from './action-list' +import ModelList from './model-list' import type { Locale } from '@/i18n' import { fetchPluginDetail } from '@/app/(commonLayout)/plugins/test/card/actions' import { BoxSparkleFill } from '@/app/components/base/icons/src/vender/plugin' @@ -20,8 +24,8 @@ import Loading from '@/app/components/base/loading' import cn from '@/utils/classnames' import { // extensionDallE, - // modelGPT4, - toolNotion, + modelGPT4, + // toolNotion, } from '@/app/components/plugins/card/card-mock' type Props = { @@ -33,7 +37,8 @@ const PluginDetailPanel: FC<Props> = ({ }) => { const { t } = useTranslation() const searchParams = useSearchParams() - const pluginID = searchParams.get('pluginID') + const org = searchParams.get('org') + const name = searchParams.get('name') const router = useRouter() const pathname = usePathname() const [loading, setLoading] = useState(true) @@ -45,12 +50,14 @@ const PluginDetailPanel: FC<Props> = ({ return pluginDetail.latest_version !== pluginDetail.version }, [pluginDetail]) - const getPluginDetail = async (pluginID: string) => { + const getPluginDetail = async (org: string, name: string) => { + console.log('organization: ', org) + console.log('plugin name: ', name) setLoading(true) - const detail = await fetchPluginDetail(pluginID) + const detail = await fetchPluginDetail(org, name) setPluginDetail({ ...detail, - ...toolNotion, + ...modelGPT4, } as any) setLoading(false) } @@ -63,11 +70,11 @@ const PluginDetailPanel: FC<Props> = ({ const handleUpdate = () => {} useEffect(() => { - if (pluginID) - getPluginDetail(pluginID) - }, [pluginID]) + if (org && name) + getPluginDetail(org, name) + }, [org, name]) - if (!pluginID) + if (!org || !name) return null return ( @@ -78,11 +85,11 @@ const PluginDetailPanel: FC<Props> = ({ footer={null} mask={false} positionCenter={false} - panelClassname={cn('mt-[64px] mr-2 mb-2 !w-[420px] !max-w-[420px] !p-0 !bg-components-panel-bg rounded-2xl border-[0.5px] border-components-panel-border shadow-xl')} + panelClassname={cn('justify-start mt-[64px] mr-2 mb-2 !w-[420px] !max-w-[420px] !p-0 !bg-components-panel-bg rounded-2xl border-[0.5px] border-components-panel-border shadow-xl')} > {loading && <Loading type='area' />} {!loading && pluginDetail && ( - <div className={cn('w-full flex flex-col')}> + <> <div className={cn('shrink-0 p-4 pb-3 border-b border-divider-subtle bg-components-panel-bg')}> <div className="flex"> <Icon src={pluginDetail.icon} /> @@ -102,7 +109,7 @@ const PluginDetailPanel: FC<Props> = ({ <div className='mb-1 flex justify-between items-center h-4'> <div className='flex items-center'> <div className='text-text-tertiary system-xs-regular'>{pluginDetail.org}</div> - <div className='mx-2 text-text-quaternary system-xs-regular'>·</div> + <div className='ml-1 text-text-quaternary system-xs-regular'>·</div> <BoxSparkleFill className='w-3.5 h-3.5 text-text-tertiary' /> </div> </div> @@ -116,7 +123,18 @@ const PluginDetailPanel: FC<Props> = ({ </div> <Description className='mt-3' text={pluginDetail.brief[locale]} descriptionLineRows={2}></Description> </div> - </div> + <div className='grow overflow-y-auto'> + {pluginDetail.type === PluginType.model && ( + <ModelList /> + )} + {pluginDetail.type !== PluginType.model && ( + <> + <EndpointList /> + <ActionList /> + </> + )} + </div> + </> )} </Drawer> ) diff --git a/web/app/components/plugins/plugin-detail-panel/model-list.tsx b/web/app/components/plugins/plugin-detail-panel/model-list.tsx new file mode 100644 index 0000000000..fcfecd9121 --- /dev/null +++ b/web/app/components/plugins/plugin-detail-panel/model-list.tsx @@ -0,0 +1,31 @@ +import React from 'react' +import { useTranslation } from 'react-i18next' +// import ModelIcon from '@/app/components/header/account-setting/model-provider-page/model-icon' +// import ModelName from '@/app/components/header/account-setting/model-provider-page/model-name' + +const ModelList = () => { + const { t } = useTranslation() + + return ( + <div className='px-4 py-2'> + <div className='mb-1 h-6 flex items-center text-text-secondary system-sm-semibold-uppercase'>{t('plugin.detailPanel.modelNum', { num: 3 })}</div> + <div className='h-8 flex items-center'> + {/* <ModelIcon + className='shrink-0 mr-2' + provider={provider} + modelName={model.model} + /> + <ModelName + className='grow text-sm font-normal text-gray-900' + modelItem={model} + showModelType + showMode + showContextSize + > + </ModelName> */} + </div> + </div> + ) +} + +export default ModelList diff --git a/web/app/components/plugins/provider-card.tsx b/web/app/components/plugins/provider-card.tsx index 7ee0b55e86..2445c4b9ab 100644 --- a/web/app/components/plugins/provider-card.tsx +++ b/web/app/components/plugins/provider-card.tsx @@ -16,18 +16,20 @@ type Props = { className?: string locale: Locale // The component is used in both client and server side, so we can't get the locale from both side(getLocaleOnServer and useContext) payload: Plugin + installed?: boolean } const ProviderCard: FC<Props> = ({ className, locale, payload, + installed = true, }) => { const { org, label } = payload return ( <div className={cn('group relative p-4 pb-3 border-[0.5px] border-components-panel-border bg-components-panel-on-panel-item-bg hover-bg-components-panel-on-panel-item-bg rounded-xl shadow-xs', className)}> - <Link href={`/plugins/test/card?pluginID=${payload.id}`}> + <Link href={`/plugins/test/card?org=${payload.org}&name=${payload.name}`}> {/* Header */} <div className="flex"> <Icon src={payload.icon} /> @@ -51,24 +53,26 @@ const ProviderCard: FC<Props> = ({ <Badge key={tag} text={tag} /> ))} </div> - <div - className='hidden group-hover:flex items-center gap-2 absolute bottom-0 left-0 right-0 p-4 pt-8' - style={{ background: 'linear-gradient(0deg, #F9FAFB 60.27%, rgba(249, 250, 251, 0.00) 100%)' }} - > - <Button - className='flex-grow' - variant='primary' + {!installed && ( + <div + className='hidden group-hover:flex items-center gap-2 absolute bottom-0 left-0 right-0 p-4 pt-8' + style={{ background: 'linear-gradient(0deg, #F9FAFB 60.27%, rgba(249, 250, 251, 0.00) 100%)' }} > - Install - </Button> - <Button - className='flex-grow' - variant='secondary' - > - Details - <RiArrowRightUpLine className='w-4 h-4' /> - </Button> - </div> + <Button + className='flex-grow' + variant='primary' + > + Install + </Button> + <Button + className='flex-grow' + variant='secondary' + > + Details + <RiArrowRightUpLine className='w-4 h-4' /> + </Button> + </div> + )} </Link> </div> ) diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts index 0c2b467326..3b8fdd12f2 100644 --- a/web/app/components/plugins/types.ts +++ b/web/app/components/plugins/types.ts @@ -8,7 +8,6 @@ export enum PluginType { } export type Plugin = { - id: string 'type': PluginType 'org': string 'name': string diff --git a/web/i18n/en-US/plugin.ts b/web/i18n/en-US/plugin.ts index 239c1fc322..26aea309ba 100644 --- a/web/i18n/en-US/plugin.ts +++ b/web/i18n/en-US/plugin.ts @@ -3,12 +3,15 @@ const translation = { endpointsEnabled: '{{num}} sets of endpoints enabled', detailPanel: { operation: { + install: 'Install', + detail: 'Detail', update: 'Update', info: 'Plugin Info', checkUpdate: 'Check Update', viewDetail: 'View Detail', remove: 'Remove', }, + modelNum: '{{num}} MODELS INCLUDED', }, } diff --git a/web/i18n/zh-Hans/plugin.ts b/web/i18n/zh-Hans/plugin.ts index e89c5bddef..3597f07784 100644 --- a/web/i18n/zh-Hans/plugin.ts +++ b/web/i18n/zh-Hans/plugin.ts @@ -3,12 +3,15 @@ const translation = { endpointsEnabled: '{{num}} 组端点已启用', detailPanel: { operation: { + install: '安装', + detail: '详情', update: '更新', info: '插件信息', checkUpdate: '检查更新', viewDetail: '查看详情', remove: '移除', }, + modelNum: '{{num}} 模型已包含', }, } From fc61fd0f5030d9553dd937a9b79ab3b053e7b45e Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Sat, 12 Oct 2024 17:08:45 +0800 Subject: [PATCH 056/346] action list --- .../plugins/plugin-detail-panel/action-list.tsx | 10 ++++++++-- .../components/plugins/plugin-detail-panel/index.tsx | 6 +++--- web/i18n/en-US/plugin.ts | 1 + web/i18n/zh-Hans/plugin.ts | 1 + 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/web/app/components/plugins/plugin-detail-panel/action-list.tsx b/web/app/components/plugins/plugin-detail-panel/action-list.tsx index f7419406d3..452018cdd8 100644 --- a/web/app/components/plugins/plugin-detail-panel/action-list.tsx +++ b/web/app/components/plugins/plugin-detail-panel/action-list.tsx @@ -1,9 +1,15 @@ import React from 'react' +import { useTranslation } from 'react-i18next' const ActionList = () => { + const { t } = useTranslation() return ( - <div> - <h1>Action List</h1> + <div className='px-4 py-2'> + <div className='mb-1 h-6 flex items-center text-text-secondary system-sm-semibold-uppercase'>{t('plugin.detailPanel.actionNum', { num: 3 })}</div> + <div className='px-4 py-3 bg-components-panel-item-bg rounded-xl border-[0.5px] border-components-panel-border-subtle shadow-xs cursor-pointer hover:bg-components-panel-on-panel-item-bg-hover'> + <div className='pb-0.5 text-text-secondary system-md-semibold'>Notion Page Search</div> + <div className='text-text-tertiary system-xs-regular line-clamp-2'>A tool for performing a Google SERP search and extracting snippets and webpages.Input should be a search query.</div> + </div> </div> ) } diff --git a/web/app/components/plugins/plugin-detail-panel/index.tsx b/web/app/components/plugins/plugin-detail-panel/index.tsx index c953e45098..b118a8c8f5 100644 --- a/web/app/components/plugins/plugin-detail-panel/index.tsx +++ b/web/app/components/plugins/plugin-detail-panel/index.tsx @@ -24,8 +24,8 @@ import Loading from '@/app/components/base/loading' import cn from '@/utils/classnames' import { // extensionDallE, - modelGPT4, - // toolNotion, + // modelGPT4, + toolNotion, } from '@/app/components/plugins/card/card-mock' type Props = { @@ -57,7 +57,7 @@ const PluginDetailPanel: FC<Props> = ({ const detail = await fetchPluginDetail(org, name) setPluginDetail({ ...detail, - ...modelGPT4, + ...toolNotion, } as any) setLoading(false) } diff --git a/web/i18n/en-US/plugin.ts b/web/i18n/en-US/plugin.ts index 26aea309ba..7779d09830 100644 --- a/web/i18n/en-US/plugin.ts +++ b/web/i18n/en-US/plugin.ts @@ -12,6 +12,7 @@ const translation = { remove: 'Remove', }, modelNum: '{{num}} MODELS INCLUDED', + actionNum: '{{num}} ACTIONS INCLUDED', }, } diff --git a/web/i18n/zh-Hans/plugin.ts b/web/i18n/zh-Hans/plugin.ts index 3597f07784..9a65f7af7d 100644 --- a/web/i18n/zh-Hans/plugin.ts +++ b/web/i18n/zh-Hans/plugin.ts @@ -12,6 +12,7 @@ const translation = { remove: '移除', }, modelNum: '{{num}} 模型已包含', + actionNum: '{{num}} ACTIONS 已包含', }, } From b8cd6ea4781f594d3bc736e47899049b2eba61b4 Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Sat, 12 Oct 2024 17:36:06 +0800 Subject: [PATCH 057/346] feat: support view choose --- .../workflow/block-selector/all-tools.tsx | 37 +++++++----- .../workflow/block-selector/hooks.ts | 2 +- .../workflow/block-selector/tools.tsx | 3 +- .../block-selector/view-type-select.tsx | 58 +++++++++++++++++++ web/i18n/zh-Hans/workflow.ts | 2 +- 5 files changed, 83 insertions(+), 19 deletions(-) create mode 100644 web/app/components/workflow/block-selector/view-type-select.tsx diff --git a/web/app/components/workflow/block-selector/all-tools.tsx b/web/app/components/workflow/block-selector/all-tools.tsx index 9ef239ce18..1338f4ef1a 100644 --- a/web/app/components/workflow/block-selector/all-tools.tsx +++ b/web/app/components/workflow/block-selector/all-tools.tsx @@ -9,6 +9,7 @@ import type { import { ToolTypeEnum } from './types' import Tools from './tools' import { useToolTabs } from './hooks' +import ViewTypeSelect, { ViewType } from './view-type-select' import cn from '@/utils/classnames' import { useGetLanguage } from '@/context/i18n' @@ -29,6 +30,7 @@ const AllTools = ({ const language = useGetLanguage() const tabs = useToolTabs() const [activeTab, setActiveTab] = useState(ToolTypeEnum.All) + const [activeView, setActiveView] = useState<ViewType>(ViewType.list) const tools = useMemo(() => { let mergedTools: ToolWithProvider[] = [] @@ -49,22 +51,25 @@ const AllTools = ({ }, [activeTab, buildInTools, customTools, workflowTools, searchText, language]) return ( <div> - <div className='flex items-center px-3 h-8 space-x-1 bg-gray-25 border-b-[0.5px] border-black/[0.08] shadow-xs'> - { - tabs.map(tab => ( - <div - className={cn( - 'flex items-center px-2 h-6 rounded-md hover:bg-gray-100 cursor-pointer', - 'text-xs font-medium text-gray-700', - activeTab === tab.key && 'bg-gray-200', - )} - key={tab.key} - onClick={() => setActiveTab(tab.key)} - > - {tab.name} - </div> - )) - } + <div className='flex items-center justify-between px-3 bg-background-default-hover border-b-[0.5px] border-black/[0.08] shadow-xs'> + <div className='flex items-center h-8 space-x-1'> + { + tabs.map(tab => ( + <div + className={cn( + 'flex items-center px-2 h-6 rounded-md hover:bg-gray-100 cursor-pointer', + 'text-xs font-medium text-gray-700', + activeTab === tab.key && 'bg-gray-200', + )} + key={tab.key} + onClick={() => setActiveTab(tab.key)} + > + {tab.name} + </div> + )) + } + </div> + <ViewTypeSelect viewType={activeView} onChange={setActiveView} /> </div> <Tools showWorkflowEmpty={activeTab === ToolTypeEnum.Workflow} diff --git a/web/app/components/workflow/block-selector/hooks.ts b/web/app/components/workflow/block-selector/hooks.ts index 592954afa3..a8b1759506 100644 --- a/web/app/components/workflow/block-selector/hooks.ts +++ b/web/app/components/workflow/block-selector/hooks.ts @@ -41,7 +41,7 @@ export const useToolTabs = () => { }, { key: ToolTypeEnum.BuiltIn, - name: t('workflow.tabs.builtInTool'), + name: t('workflow.tabs.plugin'), }, { key: ToolTypeEnum.Custom, diff --git a/web/app/components/workflow/block-selector/tools.tsx b/web/app/components/workflow/block-selector/tools.tsx index 534fe1499d..a81378dd2d 100644 --- a/web/app/components/workflow/block-selector/tools.tsx +++ b/web/app/components/workflow/block-selector/tools.tsx @@ -5,6 +5,7 @@ import { } from 'react' import { useTranslation } from 'react-i18next' import type { BlockEnum, ToolWithProvider } from '../types' +import { CollectionType } from '../../tools/types' import IndexBar, { groupItems } from './index-bar' import type { ToolDefaultValue } from './types' import ToolItem from './tool-item' @@ -42,7 +43,7 @@ const Blocks = ({ list.map(tool => ( <ToolItem key={tool.name} - isToolPlugin={toolWithProvider.type === 'builtin'} + isToolPlugin={toolWithProvider.type === CollectionType.builtIn} provider={toolWithProvider} payload={tool} onSelect={onSelect} diff --git a/web/app/components/workflow/block-selector/view-type-select.tsx b/web/app/components/workflow/block-selector/view-type-select.tsx new file mode 100644 index 0000000000..d7ba5b74a9 --- /dev/null +++ b/web/app/components/workflow/block-selector/view-type-select.tsx @@ -0,0 +1,58 @@ +'use client' +import type { FC } from 'react' +import React, { useCallback } from 'react' +import { RiNodeTree, RiSortAlphabetAsc } from '@remixicon/react' +import cn from '@/utils/classnames' + +export enum ViewType { + list = 'list', + tree = 'tree', +} + +type Props = { + viewType: ViewType + onChange: (viewType: ViewType) => void +} + +const ViewTypeSelect: FC<Props> = ({ + viewType, + onChange, +}) => { + const handleChange = useCallback((nextViewType: ViewType) => { + return () => { + if (nextViewType === viewType) + return + onChange(nextViewType) + } + }, [viewType, onChange]) + + return ( + <div className='flex items-center rounded-lg bg-components-segmented-control-bg-normal p-px'> + <div + className={ + cn('p-[3px] rounded-lg', + viewType === ViewType.list + ? 'bg-components-segmented-control-item-active-bg shadow-xs text-text-accent-light-mode-only' + : 'text-text-tertiary cursor-pointer', + ) + } + onClick={handleChange(ViewType.list)} + > + <RiSortAlphabetAsc className='w-4 h-4' /> + </div> + <div + className={ + cn('p-[3px] rounded-lg', + viewType === ViewType.tree + ? 'bg-components-segmented-control-item-active-bg shadow-xs text-text-accent-light-mode-only' + : 'text-text-tertiary cursor-pointer', + ) + } + onClick={handleChange(ViewType.tree)} + > + <RiNodeTree className='w-4 h-4 ' /> + </div> + </div> + ) +} +export default React.memo(ViewTypeSelect) diff --git a/web/i18n/zh-Hans/workflow.ts b/web/i18n/zh-Hans/workflow.ts index 3579ec5df3..2a685f1dc6 100644 --- a/web/i18n/zh-Hans/workflow.ts +++ b/web/i18n/zh-Hans/workflow.ts @@ -197,7 +197,7 @@ const translation = { 'searchTool': '搜索工具', 'tools': '工具', 'allTool': '全部', - 'builtInTool': '内置', + 'plugin': '插件', 'customTool': '自定义', 'workflowTool': '工作流', 'question-understand': '问题理解', From 0e5c16d0c281f088e176c4acf2b794e971e3b750 Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Sat, 12 Oct 2024 18:15:11 +0800 Subject: [PATCH 058/346] feat: view to ui and fix some ui promblem --- .../workflow/block-selector/all-tools.tsx | 1 + .../workflow/block-selector/index-bar.tsx | 5 +-- .../workflow/block-selector/tool-item.tsx | 33 +++++++++++-------- .../workflow/block-selector/tools.tsx | 16 ++++++--- 4 files changed, 36 insertions(+), 19 deletions(-) diff --git a/web/app/components/workflow/block-selector/all-tools.tsx b/web/app/components/workflow/block-selector/all-tools.tsx index 1338f4ef1a..f8947ad52a 100644 --- a/web/app/components/workflow/block-selector/all-tools.tsx +++ b/web/app/components/workflow/block-selector/all-tools.tsx @@ -75,6 +75,7 @@ const AllTools = ({ showWorkflowEmpty={activeTab === ToolTypeEnum.Workflow} tools={tools} onSelect={onSelect} + viewType={activeView} /> </div> ) diff --git a/web/app/components/workflow/block-selector/index-bar.tsx b/web/app/components/workflow/block-selector/index-bar.tsx index 7432358c9c..8068d9ecbc 100644 --- a/web/app/components/workflow/block-selector/index-bar.tsx +++ b/web/app/components/workflow/block-selector/index-bar.tsx @@ -47,9 +47,10 @@ const IndexBar: FC<IndexBarProps> = ({ letters, itemRefs }) => { element.scrollIntoView({ behavior: 'smooth' }) } return ( - <div className="index-bar absolute right-4 top-36 flex flex-col items-center text-xs font-medium text-gray-500"> + <div className="index-bar absolute right-4 top-36 flex flex-col items-center w-6 justify-center text-xs font-medium text-text-quaternary "> + <div className='absolute left-0 top-0 h-full w-px bg-[linear-gradient(270deg,rgba(255,255,255,0)_0%,rgba(16,24,40,0.08)_30%,rgba(16,24,40,0.08)_50%,rgba(16,24,40,0.08)_70.5%,rgba(255,255,255,0)_100%)]'></div> {letters.map(letter => ( - <div className="hover:text-gray-900 cursor-pointer" key={letter} onClick={() => handleIndexClick(letter)}> + <div className="hover:text-text-secondary cursor-pointer" key={letter} onClick={() => handleIndexClick(letter)}> {letter} </div> ))} diff --git a/web/app/components/workflow/block-selector/tool-item.tsx b/web/app/components/workflow/block-selector/tool-item.tsx index a5e1639392..5ee3b399a5 100644 --- a/web/app/components/workflow/block-selector/tool-item.tsx +++ b/web/app/components/workflow/block-selector/tool-item.tsx @@ -1,7 +1,7 @@ 'use client' import type { FC } from 'react' import React from 'react' -import { RiArrowRightSLine } from '@remixicon/react' +import { RiArrowDownSLine, RiArrowRightSLine } from '@remixicon/react' import { useBoolean } from 'ahooks' import BlockIcon from '../block-icon' import type { ToolWithProvider } from '../types' @@ -10,8 +10,10 @@ import type { ToolDefaultValue } from './types' import Tooltip from '@/app/components/base/tooltip' import type { Tool } from '@/app/components/tools/types' import { useGetLanguage } from '@/context/i18n' +import cn from '@/utils/classnames' type Props = { + className?: string isToolPlugin: boolean // Tool plugin should choose action provider: ToolWithProvider payload: Tool @@ -19,6 +21,7 @@ type Props = { } const ToolItem: FC<Props> = ({ + className, isToolPlugin, provider, payload, @@ -27,7 +30,9 @@ const ToolItem: FC<Props> = ({ const language = useGetLanguage() const [isFold, { toggle: toggleFold, - }] = useBoolean(true) + }] = useBoolean(false) + + const FoldIcon = isFold ? RiArrowDownSLine : RiArrowRightSLine const actions = [ 'DuckDuckGo AI Search', @@ -52,9 +57,9 @@ const ToolItem: FC<Props> = ({ </div> )} > - <div> + <div className={cn(className)}> <div - className='flex items-center px-3 w-full h-8 rounded-lg hover:bg-gray-50 cursor-pointer' + className='flex items-center justify-between pl-3 pr-1 w-full rounded-lg hover:bg-gray-50 cursor-pointer' onClick={() => { if (isToolPlugin) { toggleFold() @@ -70,22 +75,24 @@ const ToolItem: FC<Props> = ({ }) }} > + <div className='flex items-center h-8'> + <BlockIcon + className='shrink-0' + type={BlockEnum.Tool} + toolIcon={provider.icon} + /> + <div className='ml-2 text-sm text-gray-900 flex-1 min-w-0 truncate'>{payload.label[language]}</div> + </div> {isToolPlugin && ( - <RiArrowRightSLine className='mr-1 w-4 h-4 text-text-quaternary shrink-0' /> + <FoldIcon className={cn('w-4 h-4 text-text-quaternary shrink-0', isFold && 'text-text-tertiary')} /> )} - <BlockIcon - className='mr-2 shrink-0' - type={BlockEnum.Tool} - toolIcon={provider.icon} - /> - <div className='text-sm text-gray-900 flex-1 min-w-0 truncate'>{payload.label[language]}</div> </div> {(!isFold && isToolPlugin) && ( <div> {actions.map(action => ( <div key={action} - className='rounded-lg pl-[37px] hover:bg-state-base-hover cursor-pointer' + className='rounded-lg pl-[21px] hover:bg-state-base-hover cursor-pointer' onClick={() => { onSelect(BlockEnum.Tool, { provider_id: provider.id, @@ -97,7 +104,7 @@ const ToolItem: FC<Props> = ({ }) }} > - <div className='h-8 leading-8 border-l-2 border-divider-subtle pl-[19px] truncate text-text-secondary system-sm-medium'>{action}</div> + <div className='h-8 leading-8 border-l-2 border-divider-subtle pl-4 truncate text-text-secondary system-sm-medium'>{action}</div> </div> ))} </div> diff --git a/web/app/components/workflow/block-selector/tools.tsx b/web/app/components/workflow/block-selector/tools.tsx index a81378dd2d..43f44bf882 100644 --- a/web/app/components/workflow/block-selector/tools.tsx +++ b/web/app/components/workflow/block-selector/tools.tsx @@ -9,6 +9,7 @@ import { CollectionType } from '../../tools/types' import IndexBar, { groupItems } from './index-bar' import type { ToolDefaultValue } from './types' import ToolItem from './tool-item' +import { ViewType } from './view-type-select' import Empty from '@/app/components/tools/add-tool-modal/empty' import { useGetLanguage } from '@/context/i18n' @@ -16,14 +17,18 @@ type ToolsProps = { showWorkflowEmpty: boolean onSelect: (type: BlockEnum, tool?: ToolDefaultValue) => void tools: ToolWithProvider[] + viewType: ViewType } const Blocks = ({ showWorkflowEmpty, onSelect, tools, + viewType, }: ToolsProps) => { const { t } = useTranslation() const language = useGetLanguage() + const isListView = viewType === ViewType.list + const isTreeView = viewType === ViewType.tree const { letters, groups: groupedTools } = groupItems(tools, tool => tool.label[language][0]) const toolRefs = useRef({}) @@ -36,13 +41,16 @@ const Blocks = ({ key={toolWithProvider.id} className='mb-1 last-of-type:mb-0' > - <div className='flex items-start px-3 h-[22px] text-xs font-medium text-gray-500'> - {toolWithProvider.label[language]} - </div> + {isTreeView && ( + <div className='flex items-start px-3 h-[22px] text-xs font-medium text-gray-500'> + {toolWithProvider.label[language]} + </div> + )} { list.map(tool => ( <ToolItem key={tool.name} + className={isListView && 'mr-6'} isToolPlugin={toolWithProvider.type === CollectionType.builtIn} provider={toolWithProvider} payload={tool} @@ -79,7 +87,7 @@ const Blocks = ({ </div> )} {!!tools.length && letters.map(renderLetterGroup)} - {tools.length > 10 && <IndexBar letters={letters} itemRefs={toolRefs} />} + {isListView && tools.length > 10 && <IndexBar letters={letters} itemRefs={toolRefs} />} </div> ) } From 54f911f6cd1f51852929a4e83005848b76f44464 Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Sun, 13 Oct 2024 10:49:55 +0800 Subject: [PATCH 059/346] endpoints --- web/app/components/base/copy-btn/index.tsx | 16 +++- .../plugin-detail-panel/action-list.tsx | 31 +++++-- .../plugin-detail-panel/endpoint-list.tsx | 86 ++++++++++++++++++- .../plugins/plugin-detail-panel/index.tsx | 14 +-- web/i18n/en-US/plugin.ts | 6 +- web/i18n/zh-Hans/plugin.ts | 6 +- 6 files changed, 136 insertions(+), 23 deletions(-) diff --git a/web/app/components/base/copy-btn/index.tsx b/web/app/components/base/copy-btn/index.tsx index 2acb5d8e76..750abbf5dd 100644 --- a/web/app/components/base/copy-btn/index.tsx +++ b/web/app/components/base/copy-btn/index.tsx @@ -1,6 +1,7 @@ 'use client' import { useState } from 'react' import { t } from 'i18next' +import { debounce } from 'lodash-es' import copy from 'copy-to-clipboard' import s from './style.module.css' import Tooltip from '@/app/components/base/tooltip' @@ -18,22 +19,29 @@ const CopyBtn = ({ }: ICopyBtnProps) => { const [isCopied, setIsCopied] = useState(false) + const onClickCopy = debounce(() => { + copy(value) + setIsCopied(true) + }, 100) + + const onMouseLeave = debounce(() => { + setIsCopied(false) + }, 100) + return ( <div className={`${className}`}> <Tooltip popupContent={(isCopied ? t('appApi.copied') : t('appApi.copy'))} > <div + onMouseLeave={onMouseLeave} className={'box-border p-0.5 flex items-center justify-center rounded-md bg-white cursor-pointer'} style={!isPlain ? { boxShadow: '0px 4px 8px -2px rgba(16, 24, 40, 0.1), 0px 2px 4px -2px rgba(16, 24, 40, 0.06)', } : {}} - onClick={() => { - copy(value) - setIsCopied(true) - }} + onClick={onClickCopy} > <div className={`w-6 h-6 rounded-md hover:bg-gray-50 ${s.copyIcon} ${isCopied ? s.copied : ''}`}></div> </div> diff --git a/web/app/components/plugins/plugin-detail-panel/action-list.tsx b/web/app/components/plugins/plugin-detail-panel/action-list.tsx index 452018cdd8..26ccfe83e0 100644 --- a/web/app/components/plugins/plugin-detail-panel/action-list.tsx +++ b/web/app/components/plugins/plugin-detail-panel/action-list.tsx @@ -1,14 +1,35 @@ import React from 'react' import { useTranslation } from 'react-i18next' +import Button from '@/app/components/base/button' +import Indicator from '@/app/components/header/indicator' + +const ActionCard = () => { + return ( + <div className='px-4 py-3 bg-components-panel-item-bg rounded-xl border-[0.5px] border-components-panel-border-subtle shadow-xs cursor-pointer hover:bg-components-panel-on-panel-item-bg-hover'> + <div className='pb-0.5 text-text-secondary system-md-semibold'>Notion Page Search</div> + <div className='text-text-tertiary system-xs-regular line-clamp-2'>A tool for performing a Google SERP search and extracting snippets and webpages.Input should be a search query.</div> + </div> + ) +} const ActionList = () => { const { t } = useTranslation() return ( - <div className='px-4 py-2'> - <div className='mb-1 h-6 flex items-center text-text-secondary system-sm-semibold-uppercase'>{t('plugin.detailPanel.actionNum', { num: 3 })}</div> - <div className='px-4 py-3 bg-components-panel-item-bg rounded-xl border-[0.5px] border-components-panel-border-subtle shadow-xs cursor-pointer hover:bg-components-panel-on-panel-item-bg-hover'> - <div className='pb-0.5 text-text-secondary system-md-semibold'>Notion Page Search</div> - <div className='text-text-tertiary system-xs-regular line-clamp-2'>A tool for performing a Google SERP search and extracting snippets and webpages.Input should be a search query.</div> + <div className='px-4 pt-2 pb-4'> + <div className='mb-1 py-1'> + <div className='mb-1 h-6 flex items-center justify-between text-text-secondary system-sm-semibold-uppercase'> + {t('plugin.detailPanel.actionNum', { num: 3 })} + <Button variant='secondary' size='small'> + <Indicator className='mr-2' color={'green'} /> + {t('tools.auth.authorized')} + </Button> + </div> + <Button variant='primary' className='w-full'>{t('tools.auth.unauthorized')}</Button> + </div> + <div className='flex flex-col gap-2'> + <ActionCard /> + <ActionCard /> + <ActionCard /> </div> </div> ) diff --git a/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx b/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx index ddfe434e55..4dfd4bbd55 100644 --- a/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx +++ b/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx @@ -1,9 +1,91 @@ import React from 'react' +import { useTranslation } from 'react-i18next' +import { RiAddLine, RiLoginCircleLine } from '@remixicon/react' +import ActionButton from '@/app/components/base/action-button' +import CopyBtn from '@/app/components/base/copy-btn' +import Indicator from '@/app/components/header/indicator' +import Tooltip from '@/app/components/base/tooltip' +import Switch from '@/app/components/base/switch' + +const EndpointCard = () => { + const { t } = useTranslation() + return ( + <div className='p-0.5 bg-background-section-burn rounded-xl'> + <div className='p-2.5 pl-3 bg-components-panel-on-panel-item-bg rounded-[10px] border-[0.5px] border-components-panel-border'> + <div className='mb-1 h-6 flex items-center gap-1 text-text-secondary system-md-semibold'> + <RiLoginCircleLine className='w-4 h-4' /> + <div>Endpoint for Unreal workspace</div> + </div> + <div className='h-6 flex items-center'> + <div className='shrink-0 w-24 text-text-tertiary system-xs-regular'>Start Callback</div> + <div className='group grow flex items-center text-text-secondary system-xs-regular truncate'> + <div className='truncate'>https://extension.dify.ai/a1b2c3d4/onStart</div> + <CopyBtn + className='hidden shrink-0 ml-2 group-hover:block' + value={'https://extension.dify.ai/a1b2c3d4/onStart'} + isPlain + /> + </div> + </div> + <div className='h-6 flex items-center'> + <div className='shrink-0 w-24 text-text-tertiary system-xs-regular'>Finish Callback</div> + <div className='group grow flex items-center text-text-secondary system-xs-regular truncate'> + <div className='truncate'>https://extension.dify.ai/a1b2c3d4/onFinish</div> + <CopyBtn + className='hidden shrink-0 ml-2 group-hover:block' + value={'https://extension.dify.ai/a1b2c3d4/onFinish'} + isPlain + /> + </div> + </div> + </div> + <div className='px-3 py-2 flex items-center justify-between'> + <div className='flex items-center gap-1 system-xs-semibold-uppercase text-util-colors-green-green-600'> + <Indicator color='green' /> + {t('plugin.detailPanel.serviceOk')} + </div> + {/* <div className='flex items-center gap-1 system-xs-semibold-uppercase text-text-tertiary'> + <Indicator color='gray' /> + {t('plugin.detailPanel.disabled')} + </div> */} + <Switch + className='ml-3' + defaultValue={true} + onChange={() => {}} + size='sm' + /> + </div> + </div> + ) +} const EndpointList = () => { + const { t } = useTranslation() return ( - <div> - <h1>Endpoints</h1> + <div className='px-4 py-2 border-t border-divider-subtle'> + <div className='mb-1 h-6 flex items-center justify-between text-text-secondary system-sm-semibold-uppercase'> + <div className='flex items-center gap-0.5'> + {t('plugin.detailPanel.endpoints')} + <Tooltip + popupContent={ + <div className='w-[180px]'> + {t('appDebug.voice.voiceSettings.resolutionTooltip').split('\n').map(item => ( + <div key={item}>{item}</div> + ))} + </div> + } + /> + </div> + <ActionButton> + <RiAddLine className='w-4 h-4' /> + </ActionButton> + </div> + <div className='mb-1 p-3 flex justify-center rounded-[10px] bg-background-section text-text-tertiary system-xs-regular'>{t('plugin.detailPanel.endpointsEmpty')}</div> + <div className='flex flex-col gap-2'> + <EndpointCard /> + <EndpointCard /> + <EndpointCard /> + </div> </div> ) } diff --git a/web/app/components/plugins/plugin-detail-panel/index.tsx b/web/app/components/plugins/plugin-detail-panel/index.tsx index b118a8c8f5..62163008c1 100644 --- a/web/app/components/plugins/plugin-detail-panel/index.tsx +++ b/web/app/components/plugins/plugin-detail-panel/index.tsx @@ -5,7 +5,7 @@ import { useTranslation } from 'react-i18next' import { usePathname, useRouter, useSearchParams } from 'next/navigation' import { RiCloseLine, RiVerifiedBadgeLine } from '@remixicon/react' import type { Plugin } from '../types' -import { PluginType } from '../types' +// import { PluginType } from '../types' import Badge from '../../base/badge' import Description from '../card/base/description' import Icon from '../card/base/card-icon' @@ -124,15 +124,9 @@ const PluginDetailPanel: FC<Props> = ({ <Description className='mt-3' text={pluginDetail.brief[locale]} descriptionLineRows={2}></Description> </div> <div className='grow overflow-y-auto'> - {pluginDetail.type === PluginType.model && ( - <ModelList /> - )} - {pluginDetail.type !== PluginType.model && ( - <> - <EndpointList /> - <ActionList /> - </> - )} + <ActionList /> + <EndpointList /> + <ModelList /> </div> </> )} diff --git a/web/i18n/en-US/plugin.ts b/web/i18n/en-US/plugin.ts index 7779d09830..c73c6a448e 100644 --- a/web/i18n/en-US/plugin.ts +++ b/web/i18n/en-US/plugin.ts @@ -11,8 +11,12 @@ const translation = { viewDetail: 'View Detail', remove: 'Remove', }, - modelNum: '{{num}} MODELS INCLUDED', actionNum: '{{num}} ACTIONS INCLUDED', + endpoints: 'Endpoints', + endpointsEmpty: 'Click the \'+\' button to add an endpoint', + serviceOk: 'Service OK', + disabled: 'Disabled', + modelNum: '{{num}} MODELS INCLUDED', }, } diff --git a/web/i18n/zh-Hans/plugin.ts b/web/i18n/zh-Hans/plugin.ts index 9a65f7af7d..9bf3fdeea8 100644 --- a/web/i18n/zh-Hans/plugin.ts +++ b/web/i18n/zh-Hans/plugin.ts @@ -11,8 +11,12 @@ const translation = { viewDetail: '查看详情', remove: '移除', }, - modelNum: '{{num}} 模型已包含', actionNum: '{{num}} ACTIONS 已包含', + endpoints: 'Endpoints', + endpointsEmpty: '点击 \'+\' 按钮添加端点', + serviceOk: '服务正常', + disabled: '停用', + modelNum: '{{num}} 模型已包含', }, } From 39a6f0943d5cf45aa9853c63a9b6f2c0d4278eab Mon Sep 17 00:00:00 2001 From: StyleZhang <jasonapring2015@outlook.com> Date: Sat, 12 Oct 2024 18:02:24 +0800 Subject: [PATCH 060/346] marketplace --- .../plugins/marketplace/context.tsx | 45 +++++++++++++++++++ .../marketplace/description/wrapper.tsx | 39 ---------------- .../plugins/marketplace/header/index.tsx | 20 --------- .../plugins/marketplace/header/wrapper.tsx | 27 ----------- .../components/plugins/marketplace/index.tsx | 23 +++++----- .../marketplace/intersection-line/hooks.ts | 17 +++++-- .../marketplace/intersection-line/index.tsx | 17 ++----- .../plugins/marketplace/list/index.tsx | 4 +- .../plugins/marketplace/list/wrapper.tsx | 39 ---------------- .../marketplace/plugin-type-switch.tsx | 4 +- .../plugins/marketplace/search-box/index.tsx | 8 ++-- .../marketplace/search-box/wrapper.tsx | 14 ------ .../plugins/plugin-page/context.tsx | 8 ---- .../components/plugins/plugin-page/index.tsx | 4 +- 14 files changed, 83 insertions(+), 186 deletions(-) create mode 100644 web/app/components/plugins/marketplace/context.tsx delete mode 100644 web/app/components/plugins/marketplace/description/wrapper.tsx delete mode 100644 web/app/components/plugins/marketplace/header/index.tsx delete mode 100644 web/app/components/plugins/marketplace/header/wrapper.tsx delete mode 100644 web/app/components/plugins/marketplace/list/wrapper.tsx delete mode 100644 web/app/components/plugins/marketplace/search-box/wrapper.tsx diff --git a/web/app/components/plugins/marketplace/context.tsx b/web/app/components/plugins/marketplace/context.tsx new file mode 100644 index 0000000000..bbadb4bf3a --- /dev/null +++ b/web/app/components/plugins/marketplace/context.tsx @@ -0,0 +1,45 @@ +'use client' + +import type { ReactNode } from 'react' +import { + useState, +} from 'react' +import { + createContext, + useContextSelector, +} from 'use-context-selector' + +export type MarketplaceContextValue = { + intersected: boolean + setIntersected: (intersected: boolean) => void +} + +export const MarketplaceContext = createContext<MarketplaceContextValue>({ + intersected: true, + setIntersected: () => {}, +}) + +type MarketplaceContextProviderProps = { + children: ReactNode +} + +export function useMarketplaceContext(selector: (value: MarketplaceContextValue) => any) { + return useContextSelector(MarketplaceContext, selector) +} + +export const MarketplaceContextProvider = ({ + children, +}: MarketplaceContextProviderProps) => { + const [intersected, setIntersected] = useState(true) + + return ( + <MarketplaceContext.Provider + value={{ + intersected, + setIntersected, + }} + > + {children} + </MarketplaceContext.Provider> + ) +} diff --git a/web/app/components/plugins/marketplace/description/wrapper.tsx b/web/app/components/plugins/marketplace/description/wrapper.tsx deleted file mode 100644 index 91dd3a2ba6..0000000000 --- a/web/app/components/plugins/marketplace/description/wrapper.tsx +++ /dev/null @@ -1,39 +0,0 @@ -'use client' - -import type { ReactNode } from 'react' -import { useCallback } from 'react' -import IntersectionLine from '../intersection-line' -import { usePluginPageContext } from '@/app/components/plugins/plugin-page/context' - -type DescriptionWrapperProps = { - children: ReactNode -} -const DescriptionWrapper = ({ - children, -}: DescriptionWrapperProps) => { - const containerRef = usePluginPageContext(v => v.containerRef) - const scrollDisabled = usePluginPageContext(v => v.scrollDisabled) - const setScrollDisabled = usePluginPageContext(v => v.setScrollDisabled) - - const handleScrollIntersectionChange = useCallback((isIntersecting: boolean) => { - if (!isIntersecting && !scrollDisabled) { - setScrollDisabled(true) - setTimeout(() => { - if (containerRef && containerRef.current) - containerRef.current.scrollTop = 0 - }, 100) - } - }, [containerRef, scrollDisabled, setScrollDisabled]) - - return !scrollDisabled && ( - <> - {children} - <IntersectionLine - containerRef={containerRef} - intersectedCallback={handleScrollIntersectionChange} - /> - </> - ) -} - -export default DescriptionWrapper diff --git a/web/app/components/plugins/marketplace/header/index.tsx b/web/app/components/plugins/marketplace/header/index.tsx deleted file mode 100644 index 3caeea6c7f..0000000000 --- a/web/app/components/plugins/marketplace/header/index.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import Description from '../description' -import DescriptionWrapper from '../description/wrapper' -import SearchBoxWrapper from '../search-box/wrapper' -import PluginTypeSwitch from '../plugin-type-switch' - -const Header = () => { - return ( - <> - <DescriptionWrapper> - <Description /> - </DescriptionWrapper> - <div className='flex items-center justify-center mt-[15px] mb-4'> - <SearchBoxWrapper /> - </div> - <PluginTypeSwitch /> - </> - ) -} - -export default Header diff --git a/web/app/components/plugins/marketplace/header/wrapper.tsx b/web/app/components/plugins/marketplace/header/wrapper.tsx deleted file mode 100644 index a0c45bbc1a..0000000000 --- a/web/app/components/plugins/marketplace/header/wrapper.tsx +++ /dev/null @@ -1,27 +0,0 @@ -'use client' - -import type { ReactNode } from 'react' -import { usePluginPageContext } from '@/app/components/plugins/plugin-page/context' -import cn from '@/utils/classnames' - -type HeaderWrapperProps = { - children: ReactNode -} -const HeaderWrapper = ({ - children, -}: HeaderWrapperProps) => { - const scrollDisabled = usePluginPageContext(v => v.scrollDisabled) - - return ( - <div - className={cn( - 'py-10', - scrollDisabled && 'absolute left-1/2 -translate-x-1/2 -top-[100px] pb-3', - )} - > - {children} - </div> - ) -} - -export default HeaderWrapper diff --git a/web/app/components/plugins/marketplace/index.tsx b/web/app/components/plugins/marketplace/index.tsx index 5d737db448..e85411c1ed 100644 --- a/web/app/components/plugins/marketplace/index.tsx +++ b/web/app/components/plugins/marketplace/index.tsx @@ -1,18 +1,19 @@ -import Header from './header' -import HeaderWrapper from './header/wrapper' +import { MarketplaceContextProvider } from './context' +import Description from './description' +import IntersectionLine from './intersection-line' +import SearchBox from './search-box' +import PluginTypeSwitch from './plugin-type-switch' import List from './list' -import ListWrapper from './list/wrapper' const Marketplace = () => { return ( - <div className='grow relative flex flex-col w-full h-0'> - <HeaderWrapper> - <Header /> - </HeaderWrapper> - <ListWrapper> - <List /> - </ListWrapper> - </div> + <MarketplaceContextProvider> + <Description /> + <IntersectionLine /> + <SearchBox /> + <PluginTypeSwitch /> + <List /> + </MarketplaceContextProvider> ) } diff --git a/web/app/components/plugins/marketplace/intersection-line/hooks.ts b/web/app/components/plugins/marketplace/intersection-line/hooks.ts index a31d196179..2ebc7842df 100644 --- a/web/app/components/plugins/marketplace/intersection-line/hooks.ts +++ b/web/app/components/plugins/marketplace/intersection-line/hooks.ts @@ -1,21 +1,30 @@ import { useEffect } from 'react' +import { usePluginPageContext } from '@/app/components/plugins/plugin-page/context' +import { useMarketplaceContext } from '@/app/components/plugins/marketplace/context' export const useScrollIntersection = ( - containerRef: React.RefObject<HTMLDivElement>, anchorRef: React.RefObject<HTMLDivElement>, - callback: (isIntersecting: boolean) => void, ) => { + const containerRef = usePluginPageContext(v => v.containerRef) + const intersected = useMarketplaceContext(v => v.intersected) + const setIntersected = useMarketplaceContext(v => v.setIntersected) + useEffect(() => { let observer: IntersectionObserver | undefined if (containerRef?.current && anchorRef.current) { observer = new IntersectionObserver((entries) => { const isIntersecting = entries[0].isIntersecting - callback(isIntersecting) + + if (isIntersecting && !intersected) + setIntersected(true) + + if (!isIntersecting && intersected) + setIntersected(false) }, { root: containerRef.current, }) observer.observe(anchorRef.current) } return () => observer?.disconnect() - }, [containerRef, anchorRef, callback]) + }, [containerRef, anchorRef, intersected, setIntersected]) } diff --git a/web/app/components/plugins/marketplace/intersection-line/index.tsx b/web/app/components/plugins/marketplace/intersection-line/index.tsx index 3805ec6f13..e521d43f8c 100644 --- a/web/app/components/plugins/marketplace/intersection-line/index.tsx +++ b/web/app/components/plugins/marketplace/intersection-line/index.tsx @@ -3,24 +3,13 @@ import { useRef } from 'react' import { useScrollIntersection } from './hooks' -type IntersectionLineProps = { - containerRef: React.RefObject<HTMLDivElement> - intersectedCallback: (isIntersecting: boolean) => void -} -const IntersectionLine = ({ - containerRef, - intersectedCallback, -}: IntersectionLineProps) => { +const IntersectionLine = () => { const ref = useRef<HTMLDivElement>(null) - useScrollIntersection( - containerRef, - ref, - intersectedCallback, - ) + useScrollIntersection(ref) return ( - <div ref={ref} className='h-[1px] bg-transparent'></div> + <div ref={ref} className='mb-4 h-[1px] bg-transparent'></div> ) } diff --git a/web/app/components/plugins/marketplace/list/index.tsx b/web/app/components/plugins/marketplace/list/index.tsx index 7a8d6daa5d..fa5975bb5a 100644 --- a/web/app/components/plugins/marketplace/list/index.tsx +++ b/web/app/components/plugins/marketplace/list/index.tsx @@ -7,7 +7,7 @@ const List = () => { const locale = getLocaleOnServer() return ( - <> + <div className='px-12 py-2 bg-background-default-subtle'> <div className='py-3'> <div className='title-xl-semi-bold text-text-primary'>Featured</div> <div className='system-xs-regular text-text-tertiary'>Our top picks to get you started</div> @@ -223,7 +223,7 @@ const List = () => { /> </div> </div> - </> + </div> ) } diff --git a/web/app/components/plugins/marketplace/list/wrapper.tsx b/web/app/components/plugins/marketplace/list/wrapper.tsx deleted file mode 100644 index cf040c8d6b..0000000000 --- a/web/app/components/plugins/marketplace/list/wrapper.tsx +++ /dev/null @@ -1,39 +0,0 @@ -'use client' - -import type { ReactNode } from 'react' -import { usePluginPageContext } from '@/app/components/plugins/plugin-page/context' -import cn from '@/utils/classnames' - -type ListWrapperProps = { - children: ReactNode -} -const ListWrapper = ({ - children, -}: ListWrapperProps) => { - const scrollDisabled = usePluginPageContext(v => v.scrollDisabled) - const setScrollDisabled = usePluginPageContext(v => v.setScrollDisabled) - - return ( - <> - { - scrollDisabled && ( - <div className='h-[60px]'></div> - ) - } - <div - className={cn( - 'px-12 py-2 bg-background-default-subtle', - scrollDisabled && 'grow h-0 overflow-y-auto', - )} - onScroll={(e) => { - if ((e.target as HTMLElement).scrollTop <= 0) - setScrollDisabled(false) - }} - > - {children} - </div> - </> - ) -} - -export default ListWrapper diff --git a/web/app/components/plugins/marketplace/plugin-type-switch.tsx b/web/app/components/plugins/marketplace/plugin-type-switch.tsx index 9c9d73cdb7..16be79db26 100644 --- a/web/app/components/plugins/marketplace/plugin-type-switch.tsx +++ b/web/app/components/plugins/marketplace/plugin-type-switch.tsx @@ -43,7 +43,9 @@ const PluginTypeSwitch = ({ const [activeType, setActiveType] = useState('all') return ( - <div className='flex items-center justify-center space-x-2'> + <div className={cn( + 'sticky top-[60px] flex items-center justify-center py-3 bg-background-body space-x-2 z-10', + )}> { options.map(option => ( <div diff --git a/web/app/components/plugins/marketplace/search-box/index.tsx b/web/app/components/plugins/marketplace/search-box/index.tsx index 612130bc96..3115b87738 100644 --- a/web/app/components/plugins/marketplace/search-box/index.tsx +++ b/web/app/components/plugins/marketplace/search-box/index.tsx @@ -5,18 +5,18 @@ import { useState, } from 'react' import { RiCloseLine } from '@remixicon/react' +import { useMarketplaceContext } from '../context' import TagsFilter from './tags-filter' import ActionButton from '@/app/components/base/action-button' import cn from '@/utils/classnames' type SearchBoxProps = { onChange?: (searchText: string, tags: string[]) => void - widthShouldChange?: boolean } const SearchBox = ({ onChange, - widthShouldChange, }: SearchBoxProps) => { + const intersected = useMarketplaceContext(v => v.intersected) const [searchText, setSearchText] = useState('') const [selectedTags, setSelectedTags] = useState<string[]>([]) @@ -28,8 +28,8 @@ const SearchBox = ({ return ( <div className={cn( - 'flex items-center p-1.5 w-[640px] h-11 border border-components-chat-input-border bg-components-panel-bg-blur rounded-xl shadow-md', - widthShouldChange && 'w-[508px] transition-[width] duration-300', + 'sticky top-3 flex items-center m-auto p-1.5 w-[640px] h-11 border border-components-chat-input-border bg-components-panel-bg-blur rounded-xl shadow-md z-[11]', + !intersected && 'w-[508px] transition-[width] duration-300', )} > <TagsFilter diff --git a/web/app/components/plugins/marketplace/search-box/wrapper.tsx b/web/app/components/plugins/marketplace/search-box/wrapper.tsx deleted file mode 100644 index df42f3740c..0000000000 --- a/web/app/components/plugins/marketplace/search-box/wrapper.tsx +++ /dev/null @@ -1,14 +0,0 @@ -'use client' - -import SearchBox from '.' -import { usePluginPageContext } from '@/app/components/plugins/plugin-page/context' - -const Wrapper = () => { - const scrollDisabled = usePluginPageContext(v => v.scrollDisabled) - - return ( - <SearchBox widthShouldChange={scrollDisabled} /> - ) -} - -export default Wrapper diff --git a/web/app/components/plugins/plugin-page/context.tsx b/web/app/components/plugins/plugin-page/context.tsx index 57e00d9c5d..2d026c7cd1 100644 --- a/web/app/components/plugins/plugin-page/context.tsx +++ b/web/app/components/plugins/plugin-page/context.tsx @@ -3,7 +3,6 @@ import type { ReactNode } from 'react' import { useRef, - useState, } from 'react' import { createContext, @@ -12,14 +11,10 @@ import { export type PluginPageContextValue = { containerRef: React.RefObject<HTMLDivElement> - scrollDisabled: boolean - setScrollDisabled: (scrollDisabled: boolean) => void } export const PluginPageContext = createContext<PluginPageContextValue>({ containerRef: { current: null }, - scrollDisabled: false, - setScrollDisabled: () => {}, }) type PluginPageContextProviderProps = { @@ -34,14 +29,11 @@ export const PluginPageContextProvider = ({ children, }: PluginPageContextProviderProps) => { const containerRef = useRef<HTMLDivElement>(null) - const [scrollDisabled, setScrollDisabled] = useState(false) return ( <PluginPageContext.Provider value={{ containerRef, - scrollDisabled, - setScrollDisabled, }} > {children} diff --git a/web/app/components/plugins/plugin-page/index.tsx b/web/app/components/plugins/plugin-page/index.tsx index f79e0af275..b7c55f48e3 100644 --- a/web/app/components/plugins/plugin-page/index.tsx +++ b/web/app/components/plugins/plugin-page/index.tsx @@ -32,7 +32,6 @@ const PluginPage = ({ const { t } = useTranslation() const { setShowPluginSettingModal } = useModalContext() as any const containerRef = usePluginPageContext(v => v.containerRef) - const scrollDisabled = usePluginPageContext(v => v.scrollDisabled) const options = useMemo(() => { return [ @@ -51,12 +50,11 @@ const PluginPage = ({ className={cn('grow relative flex flex-col overflow-y-auto border-t border-divider-subtle', activeTab === 'plugins' ? 'rounded-t-xl bg-components-panel-bg' : 'bg-background-body', - activeTab === 'discover' && scrollDisabled && 'overflow-hidden', )} > <div className={cn( - 'sticky top-0 flex min-h-[60px] px-12 pt-4 pb-2 items-center self-stretch gap-1', + 'sticky top-0 flex min-h-[60px] px-12 pt-4 pb-2 items-center self-stretch gap-1 bg-background-body z-10', )} > <div className='flex justify-between items-center w-full'> From e2fec587f8bdaf44eda913d7d3b6fe8e899ce026 Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Mon, 14 Oct 2024 18:35:01 +0800 Subject: [PATCH 061/346] feat: from marketplace --- .../workflow/block-selector/all-tools.tsx | 3 + .../market-place-plugin/action.tsx | 56 +++++++++++++++++++ .../market-place-plugin/item.tsx | 54 ++++++++++++++++++ .../market-place-plugin/list.tsx | 35 ++++++++++++ .../workflow/block-selector/tool-item.tsx | 4 +- web/i18n/en-US/plugin.ts | 3 + web/i18n/en-US/workflow.ts | 2 +- web/i18n/zh-Hans/plugin.ts | 3 + 8 files changed, 157 insertions(+), 3 deletions(-) create mode 100644 web/app/components/workflow/block-selector/market-place-plugin/action.tsx create mode 100644 web/app/components/workflow/block-selector/market-place-plugin/item.tsx create mode 100644 web/app/components/workflow/block-selector/market-place-plugin/list.tsx diff --git a/web/app/components/workflow/block-selector/all-tools.tsx b/web/app/components/workflow/block-selector/all-tools.tsx index f8947ad52a..2f75f90fc3 100644 --- a/web/app/components/workflow/block-selector/all-tools.tsx +++ b/web/app/components/workflow/block-selector/all-tools.tsx @@ -12,6 +12,8 @@ import { useToolTabs } from './hooks' import ViewTypeSelect, { ViewType } from './view-type-select' import cn from '@/utils/classnames' import { useGetLanguage } from '@/context/i18n' +import PluginList from '@/app/components/workflow/block-selector/market-place-plugin/list' +import { extensionDallE, modelGPT4, toolNotion } from '@/app/components/plugins/card/card-mock' type AllToolsProps = { searchText: string @@ -71,6 +73,7 @@ const AllTools = ({ </div> <ViewTypeSelect viewType={activeView} onChange={setActiveView} /> </div> + <PluginList list={[toolNotion, extensionDallE, modelGPT4] as any} /> <Tools showWorkflowEmpty={activeTab === ToolTypeEnum.Workflow} tools={tools} diff --git a/web/app/components/workflow/block-selector/market-place-plugin/action.tsx b/web/app/components/workflow/block-selector/market-place-plugin/action.tsx new file mode 100644 index 0000000000..df606fdb41 --- /dev/null +++ b/web/app/components/workflow/block-selector/market-place-plugin/action.tsx @@ -0,0 +1,56 @@ +'use client' +import type { FC } from 'react' +import React, { useCallback, useRef, useState } from 'react' +import { useTranslation } from 'react-i18next' +import { RiMoreFill } from '@remixicon/react' +import ActionButton from '@/app/components/base/action-button' +// import Button from '@/app/components/base/button' +import { + PortalToFollowElem, + PortalToFollowElemContent, + PortalToFollowElemTrigger, +} from '@/app/components/base/portal-to-follow-elem' +import cn from '@/utils/classnames' + +type Props = { +} + +const OperationDropdown: FC<Props> = () => { + const { t } = useTranslation() + const [open, doSetOpen] = useState(false) + const openRef = useRef(open) + const setOpen = useCallback((v: boolean) => { + doSetOpen(v) + openRef.current = v + }, [doSetOpen]) + + const handleTrigger = useCallback(() => { + setOpen(!openRef.current) + }, [setOpen]) + + return ( + <PortalToFollowElem + open={open} + onOpenChange={setOpen} + placement='bottom-end' + offset={{ + mainAxis: 0, + crossAxis: 0, + }} + > + <PortalToFollowElemTrigger onClick={handleTrigger}> + <ActionButton className={cn(open && 'bg-state-base-hover')}> + <RiMoreFill className='w-4 h-4 text-components-button-secondary-accent-text' /> + </ActionButton> + </PortalToFollowElemTrigger> + <PortalToFollowElemContent className='z-50'> + <div className='w-[112px] p-1 bg-components-panel-bg-blur rounded-xl border-[0.5px] border-components-panel-border shadow-lg'> + <div className='px-3 py-1.5 rounded-lg text-text-secondary system-md-regular cursor-pointer hover:bg-state-base-hover'>{t('common.operation.download')}</div> + {/* Wait marketplace */} + {/* <div className='px-3 py-1.5 rounded-lg text-text-secondary system-md-regular cursor-pointer hover:bg-state-base-hover'>{t('common.operation.viewDetail')}</div> */} + </div> + </PortalToFollowElemContent> + </PortalToFollowElem> + ) +} +export default React.memo(OperationDropdown) diff --git a/web/app/components/workflow/block-selector/market-place-plugin/item.tsx b/web/app/components/workflow/block-selector/market-place-plugin/item.tsx new file mode 100644 index 0000000000..385cdbfd56 --- /dev/null +++ b/web/app/components/workflow/block-selector/market-place-plugin/item.tsx @@ -0,0 +1,54 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import { useContext } from 'use-context-selector' +import { useTranslation } from 'react-i18next' +import Action from './action' +import type { Plugin } from '@/app/components/plugins/types.ts' +import I18n from '@/context/i18n' + +import { formatNumber } from '@/utils/format' + +enum ActionType { + install = 'install', + download = 'download', + // viewDetail = 'viewDetail', // wait for marketplace api +} +type Props = { + payload: Plugin + onAction: (type: ActionType) => void +} + +const Item: FC<Props> = ({ + payload, +}) => { + const { t } = useTranslation() + const { locale } = useContext(I18n) + + return ( + <div className='flex rounded-lg py-2 pr-1 pl-3 hover:bg-state-base-hover'> + <div + className='shrink-0 relative w-6 h-6 border-[0.5px] border-components-panel-border-subtle rounded-md bg-center bg-no-repeat bg-contain' + style={{ backgroundImage: `url(${payload.icon})` }} + /> + <div className='ml-2 w-0 grow flex'> + <div className='w-0 grow'> + <div className='h-4 leading-4 text-text-primary system-sm-medium truncate '>{payload.label[locale]}</div> + <div className='h-5 leading-5 text-text-tertiary system-xs-regular truncate'>{payload.brief[locale]}</div> + <div className='flex text-text-tertiary system-xs-regular space-x-1'> + <div>{payload.org}</div> + <div>·</div> + <div>{t('plugin.install', { num: formatNumber(payload.install_count || 0) })}</div> + </div> + </div> + {/* Action */} + <div className='flex items-center space-x-1 h-4 text-components-button-secondary-accent-text system-xs-medium'> + <div className='px-1.5'>{t('plugin.installAction')}</div> + <Action /> + </div> + </div> + + </div> + ) +} +export default React.memo(Item) diff --git a/web/app/components/workflow/block-selector/market-place-plugin/list.tsx b/web/app/components/workflow/block-selector/market-place-plugin/list.tsx new file mode 100644 index 0000000000..33c00081c6 --- /dev/null +++ b/web/app/components/workflow/block-selector/market-place-plugin/list.tsx @@ -0,0 +1,35 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import { useTranslation } from 'react-i18next' +import Item from './item' +import type { Plugin } from '@/app/components/plugins/types.ts' + +type Props = { + list: Plugin[] + // onInstall: () => +} + +const List: FC<Props> = ({ + list, +}) => { + const { t } = useTranslation() + + return ( + <div> + <div className='pt-3 px-4 py-1 text-text-primary system-sm-medium'> + {t('plugin.fromMarketplace')} + </div> + <div className='p-1'> + {list.map((item, index) => ( + <Item + key={index} + payload={item} + onAction={() => { }} + /> + ))} + </div> + </div> + ) +} +export default React.memo(List) diff --git a/web/app/components/workflow/block-selector/tool-item.tsx b/web/app/components/workflow/block-selector/tool-item.tsx index 5ee3b399a5..7b004d6198 100644 --- a/web/app/components/workflow/block-selector/tool-item.tsx +++ b/web/app/components/workflow/block-selector/tool-item.tsx @@ -75,13 +75,13 @@ const ToolItem: FC<Props> = ({ }) }} > - <div className='flex items-center h-8'> + <div className='flex grow items-center h-8'> <BlockIcon className='shrink-0' type={BlockEnum.Tool} toolIcon={provider.icon} /> - <div className='ml-2 text-sm text-gray-900 flex-1 min-w-0 truncate'>{payload.label[language]}</div> + <div className='ml-2 text-sm text-gray-900 flex-1 w-0 grow truncate'>{payload.label[language]}</div> </div> {isToolPlugin && ( <FoldIcon className={cn('w-4 h-4 text-text-quaternary shrink-0', isFold && 'text-text-tertiary')} /> diff --git a/web/i18n/en-US/plugin.ts b/web/i18n/en-US/plugin.ts index c73c6a448e..a82cdf6707 100644 --- a/web/i18n/en-US/plugin.ts +++ b/web/i18n/en-US/plugin.ts @@ -1,5 +1,6 @@ const translation = { from: 'From', + fromMarketplace: 'From Marketplace', endpointsEnabled: '{{num}} sets of endpoints enabled', detailPanel: { operation: { @@ -18,6 +19,8 @@ const translation = { disabled: 'Disabled', modelNum: '{{num}} MODELS INCLUDED', }, + install: '{{num}} installs', + installAction: 'Install', } export default translation diff --git a/web/i18n/en-US/workflow.ts b/web/i18n/en-US/workflow.ts index d5ab6eb728..2e3576b5b8 100644 --- a/web/i18n/en-US/workflow.ts +++ b/web/i18n/en-US/workflow.ts @@ -198,7 +198,7 @@ const translation = { 'searchTool': 'Search tool', 'tools': 'Tools', 'allTool': 'All', - 'builtInTool': 'Built-in', + 'plugin': 'Plugin', 'customTool': 'Custom', 'workflowTool': 'Workflow', 'question-understand': 'Question Understand', diff --git a/web/i18n/zh-Hans/plugin.ts b/web/i18n/zh-Hans/plugin.ts index 9bf3fdeea8..5166ddedc3 100644 --- a/web/i18n/zh-Hans/plugin.ts +++ b/web/i18n/zh-Hans/plugin.ts @@ -1,5 +1,6 @@ const translation = { from: '来自', + fromMarketplace: '来自市场', endpointsEnabled: '{{num}} 组端点已启用', detailPanel: { operation: { @@ -18,6 +19,8 @@ const translation = { disabled: '停用', modelNum: '{{num}} 模型已包含', }, + install: '{{num}} 次安装', + installAction: '安装', } export default translation From a9e367e6de0b329176c63aa78c9061ee530be79a Mon Sep 17 00:00:00 2001 From: Yi <yxiaoisme@gmail.com> Date: Mon, 14 Oct 2024 18:43:08 +0800 Subject: [PATCH 062/346] feat: use-uploader hook --- .../plugins/install-plugin/uploader.tsx | 97 ------------- .../components/plugins/plugin-page/index.tsx | 42 +++++- .../plugin-page/install-plugin-dropdown.tsx | 131 +++++++++--------- .../plugins/plugin-page/plugins-panel.tsx | 6 - .../plugins/plugin-page/use-uploader.ts | 78 +++++++++++ 5 files changed, 180 insertions(+), 174 deletions(-) delete mode 100644 web/app/components/plugins/install-plugin/uploader.tsx create mode 100644 web/app/components/plugins/plugin-page/use-uploader.ts diff --git a/web/app/components/plugins/install-plugin/uploader.tsx b/web/app/components/plugins/install-plugin/uploader.tsx deleted file mode 100644 index 8e66ed21dd..0000000000 --- a/web/app/components/plugins/install-plugin/uploader.tsx +++ /dev/null @@ -1,97 +0,0 @@ -'use client' -import type { FC } from 'react' -import React, { useEffect, useRef, useState } from 'react' -import { useContext } from 'use-context-selector' -import { ToastContext } from '@/app/components/base/toast' - -export type Props = { - file: File | undefined - updateFile: (file?: File) => void - className?: string -} - -const Uploader: FC<Props> = ({ - file, - updateFile, - className, -}) => { - const { notify } = useContext(ToastContext) - const [dragging, setDragging] = useState(false) - const dropRef = useRef<HTMLDivElement>(null) - const dragRef = useRef<HTMLDivElement>(null) - const fileUploader = useRef<HTMLInputElement>(null) - - const handleDragEnter = (e: DragEvent) => { - e.preventDefault() - e.stopPropagation() - e.target !== dragRef.current && setDragging(true) - } - - const handleDragOver = (e: DragEvent) => { - e.preventDefault() - e.stopPropagation() - } - - const handleDragLeave = (e: DragEvent) => { - e.preventDefault() - e.stopPropagation() - e.target === dragRef.current && setDragging(false) - } - - const handleDrop = (e: DragEvent) => { - e.preventDefault() - e.stopPropagation() - setDragging(false) - if (!e.dataTransfer) - return - const files = [...e.dataTransfer.files] - if (files.length > 1) { - // notify({ type: 'error', message: }) - } - updateFile(files[0]) - } - - const selectHandle = () => { - - } - - const fileChangeHandle = (e: React.ChangeEvent<HTMLInputElement>) => { - const currentFile = e.target.files?.[0] - updateFile(currentFile) - } - - useEffect(() => { - dropRef.current?.addEventListener('dragenter', handleDragEnter) - dropRef.current?.addEventListener('dragover', handleDragOver) - dropRef.current?.addEventListener('dragleave', handleDragLeave) - dropRef.current?.addEventListener('drop', handleDrop) - return () => { - dropRef.current?.removeEventListener('dragenter', handleDragEnter) - dropRef.current?.removeEventListener('dragover', handleDragOver) - dropRef.current?.removeEventListener('dragleave', handleDragLeave) - dropRef.current?.removeEventListener('drop', handleDrop) - } - }, []) - - return ( - <> - <input - ref={fileUploader} - style={{ display: 'none' }} - type="file" - id="fileUploader" - accept='.difypkg' - onChange={fileChangeHandle} - /> - {dragging && ( - <div - ref={dragRef} - className='flex w-full h-full p-2 items-start gap-2 absolute left-1 bottom-[3px] - rounded-2xl border-2 border-dashed bg-components-dropzone-bg-accent'> - </div> - )} - </> - ) -} - -export default React.memo(Uploader) diff --git a/web/app/components/plugins/plugin-page/index.tsx b/web/app/components/plugins/plugin-page/index.tsx index f79e0af275..dd76880f45 100644 --- a/web/app/components/plugins/plugin-page/index.tsx +++ b/web/app/components/plugins/plugin-page/index.tsx @@ -1,18 +1,21 @@ 'use client' -import { useMemo } from 'react' +import { useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import { RiArrowRightUpLine, RiBugLine, RiClipboardLine, + RiDragDropLine, RiEqualizer2Line, } from '@remixicon/react' +import InstallFromLocalPackage from '../install-plugin/install-from-local-package' import { PluginPageContextProvider, usePluginPageContext, } from './context' import InstallPluginDropdown from './install-plugin-dropdown' +import { useUploader } from './use-uploader' import { useTabSearchParams } from '@/hooks/use-tab-searchparams' import { useModalContext } from '@/context/modal-context' import Button from '@/app/components/base/button' @@ -31,9 +34,15 @@ const PluginPage = ({ }: PluginPageProps) => { const { t } = useTranslation() const { setShowPluginSettingModal } = useModalContext() as any + const [currentFile, setCurrentFile] = useState<File | null>(null) const containerRef = usePluginPageContext(v => v.containerRef) const scrollDisabled = usePluginPageContext(v => v.scrollDisabled) + const { dragging, fileUploader, fileChangeHandle, removeFile } = useUploader({ + onFileChange: setCurrentFile, + containerRef, + }) + const options = useMemo(() => { return [ { value: 'plugins', text: t('common.menus.plugins') }, @@ -98,7 +107,7 @@ const PluginPage = ({ </> } popupClassName='flex flex-col items-start w-[256px] px-4 py-3.5 gap-1 border border-components-panel-border - rounded-xl bg-components-tooltip-bg shadows-shadow-lg z-50' + rounded-xl bg-components-tooltip-bg shadows-shadow-lg z-50' asChild={false} position='bottom' > @@ -117,12 +126,35 @@ const PluginPage = ({ </div> </div> </div> - { - activeTab === 'plugins' && plugins - } + {activeTab === 'plugins' && ( + <> + {plugins} + {dragging && ( + <div + className="absolute inset-0 m-0.5 p-2 rounded-2xl bg-[rgba(21,90,239,0.14)] border-2 + border-dashed border-components-dropzone-border-accent"> + </div> + )} + <div className={`flex py-4 justify-center items-center gap-2 ${dragging ? 'text-text-accent' : 'text-text-quaternary'}`}> + <RiDragDropLine className="w-4 h-4" /> + <span className="system-xs-regular">Drop plugin package here to install</span> + </div> + {currentFile && ( + <InstallFromLocalPackage file={currentFile} onClose={removeFile} /> + )} + </> + )} { activeTab === 'discover' && marketplace } + <input + ref={fileUploader} + className="hidden" + type="file" + id="fileUploader" + accept='.difypkg' + onChange={fileChangeHandle} + /> </div> ) } diff --git a/web/app/components/plugins/plugin-page/install-plugin-dropdown.tsx b/web/app/components/plugins/plugin-page/install-plugin-dropdown.tsx index 111f977289..962349c74a 100644 --- a/web/app/components/plugins/plugin-page/install-plugin-dropdown.tsx +++ b/web/app/components/plugins/plugin-page/install-plugin-dropdown.tsx @@ -1,6 +1,6 @@ 'use client' -import { useEffect, useRef, useState } from 'react' +import { useRef, useState } from 'react' import { RiAddLine, RiArrowDownSLine } from '@remixicon/react' import Button from '@/app/components/base/button' import { MagicBox } from '@/app/components/base/icons/src/vender/solid/mediaAndDevices' @@ -10,13 +10,17 @@ import InstallFromMarketplace from '@/app/components/plugins/install-plugin/inst import InstallFromGitHub from '@/app/components/plugins/install-plugin/install-from-github' import InstallFromLocalPackage from '@/app/components/plugins/install-plugin/install-from-local-package' import cn from '@/utils/classnames' +import { + PortalToFollowElem, + PortalToFollowElemContent, + PortalToFollowElemTrigger, +} from '@/app/components/base/portal-to-follow-elem' const InstallPluginDropdown = () => { const fileInputRef = useRef<HTMLInputElement>(null) const [isMenuOpen, setIsMenuOpen] = useState(false) const [selectedAction, setSelectedAction] = useState<string | null>(null) const [selectedFile, setSelectedFile] = useState<File | null>(null) - const menuRef = useRef<HTMLDivElement>(null) const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => { const file = event.target.files?.[0] @@ -27,76 +31,71 @@ const InstallPluginDropdown = () => { } } - useEffect(() => { - const handleClickOutside = (event: MouseEvent) => { - if (menuRef.current && !menuRef.current.contains(event.target as Node)) - setIsMenuOpen(false) - } - - document.addEventListener('mousedown', handleClickOutside) - return () => { - document.removeEventListener('mousedown', handleClickOutside) - } - }, []) - return ( - <div className="relative" ref={menuRef}> - <Button - className={cn('w-full h-full p-2 text-components-button-secondary-text', isMenuOpen && 'bg-state-base-hover')} - onClick={() => setIsMenuOpen(!isMenuOpen)} - > - <RiAddLine className='w-4 h-4' /> - <span className='pl-1'>Install plugin</span> - <RiArrowDownSLine className='w-4 h-4 ml-1' /> - </Button> - {isMenuOpen && ( - <div className='flex flex-col items-start absolute z-1000 top-full left-0 mt-1 p-1 pb-2 - w-[200px] bg-components-panel-bg-blur border border-components-panel-border rounded-xl - shadows-shadow-lg'> - <span className='flex pt-1 pb-0.5 pl-2 pr-3 items-start self-stretch text-text-tertiary - system-xs-medium-uppercase'> - Install Form - </span> - <input - type='file' - ref={fileInputRef} - style={{ display: 'none' }} - onChange={handleFileChange} - accept='.difypkg' - /> - {[ - { icon: MagicBox, text: 'Marketplace', action: 'marketplace' }, - { icon: Github, text: 'GitHub', action: 'github' }, - { icon: FileZip, text: 'Local Package File', action: 'local' }, - ].map(({ icon: Icon, text, action }) => ( - <div - key={action} - className='flex items-center w-full px-2 py-1.5 gap-1 rounded-lg hover:bg-state-base-hover cursor-pointer' - onClick={() => { - if (action === 'local') { - fileInputRef.current?.click() - } - else { - setSelectedAction(action) - setIsMenuOpen(false) - } - }} - > - <Icon className="w-4 h-4 text-text-tertiary" /> - <span className='px-1 text-text-secondary system-md-regular'>{text}</span> + <PortalToFollowElem + open={isMenuOpen} + onOpenChange={setIsMenuOpen} + placement='bottom-start' + offset={4} + > + <div className="relative"> + <PortalToFollowElemTrigger onClick={() => setIsMenuOpen(v => !v)}> + <Button + className={cn('w-full h-full p-2 text-components-button-secondary-text', isMenuOpen && 'bg-state-base-hover')} + > + <RiAddLine className='w-4 h-4' /> + <span className='pl-1'>Install plugin</span> + <RiArrowDownSLine className='w-4 h-4 ml-1' /> + </Button> + </PortalToFollowElemTrigger> + <PortalToFollowElemContent className='z-[1002]'> + <div className='flex flex-col p-1 pb-2 items-start w-[200px] bg-components-panel-bg-blur border border-components-panel-border rounded-xl shadows-shadow-lg'> + <span className='flex pt-1 pb-0.5 pl-2 pr-3 items-start self-stretch text-text-tertiary system-xs-medium-uppercase'> + Install Form + </span> + <input + type='file' + ref={fileInputRef} + style={{ display: 'none' }} + onChange={handleFileChange} + accept='.difypkg' + /> + <div className='p-1 w-full'> + {[ + { icon: MagicBox, text: 'Marketplace', action: 'marketplace' }, + { icon: Github, text: 'GitHub', action: 'github' }, + { icon: FileZip, text: 'Local Package File', action: 'local' }, + ].map(({ icon: Icon, text, action }) => ( + <div + key={action} + className='flex items-center w-full px-2 py-1.5 gap-1 rounded-lg hover:bg-state-base-hover cursor-pointer' + onClick={() => { + if (action === 'local') { + fileInputRef.current?.click() + } + else { + setSelectedAction(action) + setIsMenuOpen(false) + } + }} + > + <Icon className="w-4 h-4 text-text-tertiary" /> + <span className='px-1 text-text-secondary system-md-regular'>{text}</span> + </div> + ))} </div> - ))} - </div> - )} + </div> + </PortalToFollowElemContent> + </div> {selectedAction === 'marketplace' && <InstallFromMarketplace onClose={() => setSelectedAction(null)} />} {selectedAction === 'github' && <InstallFromGitHub onClose={() => setSelectedAction(null)}/>} {selectedAction === 'local' && selectedFile - && (<InstallFromLocalPackage - file={selectedFile} - onClose={() => setSelectedAction(null)}/> - ) + && (<InstallFromLocalPackage + file={selectedFile} + onClose={() => setSelectedAction(null)}/> + ) } - </div> + </PortalToFollowElem> ) } diff --git a/web/app/components/plugins/plugin-page/plugins-panel.tsx b/web/app/components/plugins/plugin-page/plugins-panel.tsx index 227630f7d8..4d4090f973 100644 --- a/web/app/components/plugins/plugin-page/plugins-panel.tsx +++ b/web/app/components/plugins/plugin-page/plugins-panel.tsx @@ -1,7 +1,5 @@ 'use client' -import { RiDragDropLine } from '@remixicon/react' - const PluginsPanel = () => { return ( <> @@ -14,10 +12,6 @@ const PluginsPanel = () => { <div className='flex px-12 items-start content-start gap-2 flex-grow self-stretch flex-wrap'> {/* Plugin cards go here */} </div> - <div className='flex items-center justify-center py-4 gap-2 text-text-quaternary'> - <RiDragDropLine className='w-4 h-4' /> - <span className='system-xs-regular'>Drop plugin package here to install</span> - </div> </> ) } diff --git a/web/app/components/plugins/plugin-page/use-uploader.ts b/web/app/components/plugins/plugin-page/use-uploader.ts new file mode 100644 index 0000000000..d49fe012b7 --- /dev/null +++ b/web/app/components/plugins/plugin-page/use-uploader.ts @@ -0,0 +1,78 @@ +import { useEffect, useRef, useState } from 'react' + +type UploaderHookProps = { + onFileChange: (file: File | null) => void + containerRef: React.RefObject<HTMLDivElement> +} + +export const useUploader = ({ onFileChange, containerRef }: UploaderHookProps) => { + const [dragging, setDragging] = useState(false) + const fileUploader = useRef<HTMLInputElement>(null) + + const handleDragEnter = (e: DragEvent) => { + e.preventDefault() + e.stopPropagation() + if (e.dataTransfer?.types.includes('Files')) + setDragging(true) + } + + const handleDragOver = (e: DragEvent) => { + e.preventDefault() + e.stopPropagation() + } + + const handleDragLeave = (e: DragEvent) => { + e.preventDefault() + e.stopPropagation() + if (e.relatedTarget === null || !containerRef.current?.contains(e.relatedTarget as Node)) + setDragging(false) + } + + const handleDrop = (e: DragEvent) => { + e.preventDefault() + e.stopPropagation() + setDragging(false) + if (!e.dataTransfer) + return + const files = [...e.dataTransfer.files] + if (files.length > 0) + onFileChange(files[0]) + } + + const fileChangeHandle = (e: React.ChangeEvent<HTMLInputElement>) => { + const file = e.target.files?.[0] || null + onFileChange(file) + } + + const removeFile = () => { + if (fileUploader.current) + fileUploader.current.value = '' + + onFileChange(null) + } + + useEffect(() => { + const current = containerRef.current + if (current) { + current.addEventListener('dragenter', handleDragEnter) + current.addEventListener('dragover', handleDragOver) + current.addEventListener('dragleave', handleDragLeave) + current.addEventListener('drop', handleDrop) + } + return () => { + if (current) { + current.removeEventListener('dragenter', handleDragEnter) + current.removeEventListener('dragover', handleDragOver) + current.removeEventListener('dragleave', handleDragLeave) + current.removeEventListener('drop', handleDrop) + } + } + }, [containerRef]) + + return { + dragging, + fileUploader, + fileChangeHandle, + removeFile, + } +} From 4dd144ce43dcd6dbcd68e934fa8db9ddd80d7865 Mon Sep 17 00:00:00 2001 From: StyleZhang <jasonapring2015@outlook.com> Date: Tue, 15 Oct 2024 10:41:10 +0800 Subject: [PATCH 063/346] tools list --- .../plugins/marketplace/search-box/tags-filter.tsx | 2 +- web/app/components/tools/provider-list.tsx | 14 +++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/web/app/components/plugins/marketplace/search-box/tags-filter.tsx b/web/app/components/plugins/marketplace/search-box/tags-filter.tsx index 83c1ba2872..323c4be1ab 100644 --- a/web/app/components/plugins/marketplace/search-box/tags-filter.tsx +++ b/web/app/components/plugins/marketplace/search-box/tags-filter.tsx @@ -95,7 +95,7 @@ const TagsFilter = ({ } </div> </PortalToFollowElemTrigger> - <PortalToFollowElemContent> + <PortalToFollowElemContent className='z-10'> <div className='w-[240px] border-[0.5px] border-components-panel-border bg-components-panel-bg-blur rounded-xl shadow-lg'> <div className='p-2 pb-1'> <Input diff --git a/web/app/components/tools/provider-list.tsx b/web/app/components/tools/provider-list.tsx index f429a6ec8d..6598bb6d08 100644 --- a/web/app/components/tools/provider-list.tsx +++ b/web/app/components/tools/provider-list.tsx @@ -13,13 +13,15 @@ import { Colors } from '@/app/components/base/icons/src/vender/line/others' import { Route } from '@/app/components/base/icons/src/vender/line/mapsAndTravel' import CustomCreateCard from '@/app/components/tools/provider/custom-create-card' import ContributeCard from '@/app/components/tools/provider/contribute' -import ProviderCard from '@/app/components/tools/provider/card' import ProviderDetail from '@/app/components/tools/provider/detail' import Empty from '@/app/components/tools/add-tool-modal/empty' import { fetchCollectionList } from '@/service/tools' +import Card from '@/app/components/plugins/card' +import { useGetLanguage } from '@/context/i18n' const ProviderList = () => { const { t } = useTranslation() + const language = useGetLanguage() const [activeTab, setActiveTab] = useTabSearchParams({ defaultTab: 'builtin', @@ -94,11 +96,13 @@ const ProviderList = () => { {activeTab === 'builtin' && <ContributeCard />} {activeTab === 'api' && <CustomCreateCard onRefreshData={getProviderList} />} {filteredCollectionList.map(collection => ( - <ProviderCard - active={currentProvider?.id === collection.id} - onSelect={() => setCurrentProvider(collection)} + <Card key={collection.id} - collection={collection} + locale={language} + payload={{ + ...collection, + brief: collection.description, + } as any} /> ))} {!filteredCollectionList.length && <div className='absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2'><Empty /></div>} From 1e9fbbf41b9b189d110af7478fb4ca1b65c3fd70 Mon Sep 17 00:00:00 2001 From: Yi <yxiaoisme@gmail.com> Date: Tue, 15 Oct 2024 11:02:25 +0800 Subject: [PATCH 064/346] fix: dynamic sub header color --- web/app/components/plugins/plugin-page/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/app/components/plugins/plugin-page/index.tsx b/web/app/components/plugins/plugin-page/index.tsx index da16970bec..70549a5e1d 100644 --- a/web/app/components/plugins/plugin-page/index.tsx +++ b/web/app/components/plugins/plugin-page/index.tsx @@ -63,7 +63,7 @@ const PluginPage = ({ > <div className={cn( - 'sticky top-0 flex min-h-[60px] px-12 pt-4 pb-2 items-center self-stretch gap-1 bg-background-body z-10', + 'sticky top-0 flex min-h-[60px] px-12 pt-4 pb-2 items-center self-stretch gap-1 z-10', activeTab === 'discover' && 'bg-background-body', )} > <div className='flex justify-between items-center w-full'> From 4f10f5d5f4fe6ec45c0637675f6f2675e25c557a Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Tue, 15 Oct 2024 11:57:44 +0800 Subject: [PATCH 065/346] chore: hover show action --- .../workflow/block-selector/market-place-plugin/item.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/app/components/workflow/block-selector/market-place-plugin/item.tsx b/web/app/components/workflow/block-selector/market-place-plugin/item.tsx index 385cdbfd56..725535135c 100644 --- a/web/app/components/workflow/block-selector/market-place-plugin/item.tsx +++ b/web/app/components/workflow/block-selector/market-place-plugin/item.tsx @@ -26,7 +26,7 @@ const Item: FC<Props> = ({ const { locale } = useContext(I18n) return ( - <div className='flex rounded-lg py-2 pr-1 pl-3 hover:bg-state-base-hover'> + <div className='group/plugin flex rounded-lg py-2 pr-1 pl-3 hover:bg-state-base-hover'> <div className='shrink-0 relative w-6 h-6 border-[0.5px] border-components-panel-border-subtle rounded-md bg-center bg-no-repeat bg-contain' style={{ backgroundImage: `url(${payload.icon})` }} @@ -42,7 +42,7 @@ const Item: FC<Props> = ({ </div> </div> {/* Action */} - <div className='flex items-center space-x-1 h-4 text-components-button-secondary-accent-text system-xs-medium'> + <div className='hidden group-hover/plugin:flex items-center space-x-1 h-4 text-components-button-secondary-accent-text system-xs-medium'> <div className='px-1.5'>{t('plugin.installAction')}</div> <Action /> </div> From c9ee1e9ff2220a59a08e7e01a63b40a8c6bd1fa2 Mon Sep 17 00:00:00 2001 From: Yi <yxiaoisme@gmail.com> Date: Tue, 15 Oct 2024 14:56:59 +0800 Subject: [PATCH 066/346] feat: install difypkg ui --- .../plugins/card/base/card-icon.tsx | 6 +- .../components/plugins/card/base/org-info.tsx | 33 +++- web/app/components/plugins/card/index.tsx | 43 +++-- .../install-from-github/index.tsx | 92 ++++++++-- .../install-from-local-package/index.tsx | 94 +++++++--- .../install-from-marketplace/index.tsx | 161 +++++++++++------- 6 files changed, 305 insertions(+), 124 deletions(-) diff --git a/web/app/components/plugins/card/base/card-icon.tsx b/web/app/components/plugins/card/base/card-icon.tsx index 60be58007f..0fcc28d997 100644 --- a/web/app/components/plugins/card/base/card-icon.tsx +++ b/web/app/components/plugins/card/base/card-icon.tsx @@ -18,10 +18,8 @@ const Icon = ({ }} > {installed - && <div className='p-0.5 absolute bottom-[-4px] right-[-4px] w-3 h-3 rounded-full bg-white '> - <div className='h-full rounded-full bg-state-success-solid'> - <RiCheckLine className='w-full h-full text-text-primary-on-surface' /> - </div> + && <div className='flex justify-center items-center gap-2 absolute bottom-[-4px] right-[-4px] w-[18px] h-[18px] rounded-full border-2 border-components-panel-bg bg-state-success-solid'> + <RiCheckLine className='w-3 h-3 text-text-primary-on-surface' /> </div> } </div> diff --git a/web/app/components/plugins/card/base/org-info.tsx b/web/app/components/plugins/card/base/org-info.tsx index 65cfb1cb68..ed184b8bd8 100644 --- a/web/app/components/plugins/card/base/org-info.tsx +++ b/web/app/components/plugins/card/base/org-info.tsx @@ -4,6 +4,7 @@ type Props = { orgName: string packageName: string packageNameClassName?: string + isLoading?: boolean } const OrgInfo = ({ @@ -11,12 +12,34 @@ const OrgInfo = ({ orgName, packageName, packageNameClassName, + isLoading = false, }: Props) => { - return <div className={cn('flex items-center h-4 space-x-0.5', className)}> - <span className='shrink-0 text-text-tertiary system-xs-regular'>{orgName}</span> - <span className='shrink-0 text-text-quaternary system-xs-regular'>/</span> - <span className={cn('shrink-0 w-0 grow truncate text-text-tertiary system-xs-regular', packageNameClassName)}>{packageName}</span> - </div> + const LoadingPlaceholder = ({ width }: { width: string }) => ( + <div className={`h-2 w-${width} rounded-sm opacity-20 bg-text-quaternary`} /> + ) + return ( + <div className={cn('flex items-center h-4 space-x-0.5', className)}> + {isLoading + ? ( + <LoadingPlaceholder width="[41px]" /> + ) + : ( + <span className='shrink-0 text-text-tertiary system-xs-regular'>{orgName}</span> + )} + <span className='shrink-0 text-text-quaternary system-xs-regular'> + {isLoading ? '·' : '/'} + </span> + {isLoading + ? ( + <LoadingPlaceholder width="[180px]" /> + ) + : ( + <span className={cn('shrink-0 w-0 grow truncate text-text-tertiary system-xs-regular', packageNameClassName)}> + {packageName} + </span> + )} + </div> + ) } export default OrgInfo diff --git a/web/app/components/plugins/card/index.tsx b/web/app/components/plugins/card/index.tsx index 9b00284fd4..823d9dd025 100644 --- a/web/app/components/plugins/card/index.tsx +++ b/web/app/components/plugins/card/index.tsx @@ -2,6 +2,7 @@ import React from 'react' import { RiVerifiedBadgeLine } from '@remixicon/react' import type { Plugin } from '../types' import Icon from '../card/base/card-icon' +import { Group } from '../../base/icons/src/vender/other' import CornerMark from './base/corner-mark' import Title from './base/title' import OrgInfo from './base/org-info' @@ -18,6 +19,8 @@ type Props = { descriptionLineRows?: number footer?: React.ReactNode serverLocale?: Locale + isLoading?: boolean + loadingFileName?: string } const Card = ({ @@ -28,33 +31,53 @@ const Card = ({ descriptionLineRows = 2, footer, locale, + isLoading = false, + loadingFileName, }: Props) => { - const { type, name, org, label } = payload + const { type, name, org, label, brief, icon } = payload + + const getLocalizedText = (obj: Record<string, string> | undefined) => + obj?.[locale] || obj?.['en-US'] || '' + + const LoadingPlaceholder = ({ className }: { className?: string }) => ( + <div className={cn('h-2 rounded-sm opacity-20 bg-text-quaternary', className)} /> + ) return ( <div className={cn('relative p-4 pb-3 border-[0.5px] border-components-panel-border bg-components-panel-on-panel-item-bg hover-bg-components-panel-on-panel-item-bg rounded-xl shadow-xs', className)}> - <CornerMark text={type} /> + {!isLoading && <CornerMark text={type} />} {/* Header */} <div className="flex"> - <Icon src={payload.icon} installed={installed} /> + {isLoading + ? (<div + className='flex max-w-10 max-h-10 p-1 justify-center items-center gap-2 flex-grow rounded-[10px] + border-[0.5px] border-components-panel-border bg-background-default backdrop-blur-sm'> + <div className='flex w-5 h-5 justify-center items-center'> + <Group className='text-text-tertiary' /> + </div> + </div>) + : <Icon src={icon} installed={installed} />} <div className="ml-3 grow"> <div className="flex items-center h-5"> - <Title title={label[locale]} /> - <RiVerifiedBadgeLine className="shrink-0 ml-0.5 w-4 h-4 text-text-accent" /> + <Title title={loadingFileName || getLocalizedText(label)} /> + {!isLoading && <RiVerifiedBadgeLine className="shrink-0 ml-0.5 w-4 h-4 text-text-accent" />} {titleLeft} {/* This can be version badge */} </div> <OrgInfo className="mt-0.5" orgName={org} packageName={name} + isLoading={isLoading} /> </div> </div> - <Description - className="mt-3" - text={payload.brief[locale]} - descriptionLineRows={descriptionLineRows} - /> + {isLoading + ? <LoadingPlaceholder className="mt-3 w-[420px]" /> + : <Description + className="mt-3" + text={getLocalizedText(brief)} + descriptionLineRows={descriptionLineRows} + />} {footer && <div>{footer}</div>} </div> ) diff --git a/web/app/components/plugins/install-plugin/install-from-github/index.tsx b/web/app/components/plugins/install-plugin/install-from-github/index.tsx index 8f7aebebcc..d882bff796 100644 --- a/web/app/components/plugins/install-plugin/install-from-github/index.tsx +++ b/web/app/components/plugins/install-plugin/install-from-github/index.tsx @@ -10,7 +10,7 @@ type InstallFromGitHubProps = { onClose: () => void } -type InstallStep = 'url' | 'version' | 'package' +type InstallStep = 'url' | 'version' | 'package' | 'installed' const InstallFromGitHub: React.FC<InstallFromGitHubProps> = ({ onClose }) => { const [step, setStep] = useState<InstallStep>('url') @@ -42,11 +42,38 @@ const InstallFromGitHub: React.FC<InstallFromGitHubProps> = ({ onClose }) => { setStep('package') break case 'package': - // TODO: Handle final submission + // TODO: Handle installation + setStep('installed') break } } + const isInputValid = () => { + switch (step) { + case 'url': + return !!repoUrl.trim() + case 'version': + return !!selectedVersion + case 'package': + return !!selectedPackage + default: + return true + } + } + + const InfoRow = ({ label, value }: { label: string; value: string }) => ( + <div className='flex items-center gap-3'> + <div className='flex w-[72px] items-center gap-2'> + <div className='text-text-tertiary system-sm-medium'> + {label} + </div> + </div> + <div className='flex-grow overflow-hidden text-text-secondary text-ellipsis system-sm-medium'> + {value} + </div> + </div> + ) + return ( <Modal isShow={true} @@ -61,11 +88,11 @@ const InstallFromGitHub: React.FC<InstallFromGitHubProps> = ({ onClose }) => { Install plugin from GitHub </div> <div className='self-stretch text-text-tertiary system-xs-regular'> - Please make sure that you only install plugins from a trusted source. + {step !== 'installed' && 'Please make sure that you only install plugins from a trusted source.'} </div> </div> </div> - <div className='flex px-6 py-3 flex-col justify-center items-start gap-4 self-stretch'> + <div className={`flex px-6 py-3 flex-col justify-center items-start self-stretch ${step === 'installed' ? 'gap-2' : 'gap-4'}`}> {step === 'url' && ( <> <label @@ -121,22 +148,51 @@ const InstallFromGitHub: React.FC<InstallFromGitHubProps> = ({ onClose }) => { /> </> )} + {step === 'installed' && ( + <> + <div className='text-text-secondary system-md-regular'>The plugin has been installed successfully.</div> + <div className='flex w-full p-4 flex-col justify-center items-start gap-2 rounded-2xl bg-background-section-burn'> + {[ + { label: 'Repository', value: repoUrl }, + { label: 'Version', value: selectedVersion }, + { label: 'Package', value: selectedPackage }, + ].map(({ label, value }) => ( + <InfoRow key={label} label={label} value={value} /> + ))} + </div> + </> + )} </div> <div className='flex p-6 pt-5 justify-end items-center gap-2 self-stretch'> - <Button - variant='secondary' - className='min-w-[72px]' - onClick={onClose} - > - Cancel - </Button> - <Button - variant='primary' - className='min-w-[72px]' - onClick={handleNext} - > - {step === 'package' ? 'Install' : 'Next'} - </Button> + {step === 'installed' + ? ( + <Button + variant='primary' + className='min-w-[72px]' + onClick={onClose} + > + Close + </Button> + ) + : ( + <> + <Button + variant='secondary' + className='min-w-[72px]' + onClick={onClose} + > + Cancel + </Button> + <Button + variant='primary' + className='min-w-[72px]' + onClick={handleNext} + disabled={!isInputValid()} + > + {step === 'package' ? 'Install' : 'Next'} + </Button> + </> + )} </div> </Modal> ) diff --git a/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx b/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx index c8863faf79..87e470584e 100644 --- a/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx +++ b/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx @@ -1,9 +1,13 @@ 'use client' -import React from 'react' +import React, { useCallback, useEffect, useState } from 'react' +import { useContext } from 'use-context-selector' import { RiLoader2Line } from '@remixicon/react' +import Card from '../../card' +import { toolNotion } from '../../card/card-mock' import Modal from '@/app/components/base/modal' import Button from '@/app/components/base/button' +import I18n from '@/context/i18n' type InstallFromLocalPackageProps = { file: File @@ -11,12 +15,48 @@ type InstallFromLocalPackageProps = { } const InstallFromLocalPackage: React.FC<InstallFromLocalPackageProps> = ({ onClose }) => { + const [status, setStatus] = useState<'uploading' | 'ready' | 'installing' | 'installed'>('uploading') + const { locale } = useContext(I18n) + + useEffect(() => { + const timer = setTimeout(() => setStatus('ready'), 1500) + return () => clearTimeout(timer) + }, []) + + const handleInstall = useCallback(async () => { + setStatus('installing') + await new Promise(resolve => setTimeout(resolve, 1000)) + setStatus('installed') + }, []) + + const renderStatusMessage = () => { + switch (status) { + case 'uploading': + return ( + <div className='flex items-center gap-1 self-stretch'> + <RiLoader2Line className='text-text-accent w-4 h-4' /> + <div className='text-text-secondary system-md-regular'> + Uploading notion-sync.difypkg ... + </div> + </div> + ) + case 'installed': + return <p className='text-text-secondary system-md-regular'>The plugin has been installed successfully.</p> + default: + return ( + <div className='text-text-secondary system-md-regular'> + <p>About to install the following plugin.</p> + <p>Please make sure that you only install plugins from a <span className='system-md-semibold'>trusted source</span>.</p> + </div> + ) + } + } + return ( <Modal isShow={true} onClose={onClose} - className='flex min-w-[560px] p-0 flex-col items-start rounded-2xl border-[0.5px] - border-components-panel-border bg-components-panel-bg shadows-shadow-xl' + className='flex min-w-[560px] p-0 flex-col items-start rounded-2xl border-[0.5px] border-components-panel-border bg-components-panel-bg shadows-shadow-xl' closable > <div className='flex pt-6 pl-6 pb-3 pr-14 items-start gap-2 self-stretch'> @@ -25,28 +65,38 @@ const InstallFromLocalPackage: React.FC<InstallFromLocalPackageProps> = ({ onClo </div> </div> <div className='flex flex-col px-6 py-3 justify-center items-start gap-4 self-stretch'> - <div className='flex items-center gap-1 self-stretch'> - <RiLoader2Line className='text-text-accent w-4 h-4' /> - <div className='text-text-secondary system-md-regular'> - Uploading notion-sync.difypkg ... - </div> + {renderStatusMessage()} + <div className='flex p-2 items-start content-start gap-1 self-stretch flex-wrap rounded-2xl bg-background-section-burn'> + <Card + className='w-full' + locale={locale} + payload={status === 'uploading' ? { name: 'notion-sync' } as any : toolNotion as any} + isLoading={status === 'uploading'} + loadingFileName='notion-sync.difypkg' + installed={status === 'installed'} + /> </div> </div> <div className='flex p-6 pt-5 justify-end items-center gap-2 self-stretch'> - <Button - variant='secondary' - className='min-w-[72px]' - onClick={onClose} - > - Cancel - </Button> - <Button - variant='primary' - className='min-w-[72px]' - disabled - > - Install - </Button> + {status === 'installed' + ? ( + <Button variant='primary' onClick={onClose}>Close</Button> + ) + : ( + <> + <Button variant='secondary' className='min-w-[72px]' onClick={onClose}> + Cancel + </Button> + <Button + variant='primary' + className='min-w-[72px]' + disabled={status !== 'ready'} + onClick={handleInstall} + > + {status === 'installing' ? 'Installing...' : 'Install'} + </Button> + </> + )} </div> </Modal> ) diff --git a/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx b/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx index 524588132f..96deec4da9 100644 --- a/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx +++ b/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx @@ -1,6 +1,6 @@ 'use client' -import React, { useState } from 'react' +import React, { useMemo, useState } from 'react' import { useContext } from 'use-context-selector' import { RiInformation2Line } from '@remixicon/react' import Card from '../../card' @@ -17,88 +17,119 @@ type InstallFromMarketplaceProps = { const InstallFromMarketplace: React.FC<InstallFromMarketplaceProps> = ({ onClose }) => { const { locale } = useContext(I18n) - - // Mock a plugin list - const plugins = [toolNotion, extensionDallE, modelGPT4] + const plugins = useMemo(() => [toolNotion, extensionDallE, modelGPT4], []) const [selectedPlugins, setSelectedPlugins] = useState<Set<number>>(new Set()) + const [isInstalling, setIsInstalling] = useState(false) + const [nextStep, setNextStep] = useState(false) + + const mockInstall = async () => { + setIsInstalling(true) + await new Promise(resolve => setTimeout(resolve, 1500)) + setIsInstalling(false) + } + + const pluginsToShow = useMemo(() => { + if (plugins.length === 1 || (nextStep && selectedPlugins.size === 1)) + return plugins.length === 1 ? plugins : plugins.filter((_, index) => selectedPlugins.has(index)) + + return nextStep ? plugins.filter((_, index) => selectedPlugins.has(index)) : plugins + }, [plugins, nextStep, selectedPlugins]) + + const renderPluginCard = (plugin: any, index: number) => ( + <Card + key={index} + installed={nextStep && !isInstalling} + payload={plugin} + locale={locale} + className='w-full' + titleLeft={ + plugin.version === plugin.latest_version + ? ( + <Badge className='mx-1' size="s" state={BadgeState.Default}>{plugin.version}</Badge> + ) + : ( + <> + <Badge className='mx-1' size="s" state={BadgeState.Warning}> + {`${plugin.version} -> ${plugin.latest_version}`} + </Badge> + <div className='flex px-0.5 justify-center items-center gap-0.5'> + <div className='text-text-warning system-xs-medium'>Used in 3 apps</div> + <RiInformation2Line className='w-4 h-4 text-text-tertiary' /> + </div> + </> + ) + } + /> + ) return ( <Modal isShow={true} onClose={onClose} - className='flex min-w-[560px] flex-col items-start p-0 rounded-2xl border-[0.5px] - border-components-panel-border bg-components-panel-bg shadows-shadow-xl' + className='flex min-w-[560px] flex-col items-start p-0 rounded-2xl border-[0.5px] border-components-panel-border bg-components-panel-bg shadows-shadow-xl' closable > <div className='flex pt-6 pl-6 pb-3 pr-14 items-start gap-2 self-stretch'> - <div className='self-stretch text-text-primary title-2xl-semi-bold'>Install plugin</div> + <div className='self-stretch text-text-primary title-2xl-semi-bold'> + {nextStep ? (isInstalling ? 'Install plugin' : 'Installation successful') : 'Install plugin'} + </div> </div> <div className='flex px-6 py-3 flex-col justify-center items-start gap-4 self-stretch'> <div className='flex flex-col items-start gap-2 self-stretch'> - <div className='text-text-secondary system-md-regular'>About to install the following plugin</div> + <div className='text-text-secondary system-md-regular'> + {(nextStep && !isInstalling) + ? `The following ${pluginsToShow.length === 1 ? 'plugin has' : `${pluginsToShow.length} plugins have`} been installed successfully` + : `About to install the following ${pluginsToShow.length === 1 ? 'plugin' : `${pluginsToShow.length} plugins`}`} + </div> </div> - <div className='flex p-2 items-start content-start gap-1 self-stretch flex-wrap - rounded-2xl bg-background-section-burn'> - {plugins.length === 1 - && <Card - payload={plugins[0] as any} - locale={locale} - className='w-full' - > - </Card> - } - {plugins.length > 1 && plugins.map((plugin, index) => ( - <div className='flex pl-1 items-center gap-2 flex-grow' key={index}> - <Checkbox - checked={selectedPlugins.has(index)} - onCheck={() => { - const newSelectedPlugins = new Set(selectedPlugins) - if (newSelectedPlugins.has(index)) - newSelectedPlugins.delete(index) - else - newSelectedPlugins.add(index) - - setSelectedPlugins(newSelectedPlugins) - }} - /> - <Card - key={index} - payload={plugin as any} - locale={locale} - className='w-full' - titleLeft={plugin.version === plugin.latest_version - ? <Badge className='mx-1' size="s" state={BadgeState.Default}>{plugin.version}</Badge> - : <> - <Badge - className='mx-1' - size="s" - state={BadgeState.Warning}>{`${plugin.version} -> ${plugin.latest_version}`} - </Badge> - <div className='flex px-0.5 justify-center items-center gap-0.5'> - <div className='text-text-warning system-xs-medium'>Used in 3 apps</div> - <RiInformation2Line className='w-4 h-4 text-text-tertiary' /> - </div> - </> - } - /> + <div className='flex p-2 items-start content-start gap-1 self-stretch flex-wrap rounded-2xl bg-background-section-burn'> + {pluginsToShow.map((plugin, index) => ( + <div key={index} className={`flex ${(plugins.length > 1 && !nextStep) ? 'pl-1 items-center gap-2' : ''} flex-grow`}> + {(plugins.length > 1 && !nextStep) && ( + <Checkbox + checked={selectedPlugins.has(index)} + onCheck={() => { + const newSelectedPlugins = new Set(selectedPlugins) + newSelectedPlugins.has(index) ? newSelectedPlugins.delete(index) : newSelectedPlugins.add(index) + setSelectedPlugins(newSelectedPlugins) + }} + /> + )} + {renderPluginCard(plugin, index)} </div> ))} </div> </div> <div className='flex p-6 pt-5 justify-end items-center gap-2 self-stretch'> - <Button - variant='secondary' - className='min-w-[72px]' - onClick={onClose} - > - Cancel - </Button> - <Button - variant='primary' - className='min-w-[72px]' - > - Install - </Button> + {nextStep + ? ( + <Button + variant='primary' + disabled={isInstalling} + loading={isInstalling} + onClick={onClose} + > + {isInstalling ? 'Installing...' : 'Close'} + </Button> + ) + : ( + <> + <Button variant='secondary' className='min-w-[72px]' onClick={onClose}> + Cancel + </Button> + <Button + variant='primary' + className='min-w-[72px]' + disabled={plugins.length > 1 && selectedPlugins.size < 1} + onClick={() => { + setNextStep(true) + mockInstall() + }} + > + Install + </Button> + </> + )} </div> </Modal> ) From 2cc37ac8e526b8a997091272e5946289097fe261 Mon Sep 17 00:00:00 2001 From: StyleZhang <jasonapring2015@outlook.com> Date: Tue, 15 Oct 2024 14:56:41 +0800 Subject: [PATCH 067/346] tool list --- web/app/components/tools/marketplace.tsx | 262 +++++++++++++++++++++ web/app/components/tools/provider-list.tsx | 21 +- 2 files changed, 279 insertions(+), 4 deletions(-) create mode 100644 web/app/components/tools/marketplace.tsx diff --git a/web/app/components/tools/marketplace.tsx b/web/app/components/tools/marketplace.tsx new file mode 100644 index 0000000000..d38b165615 --- /dev/null +++ b/web/app/components/tools/marketplace.tsx @@ -0,0 +1,262 @@ +import { RiArrowUpDoubleLine } from '@remixicon/react' +import Card from '@/app/components/plugins/card' +import CardMoreInfo from '@/app/components/plugins/card/card-more-info' +import { toolNotion } from '@/app/components/plugins/card/card-mock' +import { useGetLanguage } from '@/context/i18n' + +type MarketplaceProps = { + onMarketplaceScroll: () => void +} +const Marketplace = ({ + onMarketplaceScroll, +}: MarketplaceProps) => { + const locale = useGetLanguage() + + return ( + <div className='shrink-0 sticky -bottom-[442px] h-[530px] overflow-y-auto px-12 py-2 bg-background-default-subtle'> + <RiArrowUpDoubleLine + className='absolute top-2 left-1/2 -translate-x-1/2 w-4 h-4 text-text-quaternary cursor-pointer' + onClick={() => onMarketplaceScroll()} + /> + <div className='pt-4 pb-3'> + <div className='title-2xl-semi-bold bg-gradient-to-r from-[rgba(11,165,236,0.95)] to-[rgba(21,90,239,0.95)] bg-clip-text text-transparent'>More from Marketplace</div> + <div className='flex items-center text-center body-md-regular text-text-tertiary'> + Discover + <span className="relative ml-1 body-md-medium text-text-secondary after:content-[''] after:absolute after:left-0 after:bottom-[1.5px] after:w-full after:h-2 after:bg-text-text-selected"> + models + </span> + , + <span className="relative ml-1 body-md-medium text-text-secondary after:content-[''] after:absolute after:left-0 after:bottom-[1.5px] after:w-full after:h-2 after:bg-text-text-selected"> + tools + </span> + , + <span className="relative ml-1 mr-1 body-md-medium text-text-secondary after:content-[''] after:absolute after:left-0 after:bottom-[1.5px] after:w-full after:h-2 after:bg-text-text-selected"> + extensions + </span> + and + <span className="relative ml-1 mr-1 body-md-medium text-text-secondary after:content-[''] after:absolute after:left-0 after:bottom-[1.5px] after:w-full after:h-2 after:bg-text-text-selected"> + bundles + </span> + in Dify Marketplace + </div> + </div> + <div className='py-3'> + <div className='title-xl-semi-bold text-text-primary'>Featured</div> + <div className='system-xs-regular text-text-tertiary'>Our top picks to get you started</div> + <div className='grid grid-cols-4 gap-3 mt-2'> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + </div> + </div> + <div className='py-3'> + <div className='title-xl-semi-bold text-text-primary'>Popular</div> + <div className='system-xs-regular text-text-tertiary'>Explore the library and discover the incredible work of our community</div> + <div className='grid grid-cols-4 gap-3 mt-2'> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + <Card + locale={locale} + payload={toolNotion as any} + footer={ + <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> + } + /> + </div> + </div> + </div> + ) +} + +export default Marketplace diff --git a/web/app/components/tools/provider-list.tsx b/web/app/components/tools/provider-list.tsx index 6598bb6d08..8b44ecd296 100644 --- a/web/app/components/tools/provider-list.tsx +++ b/web/app/components/tools/provider-list.tsx @@ -1,8 +1,9 @@ 'use client' -import { useEffect, useMemo, useState } from 'react' +import { useEffect, useMemo, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' import { RiCloseLine } from '@remixicon/react' import type { Collection } from './types' +import Marketplace from './marketplace' import cn from '@/utils/classnames' import { useTabSearchParams } from '@/hooks/use-tab-searchparams' import TabSliderNew from '@/app/components/base/tab-slider-new' @@ -12,16 +13,17 @@ import { DotsGrid } from '@/app/components/base/icons/src/vender/line/general' import { Colors } from '@/app/components/base/icons/src/vender/line/others' import { Route } from '@/app/components/base/icons/src/vender/line/mapsAndTravel' import CustomCreateCard from '@/app/components/tools/provider/custom-create-card' -import ContributeCard from '@/app/components/tools/provider/contribute' import ProviderDetail from '@/app/components/tools/provider/detail' import Empty from '@/app/components/tools/add-tool-modal/empty' import { fetchCollectionList } from '@/service/tools' import Card from '@/app/components/plugins/card' import { useGetLanguage } from '@/context/i18n' +import CardMoreInfo from '@/app/components/plugins/card/card-more-info' const ProviderList = () => { const { t } = useTranslation() const language = useGetLanguage() + const containerRef = useRef<HTMLDivElement>(null) const [activeTab, setActiveTab] = useTabSearchParams({ defaultTab: 'builtin', @@ -70,7 +72,10 @@ const ProviderList = () => { return ( <div className='relative flex overflow-hidden bg-gray-100 shrink-0 h-0 grow'> - <div className='relative flex flex-col overflow-y-auto bg-gray-100 grow'> + <div + ref={containerRef} + className='relative flex flex-col overflow-y-auto bg-gray-100 grow' + > <div className={cn( 'sticky top-0 flex justify-between items-center pt-4 px-12 pb-2 leading-[56px] bg-gray-100 z-20 flex-wrap gap-y-2', currentProvider && 'pr-6', @@ -93,7 +98,6 @@ const ProviderList = () => { 'relative grid content-start grid-cols-1 gap-4 px-12 pt-2 pb-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 grow shrink-0', currentProvider && 'pr-6 sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-3', )}> - {activeTab === 'builtin' && <ContributeCard />} {activeTab === 'api' && <CustomCreateCard onRefreshData={getProviderList} />} {filteredCollectionList.map(collection => ( <Card @@ -103,10 +107,19 @@ const ProviderList = () => { ...collection, brief: collection.description, } as any} + footer={ + <CardMoreInfo + downloadCount={0} + tags={collection.labels} + /> + } /> ))} {!filteredCollectionList.length && <div className='absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2'><Empty /></div>} </div> + <Marketplace onMarketplaceScroll={() => { + containerRef.current?.scrollTo({ top: containerRef.current.scrollHeight, behavior: 'smooth' }) + }} /> </div> <div className={cn( 'shrink-0 w-0 border-l-[0.5px] border-black/8 overflow-y-auto transition-all duration-200 ease-in-out', From a8c5e0b0b0d6d90c206caa0caeb3bdae6585a08b Mon Sep 17 00:00:00 2001 From: StyleZhang <jasonapring2015@outlook.com> Date: Tue, 15 Oct 2024 15:12:42 +0800 Subject: [PATCH 068/346] tool list item click --- web/app/components/tools/marketplace.tsx | 4 +-- web/app/components/tools/provider-list.tsx | 34 +++++++++++++--------- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/web/app/components/tools/marketplace.tsx b/web/app/components/tools/marketplace.tsx index d38b165615..56f85d447d 100644 --- a/web/app/components/tools/marketplace.tsx +++ b/web/app/components/tools/marketplace.tsx @@ -13,12 +13,12 @@ const Marketplace = ({ const locale = useGetLanguage() return ( - <div className='shrink-0 sticky -bottom-[442px] h-[530px] overflow-y-auto px-12 py-2 bg-background-default-subtle'> + <div className='shrink-0 sticky -bottom-[442px] h-[530px] overflow-y-auto px-12 py-2 pt-0 bg-background-default-subtle'> <RiArrowUpDoubleLine className='absolute top-2 left-1/2 -translate-x-1/2 w-4 h-4 text-text-quaternary cursor-pointer' onClick={() => onMarketplaceScroll()} /> - <div className='pt-4 pb-3'> + <div className='sticky top-0 pt-5 pb-3 bg-background-default-subtle z-10'> <div className='title-2xl-semi-bold bg-gradient-to-r from-[rgba(11,165,236,0.95)] to-[rgba(21,90,239,0.95)] bg-clip-text text-transparent'>More from Marketplace</div> <div className='flex items-center text-center body-md-regular text-text-tertiary'> Discover diff --git a/web/app/components/tools/provider-list.tsx b/web/app/components/tools/provider-list.tsx index 8b44ecd296..fa9074f3d1 100644 --- a/web/app/components/tools/provider-list.tsx +++ b/web/app/components/tools/provider-list.tsx @@ -100,20 +100,28 @@ const ProviderList = () => { )}> {activeTab === 'api' && <CustomCreateCard onRefreshData={getProviderList} />} {filteredCollectionList.map(collection => ( - <Card + <div key={collection.id} - locale={language} - payload={{ - ...collection, - brief: collection.description, - } as any} - footer={ - <CardMoreInfo - downloadCount={0} - tags={collection.labels} - /> - } - /> + onClick={() => setCurrentProvider(collection)} + > + <Card + className={cn( + 'border-[1.5px] border-transparent', + currentProvider?.id === collection.id && 'border-components-option-card-option-selected-border', + )} + locale={language} + payload={{ + ...collection, + brief: collection.description, + } as any} + footer={ + <CardMoreInfo + downloadCount={0} + tags={collection.labels} + /> + } + /> + </div> ))} {!filteredCollectionList.length && <div className='absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2'><Empty /></div>} </div> From d83f94c55cfe6eeac4fd8a5f9d5868d5a2a42dc7 Mon Sep 17 00:00:00 2001 From: Yi <yxiaoisme@gmail.com> Date: Tue, 15 Oct 2024 15:47:54 +0800 Subject: [PATCH 069/346] fix: set constrain for uploading packages only works in the Plugins tab --- .../components/plugins/plugin-page/index.tsx | 33 ++++++++++--------- .../plugins/plugin-page/use-uploader.ts | 32 +++++++++++------- 2 files changed, 37 insertions(+), 28 deletions(-) diff --git a/web/app/components/plugins/plugin-page/index.tsx b/web/app/components/plugins/plugin-page/index.tsx index 70549a5e1d..14e065250a 100644 --- a/web/app/components/plugins/plugin-page/index.tsx +++ b/web/app/components/plugins/plugin-page/index.tsx @@ -36,23 +36,24 @@ const PluginPage = ({ const { setShowPluginSettingModal } = useModalContext() as any const [currentFile, setCurrentFile] = useState<File | null>(null) const containerRef = usePluginPageContext(v => v.containerRef) - - const { dragging, fileUploader, fileChangeHandle, removeFile } = useUploader({ - onFileChange: setCurrentFile, - containerRef, - }) - const options = useMemo(() => { return [ { value: 'plugins', text: t('common.menus.plugins') }, { value: 'discover', text: 'Explore Marketplace' }, ] }, [t]) - const [activeTab, setActiveTab] = useTabSearchParams({ defaultTab: options[0].value, }) + const uploaderProps = useUploader({ + onFileChange: setCurrentFile, + containerRef, + enabled: activeTab === 'plugins', + }) + + const { dragging, fileUploader, fileChangeHandle, removeFile } = uploaderProps + return ( <div ref={containerRef} @@ -138,21 +139,21 @@ const PluginPage = ({ <span className="system-xs-regular">Drop plugin package here to install</span> </div> {currentFile && ( - <InstallFromLocalPackage file={currentFile} onClose={removeFile} /> + <InstallFromLocalPackage file={currentFile} onClose={removeFile ?? (() => {})} /> )} + <input + ref={fileUploader} + className="hidden" + type="file" + id="fileUploader" + accept='.difypkg' + onChange={fileChangeHandle ?? (() => {})} + /> </> )} { activeTab === 'discover' && marketplace } - <input - ref={fileUploader} - className="hidden" - type="file" - id="fileUploader" - accept='.difypkg' - onChange={fileChangeHandle} - /> </div> ) } diff --git a/web/app/components/plugins/plugin-page/use-uploader.ts b/web/app/components/plugins/plugin-page/use-uploader.ts index d49fe012b7..fb3974c448 100644 --- a/web/app/components/plugins/plugin-page/use-uploader.ts +++ b/web/app/components/plugins/plugin-page/use-uploader.ts @@ -3,9 +3,10 @@ import { useEffect, useRef, useState } from 'react' type UploaderHookProps = { onFileChange: (file: File | null) => void containerRef: React.RefObject<HTMLDivElement> + enabled?: boolean } -export const useUploader = ({ onFileChange, containerRef }: UploaderHookProps) => { +export const useUploader = ({ onFileChange, containerRef, enabled = true }: UploaderHookProps) => { const [dragging, setDragging] = useState(false) const fileUploader = useRef<HTMLInputElement>(null) @@ -39,19 +40,26 @@ export const useUploader = ({ onFileChange, containerRef }: UploaderHookProps) = onFileChange(files[0]) } - const fileChangeHandle = (e: React.ChangeEvent<HTMLInputElement>) => { - const file = e.target.files?.[0] || null - onFileChange(file) - } + const fileChangeHandle = enabled + ? (e: React.ChangeEvent<HTMLInputElement>) => { + const file = e.target.files?.[0] || null + onFileChange(file) + } + : null - const removeFile = () => { - if (fileUploader.current) - fileUploader.current.value = '' + const removeFile = enabled + ? () => { + if (fileUploader.current) + fileUploader.current.value = '' - onFileChange(null) - } + onFileChange(null) + } + : null useEffect(() => { + if (!enabled) + return + const current = containerRef.current if (current) { current.addEventListener('dragenter', handleDragEnter) @@ -67,10 +75,10 @@ export const useUploader = ({ onFileChange, containerRef }: UploaderHookProps) = current.removeEventListener('drop', handleDrop) } } - }, [containerRef]) + }, [containerRef, enabled]) return { - dragging, + dragging: enabled ? dragging : false, fileUploader, fileChangeHandle, removeFile, From 57f4dfdb6f21fe8795ed42d94536c957a3060730 Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Tue, 15 Oct 2024 19:20:59 +0800 Subject: [PATCH 070/346] feat: add permission data logic --- .../modal.tsx | 45 ++++--- .../style.module.css | 0 .../plugins/plugin-page/context.tsx | 17 +++ .../components/plugins/plugin-page/index.tsx | 124 +++++++++++------- .../plugins/plugin-page/use-permission.ts | 39 ++++++ web/app/components/plugins/types.ts | 11 ++ web/context/modal-context.tsx | 14 -- 7 files changed, 171 insertions(+), 79 deletions(-) rename web/app/components/plugins/{plugin-setting => permission-setting-modal}/modal.tsx (66%) rename web/app/components/plugins/{plugin-setting => permission-setting-modal}/style.module.css (100%) create mode 100644 web/app/components/plugins/plugin-page/use-permission.ts diff --git a/web/app/components/plugins/plugin-setting/modal.tsx b/web/app/components/plugins/permission-setting-modal/modal.tsx similarity index 66% rename from web/app/components/plugins/plugin-setting/modal.tsx rename to web/app/components/plugins/permission-setting-modal/modal.tsx index 83076cfd2b..a6eb0db852 100644 --- a/web/app/components/plugins/plugin-setting/modal.tsx +++ b/web/app/components/plugins/permission-setting-modal/modal.tsx @@ -1,33 +1,43 @@ 'use client' import type { FC } from 'react' -import React, { useState } from 'react' +import React, { useCallback, useState } from 'react' import { useTranslation } from 'react-i18next' import Modal from '@/app/components/base/modal' import OptionCard from '@/app/components/workflow/nodes/_base/components/option-card' import Button from '@/app/components/base/button' - -enum PluginManagementOption { - Everyone = 'Everyone', - Admins = 'Admins', - NoOne = 'No one', -} +import type { Permissions } from '@/app/components/plugins/types' +import { PermissionType } from '@/app/components/plugins/types' type Props = { - show: boolean + payload: Permissions onHide: () => void + onSave: (payload: Permissions) => void } const PluginSettingModal: FC<Props> = ({ - show, + payload, onHide, + onSave, }) => { const { t } = useTranslation() - const [manageOption, setManageOption] = useState<PluginManagementOption>(PluginManagementOption.Everyone) - const [debugOption, setDebugOption] = useState<PluginManagementOption>(PluginManagementOption.Everyone) + const [tempPrivilege, setTempPrivilege] = useState<Permissions>(payload) + const handlePrivilegeChange = useCallback((key: string) => { + return (value: PermissionType) => { + setTempPrivilege({ + ...tempPrivilege, + [key]: value, + }) + } + }, [tempPrivilege]) + + const handleSave = useCallback(() => { + onSave(tempPrivilege) + onHide() + }, [tempPrivilege]) return ( <Modal - isShow={show} + isShow onClose={onHide} closable className='!p-0 w-[420px]' @@ -38,19 +48,19 @@ const PluginSettingModal: FC<Props> = ({ </div> <div className='flex px-6 py-3 flex-col justify-center items-start gap-4 self-stretch'> {[ - { title: 'Who can install and manage plugins?', key: 'manage', value: manageOption, setValue: setManageOption }, - { title: 'Who can debug plugins?', key: 'debug', value: debugOption, setValue: setDebugOption }, - ].map(({ title, key, value, setValue }) => ( + { title: 'Who can install and manage plugins?', key: 'canInstall', value: tempPrivilege.canInstall }, + { title: 'Who can debug plugins?', key: 'canDebugger', value: tempPrivilege.canDebugger }, + ].map(({ title, key, value }) => ( <div key={key} className='flex flex-col items-start gap-1 self-stretch'> <div className='flex m-h-6 items-center gap-0.5'> <span className='text-text-secondary system-sm-semibold'>{title}</span> </div> <div className='flex items-start gap-2 justify-between w-full'> - {Object.values(PluginManagementOption).map(option => ( + {[PermissionType.everyone, PermissionType.admin, PermissionType.noOne].map(option => ( <OptionCard key={option} title={option} - onSelect={() => setValue(option)} + onSelect={() => handlePrivilegeChange(key)(option)} selected={value === option} className="flex-1" /> @@ -69,6 +79,7 @@ const PluginSettingModal: FC<Props> = ({ <Button className='min-w-[72px]' variant={'primary'} + onClick={handleSave} > Save </Button> diff --git a/web/app/components/plugins/plugin-setting/style.module.css b/web/app/components/plugins/permission-setting-modal/style.module.css similarity index 100% rename from web/app/components/plugins/plugin-setting/style.module.css rename to web/app/components/plugins/permission-setting-modal/style.module.css diff --git a/web/app/components/plugins/plugin-page/context.tsx b/web/app/components/plugins/plugin-page/context.tsx index 2d026c7cd1..edf0591f81 100644 --- a/web/app/components/plugins/plugin-page/context.tsx +++ b/web/app/components/plugins/plugin-page/context.tsx @@ -3,18 +3,29 @@ import type { ReactNode } from 'react' import { useRef, + useState, } from 'react' import { createContext, useContextSelector, } from 'use-context-selector' +import type { Permissions } from '../types' +import { PermissionType } from '../types' export type PluginPageContextValue = { containerRef: React.RefObject<HTMLDivElement> + permissions: Permissions + setPermissions: (permissions: PluginPageContextValue['permissions']) => void + } export const PluginPageContext = createContext<PluginPageContextValue>({ containerRef: { current: null }, + permissions: { + canInstall: PermissionType.noOne, + canDebugger: PermissionType.noOne, + }, + setPermissions: () => { }, }) type PluginPageContextProviderProps = { @@ -29,11 +40,17 @@ export const PluginPageContextProvider = ({ children, }: PluginPageContextProviderProps) => { const containerRef = useRef<HTMLDivElement>(null) + const [permissions, setPermissions] = useState<PluginPageContextValue['permissions']>({ + canInstall: PermissionType.noOne, + canDebugger: PermissionType.noOne, + }) return ( <PluginPageContext.Provider value={{ containerRef, + permissions, + setPermissions, }} > {children} diff --git a/web/app/components/plugins/plugin-page/index.tsx b/web/app/components/plugins/plugin-page/index.tsx index 14e065250a..2240db20dd 100644 --- a/web/app/components/plugins/plugin-page/index.tsx +++ b/web/app/components/plugins/plugin-page/index.tsx @@ -9,6 +9,7 @@ import { RiDragDropLine, RiEqualizer2Line, } from '@remixicon/react' +import { useBoolean } from 'ahooks' import InstallFromLocalPackage from '../install-plugin/install-from-local-package' import { PluginPageContextProvider, @@ -16,13 +17,14 @@ import { } from './context' import InstallPluginDropdown from './install-plugin-dropdown' import { useUploader } from './use-uploader' +import usePermission from './use-permission' import { useTabSearchParams } from '@/hooks/use-tab-searchparams' -import { useModalContext } from '@/context/modal-context' import Button from '@/app/components/base/button' import TabSlider from '@/app/components/base/tab-slider' import ActionButton from '@/app/components/base/action-button' import Tooltip from '@/app/components/base/tooltip' import cn from '@/utils/classnames' +import PermissionSetModal from '@/app/components/plugins/permission-setting-modal/modal' export type PluginPageProps = { plugins: React.ReactNode @@ -33,7 +35,17 @@ const PluginPage = ({ marketplace, }: PluginPageProps) => { const { t } = useTranslation() - const { setShowPluginSettingModal } = useModalContext() as any + const { + canInstall, + canDebugger, + canSetPermissions, + permissions, + setPermissions, + } = usePermission() + const [showPluginSettingModal, { + setTrue: setShowPluginSettingModal, + setFalse: setHidePluginSettingModal, + }] = useBoolean() const [currentFile, setCurrentFile] = useState<File | null>(null) const containerRef = usePluginPageContext(v => v.containerRef) const options = useMemo(() => { @@ -76,52 +88,60 @@ const PluginPage = ({ /> </div> <div className='flex flex-shrink-0 items-center gap-1'> - <InstallPluginDropdown /> - <Tooltip - triggerMethod='click' - popupContent={ - <> - <div className='flex items-center gap-1 self-stretch'> - <span className='flex flex-col justify-center items-start flex-grow flex-shrink-0 basis-0 text-text-secondary system-sm-semibold'>Debugging</span> - <div className='flex items-center gap-0.5 text-text-accent-light-mode-only cursor-pointer'> - <span className='system-xs-medium'>View docs</span> - <RiArrowRightUpLine className='w-3 h-3' /> - </div> - </div> - <div className='flex flex-col items-start gap-0.5 self-stretch'> - {['Port', 'Key'].map((label, index) => ( - <div key={label} className='flex items-center gap-1 self-stretch'> - <span className='flex w-10 flex-col justify-center items-start text-text-tertiary system-xs-medium'>{label}</span> - <div className='flex justify-center items-center gap-0.5'> - <span className='system-xs-medium text-text-secondary'> - {index === 0 ? 'cloud.dify,ai:2048' : 'A1B2C3D4E5F6G7H8'} - </span> - <ActionButton> - <RiClipboardLine className='w-3.5 h-3.5 text-text-tertiary' /> - </ActionButton> + {canInstall && ( + <InstallPluginDropdown /> + )} + { + canDebugger && ( + <Tooltip + triggerMethod='click' + popupContent={ + <> + <div className='flex items-center gap-1 self-stretch'> + <span className='flex flex-col justify-center items-start flex-grow flex-shrink-0 basis-0 text-text-secondary system-sm-semibold'>Debugging</span> + <div className='flex items-center gap-0.5 text-text-accent-light-mode-only cursor-pointer'> + <span className='system-xs-medium'>View docs</span> + <RiArrowRightUpLine className='w-3 h-3' /> </div> </div> - ))} - </div> - </> - } - popupClassName='flex flex-col items-start w-[256px] px-4 py-3.5 gap-1 border border-components-panel-border - rounded-xl bg-components-tooltip-bg shadows-shadow-lg z-50' - asChild={false} - position='bottom' - > - <Button className='w-full h-full p-2 text-components-button-secondary-text'> - <RiBugLine className='w-4 h-4' /> - </Button> - </Tooltip> - <Button - className='w-full h-full p-2 text-components-button-secondary-text group' - onClick={() => { - setShowPluginSettingModal() - }} - > - <RiEqualizer2Line className='w-4 h-4' /> - </Button> + <div className='flex flex-col items-start gap-0.5 self-stretch'> + {['Port', 'Key'].map((label, index) => ( + <div key={label} className='flex items-center gap-1 self-stretch'> + <span className='flex w-10 flex-col justify-center items-start text-text-tertiary system-xs-medium'>{label}</span> + <div className='flex justify-center items-center gap-0.5'> + <span className='system-xs-medium text-text-secondary'> + {index === 0 ? 'cloud.dify,ai:2048' : 'A1B2C3D4E5F6G7H8'} + </span> + <ActionButton> + <RiClipboardLine className='w-3.5 h-3.5 text-text-tertiary' /> + </ActionButton> + </div> + </div> + ))} + </div> + </> + } + popupClassName='flex flex-col items-start w-[256px] px-4 py-3.5 gap-1 border border-components-panel-border + rounded-xl bg-components-tooltip-bg shadows-shadow-lg z-50' + asChild={false} + position='bottom' + > + <Button className='w-full h-full p-2 text-components-button-secondary-text'> + <RiBugLine className='w-4 h-4' /> + </Button> + </Tooltip> + ) + } + { + canSetPermissions && ( + <Button + className='w-full h-full p-2 text-components-button-secondary-text group' + onClick={setShowPluginSettingModal} + > + <RiEqualizer2Line className='w-4 h-4' /> + </Button> + ) + } </div> </div> </div> @@ -139,7 +159,7 @@ const PluginPage = ({ <span className="system-xs-regular">Drop plugin package here to install</span> </div> {currentFile && ( - <InstallFromLocalPackage file={currentFile} onClose={removeFile ?? (() => {})} /> + <InstallFromLocalPackage file={currentFile} onClose={removeFile ?? (() => { })} /> )} <input ref={fileUploader} @@ -147,13 +167,21 @@ const PluginPage = ({ type="file" id="fileUploader" accept='.difypkg' - onChange={fileChangeHandle ?? (() => {})} + onChange={fileChangeHandle ?? (() => { })} /> </> )} { activeTab === 'discover' && marketplace } + + {showPluginSettingModal && ( + <PermissionSetModal + payload={permissions} + onHide={setHidePluginSettingModal} + onSave={setPermissions} + /> + )} </div> ) } diff --git a/web/app/components/plugins/plugin-page/use-permission.ts b/web/app/components/plugins/plugin-page/use-permission.ts new file mode 100644 index 0000000000..583839be94 --- /dev/null +++ b/web/app/components/plugins/plugin-page/use-permission.ts @@ -0,0 +1,39 @@ +import { useEffect } from 'react' +import { PermissionType } from '../types' +import { + usePluginPageContext, +} from './context' +import { useAppContext } from '@/context/app-context' + +const hasPermission = (permission: PermissionType, isAdmin: boolean) => { + if (permission === PermissionType.noOne) + return false + + if (permission === PermissionType.everyone) + return true + + return isAdmin +} + +const usePermission = () => { + const { isCurrentWorkspaceManager, isCurrentWorkspaceOwner } = useAppContext() + const [permissions, setPermissions] = usePluginPageContext(v => [v.permissions, v.setPermissions]) + const isAdmin = isCurrentWorkspaceManager || isCurrentWorkspaceOwner + + useEffect(() => { + // TODO: fetch permissions from server + setPermissions({ + canInstall: PermissionType.everyone, + canDebugger: PermissionType.everyone, + }) + }, []) + return { + canInstall: hasPermission(permissions.canInstall, isAdmin), + canDebugger: hasPermission(permissions.canDebugger, isAdmin), + canSetPermissions: isAdmin, + permissions, + setPermissions, + } +} + +export default usePermission diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts index 3b8fdd12f2..d5b5098ab7 100644 --- a/web/app/components/plugins/types.ts +++ b/web/app/components/plugins/types.ts @@ -25,3 +25,14 @@ export type Plugin = { settings: CredentialFormSchemaBase[] } } + +export enum PermissionType { + everyone = 'everyone', + admin = 'admin', + noOne = 'noOne', +} + +export type Permissions = { + canInstall: PermissionType + canDebugger: PermissionType +} diff --git a/web/context/modal-context.tsx b/web/context/modal-context.tsx index 289c6dcdd2..727268a29a 100644 --- a/web/context/modal-context.tsx +++ b/web/context/modal-context.tsx @@ -5,7 +5,6 @@ import { useCallback, useState } from 'react' import { createContext, useContext, useContextSelector } from 'use-context-selector' import { useRouter, useSearchParams } from 'next/navigation' import AccountSetting from '@/app/components/header/account-setting' -import PluginSettingModal from '@/app/components/plugins/plugin-setting/modal' import ApiBasedExtensionModal from '@/app/components/header/account-setting/api-based-extension-page/modal' import ModerationSettingModal from '@/app/components/app/configuration/toolbox/moderation/moderation-setting-modal' import ExternalDataToolModal from '@/app/components/app/configuration/tools/external-data-tool-modal' @@ -52,7 +51,6 @@ export type LoadBalancingEntryModalType = ModelModalType & { } export type ModalContextState = { setShowAccountSettingModal: Dispatch<SetStateAction<ModalState<string> | null>> - setShowPluginSettingModal: () => void setShowApiBasedExtensionModal: Dispatch<SetStateAction<ModalState<ApiBasedExtension> | null>> setShowModerationSettingModal: Dispatch<SetStateAction<ModalState<ModerationConfig> | null>> setShowExternalDataToolModal: Dispatch<SetStateAction<ModalState<ExternalDataTool> | null>> @@ -65,7 +63,6 @@ export type ModalContextState = { } const ModalContext = createContext<ModalContextState>({ setShowAccountSettingModal: () => { }, - setShowPluginSettingModal: () => { }, setShowApiBasedExtensionModal: () => { }, setShowModerationSettingModal: () => { }, setShowExternalDataToolModal: () => { }, @@ -103,7 +100,6 @@ export const ModalContextProvider = ({ const router = useRouter() const [showPricingModal, setShowPricingModal] = useState(searchParams.get('show-pricing') === '1') const [showAnnotationFullModal, setShowAnnotationFullModal] = useState(false) - const [showPluginSettingModal, setShowPluginSettingModal] = useState(false) const handleCancelAccountSettingModal = () => { setShowAccountSettingModal(null) if (showAccountSettingModal?.onCancelCallback) @@ -197,7 +193,6 @@ export const ModalContextProvider = ({ return ( <ModalContext.Provider value={{ setShowAccountSettingModal, - setShowPluginSettingModal: () => setShowPluginSettingModal(true), setShowApiBasedExtensionModal, setShowModerationSettingModal, setShowExternalDataToolModal, @@ -219,15 +214,6 @@ export const ModalContextProvider = ({ ) } - { - !!showPluginSettingModal && ( - <PluginSettingModal - show={showPluginSettingModal} - onHide={() => setShowPluginSettingModal(false)} - /> - ) - } - { !!showApiBasedExtensionModal && ( <ApiBasedExtensionModal From 70a5d78cc5532d46a6ac99cbf78e08ba02fe8ecf Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Tue, 15 Oct 2024 21:31:06 +0800 Subject: [PATCH 071/346] chore: priviege i18n --- .../plugins/permission-setting-modal/modal.tsx | 15 ++++++++------- web/app/components/plugins/plugin-page/index.tsx | 14 +++++++++----- web/i18n/en-US/plugin.ts | 8 ++++++++ web/i18n/zh-Hans/plugin.ts | 8 ++++++++ 4 files changed, 33 insertions(+), 12 deletions(-) diff --git a/web/app/components/plugins/permission-setting-modal/modal.tsx b/web/app/components/plugins/permission-setting-modal/modal.tsx index a6eb0db852..4c59bdc0ca 100644 --- a/web/app/components/plugins/permission-setting-modal/modal.tsx +++ b/web/app/components/plugins/permission-setting-modal/modal.tsx @@ -8,6 +8,7 @@ import Button from '@/app/components/base/button' import type { Permissions } from '@/app/components/plugins/types' import { PermissionType } from '@/app/components/plugins/types' +const i18nPrefix = 'plugin.privilege' type Props = { payload: Permissions onHide: () => void @@ -44,22 +45,22 @@ const PluginSettingModal: FC<Props> = ({ > <div className='flex flex-col items-start w-[420px] rounded-2xl border border-components-panel-border bg-components-panel-bg shadows-shadow-xl'> <div className='flex pt-6 pb-3 pl-6 pr-14 items-start gap-2 self-stretch'> - <span className='self-stretch text-text-primary title-2xl-semi-bold'>Plugin Preferences</span> + <span className='self-stretch text-text-primary title-2xl-semi-bold'>{t(`${i18nPrefix}.title`)}</span> </div> <div className='flex px-6 py-3 flex-col justify-center items-start gap-4 self-stretch'> {[ - { title: 'Who can install and manage plugins?', key: 'canInstall', value: tempPrivilege.canInstall }, - { title: 'Who can debug plugins?', key: 'canDebugger', value: tempPrivilege.canDebugger }, + { title: t(`${i18nPrefix}.whoCanInstall`), key: 'canInstall', value: tempPrivilege.canInstall }, + { title: t(`${i18nPrefix}.whoCanDebug`), key: 'canDebugger', value: tempPrivilege.canDebugger }, ].map(({ title, key, value }) => ( <div key={key} className='flex flex-col items-start gap-1 self-stretch'> - <div className='flex m-h-6 items-center gap-0.5'> + <div className='flex h-6 items-center gap-0.5'> <span className='text-text-secondary system-sm-semibold'>{title}</span> </div> <div className='flex items-start gap-2 justify-between w-full'> {[PermissionType.everyone, PermissionType.admin, PermissionType.noOne].map(option => ( <OptionCard key={option} - title={option} + title={t(`${i18nPrefix}.${option}`)} onSelect={() => handlePrivilegeChange(key)(option)} selected={value === option} className="flex-1" @@ -74,14 +75,14 @@ const PluginSettingModal: FC<Props> = ({ className='min-w-[72px]' onClick={onHide} > - Cancel + {t('common.operation.cancel')} </Button> <Button className='min-w-[72px]' variant={'primary'} onClick={handleSave} > - Save + {t('common.operation.save')} </Button> </div> </div> diff --git a/web/app/components/plugins/plugin-page/index.tsx b/web/app/components/plugins/plugin-page/index.tsx index 2240db20dd..3aee11c352 100644 --- a/web/app/components/plugins/plugin-page/index.tsx +++ b/web/app/components/plugins/plugin-page/index.tsx @@ -134,12 +134,16 @@ const PluginPage = ({ } { canSetPermissions && ( - <Button - className='w-full h-full p-2 text-components-button-secondary-text group' - onClick={setShowPluginSettingModal} + <Tooltip + popupContent={t('plugin.privilege.title')} > - <RiEqualizer2Line className='w-4 h-4' /> - </Button> + <Button + className='w-full h-full p-2 text-components-button-secondary-text group' + onClick={setShowPluginSettingModal} + > + <RiEqualizer2Line className='w-4 h-4' /> + </Button> + </Tooltip> ) } </div> diff --git a/web/i18n/en-US/plugin.ts b/web/i18n/en-US/plugin.ts index a82cdf6707..348939de94 100644 --- a/web/i18n/en-US/plugin.ts +++ b/web/i18n/en-US/plugin.ts @@ -21,6 +21,14 @@ const translation = { }, install: '{{num}} installs', installAction: 'Install', + privilege: { + title: 'Plugin Preferences', + whoCanInstall: 'Who can install and manage plugins?', + whoCanDebug: 'Who can debug plugins?', + everyone: 'Everyone', + admin: 'Admins', + noOne: 'No one', + }, } export default translation diff --git a/web/i18n/zh-Hans/plugin.ts b/web/i18n/zh-Hans/plugin.ts index 5166ddedc3..3543e6b526 100644 --- a/web/i18n/zh-Hans/plugin.ts +++ b/web/i18n/zh-Hans/plugin.ts @@ -21,6 +21,14 @@ const translation = { }, install: '{{num}} 次安装', installAction: '安装', + privilege: { + title: '插件偏好', + whoCanInstall: '谁可以安装和管理插件?', + whoCanDebug: '谁可以调试插件?', + everyone: '所有人', + admin: '管理员', + noOne: '无人', + }, } export default translation From 31ece363c3ecdae5d6051c416cba57ece6be6945 Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Tue, 15 Oct 2024 21:35:56 +0800 Subject: [PATCH 072/346] chore: chagne mangament attr name --- web/app/components/plugins/permission-setting-modal/modal.tsx | 2 +- web/app/components/plugins/plugin-page/context.tsx | 4 ++-- web/app/components/plugins/plugin-page/index.tsx | 4 ++-- web/app/components/plugins/plugin-page/use-permission.ts | 4 ++-- web/app/components/plugins/types.ts | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/web/app/components/plugins/permission-setting-modal/modal.tsx b/web/app/components/plugins/permission-setting-modal/modal.tsx index 4c59bdc0ca..67fed1ad0c 100644 --- a/web/app/components/plugins/permission-setting-modal/modal.tsx +++ b/web/app/components/plugins/permission-setting-modal/modal.tsx @@ -49,7 +49,7 @@ const PluginSettingModal: FC<Props> = ({ </div> <div className='flex px-6 py-3 flex-col justify-center items-start gap-4 self-stretch'> {[ - { title: t(`${i18nPrefix}.whoCanInstall`), key: 'canInstall', value: tempPrivilege.canInstall }, + { title: t(`${i18nPrefix}.whoCanInstall`), key: 'canManagement', value: tempPrivilege.canManagement }, { title: t(`${i18nPrefix}.whoCanDebug`), key: 'canDebugger', value: tempPrivilege.canDebugger }, ].map(({ title, key, value }) => ( <div key={key} className='flex flex-col items-start gap-1 self-stretch'> diff --git a/web/app/components/plugins/plugin-page/context.tsx b/web/app/components/plugins/plugin-page/context.tsx index edf0591f81..3d714f8aa0 100644 --- a/web/app/components/plugins/plugin-page/context.tsx +++ b/web/app/components/plugins/plugin-page/context.tsx @@ -22,7 +22,7 @@ export type PluginPageContextValue = { export const PluginPageContext = createContext<PluginPageContextValue>({ containerRef: { current: null }, permissions: { - canInstall: PermissionType.noOne, + canManagement: PermissionType.noOne, canDebugger: PermissionType.noOne, }, setPermissions: () => { }, @@ -41,7 +41,7 @@ export const PluginPageContextProvider = ({ }: PluginPageContextProviderProps) => { const containerRef = useRef<HTMLDivElement>(null) const [permissions, setPermissions] = useState<PluginPageContextValue['permissions']>({ - canInstall: PermissionType.noOne, + canManagement: PermissionType.noOne, canDebugger: PermissionType.noOne, }) diff --git a/web/app/components/plugins/plugin-page/index.tsx b/web/app/components/plugins/plugin-page/index.tsx index 3aee11c352..d51a0270f8 100644 --- a/web/app/components/plugins/plugin-page/index.tsx +++ b/web/app/components/plugins/plugin-page/index.tsx @@ -36,7 +36,7 @@ const PluginPage = ({ }: PluginPageProps) => { const { t } = useTranslation() const { - canInstall, + canManagement, canDebugger, canSetPermissions, permissions, @@ -88,7 +88,7 @@ const PluginPage = ({ /> </div> <div className='flex flex-shrink-0 items-center gap-1'> - {canInstall && ( + {canManagement && ( <InstallPluginDropdown /> )} { diff --git a/web/app/components/plugins/plugin-page/use-permission.ts b/web/app/components/plugins/plugin-page/use-permission.ts index 583839be94..fe3f64531b 100644 --- a/web/app/components/plugins/plugin-page/use-permission.ts +++ b/web/app/components/plugins/plugin-page/use-permission.ts @@ -23,12 +23,12 @@ const usePermission = () => { useEffect(() => { // TODO: fetch permissions from server setPermissions({ - canInstall: PermissionType.everyone, + canManagement: PermissionType.everyone, canDebugger: PermissionType.everyone, }) }, []) return { - canInstall: hasPermission(permissions.canInstall, isAdmin), + canManagement: hasPermission(permissions.canManagement, isAdmin), canDebugger: hasPermission(permissions.canDebugger, isAdmin), canSetPermissions: isAdmin, permissions, diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts index d5b5098ab7..a14f7825da 100644 --- a/web/app/components/plugins/types.ts +++ b/web/app/components/plugins/types.ts @@ -33,6 +33,6 @@ export enum PermissionType { } export type Permissions = { - canInstall: PermissionType + canManagement: PermissionType canDebugger: PermissionType } From aa61a890b2518cf011b32b0cedb7fae7b1b51d32 Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Tue, 15 Oct 2024 21:43:20 +0800 Subject: [PATCH 073/346] chore: change downloadCount to optional --- web/app/components/plugins/card/card-more-info.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/web/app/components/plugins/card/card-more-info.tsx b/web/app/components/plugins/card/card-more-info.tsx index 8c9d324c35..b3328e53bd 100644 --- a/web/app/components/plugins/card/card-more-info.tsx +++ b/web/app/components/plugins/card/card-more-info.tsx @@ -1,7 +1,7 @@ import DownloadCount from './base/download-count' type Props = { - downloadCount: number + downloadCount?: number tags: string[] } @@ -11,10 +11,10 @@ const CardMoreInfo = ({ }: Props) => { return ( <div className="flex items-center h-5"> - <DownloadCount downloadCount={downloadCount} /> + {downloadCount !== undefined && <DownloadCount downloadCount={downloadCount} />} + {downloadCount !== undefined && tags && tags.length > 0 && <div className="mx-2 text-text-quaternary system-xs-regular">·</div>} {tags && tags.length > 0 && ( <> - <div className="mx-2 text-text-quaternary system-xs-regular">·</div> <div className="flex space-x-2"> {tags.map(tag => ( <div key={tag} className="flex space-x-1 system-xs-regular"> From 89fb6eb648e507a4589a5c14c0b22b96bbb7a59d Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Tue, 15 Oct 2024 21:45:30 +0800 Subject: [PATCH 074/346] chore: set hideCornerMark to optional --- web/app/components/plugins/card/index.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/web/app/components/plugins/card/index.tsx b/web/app/components/plugins/card/index.tsx index 823d9dd025..75ff9236a9 100644 --- a/web/app/components/plugins/card/index.tsx +++ b/web/app/components/plugins/card/index.tsx @@ -16,6 +16,7 @@ type Props = { locale: Locale // The component is used in both client and server side, so we can't get the locale from both side(getLocaleOnServer and useContext) titleLeft?: React.ReactNode installed?: boolean + hideCornerMark?: boolean descriptionLineRows?: number footer?: React.ReactNode serverLocale?: Locale @@ -28,6 +29,7 @@ const Card = ({ payload, titleLeft, installed, + hideCornerMark, descriptionLineRows = 2, footer, locale, @@ -45,7 +47,7 @@ const Card = ({ return ( <div className={cn('relative p-4 pb-3 border-[0.5px] border-components-panel-border bg-components-panel-on-panel-item-bg hover-bg-components-panel-on-panel-item-bg rounded-xl shadow-xs', className)}> - {!isLoading && <CornerMark text={type} />} + {!hideCornerMark && !isLoading && <CornerMark text={type} />} {/* Header */} <div className="flex"> {isLoading From 35384bda410c9f6f34c383dd4e4a33e251e9bf97 Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Tue, 15 Oct 2024 22:52:57 +0800 Subject: [PATCH 075/346] chore: refactor card loading --- .../components/plugins/card/base/org-info.tsx | 27 ++--------- .../plugins/card/base/placeholder.tsx | 46 +++++++++++++++++++ web/app/components/plugins/card/index.tsx | 43 ++++++++--------- 3 files changed, 70 insertions(+), 46 deletions(-) create mode 100644 web/app/components/plugins/card/base/placeholder.tsx diff --git a/web/app/components/plugins/card/base/org-info.tsx b/web/app/components/plugins/card/base/org-info.tsx index ed184b8bd8..d68f31cf37 100644 --- a/web/app/components/plugins/card/base/org-info.tsx +++ b/web/app/components/plugins/card/base/org-info.tsx @@ -4,7 +4,6 @@ type Props = { orgName: string packageName: string packageNameClassName?: string - isLoading?: boolean } const OrgInfo = ({ @@ -12,32 +11,16 @@ const OrgInfo = ({ orgName, packageName, packageNameClassName, - isLoading = false, }: Props) => { - const LoadingPlaceholder = ({ width }: { width: string }) => ( - <div className={`h-2 w-${width} rounded-sm opacity-20 bg-text-quaternary`} /> - ) return ( <div className={cn('flex items-center h-4 space-x-0.5', className)}> - {isLoading - ? ( - <LoadingPlaceholder width="[41px]" /> - ) - : ( - <span className='shrink-0 text-text-tertiary system-xs-regular'>{orgName}</span> - )} + <span className='shrink-0 text-text-tertiary system-xs-regular'>{orgName}</span> <span className='shrink-0 text-text-quaternary system-xs-regular'> - {isLoading ? '·' : '/'} + / + </span> + <span className={cn('shrink-0 w-0 grow truncate text-text-tertiary system-xs-regular', packageNameClassName)}> + {packageName} </span> - {isLoading - ? ( - <LoadingPlaceholder width="[180px]" /> - ) - : ( - <span className={cn('shrink-0 w-0 grow truncate text-text-tertiary system-xs-regular', packageNameClassName)}> - {packageName} - </span> - )} </div> ) } diff --git a/web/app/components/plugins/card/base/placeholder.tsx b/web/app/components/plugins/card/base/placeholder.tsx new file mode 100644 index 0000000000..a8b106a40b --- /dev/null +++ b/web/app/components/plugins/card/base/placeholder.tsx @@ -0,0 +1,46 @@ +import { Group } from '../../../base/icons/src/vender/other' +import Title from './title' +import cn from '@/utils/classnames' + +type Props = { + wrapClassName: string + loadingFileName: string +} + +export const LoadingPlaceholder = ({ className }: { className?: string }) => ( + <div className={cn('h-2 rounded-sm opacity-20 bg-text-quaternary', className)} /> +) + +const Placeholder = ({ + wrapClassName, + loadingFileName, +}: Props) => { + return ( + <div className={wrapClassName}> + <div className="flex"> + <div + className='flex w-10 h-10 p-1 justify-center items-center gap-2 rounded-[10px] + border-[0.5px] border-components-panel-border bg-background-default backdrop-blur-sm'> + <div className='flex w-5 h-5 justify-center items-center'> + <Group className='text-text-tertiary' /> + </div> + </div> + <div className="ml-3 grow"> + <div className="flex items-center h-5"> + <Title title={loadingFileName} /> + </div> + <div className={cn('flex items-center h-4 space-x-0.5')}> + <LoadingPlaceholder className="w-[41px]" /> + <span className='shrink-0 text-text-quaternary system-xs-regular'> + · + </span> + <LoadingPlaceholder className="w-[180px]" /> + </div> + </div> + </div> + <LoadingPlaceholder className="mt-3 w-[420px]" /> + </div> + ) +} + +export default Placeholder diff --git a/web/app/components/plugins/card/index.tsx b/web/app/components/plugins/card/index.tsx index 75ff9236a9..6b9432633a 100644 --- a/web/app/components/plugins/card/index.tsx +++ b/web/app/components/plugins/card/index.tsx @@ -2,11 +2,11 @@ import React from 'react' import { RiVerifiedBadgeLine } from '@remixicon/react' import type { Plugin } from '../types' import Icon from '../card/base/card-icon' -import { Group } from '../../base/icons/src/vender/other' import CornerMark from './base/corner-mark' import Title from './base/title' import OrgInfo from './base/org-info' import Description from './base/description' +import Placeholder from './base/placeholder' import cn from '@/utils/classnames' import type { Locale } from '@/i18n' @@ -41,45 +41,40 @@ const Card = ({ const getLocalizedText = (obj: Record<string, string> | undefined) => obj?.[locale] || obj?.['en-US'] || '' - const LoadingPlaceholder = ({ className }: { className?: string }) => ( - <div className={cn('h-2 rounded-sm opacity-20 bg-text-quaternary', className)} /> - ) + const wrapClassName = cn('relative p-4 pb-3 border-[0.5px] border-components-panel-border bg-components-panel-on-panel-item-bg hover-bg-components-panel-on-panel-item-bg rounded-xl shadow-xs', className) + if (isLoading) { + return ( + <Placeholder + wrapClassName={wrapClassName} + loadingFileName={loadingFileName!} + /> + ) + } return ( <div className={cn('relative p-4 pb-3 border-[0.5px] border-components-panel-border bg-components-panel-on-panel-item-bg hover-bg-components-panel-on-panel-item-bg rounded-xl shadow-xs', className)}> - {!hideCornerMark && !isLoading && <CornerMark text={type} />} + {!hideCornerMark && <CornerMark text={type} />} {/* Header */} <div className="flex"> - {isLoading - ? (<div - className='flex max-w-10 max-h-10 p-1 justify-center items-center gap-2 flex-grow rounded-[10px] - border-[0.5px] border-components-panel-border bg-background-default backdrop-blur-sm'> - <div className='flex w-5 h-5 justify-center items-center'> - <Group className='text-text-tertiary' /> - </div> - </div>) - : <Icon src={icon} installed={installed} />} + <Icon src={icon} installed={installed} /> <div className="ml-3 grow"> <div className="flex items-center h-5"> - <Title title={loadingFileName || getLocalizedText(label)} /> - {!isLoading && <RiVerifiedBadgeLine className="shrink-0 ml-0.5 w-4 h-4 text-text-accent" />} + <Title title={getLocalizedText(label)} /> + <RiVerifiedBadgeLine className="shrink-0 ml-0.5 w-4 h-4 text-text-accent" /> {titleLeft} {/* This can be version badge */} </div> <OrgInfo className="mt-0.5" orgName={org} packageName={name} - isLoading={isLoading} /> </div> </div> - {isLoading - ? <LoadingPlaceholder className="mt-3 w-[420px]" /> - : <Description - className="mt-3" - text={getLocalizedText(brief)} - descriptionLineRows={descriptionLineRows} - />} + <Description + className="mt-3" + text={getLocalizedText(brief)} + descriptionLineRows={descriptionLineRows} + /> {footer && <div>{footer}</div>} </div> ) From d1dcd391917bc7b8ffff635604aa275bf87b5e76 Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Wed, 16 Oct 2024 10:52:16 +0800 Subject: [PATCH 076/346] feat: add debug info i18n and extract common to components --- .../plugins/base/key-value-item.tsx | 42 +++++++++++++++ web/app/components/plugins/card/index.tsx | 2 +- .../plugins/plugin-page/debug-info.tsx | 53 +++++++++++++++++++ .../components/plugins/plugin-page/index.tsx | 43 +-------------- web/i18n/en-US/plugin.ts | 4 ++ web/i18n/zh-Hans/plugin.ts | 4 ++ 6 files changed, 106 insertions(+), 42 deletions(-) create mode 100644 web/app/components/plugins/base/key-value-item.tsx create mode 100644 web/app/components/plugins/plugin-page/debug-info.tsx diff --git a/web/app/components/plugins/base/key-value-item.tsx b/web/app/components/plugins/base/key-value-item.tsx new file mode 100644 index 0000000000..001bff2c60 --- /dev/null +++ b/web/app/components/plugins/base/key-value-item.tsx @@ -0,0 +1,42 @@ +'use client' +import type { FC } from 'react' +import React, { useCallback } from 'react' +import copy from 'copy-to-clipboard' + +import { + RiClipboardLine, +} from '@remixicon/react' +import { useTranslation } from 'react-i18next' +import Toast from '../../base/toast' +import ActionButton from '@/app/components/base/action-button' +type Props = { + label: string + value: string +} + +const KeyValueItem: FC<Props> = ({ + label, + value, +}) => { + const { t } = useTranslation() + const handleCopy = useCallback(() => { + copy(value) + Toast.notify({ type: 'success', message: t('common.actionMsg.copySuccessfully') }) + }, [value]) + + return ( + <div className='flex items-center gap-1 self-stretch'> + <span className='flex w-10 flex-col justify-center items-start text-text-tertiary system-xs-medium'>{label}</span> + <div className='flex justify-center items-center gap-0.5'> + <span className='system-xs-medium text-text-secondary'> + {value} + </span> + <ActionButton onClick={handleCopy}> + <RiClipboardLine className='w-3.5 h-3.5 text-text-tertiary' /> + </ActionButton> + </div> + </div> + ) +} + +export default React.memo(KeyValueItem) diff --git a/web/app/components/plugins/card/index.tsx b/web/app/components/plugins/card/index.tsx index 6b9432633a..d68c410a49 100644 --- a/web/app/components/plugins/card/index.tsx +++ b/web/app/components/plugins/card/index.tsx @@ -52,7 +52,7 @@ const Card = ({ } return ( - <div className={cn('relative p-4 pb-3 border-[0.5px] border-components-panel-border bg-components-panel-on-panel-item-bg hover-bg-components-panel-on-panel-item-bg rounded-xl shadow-xs', className)}> + <div className={wrapClassName}> {!hideCornerMark && <CornerMark text={type} />} {/* Header */} <div className="flex"> diff --git a/web/app/components/plugins/plugin-page/debug-info.tsx b/web/app/components/plugins/plugin-page/debug-info.tsx new file mode 100644 index 0000000000..e789f906ec --- /dev/null +++ b/web/app/components/plugins/plugin-page/debug-info.tsx @@ -0,0 +1,53 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import { + RiArrowRightUpLine, + RiBugLine, +} from '@remixicon/react' +import { useTranslation } from 'react-i18next' +import KeyValueItem from '../base/key-value-item' +import Tooltip from '@/app/components/base/tooltip' +import Button from '@/app/components/base/button' + +const i18nPrefix = 'plugin.debugInfo' + +const DebugInfo: FC = () => { + const { t } = useTranslation() + return ( + <Tooltip + triggerMethod='click' + popupContent={ + <> + <div className='flex items-center gap-1 self-stretch'> + <span className='flex flex-col justify-center items-start flex-grow flex-shrink-0 basis-0 text-text-secondary system-sm-semibold'>{t(`${i18nPrefix}.title`)}</span> + <a href='' target='_blank' className='flex items-center gap-0.5 text-text-accent-light-mode-only cursor-pointer'> + <span className='system-xs-medium'>{t(`${i18nPrefix}.viewDocs`)}</span> + <RiArrowRightUpLine className='w-3 h-3' /> + </a> + </div> + <div className='flex flex-col items-start gap-0.5 self-stretch'> + <KeyValueItem + label={'Port'} + value={'cloud.dify,ai:2048'} + /> + <KeyValueItem + label={'Key'} + value={'A1B2C3D4E5F6G7H8'} + /> + </div> + </> + } + popupClassName='flex flex-col items-start w-[256px] px-4 py-3.5 gap-1 border border-components-panel-border + rounded-xl bg-components-tooltip-bg shadows-shadow-lg z-50' + asChild={false} + position='bottom' + > + <Button className='w-full h-full p-2 text-components-button-secondary-text'> + <RiBugLine className='w-4 h-4' /> + </Button> + </Tooltip> + ) +} + +export default React.memo(DebugInfo) diff --git a/web/app/components/plugins/plugin-page/index.tsx b/web/app/components/plugins/plugin-page/index.tsx index d51a0270f8..bed200e9f0 100644 --- a/web/app/components/plugins/plugin-page/index.tsx +++ b/web/app/components/plugins/plugin-page/index.tsx @@ -3,9 +3,6 @@ import { useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import { - RiArrowRightUpLine, - RiBugLine, - RiClipboardLine, RiDragDropLine, RiEqualizer2Line, } from '@remixicon/react' @@ -18,10 +15,10 @@ import { import InstallPluginDropdown from './install-plugin-dropdown' import { useUploader } from './use-uploader' import usePermission from './use-permission' +import DebugInfo from './debug-info' import { useTabSearchParams } from '@/hooks/use-tab-searchparams' import Button from '@/app/components/base/button' import TabSlider from '@/app/components/base/tab-slider' -import ActionButton from '@/app/components/base/action-button' import Tooltip from '@/app/components/base/tooltip' import cn from '@/utils/classnames' import PermissionSetModal from '@/app/components/plugins/permission-setting-modal/modal' @@ -93,43 +90,7 @@ const PluginPage = ({ )} { canDebugger && ( - <Tooltip - triggerMethod='click' - popupContent={ - <> - <div className='flex items-center gap-1 self-stretch'> - <span className='flex flex-col justify-center items-start flex-grow flex-shrink-0 basis-0 text-text-secondary system-sm-semibold'>Debugging</span> - <div className='flex items-center gap-0.5 text-text-accent-light-mode-only cursor-pointer'> - <span className='system-xs-medium'>View docs</span> - <RiArrowRightUpLine className='w-3 h-3' /> - </div> - </div> - <div className='flex flex-col items-start gap-0.5 self-stretch'> - {['Port', 'Key'].map((label, index) => ( - <div key={label} className='flex items-center gap-1 self-stretch'> - <span className='flex w-10 flex-col justify-center items-start text-text-tertiary system-xs-medium'>{label}</span> - <div className='flex justify-center items-center gap-0.5'> - <span className='system-xs-medium text-text-secondary'> - {index === 0 ? 'cloud.dify,ai:2048' : 'A1B2C3D4E5F6G7H8'} - </span> - <ActionButton> - <RiClipboardLine className='w-3.5 h-3.5 text-text-tertiary' /> - </ActionButton> - </div> - </div> - ))} - </div> - </> - } - popupClassName='flex flex-col items-start w-[256px] px-4 py-3.5 gap-1 border border-components-panel-border - rounded-xl bg-components-tooltip-bg shadows-shadow-lg z-50' - asChild={false} - position='bottom' - > - <Button className='w-full h-full p-2 text-components-button-secondary-text'> - <RiBugLine className='w-4 h-4' /> - </Button> - </Tooltip> + <DebugInfo /> ) } { diff --git a/web/i18n/en-US/plugin.ts b/web/i18n/en-US/plugin.ts index 348939de94..817c9e0296 100644 --- a/web/i18n/en-US/plugin.ts +++ b/web/i18n/en-US/plugin.ts @@ -21,6 +21,10 @@ const translation = { }, install: '{{num}} installs', installAction: 'Install', + debugInfo: { + title: 'Debugging', + viewDocs: 'View Docs', + }, privilege: { title: 'Plugin Preferences', whoCanInstall: 'Who can install and manage plugins?', diff --git a/web/i18n/zh-Hans/plugin.ts b/web/i18n/zh-Hans/plugin.ts index 3543e6b526..d40920e0aa 100644 --- a/web/i18n/zh-Hans/plugin.ts +++ b/web/i18n/zh-Hans/plugin.ts @@ -21,6 +21,10 @@ const translation = { }, install: '{{num}} 次安装', installAction: '安装', + debugInfo: { + title: '调试', + viewDocs: '查看文档', + }, privilege: { title: '插件偏好', whoCanInstall: '谁可以安装和管理插件?', From 1bd70bd8bf15e94ff0ea2feee73d3647ded4733c Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Wed, 16 Oct 2024 11:05:51 +0800 Subject: [PATCH 077/346] chore: copy button --- .../plugins/base/key-value-item.tsx | 29 +++++++++++++++---- web/i18n/en-US/common.ts | 1 + web/i18n/zh-Hans/common.ts | 1 + 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/web/app/components/plugins/base/key-value-item.tsx b/web/app/components/plugins/base/key-value-item.tsx index 001bff2c60..58c4962a6c 100644 --- a/web/app/components/plugins/base/key-value-item.tsx +++ b/web/app/components/plugins/base/key-value-item.tsx @@ -1,13 +1,14 @@ 'use client' import type { FC } from 'react' -import React, { useCallback } from 'react' +import React, { useCallback, useEffect, useState } from 'react' import copy from 'copy-to-clipboard' import { RiClipboardLine, } from '@remixicon/react' import { useTranslation } from 'react-i18next' -import Toast from '../../base/toast' +import { ClipboardCheck } from '../../base/icons/src/vender/line/files' +import Tooltip from '../../base/tooltip' import ActionButton from '@/app/components/base/action-button' type Props = { label: string @@ -19,11 +20,25 @@ const KeyValueItem: FC<Props> = ({ value, }) => { const { t } = useTranslation() + const [isCopied, setIsCopied] = useState(false) const handleCopy = useCallback(() => { copy(value) - Toast.notify({ type: 'success', message: t('common.actionMsg.copySuccessfully') }) + setIsCopied(true) }, [value]) + useEffect(() => { + if (isCopied) { + const timer = setTimeout(() => { + setIsCopied(false) + }, 2000) + return () => { + clearTimeout(timer) + } + } + }, [isCopied]) + + const CopyIcon = isCopied ? ClipboardCheck : RiClipboardLine + return ( <div className='flex items-center gap-1 self-stretch'> <span className='flex w-10 flex-col justify-center items-start text-text-tertiary system-xs-medium'>{label}</span> @@ -31,9 +46,11 @@ const KeyValueItem: FC<Props> = ({ <span className='system-xs-medium text-text-secondary'> {value} </span> - <ActionButton onClick={handleCopy}> - <RiClipboardLine className='w-3.5 h-3.5 text-text-tertiary' /> - </ActionButton> + <Tooltip popupContent={t(`common.operation.${isCopied ? 'copied' : 'copy'}`)} position='top'> + <ActionButton onClick={handleCopy}> + <CopyIcon className='w-3.5 h-3.5 text-text-tertiary' /> + </ActionButton> + </Tooltip> </div> </div> ) diff --git a/web/i18n/en-US/common.ts b/web/i18n/en-US/common.ts index d7175d26c8..29d5581f35 100644 --- a/web/i18n/en-US/common.ts +++ b/web/i18n/en-US/common.ts @@ -23,6 +23,7 @@ const translation = { remove: 'Remove', send: 'Send', copy: 'Copy', + copied: 'Copied', lineBreak: 'Line break', sure: 'I\'m sure', download: 'Download', diff --git a/web/i18n/zh-Hans/common.ts b/web/i18n/zh-Hans/common.ts index 187bbf122e..e683708e04 100644 --- a/web/i18n/zh-Hans/common.ts +++ b/web/i18n/zh-Hans/common.ts @@ -23,6 +23,7 @@ const translation = { remove: '移除', send: '发送', copy: '复制', + copied: ' 已复制', lineBreak: '换行', sure: '我确定', download: '下载', From bca94854f700237006d35a4e0a111ed48181405d Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Wed, 16 Oct 2024 11:30:04 +0800 Subject: [PATCH 078/346] feat: plugin info --- .../plugins/base/key-value-item.tsx | 5 ++- .../components/plugins/plugin-item/action.tsx | 24 ++++++++--- .../plugins/plugin-page/debug-info.tsx | 2 +- .../plugins/plugin-page/plugin-info.tsx | 40 +++++++++++++++++++ web/i18n/en-US/plugin.ts | 6 +++ web/i18n/zh-Hans/plugin.ts | 6 +++ 6 files changed, 76 insertions(+), 7 deletions(-) create mode 100644 web/app/components/plugins/plugin-page/plugin-info.tsx diff --git a/web/app/components/plugins/base/key-value-item.tsx b/web/app/components/plugins/base/key-value-item.tsx index 58c4962a6c..ec8e8155cb 100644 --- a/web/app/components/plugins/base/key-value-item.tsx +++ b/web/app/components/plugins/base/key-value-item.tsx @@ -9,14 +9,17 @@ import { import { useTranslation } from 'react-i18next' import { ClipboardCheck } from '../../base/icons/src/vender/line/files' import Tooltip from '../../base/tooltip' +import cn from '@/utils/classnames' import ActionButton from '@/app/components/base/action-button' type Props = { label: string + labelWidthClassName?: string value: string } const KeyValueItem: FC<Props> = ({ label, + labelWidthClassName = 'w-10', value, }) => { const { t } = useTranslation() @@ -41,7 +44,7 @@ const KeyValueItem: FC<Props> = ({ return ( <div className='flex items-center gap-1 self-stretch'> - <span className='flex w-10 flex-col justify-center items-start text-text-tertiary system-xs-medium'>{label}</span> + <span className={cn('flex flex-col justify-center items-start text-text-tertiary system-xs-medium', labelWidthClassName)}>{label}</span> <div className='flex justify-center items-center gap-0.5'> <span className='system-xs-medium text-text-secondary'> {value} diff --git a/web/app/components/plugins/plugin-item/action.tsx b/web/app/components/plugins/plugin-item/action.tsx index 86198b9d70..998c808654 100644 --- a/web/app/components/plugins/plugin-item/action.tsx +++ b/web/app/components/plugins/plugin-item/action.tsx @@ -3,6 +3,9 @@ import type { FC } from 'react' import React from 'react' import { useRouter } from 'next/navigation' import { RiDeleteBinLine, RiInformation2Line, RiLoopLeftLine } from '@remixicon/react' +import { useBoolean } from 'ahooks' +import PluginInfo from '../plugin-page/plugin-info' +import ActionButton from '../../base/action-button' type Props = { pluginId: string @@ -19,11 +22,13 @@ const Action: FC<Props> = ({ onDelete, }) => { const router = useRouter() + const [isShowPluginInfo, { + setTrue: showPluginInfo, + setFalse: hidePluginInfo, + }] = useBoolean(false) const handleFetchNewVersion = () => { } - const handleShowInfo = () => { - router.refresh() // refresh the page ... - } + // const handleDelete = () => { } return ( <div className='flex space-x-1'> @@ -34,9 +39,9 @@ const Action: FC<Props> = ({ } { isShowInfo - && <div className='p-0.5 cursor-pointer' onClick={handleShowInfo}> + && <ActionButton onClick={showPluginInfo}> <RiInformation2Line className='w-5 h-5 text-text-tertiary' /> - </div> + </ActionButton> } { isShowDelete @@ -44,6 +49,15 @@ const Action: FC<Props> = ({ <RiDeleteBinLine className='w-5 h-5 text-text-tertiary' /> </div> } + + {isShowPluginInfo && ( + <PluginInfo + repository='https://github.com/langgenius/dify-github-plugin' + release='1.2.5' + packageName='notion-sync.difypkg' + onHide={hidePluginInfo} + /> + )} </div> ) } diff --git a/web/app/components/plugins/plugin-page/debug-info.tsx b/web/app/components/plugins/plugin-page/debug-info.tsx index e789f906ec..308b141836 100644 --- a/web/app/components/plugins/plugin-page/debug-info.tsx +++ b/web/app/components/plugins/plugin-page/debug-info.tsx @@ -26,7 +26,7 @@ const DebugInfo: FC = () => { <RiArrowRightUpLine className='w-3 h-3' /> </a> </div> - <div className='flex flex-col items-start gap-0.5 self-stretch'> + <div className='space-y-0.5'> <KeyValueItem label={'Port'} value={'cloud.dify,ai:2048'} diff --git a/web/app/components/plugins/plugin-page/plugin-info.tsx b/web/app/components/plugins/plugin-page/plugin-info.tsx new file mode 100644 index 0000000000..ebec25f216 --- /dev/null +++ b/web/app/components/plugins/plugin-page/plugin-info.tsx @@ -0,0 +1,40 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import { useTranslation } from 'react-i18next' +import KeyValueItem from '../base/key-value-item' +import Modal from '../../base/modal' + +const i18nPrefix = 'plugin.pluginInfoModal' +type Props = { + repository: string + release: string + packageName: string + onHide: () => void +} + +const PlugInfo: FC<Props> = ({ + repository, + release, + packageName, + onHide, +}) => { + const { t } = useTranslation() + const labelWidthClassName = 'w-[96px]' + return ( + <Modal + title={t(`${i18nPrefix}.title`)} + className='w-[480px]' + isShow + onClose={onHide} + closable + > + <div className='mt-5 space-y-3'> + <KeyValueItem label={t(`${i18nPrefix}.repository`)} labelWidthClassName={labelWidthClassName} value={repository} /> + <KeyValueItem label={t(`${i18nPrefix}.release`)} labelWidthClassName={labelWidthClassName} value={release} /> + <KeyValueItem label={t(`${i18nPrefix}.packageName`)} labelWidthClassName={labelWidthClassName} value={packageName} /> + </div> + </Modal> + ) +} +export default React.memo(PlugInfo) diff --git a/web/i18n/en-US/plugin.ts b/web/i18n/en-US/plugin.ts index 817c9e0296..3d09474264 100644 --- a/web/i18n/en-US/plugin.ts +++ b/web/i18n/en-US/plugin.ts @@ -33,6 +33,12 @@ const translation = { admin: 'Admins', noOne: 'No one', }, + pluginInfoModal: { + title: 'Plugin info', + repository: 'Repository', + release: 'Release', + packageName: 'Package', + }, } export default translation diff --git a/web/i18n/zh-Hans/plugin.ts b/web/i18n/zh-Hans/plugin.ts index d40920e0aa..7f88bda567 100644 --- a/web/i18n/zh-Hans/plugin.ts +++ b/web/i18n/zh-Hans/plugin.ts @@ -33,6 +33,12 @@ const translation = { admin: '管理员', noOne: '无人', }, + pluginInfoModal: { + title: '插件信息', + repository: '仓库', + release: '发布版本', + packageName: '包', + }, } export default translation From 846555af1b53a7761083b194c51c53c03af1bede Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Wed, 16 Oct 2024 11:45:25 +0800 Subject: [PATCH 079/346] fix: action buttion ui --- web/app/components/base/action-button/index.css | 16 ++++------------ web/app/components/base/action-button/index.tsx | 2 +- .../components/plugins/plugin-item/action.tsx | 14 +++++++------- 3 files changed, 12 insertions(+), 20 deletions(-) diff --git a/web/app/components/base/action-button/index.css b/web/app/components/base/action-button/index.css index 96fbb14c6c..13f333b11d 100644 --- a/web/app/components/base/action-button/index.css +++ b/web/app/components/base/action-button/index.css @@ -2,9 +2,7 @@ @layer components { .action-btn { - @apply inline-flex justify-center items-center cursor-pointer text-text-tertiary - hover:text-text-secondary - hover:bg-state-base-hover + @apply inline-flex justify-center items-center cursor-pointer text-text-tertiary hover:text-text-secondary hover:bg-state-base-hover } .action-btn-disabled { @@ -29,21 +27,15 @@ } .action-btn.action-btn-active { - @apply - text-text-accent - bg-state-accent-active - hover:bg-state-accent-active-alt + @apply text-text-accent bg-state-accent-active hover:bg-state-accent-active-alt } .action-btn.action-btn-disabled { - @apply - text-text-disabled + @apply text-text-disabled } .action-btn.action-btn-destructive { - @apply - text-text-destructive - bg-state-destructive-hover + @apply text-text-destructive bg-state-destructive-hover } } \ No newline at end of file diff --git a/web/app/components/base/action-button/index.tsx b/web/app/components/base/action-button/index.tsx index 9e4552a2b7..845edfbd6d 100644 --- a/web/app/components/base/action-button/index.tsx +++ b/web/app/components/base/action-button/index.tsx @@ -28,7 +28,7 @@ const actionButtonVariants = cva( ) export type ActionButtonProps = { - size?: 'xs' | 'm' | 'l' | 'xl' + size?: 'xs' | 's' | 'm' | 'l' | 'xl' state?: ActionButtonState styleCss?: CSSProperties } & React.ButtonHTMLAttributes<HTMLButtonElement> & VariantProps<typeof actionButtonVariants> diff --git a/web/app/components/plugins/plugin-item/action.tsx b/web/app/components/plugins/plugin-item/action.tsx index 998c808654..59ab0e3e0f 100644 --- a/web/app/components/plugins/plugin-item/action.tsx +++ b/web/app/components/plugins/plugin-item/action.tsx @@ -33,21 +33,21 @@ const Action: FC<Props> = ({ return ( <div className='flex space-x-1'> {isShowFetchNewVersion - && <div className='p-0.5 cursor-pointer' onClick={handleFetchNewVersion}> - <RiLoopLeftLine className='w-5 h-5 text-text-tertiary' /> - </div> + && <ActionButton onClick={handleFetchNewVersion}> + <RiLoopLeftLine className='w-4 h-4 text-text-tertiary' /> + </ActionButton> } { isShowInfo && <ActionButton onClick={showPluginInfo}> - <RiInformation2Line className='w-5 h-5 text-text-tertiary' /> + <RiInformation2Line className='w-4 h-4 text-text-tertiary' /> </ActionButton> } { isShowDelete - && <div className='p-0.5 cursor-pointer' onClick={onDelete}> - <RiDeleteBinLine className='w-5 h-5 text-text-tertiary' /> - </div> + && <ActionButton className='hover:bg-state-destructive-hover text-text-tertiary hover:text-text-destructive' onClick={onDelete}> + <RiDeleteBinLine className='w-4 h-4' /> + </ActionButton> } {isShowPluginInfo && ( From 1a64c660ba18d48a68104f66fff1b0e803b07f3f Mon Sep 17 00:00:00 2001 From: StyleZhang <jasonapring2015@outlook.com> Date: Wed, 16 Oct 2024 15:49:56 +0800 Subject: [PATCH 080/346] enable marketplace --- web/app/components/plugins/plugin-page/index.tsx | 12 +++++++++--- .../plugin-page/install-plugin-dropdown.tsx | 8 +++++++- web/app/components/tools/provider-list.tsx | 14 ++++++++++---- web/types/feature.ts | 2 ++ 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/web/app/components/plugins/plugin-page/index.tsx b/web/app/components/plugins/plugin-page/index.tsx index bed200e9f0..962388babc 100644 --- a/web/app/components/plugins/plugin-page/index.tsx +++ b/web/app/components/plugins/plugin-page/index.tsx @@ -22,6 +22,7 @@ import TabSlider from '@/app/components/base/tab-slider' import Tooltip from '@/app/components/base/tooltip' import cn from '@/utils/classnames' import PermissionSetModal from '@/app/components/plugins/permission-setting-modal/modal' +import { useSelector as useAppContextSelector } from '@/context/app-context' export type PluginPageProps = { plugins: React.ReactNode @@ -45,12 +46,17 @@ const PluginPage = ({ }] = useBoolean() const [currentFile, setCurrentFile] = useState<File | null>(null) const containerRef = usePluginPageContext(v => v.containerRef) + const { enable_marketplace } = useAppContextSelector(s => s.systemFeatures) const options = useMemo(() => { return [ { value: 'plugins', text: t('common.menus.plugins') }, - { value: 'discover', text: 'Explore Marketplace' }, + ...( + !enable_marketplace + ? [{ value: 'discover', text: 'Explore Marketplace' }] + : [] + ), ] - }, [t]) + }, [t, enable_marketplace]) const [activeTab, setActiveTab] = useTabSearchParams({ defaultTab: options[0].value, }) @@ -137,7 +143,7 @@ const PluginPage = ({ </> )} { - activeTab === 'discover' && marketplace + activeTab === 'discover' && !enable_marketplace && marketplace } {showPluginSettingModal && ( diff --git a/web/app/components/plugins/plugin-page/install-plugin-dropdown.tsx b/web/app/components/plugins/plugin-page/install-plugin-dropdown.tsx index 962349c74a..e3c3a77755 100644 --- a/web/app/components/plugins/plugin-page/install-plugin-dropdown.tsx +++ b/web/app/components/plugins/plugin-page/install-plugin-dropdown.tsx @@ -15,12 +15,14 @@ import { PortalToFollowElemContent, PortalToFollowElemTrigger, } from '@/app/components/base/portal-to-follow-elem' +import { useSelector as useAppContextSelector } from '@/context/app-context' const InstallPluginDropdown = () => { const fileInputRef = useRef<HTMLInputElement>(null) const [isMenuOpen, setIsMenuOpen] = useState(false) const [selectedAction, setSelectedAction] = useState<string | null>(null) const [selectedFile, setSelectedFile] = useState<File | null>(null) + const { enable_marketplace } = useAppContextSelector(s => s.systemFeatures) const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => { const file = event.target.files?.[0] @@ -62,7 +64,11 @@ const InstallPluginDropdown = () => { /> <div className='p-1 w-full'> {[ - { icon: MagicBox, text: 'Marketplace', action: 'marketplace' }, + ...( + enable_marketplace + ? [{ icon: MagicBox, text: 'Marketplace', action: 'marketplace' }] + : [] + ), { icon: Github, text: 'GitHub', action: 'github' }, { icon: FileZip, text: 'Local Package File', action: 'local' }, ].map(({ icon: Icon, text, action }) => ( diff --git a/web/app/components/tools/provider-list.tsx b/web/app/components/tools/provider-list.tsx index fa9074f3d1..e0ee954e62 100644 --- a/web/app/components/tools/provider-list.tsx +++ b/web/app/components/tools/provider-list.tsx @@ -19,11 +19,13 @@ import { fetchCollectionList } from '@/service/tools' import Card from '@/app/components/plugins/card' import { useGetLanguage } from '@/context/i18n' import CardMoreInfo from '@/app/components/plugins/card/card-more-info' +import { useSelector as useAppContextSelector } from '@/context/app-context' const ProviderList = () => { const { t } = useTranslation() const language = useGetLanguage() const containerRef = useRef<HTMLDivElement>(null) + const { enable_marketplace } = useAppContextSelector(s => s.systemFeatures) const [activeTab, setActiveTab] = useTabSearchParams({ defaultTab: 'builtin', @@ -109,6 +111,7 @@ const ProviderList = () => { 'border-[1.5px] border-transparent', currentProvider?.id === collection.id && 'border-components-option-card-option-selected-border', )} + hideCornerMark locale={language} payload={{ ...collection, @@ -116,7 +119,6 @@ const ProviderList = () => { } as any} footer={ <CardMoreInfo - downloadCount={0} tags={collection.labels} /> } @@ -125,9 +127,13 @@ const ProviderList = () => { ))} {!filteredCollectionList.length && <div className='absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2'><Empty /></div>} </div> - <Marketplace onMarketplaceScroll={() => { - containerRef.current?.scrollTo({ top: containerRef.current.scrollHeight, behavior: 'smooth' }) - }} /> + { + !enable_marketplace && ( + <Marketplace onMarketplaceScroll={() => { + containerRef.current?.scrollTo({ top: containerRef.current.scrollHeight, behavior: 'smooth' }) + }} /> + ) + } </div> <div className={cn( 'shrink-0 w-0 border-l-[0.5px] border-black/8 overflow-y-auto transition-all duration-200 ease-in-out', diff --git a/web/types/feature.ts b/web/types/feature.ts index b129da3aee..f5d77de629 100644 --- a/web/types/feature.ts +++ b/web/types/feature.ts @@ -4,6 +4,7 @@ export type SystemFeatures = { sso_enforced_for_web: boolean sso_enforced_for_web_protocol: string enable_web_sso_switch_component: boolean + enable_marketplace: boolean } export const defaultSystemFeatures: SystemFeatures = { @@ -12,4 +13,5 @@ export const defaultSystemFeatures: SystemFeatures = { sso_enforced_for_web: false, sso_enforced_for_web_protocol: '', enable_web_sso_switch_component: false, + enable_marketplace: false, } From fbc853af9239e589eaf6525ef20949a3e5a48df2 Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Wed, 16 Oct 2024 15:13:19 +0800 Subject: [PATCH 081/346] feat: remove config --- .../components/plugins/plugin-item/action.tsx | 64 ++++++++++++++++--- .../components/plugins/plugin-item/index.tsx | 2 + web/i18n/en-US/plugin.ts | 8 +++ web/i18n/zh-Hans/plugin.ts | 8 +++ 4 files changed, 73 insertions(+), 9 deletions(-) diff --git a/web/app/components/plugins/plugin-item/action.tsx b/web/app/components/plugins/plugin-item/action.tsx index 59ab0e3e0f..5aae4649bb 100644 --- a/web/app/components/plugins/plugin-item/action.tsx +++ b/web/app/components/plugins/plugin-item/action.tsx @@ -4,11 +4,18 @@ import React from 'react' import { useRouter } from 'next/navigation' import { RiDeleteBinLine, RiInformation2Line, RiLoopLeftLine } from '@remixicon/react' import { useBoolean } from 'ahooks' +import { useTranslation } from 'react-i18next' import PluginInfo from '../plugin-page/plugin-info' import ActionButton from '../../base/action-button' +import Tooltip from '../../base/tooltip' +import Confirm from '../../base/confirm' + +const i18nPrefix = 'plugin.action' type Props = { pluginId: string + pluginName: string + usedInApps: number isShowFetchNewVersion: boolean isShowInfo: boolean isShowDelete: boolean @@ -16,11 +23,14 @@ type Props = { } const Action: FC<Props> = ({ + pluginName, + usedInApps, isShowFetchNewVersion, isShowInfo, isShowDelete, onDelete, }) => { + const { t } = useTranslation() const router = useRouter() const [isShowPluginInfo, { setTrue: showPluginInfo, @@ -29,25 +39,45 @@ const Action: FC<Props> = ({ const handleFetchNewVersion = () => { } + const [isShowDeleteConfirm, { + setTrue: showDeleteConfirm, + setFalse: hideDeleteConfirm, + }] = useBoolean(false) + // const handleDelete = () => { } return ( <div className='flex space-x-1'> {isShowFetchNewVersion - && <ActionButton onClick={handleFetchNewVersion}> - <RiLoopLeftLine className='w-4 h-4 text-text-tertiary' /> - </ActionButton> + && ( + <Tooltip popupContent={t(`${i18nPrefix}.checkForUpdates`)}> + <ActionButton onClick={handleFetchNewVersion}> + <RiLoopLeftLine className='w-4 h-4 text-text-tertiary' /> + </ActionButton> + </Tooltip> + ) } { isShowInfo - && <ActionButton onClick={showPluginInfo}> - <RiInformation2Line className='w-4 h-4 text-text-tertiary' /> - </ActionButton> + && ( + <Tooltip popupContent={t(`${i18nPrefix}.pluginInfo`)}> + <ActionButton onClick={showPluginInfo}> + <RiInformation2Line className='w-4 h-4 text-text-tertiary' /> + </ActionButton> + </Tooltip> + ) } { isShowDelete - && <ActionButton className='hover:bg-state-destructive-hover text-text-tertiary hover:text-text-destructive' onClick={onDelete}> - <RiDeleteBinLine className='w-4 h-4' /> - </ActionButton> + && ( + <Tooltip popupContent={t(`${i18nPrefix}.delete`)}> + <ActionButton + className='hover:bg-state-destructive-hover text-text-tertiary hover:text-text-destructive' + onClick={showDeleteConfirm} + > + <RiDeleteBinLine className='w-4 h-4' /> + </ActionButton> + </Tooltip> + ) } {isShowPluginInfo && ( @@ -58,6 +88,22 @@ const Action: FC<Props> = ({ onHide={hidePluginInfo} /> )} + { + isShowDeleteConfirm && ( + <Confirm + isShow + title={t(`${i18nPrefix}.delete`)} + content={ + <div> + {t(`${i18nPrefix}.deleteContentLeft`)}<span className='system-md-semibold'>{pluginName}</span>{t(`${i18nPrefix}.deleteContentRight`)}<br /> + {usedInApps > 0 && t(`${i18nPrefix}.usedInApps`, { num: usedInApps })} + </div> + } + onCancel={hideDeleteConfirm} + onConfirm={onDelete} + /> + ) + } </div> ) } diff --git a/web/app/components/plugins/plugin-item/index.tsx b/web/app/components/plugins/plugin-item/index.tsx index d4f4159af5..452796c27b 100644 --- a/web/app/components/plugins/plugin-item/index.tsx +++ b/web/app/components/plugins/plugin-item/index.tsx @@ -52,6 +52,8 @@ const PluginItem: FC<Props> = ({ <Description text={payload.brief[locale]} descriptionLineRows={1}></Description> <Action pluginId='xxx' + pluginName={label[locale]} + usedInApps={5} isShowFetchNewVersion={hasNewVersion} isShowInfo isShowDelete diff --git a/web/i18n/en-US/plugin.ts b/web/i18n/en-US/plugin.ts index 3d09474264..73361f9fe1 100644 --- a/web/i18n/en-US/plugin.ts +++ b/web/i18n/en-US/plugin.ts @@ -39,6 +39,14 @@ const translation = { release: 'Release', packageName: 'Package', }, + action: { + checkForUpdates: 'Check for updates', + pluginInfo: 'Plugin info', + delete: 'Remove plugin', + deleteContentLeft: 'Would you like to remove ', + deleteContentRight: ' plugin?', + usedInApps: 'This plugin is being used in {{num}} apps.', + }, } export default translation diff --git a/web/i18n/zh-Hans/plugin.ts b/web/i18n/zh-Hans/plugin.ts index 7f88bda567..2549533865 100644 --- a/web/i18n/zh-Hans/plugin.ts +++ b/web/i18n/zh-Hans/plugin.ts @@ -39,6 +39,14 @@ const translation = { release: '发布版本', packageName: '包', }, + action: { + checkForUpdates: '检查更新', + pluginInfo: '插件信息', + delete: '移除插件', + deleteContentLeft: '是否要移除 ', + deleteContentRight: ' 插件?', + usedInApps: '此插件正在 {{num}} 个应用中使用。', + }, } export default translation From f981494613c138353ebe08e78ca6fe004288105c Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Wed, 16 Oct 2024 16:28:07 +0800 Subject: [PATCH 082/346] feat: plugin support emoji icon --- .../(commonLayout)/plugins/test/card/page.tsx | 4 ++-- .../plugins/card/base/card-icon.tsx | 19 ++++++++++++++++++- .../components/plugins/card/base/org-info.tsx | 14 +++++++++----- web/app/components/plugins/card/card-mock.ts | 19 +++++++++++++++++++ .../components/plugins/plugin-item/action.tsx | 1 + 5 files changed, 49 insertions(+), 8 deletions(-) diff --git a/web/app/(commonLayout)/plugins/test/card/page.tsx b/web/app/(commonLayout)/plugins/test/card/page.tsx index 81ac3e4ea6..db54d5c9d3 100644 --- a/web/app/(commonLayout)/plugins/test/card/page.tsx +++ b/web/app/(commonLayout)/plugins/test/card/page.tsx @@ -1,7 +1,7 @@ import { handleDelete } from './actions' import TestClientPlugin from './test-client-plugin' import Card from '@/app/components/plugins/card' -import { extensionDallE, modelGPT4, toolNotion } from '@/app/components/plugins/card/card-mock' +import { customTool, extensionDallE, modelGPT4, toolNotion } from '@/app/components/plugins/card/card-mock' import PluginItem from '@/app/components/plugins/plugin-item' import CardMoreInfo from '@/app/components/plugins/card/card-more-info' import ProviderCard from '@/app/components/plugins/provider-card' @@ -10,7 +10,7 @@ import { getLocaleOnServer, useTranslation as translate } from '@/i18n/server' import Badge from '@/app/components/base/badge' const PluginList = async () => { const locale = getLocaleOnServer() - const pluginList = [toolNotion, extensionDallE, modelGPT4] + const pluginList = [toolNotion, extensionDallE, modelGPT4, customTool] const { t: pluginI8n } = await translate(locale, 'plugin') return ( <div className='pb-3 bg-white'> diff --git a/web/app/components/plugins/card/base/card-icon.tsx b/web/app/components/plugins/card/base/card-icon.tsx index 0fcc28d997..4c0335c248 100644 --- a/web/app/components/plugins/card/base/card-icon.tsx +++ b/web/app/components/plugins/card/base/card-icon.tsx @@ -1,4 +1,5 @@ import { RiCheckLine } from '@remixicon/react' +import AppIcon from '@/app/components/base/app-icon' import cn from '@/utils/classnames' const Icon = ({ @@ -7,9 +8,25 @@ const Icon = ({ installed = false, }: { className?: string - src: string + src: string | { + 'content': string + 'background': string + } installed?: boolean }) => { + if (typeof src === 'object') { + return ( + <div className={cn('relative', className)}> + <AppIcon + size='large' + iconType={'emoji'} + icon={src.content} + background={src.background} + className='rounded-md' + /> + </div> + ) + } return ( <div className={cn('shrink-0 relative w-10 h-10 rounded-md bg-center bg-no-repeat bg-contain', className)} diff --git a/web/app/components/plugins/card/base/org-info.tsx b/web/app/components/plugins/card/base/org-info.tsx index d68f31cf37..0d335eacad 100644 --- a/web/app/components/plugins/card/base/org-info.tsx +++ b/web/app/components/plugins/card/base/org-info.tsx @@ -1,7 +1,7 @@ import cn from '@/utils/classnames' type Props = { className?: string - orgName: string + orgName?: string packageName: string packageNameClassName?: string } @@ -14,10 +14,14 @@ const OrgInfo = ({ }: Props) => { return ( <div className={cn('flex items-center h-4 space-x-0.5', className)}> - <span className='shrink-0 text-text-tertiary system-xs-regular'>{orgName}</span> - <span className='shrink-0 text-text-quaternary system-xs-regular'> - / - </span> + {orgName && ( + <> + <span className='shrink-0 text-text-tertiary system-xs-regular'>{orgName}</span> + <span className='shrink-0 text-text-quaternary system-xs-regular'> + / + </span> + </> + )} <span className={cn('shrink-0 w-0 grow truncate text-text-tertiary system-xs-regular', packageNameClassName)}> {packageName} </span> diff --git a/web/app/components/plugins/card/card-mock.ts b/web/app/components/plugins/card/card-mock.ts index d411288db7..4679a367f4 100644 --- a/web/app/components/plugins/card/card-mock.ts +++ b/web/app/components/plugins/card/card-mock.ts @@ -52,3 +52,22 @@ export const modelGPT4 = { 'zh-Hans': '一个使用 OpenAI GPT-4 模型的简单插件。', }, } + +export const customTool = { + type: PluginType.tool, + name: 'notion page search', + version: '1.2.0', + latest_version: '1.3.0', + icon: { + content: '🕵️', + background: '#FEF7C3', + }, + label: { + 'en-US': 'Notion Page Search', + 'zh-Hans': 'Notion 页面搜索', + }, + brief: { + 'en-US': 'Description: Search Notion pages and open visited ones faster. No admin access required.More and more info...More and more info...More and more info...', + 'zh-Hans': '搜索 Notion 页面并更快地打开已访问的页面。无需管理员访问权限。More and more info...More and more info...More and more info...', + }, +} diff --git a/web/app/components/plugins/plugin-item/action.tsx b/web/app/components/plugins/plugin-item/action.tsx index 5aae4649bb..d995f8c8f8 100644 --- a/web/app/components/plugins/plugin-item/action.tsx +++ b/web/app/components/plugins/plugin-item/action.tsx @@ -47,6 +47,7 @@ const Action: FC<Props> = ({ // const handleDelete = () => { } return ( <div className='flex space-x-1'> + {/* Only plugin installed from GitHub need to check if it's the new version */} {isShowFetchNewVersion && ( <Tooltip popupContent={t(`${i18nPrefix}.checkForUpdates`)}> From 1787c5c93f32059881fdb4f649de280cb878d532 Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Wed, 16 Oct 2024 16:39:47 +0800 Subject: [PATCH 083/346] chore: handle tag name too long --- web/app/(commonLayout)/plugins/test/card/page.tsx | 2 +- web/app/components/plugins/card/base/org-info.tsx | 4 +--- web/app/components/plugins/card/card-more-info.tsx | 10 +++++++--- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/web/app/(commonLayout)/plugins/test/card/page.tsx b/web/app/(commonLayout)/plugins/test/card/page.tsx index db54d5c9d3..eea1d32bec 100644 --- a/web/app/(commonLayout)/plugins/test/card/page.tsx +++ b/web/app/(commonLayout)/plugins/test/card/page.tsx @@ -67,7 +67,7 @@ const PluginList = async () => { payload={plugin as any} locale={locale} footer={ - <CardMoreInfo downloadCount={index % 2 === 0 ? 1234 : 6} tags={index % 2 === 0 ? ['Search', 'Productivity'] : []} /> + <CardMoreInfo downloadCount={index % 2 === 0 ? 1234 : 6} tags={index % 2 === 0 ? ['Search', 'Tag that has very very long name', 'Productivity', 'Tag2'] : []} /> } /> ))} diff --git a/web/app/components/plugins/card/base/org-info.tsx b/web/app/components/plugins/card/base/org-info.tsx index 0d335eacad..3d549d6c5e 100644 --- a/web/app/components/plugins/card/base/org-info.tsx +++ b/web/app/components/plugins/card/base/org-info.tsx @@ -17,9 +17,7 @@ const OrgInfo = ({ {orgName && ( <> <span className='shrink-0 text-text-tertiary system-xs-regular'>{orgName}</span> - <span className='shrink-0 text-text-quaternary system-xs-regular'> - / - </span> + <span className='shrink-0 text-text-quaternary system-xs-regular'>/</span> </> )} <span className={cn('shrink-0 w-0 grow truncate text-text-tertiary system-xs-regular', packageNameClassName)}> diff --git a/web/app/components/plugins/card/card-more-info.tsx b/web/app/components/plugins/card/card-more-info.tsx index b3328e53bd..b7ba8c1a53 100644 --- a/web/app/components/plugins/card/card-more-info.tsx +++ b/web/app/components/plugins/card/card-more-info.tsx @@ -15,11 +15,15 @@ const CardMoreInfo = ({ {downloadCount !== undefined && tags && tags.length > 0 && <div className="mx-2 text-text-quaternary system-xs-regular">·</div>} {tags && tags.length > 0 && ( <> - <div className="flex space-x-2"> + <div className="flex flex-wrap space-x-2 h-4 overflow-hidden"> {tags.map(tag => ( - <div key={tag} className="flex space-x-1 system-xs-regular"> + <div + key={tag} + className="flex space-x-1 system-xs-regular max-w-[120px] overflow-hidden" + title={`# ${tag}`} + > <span className="text-text-quaternary">#</span> - <span className="text-text-tertiary">{tag}</span> + <span className="truncate text-text-tertiary">{tag}</span> </div> ))} </div> From 18f5f9cc3776e1d862c3a46f4ca0a1906366dada Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Wed, 16 Oct 2024 18:05:55 +0800 Subject: [PATCH 084/346] feat: plugin upgrade --- .../(commonLayout)/plugins/test/card/page.tsx | 2 + .../plugins/test/other/page.tsx | 20 ++++ .../plugins/update-plugin/index.tsx | 101 ++++++++++++++++++ web/i18n/en-US/plugin.ts | 9 ++ web/i18n/zh-Hans/plugin.ts | 9 ++ 5 files changed, 141 insertions(+) create mode 100644 web/app/(commonLayout)/plugins/test/other/page.tsx create mode 100644 web/app/components/plugins/update-plugin/index.tsx diff --git a/web/app/(commonLayout)/plugins/test/card/page.tsx b/web/app/(commonLayout)/plugins/test/card/page.tsx index eea1d32bec..6316f40e64 100644 --- a/web/app/(commonLayout)/plugins/test/card/page.tsx +++ b/web/app/(commonLayout)/plugins/test/card/page.tsx @@ -8,10 +8,12 @@ import ProviderCard from '@/app/components/plugins/provider-card' import PluginDetailPanel from '@/app/components/plugins/plugin-detail-panel' import { getLocaleOnServer, useTranslation as translate } from '@/i18n/server' import Badge from '@/app/components/base/badge' + const PluginList = async () => { const locale = getLocaleOnServer() const pluginList = [toolNotion, extensionDallE, modelGPT4, customTool] const { t: pluginI8n } = await translate(locale, 'plugin') + return ( <div className='pb-3 bg-white'> <div className='mx-3 '> diff --git a/web/app/(commonLayout)/plugins/test/other/page.tsx b/web/app/(commonLayout)/plugins/test/other/page.tsx new file mode 100644 index 0000000000..3166e34ba3 --- /dev/null +++ b/web/app/(commonLayout)/plugins/test/other/page.tsx @@ -0,0 +1,20 @@ +'use client' +import { useBoolean } from 'ahooks' +import UpdatePlugin from '@/app/components/plugins/update-plugin' + +const Page = () => { + const [isShowUpdateModal, { + setTrue: showUpdateModal, + setFalse: hideUpdateModal, + }] = useBoolean(false) + return ( + <div> + <div onClick={showUpdateModal}>Show Upgrade</div> + {isShowUpdateModal && ( + <UpdatePlugin onHide={hideUpdateModal} /> + )} + </div> + ) +} + +export default Page diff --git a/web/app/components/plugins/update-plugin/index.tsx b/web/app/components/plugins/update-plugin/index.tsx new file mode 100644 index 0000000000..d0abd21e0c --- /dev/null +++ b/web/app/components/plugins/update-plugin/index.tsx @@ -0,0 +1,101 @@ +'use client' +import type { FC } from 'react' +import React, { useCallback, useMemo, useState } from 'react' +import { useContext } from 'use-context-selector' +import { RiInformation2Line } from '@remixicon/react' +import { useTranslation } from 'react-i18next' +import Card from '@/app/components/plugins/card' +import Modal from '@/app/components/base/modal' +import Button from '@/app/components/base/button' +import Badge, { BadgeState } from '@/app/components/base/badge/index' +import I18n from '@/context/i18n' +import { toolNotion } from '@/app/components/plugins/card/card-mock' + +const i18nPrefix = 'plugin.upgrade' + +type Props = { + onHide: () => void +} + +enum UploadStep { + notStarted = 'notStarted', + upgrading = 'upgrading', + installed = 'installed', +} + +const UpdatePluginModal: FC<Props> = ({ + onHide, +}) => { + const { locale } = useContext(I18n) + const { t } = useTranslation() + const [uploadStep, setUploadStep] = useState<UploadStep>(UploadStep.notStarted) + const configBtnText = useMemo(() => { + return ({ + [UploadStep.notStarted]: t(`${i18nPrefix}.upgrade`), + [UploadStep.upgrading]: t(`${i18nPrefix}.upgrading`), + [UploadStep.installed]: t(`${i18nPrefix}.close`), + })[uploadStep] + }, [uploadStep]) + const handleConfirm = useCallback(() => { + if (uploadStep === UploadStep.notStarted) { + setUploadStep(UploadStep.upgrading) + setTimeout(() => { + setUploadStep(UploadStep.installed) + }, 1500) + return + } + if (uploadStep === UploadStep.installed) + onHide() + }, [uploadStep]) + return ( + <Modal + isShow={true} + onClose={onHide} + className='min-w-[560px]' + closable + title={t(`${i18nPrefix}.${uploadStep === UploadStep.installed ? 'successfulTitle' : 'title'}`)} + > + <div className='mt-3 mb-2 text-text-secondary system-md-regular'> + {t(`${i18nPrefix}.description`)} + </div> + <div className='flex p-2 items-start content-start gap-1 self-stretch flex-wrap rounded-2xl bg-background-section-burn'> + <Card + installed={uploadStep === UploadStep.installed} + payload={toolNotion as any} + locale={locale} + className='w-full' + titleLeft={ + <> + <Badge className='mx-1' size="s" state={BadgeState.Warning}> + {'1.2.0 -> 1.3.2'} + </Badge> + <div className='flex px-0.5 justify-center items-center gap-0.5'> + <div className='text-text-warning system-xs-medium'>{t(`${i18nPrefix}.usedInApps`, { num: 3 })}</div> + {/* show the used apps */} + <RiInformation2Line className='w-4 h-4 text-text-tertiary' /> + </div> + </> + } + /> + </div> + <div className='flex pt-5 justify-end items-center gap-2 self-stretch'> + {uploadStep === UploadStep.notStarted && ( + <Button + onClick={onHide} + > + {t('common.operation.cancel')} + </Button> + )} + <Button + variant='primary' + loading={uploadStep === UploadStep.upgrading} + onClick={handleConfirm} + disabled={uploadStep === UploadStep.upgrading} + > + {configBtnText} + </Button> + </div> + </Modal> + ) +} +export default React.memo(UpdatePluginModal) diff --git a/web/i18n/en-US/plugin.ts b/web/i18n/en-US/plugin.ts index 73361f9fe1..9d94549d64 100644 --- a/web/i18n/en-US/plugin.ts +++ b/web/i18n/en-US/plugin.ts @@ -47,6 +47,15 @@ const translation = { deleteContentRight: ' plugin?', usedInApps: 'This plugin is being used in {{num}} apps.', }, + upgrade: { + title: 'Upgrade Plugin', + successfulTitle: 'Upgrade successful', + description: 'About to upgrade the following plugin', + usedInApps: 'Used in {{num}} apps', + upgrade: 'Upgrade', + upgrading: 'Upgrading...', + close: 'Close', + }, } export default translation diff --git a/web/i18n/zh-Hans/plugin.ts b/web/i18n/zh-Hans/plugin.ts index 2549533865..30f6032261 100644 --- a/web/i18n/zh-Hans/plugin.ts +++ b/web/i18n/zh-Hans/plugin.ts @@ -47,6 +47,15 @@ const translation = { deleteContentRight: ' 插件?', usedInApps: '此插件正在 {{num}} 个应用中使用。', }, + upgrade: { + title: '升级插件', + successfulTitle: '升级成功', + description: '即将升级以下插件', + usedInApps: '在 {{num}} 个应用中使用', + upgrade: '升级', + upgrading: '升级中...', + close: '关闭', + }, } export default translation From cac04c5f3caeefca28b6437f88a19dfd4e487bb5 Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Thu, 17 Oct 2024 15:06:06 +0800 Subject: [PATCH 085/346] refactor: chagne card to client component --- .../(commonLayout)/plugins/test/card/page.tsx | 13 ++------- .../plugins/test/card/test-client-plugin.tsx | 21 -------------- .../model-provider-page/index.tsx | 4 +-- web/app/components/plugins/card/index.tsx | 11 +++---- .../install-from-local-package/index.tsx | 3 +- .../install-from-marketplace/index.tsx | 8 ++--- .../plugins/marketplace/list/index.tsx | 29 ------------------- .../components/plugins/plugin-item/index.tsx | 20 ++++++------- web/app/components/plugins/provider-card.tsx | 7 +++-- .../plugins/update-plugin/index.tsx | 4 --- web/app/components/tools/marketplace.tsx | 29 ------------------- web/app/components/tools/provider-list.tsx | 1 - 12 files changed, 26 insertions(+), 124 deletions(-) delete mode 100644 web/app/(commonLayout)/plugins/test/card/test-client-plugin.tsx diff --git a/web/app/(commonLayout)/plugins/test/card/page.tsx b/web/app/(commonLayout)/plugins/test/card/page.tsx index 6316f40e64..a2ec11e223 100644 --- a/web/app/(commonLayout)/plugins/test/card/page.tsx +++ b/web/app/(commonLayout)/plugins/test/card/page.tsx @@ -1,18 +1,16 @@ import { handleDelete } from './actions' -import TestClientPlugin from './test-client-plugin' import Card from '@/app/components/plugins/card' import { customTool, extensionDallE, modelGPT4, toolNotion } from '@/app/components/plugins/card/card-mock' import PluginItem from '@/app/components/plugins/plugin-item' import CardMoreInfo from '@/app/components/plugins/card/card-more-info' import ProviderCard from '@/app/components/plugins/provider-card' import PluginDetailPanel from '@/app/components/plugins/plugin-detail-panel' -import { getLocaleOnServer, useTranslation as translate } from '@/i18n/server' +import { getLocaleOnServer } from '@/i18n/server' import Badge from '@/app/components/base/badge' const PluginList = async () => { const locale = getLocaleOnServer() const pluginList = [toolNotion, extensionDallE, modelGPT4, customTool] - const { t: pluginI8n } = await translate(locale, 'plugin') return ( <div className='pb-3 bg-white'> @@ -24,19 +22,14 @@ const PluginList = async () => { key={index} payload={plugin as any} onDelete={handleDelete} - pluginI8n={pluginI8n} - locale={locale} /> ))} </div> - <h2>Client plugin item</h2> - <TestClientPlugin /> <h2 className='my-3'>Install Plugin / Package under bundle</h2> <div className='w-[512px] rounded-2xl bg-background-section-burn p-2'> <Card payload={toolNotion as any} - locale={locale} descriptionLineRows={1} titleLeft={ <Badge className='ml-1' text={toolNotion.version} /> @@ -47,7 +40,6 @@ const PluginList = async () => { <div className='w-[512px] rounded-2xl bg-background-section-burn p-2'> <Card payload={toolNotion as any} - locale={locale} descriptionLineRows={1} installed /> @@ -56,7 +48,7 @@ const PluginList = async () => { <h3 className='my-1'>Install model provide</h3> <div className='grid grid-cols-2 gap-3'> {pluginList.map((plugin, index) => ( - <ProviderCard key={index} locale={locale} payload={plugin as any} /> + <ProviderCard key={index} payload={plugin as any} /> ))} </div> @@ -67,7 +59,6 @@ const PluginList = async () => { <Card key={index} payload={plugin as any} - locale={locale} footer={ <CardMoreInfo downloadCount={index % 2 === 0 ? 1234 : 6} tags={index % 2 === 0 ? ['Search', 'Tag that has very very long name', 'Productivity', 'Tag2'] : []} /> } diff --git a/web/app/(commonLayout)/plugins/test/card/test-client-plugin.tsx b/web/app/(commonLayout)/plugins/test/card/test-client-plugin.tsx deleted file mode 100644 index 8187428d9c..0000000000 --- a/web/app/(commonLayout)/plugins/test/card/test-client-plugin.tsx +++ /dev/null @@ -1,21 +0,0 @@ -'use client' -import React from 'react' -import { useTranslation } from 'react-i18next' -import { useContext } from 'use-context-selector' -import { extensionDallE } from '@/app/components/plugins/card/card-mock' -import PluginItem from '@/app/components/plugins/plugin-item' -import I18n from '@/context/i18n' - -const TestClientPlugin = () => { - const { locale } = useContext(I18n) - const { t } = useTranslation() - return ( - <PluginItem - payload={extensionDallE as any} - onDelete={() => { }} - pluginI8n={t} - locale={locale} - /> - ) -} -export default React.memo(TestClientPlugin) diff --git a/web/app/components/header/account-setting/model-provider-page/index.tsx b/web/app/components/header/account-setting/model-provider-page/index.tsx index 70965c0b6b..6e441c3dc9 100644 --- a/web/app/components/header/account-setting/model-provider-page/index.tsx +++ b/web/app/components/header/account-setting/model-provider-page/index.tsx @@ -115,7 +115,7 @@ const ModelProviderPage = () => { 'shrink-0 relative flex items-center justify-end gap-2 p-0.5 rounded-lg border border-transparent', defaultModelNotConfigured && 'pl-2 bg-components-panel-bg-blur border-components-panel-border shadow-xs', )}> - {defaultModelNotConfigured && <div className='absolute top-0 bottom-0 right-0 left-0 opacity-40' style={{ background: 'linear-gradient(92deg, rgba(247, 144, 9, 0.25) 0%, rgba(255, 255, 255, 0.00) 100%)' }}/>} + {defaultModelNotConfigured && <div className='absolute top-0 bottom-0 right-0 left-0 opacity-40' style={{ background: 'linear-gradient(92deg, rgba(247, 144, 9, 0.25) 0%, rgba(255, 255, 255, 0.00) 100%)' }} />} {defaultModelNotConfigured && ( <div className='flex items-center gap-1 text-text-primary system-xs-medium'> <RiAlertFill className='w-4 h-4 text-text-warning-secondary' /> @@ -185,7 +185,7 @@ const ModelProviderPage = () => { {!collapse && ( <div className='grid grid-cols-2 gap-2'> {pluginList.map((plugin, index) => ( - <ProviderCard key={index} installed={false} locale={locale} payload={plugin as any} /> + <ProviderCard key={index} installed={false} payload={plugin as any} /> ))} </div> )} diff --git a/web/app/components/plugins/card/index.tsx b/web/app/components/plugins/card/index.tsx index d68c410a49..ef0c146512 100644 --- a/web/app/components/plugins/card/index.tsx +++ b/web/app/components/plugins/card/index.tsx @@ -1,4 +1,6 @@ +'use client' import React from 'react' +import { useContext } from 'use-context-selector' import { RiVerifiedBadgeLine } from '@remixicon/react' import type { Plugin } from '../types' import Icon from '../card/base/card-icon' @@ -8,18 +10,16 @@ import OrgInfo from './base/org-info' import Description from './base/description' import Placeholder from './base/placeholder' import cn from '@/utils/classnames' -import type { Locale } from '@/i18n' +import I18n from '@/context/i18n' type Props = { className?: string payload: Plugin - locale: Locale // The component is used in both client and server side, so we can't get the locale from both side(getLocaleOnServer and useContext) titleLeft?: React.ReactNode installed?: boolean hideCornerMark?: boolean descriptionLineRows?: number footer?: React.ReactNode - serverLocale?: Locale isLoading?: boolean loadingFileName?: string } @@ -32,10 +32,11 @@ const Card = ({ hideCornerMark, descriptionLineRows = 2, footer, - locale, isLoading = false, loadingFileName, }: Props) => { + const { locale } = useContext(I18n) + const { type, name, org, label, brief, icon } = payload const getLocalizedText = (obj: Record<string, string> | undefined) => @@ -80,4 +81,4 @@ const Card = ({ ) } -export default Card +export default React.memo(Card) diff --git a/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx b/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx index 87e470584e..6fd0feead9 100644 --- a/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx +++ b/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx @@ -69,7 +69,6 @@ const InstallFromLocalPackage: React.FC<InstallFromLocalPackageProps> = ({ onClo <div className='flex p-2 items-start content-start gap-1 self-stretch flex-wrap rounded-2xl bg-background-section-burn'> <Card className='w-full' - locale={locale} payload={status === 'uploading' ? { name: 'notion-sync' } as any : toolNotion as any} isLoading={status === 'uploading'} loadingFileName='notion-sync.difypkg' @@ -85,7 +84,7 @@ const InstallFromLocalPackage: React.FC<InstallFromLocalPackageProps> = ({ onClo : ( <> <Button variant='secondary' className='min-w-[72px]' onClick={onClose}> - Cancel + Cancel </Button> <Button variant='primary' diff --git a/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx b/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx index 96deec4da9..ddea0c346f 100644 --- a/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx +++ b/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx @@ -1,7 +1,6 @@ 'use client' import React, { useMemo, useState } from 'react' -import { useContext } from 'use-context-selector' import { RiInformation2Line } from '@remixicon/react' import Card from '../../card' import { extensionDallE, modelGPT4, toolNotion } from '../../card/card-mock' @@ -9,14 +8,12 @@ import Modal from '@/app/components/base/modal' import Button from '@/app/components/base/button' import Checkbox from '@/app/components/base/checkbox' import Badge, { BadgeState } from '@/app/components/base/badge/index' -import I18n from '@/context/i18n' type InstallFromMarketplaceProps = { onClose: () => void } const InstallFromMarketplace: React.FC<InstallFromMarketplaceProps> = ({ onClose }) => { - const { locale } = useContext(I18n) const plugins = useMemo(() => [toolNotion, extensionDallE, modelGPT4], []) const [selectedPlugins, setSelectedPlugins] = useState<Set<number>>(new Set()) const [isInstalling, setIsInstalling] = useState(false) @@ -40,7 +37,6 @@ const InstallFromMarketplace: React.FC<InstallFromMarketplaceProps> = ({ onClose key={index} installed={nextStep && !isInstalling} payload={plugin} - locale={locale} className='w-full' titleLeft={ plugin.version === plugin.latest_version @@ -115,7 +111,7 @@ const InstallFromMarketplace: React.FC<InstallFromMarketplaceProps> = ({ onClose : ( <> <Button variant='secondary' className='min-w-[72px]' onClick={onClose}> - Cancel + Cancel </Button> <Button variant='primary' @@ -126,7 +122,7 @@ const InstallFromMarketplace: React.FC<InstallFromMarketplaceProps> = ({ onClose mockInstall() }} > - Install + Install </Button> </> )} diff --git a/web/app/components/plugins/marketplace/list/index.tsx b/web/app/components/plugins/marketplace/list/index.tsx index fa5975bb5a..c3d7ff1d24 100644 --- a/web/app/components/plugins/marketplace/list/index.tsx +++ b/web/app/components/plugins/marketplace/list/index.tsx @@ -13,35 +13,30 @@ const List = () => { <div className='system-xs-regular text-text-tertiary'>Our top picks to get you started</div> <div className='grid grid-cols-4 gap-3 mt-2'> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> @@ -54,168 +49,144 @@ const List = () => { <div className='system-xs-regular text-text-tertiary'>Explore the library and discover the incredible work of our community</div> <div className='grid grid-cols-4 gap-3 mt-2'> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> diff --git a/web/app/components/plugins/plugin-item/index.tsx b/web/app/components/plugins/plugin-item/index.tsx index 452796c27b..08e4bf1419 100644 --- a/web/app/components/plugins/plugin-item/index.tsx +++ b/web/app/components/plugins/plugin-item/index.tsx @@ -1,6 +1,9 @@ +'use client' import type { FC } from 'react' import React from 'react' +import { useContext } from 'use-context-selector' import { RiArrowRightUpLine, RiLoginCircleLine, RiVerifiedBadgeLine } from '@remixicon/react' +import { useTranslation } from 'react-i18next' import { Github } from '../../base/icons/src/public/common' import Badge from '../../base/badge' import type { Plugin } from '../types' @@ -11,26 +14,21 @@ import OrgInfo from '../card/base/org-info' import Title from '../card/base/title' import Action from './action' import cn from '@/utils/classnames' -import type { Locale } from '@/i18n' +import I18n from '@/context/i18n' type Props = { className?: string payload: Plugin - locale: Locale onDelete: () => void - pluginI8n: any - isClient?: boolean } const PluginItem: FC<Props> = ({ className, payload, onDelete, - locale, - pluginI8n, - isClient, }) => { - const t = (key: string, param?: object) => pluginI8n(`${isClient ? 'plugin.' : ''}${key}`, param) + const { locale } = useContext(I18n) + const { t } = useTranslation() const { type, name, org, label } = payload const hasNewVersion = payload.latest_version !== payload.version @@ -74,12 +72,12 @@ const PluginItem: FC<Props> = ({ <div className='mx-2 text-text-quaternary system-xs-regular'>·</div> <div className='flex text-text-tertiary system-xs-regular space-x-1'> <RiLoginCircleLine className='w-4 h-4' /> - <span>{t('endpointsEnabled', { num: 2 })}</span> + <span>{t('plugin.endpointsEnabled', { num: 2 })}</span> </div> </div> <div className='flex items-center'> - <a href='' target='_blank' className='mr-1 text-text-tertiary system-2xs-medium-uppercase'>{t('from')}</a> + <a href='' target='_blank' className='mr-1 text-text-tertiary system-2xs-medium-uppercase'>{t('plugin.from')}</a> <div className='flex items-center space-x-0.5 text-text-secondary'> <Github className='ml-1 w-3 h-3' /> <div className='system-2xs-semibold-uppercase'>GitHub</div> @@ -91,4 +89,4 @@ const PluginItem: FC<Props> = ({ ) } -export default PluginItem +export default React.memo(PluginItem) diff --git a/web/app/components/plugins/provider-card.tsx b/web/app/components/plugins/provider-card.tsx index 2445c4b9ab..7d9f21ea43 100644 --- a/web/app/components/plugins/provider-card.tsx +++ b/web/app/components/plugins/provider-card.tsx @@ -1,4 +1,6 @@ +'use client' import React from 'react' +import { useContext } from 'use-context-selector' import type { FC } from 'react' import Link from 'next/link' import { RiArrowRightUpLine, RiVerifiedBadgeLine } from '@remixicon/react' @@ -9,22 +11,21 @@ import Icon from './card/base/card-icon' import Title from './card/base/title' import DownloadCount from './card/base/download-count' import Button from '@/app/components/base/button' -import type { Locale } from '@/i18n' import cn from '@/utils/classnames' +import I18n from '@/context/i18n' type Props = { className?: string - locale: Locale // The component is used in both client and server side, so we can't get the locale from both side(getLocaleOnServer and useContext) payload: Plugin installed?: boolean } const ProviderCard: FC<Props> = ({ className, - locale, payload, installed = true, }) => { + const { locale } = useContext(I18n) const { org, label } = payload return ( diff --git a/web/app/components/plugins/update-plugin/index.tsx b/web/app/components/plugins/update-plugin/index.tsx index d0abd21e0c..0a358debac 100644 --- a/web/app/components/plugins/update-plugin/index.tsx +++ b/web/app/components/plugins/update-plugin/index.tsx @@ -1,14 +1,12 @@ 'use client' import type { FC } from 'react' import React, { useCallback, useMemo, useState } from 'react' -import { useContext } from 'use-context-selector' import { RiInformation2Line } from '@remixicon/react' import { useTranslation } from 'react-i18next' import Card from '@/app/components/plugins/card' import Modal from '@/app/components/base/modal' import Button from '@/app/components/base/button' import Badge, { BadgeState } from '@/app/components/base/badge/index' -import I18n from '@/context/i18n' import { toolNotion } from '@/app/components/plugins/card/card-mock' const i18nPrefix = 'plugin.upgrade' @@ -26,7 +24,6 @@ enum UploadStep { const UpdatePluginModal: FC<Props> = ({ onHide, }) => { - const { locale } = useContext(I18n) const { t } = useTranslation() const [uploadStep, setUploadStep] = useState<UploadStep>(UploadStep.notStarted) const configBtnText = useMemo(() => { @@ -62,7 +59,6 @@ const UpdatePluginModal: FC<Props> = ({ <Card installed={uploadStep === UploadStep.installed} payload={toolNotion as any} - locale={locale} className='w-full' titleLeft={ <> diff --git a/web/app/components/tools/marketplace.tsx b/web/app/components/tools/marketplace.tsx index 56f85d447d..9608f4ac69 100644 --- a/web/app/components/tools/marketplace.tsx +++ b/web/app/components/tools/marketplace.tsx @@ -45,35 +45,30 @@ const Marketplace = ({ <div className='system-xs-regular text-text-tertiary'>Our top picks to get you started</div> <div className='grid grid-cols-4 gap-3 mt-2'> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> @@ -86,168 +81,144 @@ const Marketplace = ({ <div className='system-xs-regular text-text-tertiary'>Explore the library and discover the incredible work of our community</div> <div className='grid grid-cols-4 gap-3 mt-2'> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> } /> <Card - locale={locale} payload={toolNotion as any} footer={ <CardMoreInfo downloadCount={1234} tags={['Search', 'Productivity']} /> diff --git a/web/app/components/tools/provider-list.tsx b/web/app/components/tools/provider-list.tsx index e0ee954e62..6f8fbc76bf 100644 --- a/web/app/components/tools/provider-list.tsx +++ b/web/app/components/tools/provider-list.tsx @@ -112,7 +112,6 @@ const ProviderList = () => { currentProvider?.id === collection.id && 'border-components-option-card-option-selected-border', )} hideCornerMark - locale={language} payload={{ ...collection, brief: collection.description, From 28f7bbf83af24b847f6fe0e91f75db82e1da746b Mon Sep 17 00:00:00 2001 From: Yi <yxiaoisme@gmail.com> Date: Thu, 17 Oct 2024 15:21:56 +0800 Subject: [PATCH 086/346] chore: installation progress bar --- .../components/plugins/plugin-page/index.tsx | 19 ++++++++++++ .../plugins/plugin-page/list/index.tsx | 30 +++++++++++++++++++ .../plugins/plugin-page/plugins-panel.tsx | 6 ++-- 3 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 web/app/components/plugins/plugin-page/list/index.tsx diff --git a/web/app/components/plugins/plugin-page/index.tsx b/web/app/components/plugins/plugin-page/index.tsx index 962388babc..66c2cd1318 100644 --- a/web/app/components/plugins/plugin-page/index.tsx +++ b/web/app/components/plugins/plugin-page/index.tsx @@ -5,6 +5,7 @@ import { useTranslation } from 'react-i18next' import { RiDragDropLine, RiEqualizer2Line, + RiInstallFill, } from '@remixicon/react' import { useBoolean } from 'ahooks' import InstallFromLocalPackage from '../install-plugin/install-from-local-package' @@ -47,6 +48,8 @@ const PluginPage = ({ const [currentFile, setCurrentFile] = useState<File | null>(null) const containerRef = usePluginPageContext(v => v.containerRef) const { enable_marketplace } = useAppContextSelector(s => s.systemFeatures) + const [installed, total] = [2, 3] // Replace this with the actual progress + const progressPercentage = (installed / total) * 100 const options = useMemo(() => { return [ { value: 'plugins', text: t('common.menus.plugins') }, @@ -91,6 +94,22 @@ const PluginPage = ({ /> </div> <div className='flex flex-shrink-0 items-center gap-1'> + <div className='relative'> + <Button + className='relative overflow-hidden border !border-[rgba(178,202,255,1)] !bg-[rgba(255,255,255,0.95)] cursor-default' + > + <div + className='absolute left-0 top-0 h-full bg-state-accent-active' + style={{ width: `${progressPercentage}%` }} + ></div> + <div className='relative z-10 flex items-center'> + <RiInstallFill className='w-4 h-4 text-text-accent' /> + <div className='flex px-0.5 justify-center items-center gap-1'> + <span className='text-text-accent system-sm-medium'>{activeTab === 'plugins' ? `Installing ${installed}/${total} plugins` : `${installed}/${total}`}</span> + </div> + </div> + </Button> + </div> {canManagement && ( <InstallPluginDropdown /> )} diff --git a/web/app/components/plugins/plugin-page/list/index.tsx b/web/app/components/plugins/plugin-page/list/index.tsx new file mode 100644 index 0000000000..92b2a06805 --- /dev/null +++ b/web/app/components/plugins/plugin-page/list/index.tsx @@ -0,0 +1,30 @@ +import { useTranslation } from 'react-i18next' +import { useContext } from 'use-context-selector' +import PluginItem from '../../plugin-item' +import { customTool, extensionDallE, modelGPT4, toolNotion } from '@/app/components/plugins/card/card-mock' +import I18n from '@/context/i18n' + +const PluginList = () => { + const { locale } = useContext(I18n) + const { t } = useTranslation() + const pluginList = [toolNotion, extensionDallE, modelGPT4, customTool] + + return ( + <div className='pb-3 bg-white'> + <div> + <div className='grid grid-cols-2 gap-3'> + {pluginList.map((plugin, index) => ( + <PluginItem + key={index} + payload={plugin as any} + onDelete={() => {}} + pluginI8n={t} + locale={locale} + /> + ))} + </div> + </div> + </div> + ) +} +export default PluginList diff --git a/web/app/components/plugins/plugin-page/plugins-panel.tsx b/web/app/components/plugins/plugin-page/plugins-panel.tsx index 4d4090f973..81385bcb57 100644 --- a/web/app/components/plugins/plugin-page/plugins-panel.tsx +++ b/web/app/components/plugins/plugin-page/plugins-panel.tsx @@ -1,16 +1,18 @@ 'use client' +import List from './list' + const PluginsPanel = () => { return ( <> <div className='flex flex-col pt-1 pb-3 px-12 justify-center items-start gap-3 self-stretch'> <div className='h-px self-stretch bg-divider-subtle'></div> <div className='flex items-center gap-2 self-stretch'> - {/* Filter goes here */} + {/* Filters go here */} </div> </div> <div className='flex px-12 items-start content-start gap-2 flex-grow self-stretch flex-wrap'> - {/* Plugin cards go here */} + <List /> </div> </> ) From 425f624de589e9d6ae389a360ebc24c8065725d4 Mon Sep 17 00:00:00 2001 From: Yi <yxiaoisme@gmail.com> Date: Fri, 18 Oct 2024 14:02:40 +0800 Subject: [PATCH 087/346] chore: add plugin panel --- .../marketplace/search-box/tags-filter.tsx | 2 +- .../components/plugins/plugin-item/index.tsx | 52 +++++-- .../filter-management/category-filter.tsx | 136 ++++++++++++++++++ .../plugin-page/filter-management/constant.ts | 11 ++ .../plugin-page/filter-management/index.tsx | 47 ++++++ .../filter-management/search-box.tsx | 26 ++++ .../plugin-page/filter-management/store.ts | 27 ++++ .../filter-management/tag-filter.tsx | 128 +++++++++++++++++ .../plugins/plugin-page/list/index.tsx | 8 +- .../plugins/plugin-page/plugins-panel.tsx | 16 ++- 10 files changed, 433 insertions(+), 20 deletions(-) create mode 100644 web/app/components/plugins/plugin-page/filter-management/category-filter.tsx create mode 100644 web/app/components/plugins/plugin-page/filter-management/constant.ts create mode 100644 web/app/components/plugins/plugin-page/filter-management/index.tsx create mode 100644 web/app/components/plugins/plugin-page/filter-management/search-box.tsx create mode 100644 web/app/components/plugins/plugin-page/filter-management/store.ts create mode 100644 web/app/components/plugins/plugin-page/filter-management/tag-filter.tsx diff --git a/web/app/components/plugins/marketplace/search-box/tags-filter.tsx b/web/app/components/plugins/marketplace/search-box/tags-filter.tsx index 323c4be1ab..30337567b3 100644 --- a/web/app/components/plugins/marketplace/search-box/tags-filter.tsx +++ b/web/app/components/plugins/marketplace/search-box/tags-filter.tsx @@ -111,11 +111,11 @@ const TagsFilter = ({ <div key={option.value} className='flex items-center px-2 py-1.5 h-7 rounded-lg cursor-pointer hover:bg-state-base-hover' + onClick={() => handleCheck(option.value)} > <Checkbox className='mr-1' checked={value.includes(option.value)} - onCheck={() => handleCheck(option.value)} /> <div className='px-1 system-sm-medium text-text-secondary'> {option.text} diff --git a/web/app/components/plugins/plugin-item/index.tsx b/web/app/components/plugins/plugin-item/index.tsx index 08e4bf1419..739b5a6ebc 100644 --- a/web/app/components/plugins/plugin-item/index.tsx +++ b/web/app/components/plugins/plugin-item/index.tsx @@ -2,7 +2,7 @@ import type { FC } from 'react' import React from 'react' import { useContext } from 'use-context-selector' -import { RiArrowRightUpLine, RiLoginCircleLine, RiVerifiedBadgeLine } from '@remixicon/react' +import { RiArrowRightUpLine, RiBugLine, RiHardDrive3Line, RiLoginCircleLine, RiVerifiedBadgeLine } from '@remixicon/react' import { useTranslation } from 'react-i18next' import { Github } from '../../base/icons/src/public/common' import Badge from '../../base/badge' @@ -19,12 +19,14 @@ import I18n from '@/context/i18n' type Props = { className?: string payload: Plugin + source: 'github' | 'marketplace' | 'local' | 'debug' onDelete: () => void } const PluginItem: FC<Props> = ({ className, payload, + source, onDelete, }) => { const { locale } = useContext(I18n) @@ -34,7 +36,11 @@ const PluginItem: FC<Props> = ({ const hasNewVersion = payload.latest_version !== payload.version return ( - <div className='p-1 bg-background-section-burn rounded-xl'> + <div className={`p-1 ${source === 'debug' + ? 'bg-[repeating-linear-gradient(-45deg,rgba(16,24,40,0.04),rgba(16,24,40,0.04)_5px,rgba(0,0,0,0.02)_5px,rgba(0,0,0,0.02)_10px)]' + : 'bg-background-section-burn'} + rounded-xl`} + > <div className={cn('relative p-4 pb-3 border-[0.5px] border-components-panel-border bg-components-panel-on-panel-item-bg hover-bg-components-panel-on-panel-item-bg rounded-xl shadow-xs', className)}> <CornerMark text={type} /> {/* Header */} @@ -77,12 +83,42 @@ const PluginItem: FC<Props> = ({ </div> <div className='flex items-center'> - <a href='' target='_blank' className='mr-1 text-text-tertiary system-2xs-medium-uppercase'>{t('plugin.from')}</a> - <div className='flex items-center space-x-0.5 text-text-secondary'> - <Github className='ml-1 w-3 h-3' /> - <div className='system-2xs-semibold-uppercase'>GitHub</div> - <RiArrowRightUpLine className='w-3 h-3' /> - </div> + {source === 'github' + && <> + <a href='' target='_blank' className='flex items-center gap-1'> + <div className='text-text-tertiary system-2xs-medium-uppercase'>{t('plugin.from')}</div> + <div className='flex items-center space-x-0.5 text-text-secondary'> + <Github className='w-3 h-3' /> + <div className='system-2xs-semibold-uppercase'>GitHub</div> + <RiArrowRightUpLine className='w-3 h-3' /> + </div> + </a> + </> + } + {source === 'marketplace' + && <> + <a href='' target='_blank' className='flex items-center gap-0.5'> + <div className='text-text-tertiary system-2xs-medium-uppercase'>{t('plugin.from')} <span className='text-text-secondary'>marketplace</span></div> + <RiArrowRightUpLine className='w-3 h-3' /> + </a> + </> + } + {source === 'local' + && <> + <div className='flex items-center gap-1'> + <RiHardDrive3Line className='text-text-tertiary w-3 h-3' /> + <div className='text-text-tertiary system-2xs-medium-uppercase'>Local Plugin</div> + </div> + </> + } + {source === 'debug' + && <> + <div className='flex items-center gap-1'> + <RiBugLine className='w-3 h-3 text-text-warning' /> + <div className='text-text-warning system-2xs-medium-uppercase'>Debugging Plugin</div> + </div> + </> + } </div> </div> </div> diff --git a/web/app/components/plugins/plugin-page/filter-management/category-filter.tsx b/web/app/components/plugins/plugin-page/filter-management/category-filter.tsx new file mode 100644 index 0000000000..b7a60a7e43 --- /dev/null +++ b/web/app/components/plugins/plugin-page/filter-management/category-filter.tsx @@ -0,0 +1,136 @@ +'use client' + +import { useState } from 'react' +import { + RiArrowDownSLine, + RiCloseCircleFill, +} from '@remixicon/react' +import { + PortalToFollowElem, + PortalToFollowElemContent, + PortalToFollowElemTrigger, +} from '@/app/components/base/portal-to-follow-elem' +import Checkbox from '@/app/components/base/checkbox' +import cn from '@/utils/classnames' +import Input from '@/app/components/base/input' + +type CategoriesFilterProps = { + value: string[] + onChange: (categories: string[]) => void +} +const CategoriesFilter = ({ + value, + onChange, +}: CategoriesFilterProps) => { + const [open, setOpen] = useState(false) + const [searchText, setSearchText] = useState('') + const options = [ + { + value: 'model', + text: 'Model', + }, + { + value: 'tool', + text: 'Tool', + }, + { + value: 'extension', + text: 'Extension', + }, + { + value: 'bundle', + text: 'Bundle', + }, + ] + const filteredOptions = options.filter(option => option.text.toLowerCase().includes(searchText.toLowerCase())) + const handleCheck = (id: string) => { + if (value.includes(id)) + onChange(value.filter(tag => tag !== id)) + else + onChange([...value, id]) + } + const selectedTagsLength = value.length + + return ( + <PortalToFollowElem + placement='bottom-start' + offset={{ + mainAxis: 4, + }} + open={open} + onOpenChange={setOpen} + > + <PortalToFollowElemTrigger onClick={() => setOpen(v => !v)}> + <div className={cn( + 'flex items-center px-2 py-1 h-8 text-text-tertiary rounded-lg bg-components-input-bg-normal hover:bg-state-base-hover-alt cursor-pointer', + selectedTagsLength && 'text-text-secondary', + open && 'bg-state-base-hover', + )}> + <div className={cn( + 'flex items-center p-1 system-sm-medium', + )}> + { + !selectedTagsLength && 'All Categories' + } + { + !!selectedTagsLength && value.slice(0, 2).join(',') + } + { + selectedTagsLength > 2 && ( + <div className='ml-1 system-xs-medium text-text-tertiary'> + +{selectedTagsLength - 2} + </div> + ) + } + </div> + { + !!selectedTagsLength && ( + <RiCloseCircleFill + className='w-4 h-4 text-text-quaternary cursor-pointer' + onClick={() => onChange([])} + /> + ) + } + { + !selectedTagsLength && ( + <RiArrowDownSLine className='w-4 h-4' /> + ) + } + </div> + </PortalToFollowElemTrigger> + <PortalToFollowElemContent className='z-10'> + <div className='w-[240px] border-[0.5px] border-components-panel-border bg-components-panel-bg-blur rounded-xl shadow-lg'> + <div className='p-2 pb-1'> + <Input + showLeftIcon + value={searchText} + onChange={e => setSearchText(e.target.value)} + placeholder='Search categories' + /> + </div> + <div className='p-1 max-h-[448px] overflow-y-auto'> + { + filteredOptions.map(option => ( + <div + key={option.value} + className='flex items-center px-2 py-1.5 h-7 rounded-lg cursor-pointer hover:bg-state-base-hover' + onClick={() => handleCheck(option.value)} + > + <Checkbox + className='mr-1' + checked={value.includes(option.value)} + /> + <div className='px-1 system-sm-medium text-text-secondary'> + {option.text} + </div> + </div> + )) + } + </div> + </div> + </PortalToFollowElemContent> + </PortalToFollowElem> + ) +} + +export default CategoriesFilter diff --git a/web/app/components/plugins/plugin-page/filter-management/constant.ts b/web/app/components/plugins/plugin-page/filter-management/constant.ts new file mode 100644 index 0000000000..80f786230c --- /dev/null +++ b/web/app/components/plugins/plugin-page/filter-management/constant.ts @@ -0,0 +1,11 @@ +export type Tag = { + id: string + name: string + type: string + binding_count: number +} + +export type Category = { + name: 'model' | 'tool' | 'extension' | 'bundle' + binding_count: number +} diff --git a/web/app/components/plugins/plugin-page/filter-management/index.tsx b/web/app/components/plugins/plugin-page/filter-management/index.tsx new file mode 100644 index 0000000000..1b09f4875e --- /dev/null +++ b/web/app/components/plugins/plugin-page/filter-management/index.tsx @@ -0,0 +1,47 @@ +import React, { useState } from 'react' +import CategoriesFilter from './category-filter' +import TagFilter from './tag-filter' +import SearchBox from './search-box' + +export type FilterState = { + categories: string[] + tags: string[] + searchQuery: string +} + +type FilterManagementProps = { + onFilterChange: (filters: FilterState) => void +} + +const FilterManagement: React.FC<FilterManagementProps> = ({ onFilterChange }) => { + const [filters, setFilters] = useState<FilterState>({ + categories: [], + tags: [], + searchQuery: '', + }) + + const updateFilters = (newFilters: Partial<FilterState>) => { + const updatedFilters = { ...filters, ...newFilters } + setFilters(updatedFilters) + onFilterChange(updatedFilters) + } + + return ( + <div className='flex items-center gap-2 self-stretch'> + <CategoriesFilter + value={filters.categories} + onChange={categories => updateFilters({ categories })} + /> + <TagFilter + value={filters.tags} + onChange={tags => updateFilters({ tags })} + /> + <SearchBox + searchQuery={filters.searchQuery} + onChange={searchQuery => updateFilters({ searchQuery })} + /> + </div> + ) +} + +export default FilterManagement diff --git a/web/app/components/plugins/plugin-page/filter-management/search-box.tsx b/web/app/components/plugins/plugin-page/filter-management/search-box.tsx new file mode 100644 index 0000000000..fa158aadf0 --- /dev/null +++ b/web/app/components/plugins/plugin-page/filter-management/search-box.tsx @@ -0,0 +1,26 @@ +'use client' + +import Input from '@/app/components/base/input' +type SearchBoxProps = { + searchQuery: string + onChange: (query: string) => void +} + +const SearchBox: React.FC<SearchBoxProps> = ({ + searchQuery, + onChange, +}) => { + return ( + <Input + wrapperClassName='flex w-[200px] items-center rounded-lg bg-components-input-bg-normal' + showLeftIcon + value={searchQuery} + placeholder='Search' + onChange={(e) => { + onChange(e.target.value) + }} + /> + ) +} + +export default SearchBox diff --git a/web/app/components/plugins/plugin-page/filter-management/store.ts b/web/app/components/plugins/plugin-page/filter-management/store.ts new file mode 100644 index 0000000000..4b55bf2681 --- /dev/null +++ b/web/app/components/plugins/plugin-page/filter-management/store.ts @@ -0,0 +1,27 @@ +import { create } from 'zustand' +import type { Category, Tag } from './constant' + +type State = { + tagList: Tag[] + categoryList: Category[] + showTagManagementModal: boolean + showCategoryManagementModal: boolean +} + +type Action = { + setTagList: (tagList?: Tag[]) => void + setCategoryList: (categoryList?: Category[]) => void + setShowTagManagementModal: (showTagManagementModal: boolean) => void + setShowCategoryManagementModal: (showCategoryManagementModal: boolean) => void +} + +export const useStore = create<State & Action>(set => ({ + tagList: [], + categoryList: [], + setTagList: tagList => set(() => ({ tagList })), + setCategoryList: categoryList => set(() => ({ categoryList })), + showTagManagementModal: false, + showCategoryManagementModal: false, + setShowTagManagementModal: showTagManagementModal => set(() => ({ showTagManagementModal })), + setShowCategoryManagementModal: showCategoryManagementModal => set(() => ({ showCategoryManagementModal })), +})) diff --git a/web/app/components/plugins/plugin-page/filter-management/tag-filter.tsx b/web/app/components/plugins/plugin-page/filter-management/tag-filter.tsx new file mode 100644 index 0000000000..d337f17495 --- /dev/null +++ b/web/app/components/plugins/plugin-page/filter-management/tag-filter.tsx @@ -0,0 +1,128 @@ +'use client' + +import { useState } from 'react' +import { + RiArrowDownSLine, + RiCloseCircleFill, +} from '@remixicon/react' +import { + PortalToFollowElem, + PortalToFollowElemContent, + PortalToFollowElemTrigger, +} from '@/app/components/base/portal-to-follow-elem' +import Checkbox from '@/app/components/base/checkbox' +import cn from '@/utils/classnames' +import Input from '@/app/components/base/input' + +type TagsFilterProps = { + value: string[] + onChange: (tags: string[]) => void +} +const TagsFilter = ({ + value, + onChange, +}: TagsFilterProps) => { + const [open, setOpen] = useState(false) + const [searchText, setSearchText] = useState('') + const options = [ + { + value: 'search', + text: 'Search', + }, + { + value: 'image', + text: 'Image', + }, + ] + const filteredOptions = options.filter(option => option.text.toLowerCase().includes(searchText.toLowerCase())) + const handleCheck = (id: string) => { + if (value.includes(id)) + onChange(value.filter(tag => tag !== id)) + else + onChange([...value, id]) + } + const selectedTagsLength = value.length + + return ( + <PortalToFollowElem + placement='bottom-start' + offset={{ + mainAxis: 4, + }} + open={open} + onOpenChange={setOpen} + > + <PortalToFollowElemTrigger onClick={() => setOpen(v => !v)}> + <div className={cn( + 'flex items-center px-2 py-1 h-8 text-text-tertiary rounded-lg bg-components-input-bg-normal hover:bg-state-base-hover-alt cursor-pointer', + selectedTagsLength && 'text-text-secondary', + open && 'bg-state-base-hover', + )}> + <div className={cn( + 'flex items-center p-1 system-sm-medium', + )}> + { + !selectedTagsLength && 'All Tags' + } + { + !!selectedTagsLength && value.slice(0, 2).join(',') + } + { + selectedTagsLength > 2 && ( + <div className='ml-1 system-xs-medium text-text-tertiary'> + +{selectedTagsLength - 2} + </div> + ) + } + </div> + { + !!selectedTagsLength && ( + <RiCloseCircleFill + className='w-4 h-4 text-text-quaternary cursor-pointer' + onClick={() => onChange([])} + /> + ) + } + { + !selectedTagsLength && ( + <RiArrowDownSLine className='w-4 h-4' /> + ) + } + </div> + </PortalToFollowElemTrigger> + <PortalToFollowElemContent className='z-10'> + <div className='w-[240px] border-[0.5px] border-components-panel-border bg-components-panel-bg-blur rounded-xl shadow-lg'> + <div className='p-2 pb-1'> + <Input + showLeftIcon + value={searchText} + onChange={e => setSearchText(e.target.value)} + placeholder='Search tags' + /> + </div> + <div className='p-1 max-h-[448px] overflow-y-auto'> + { + filteredOptions.map(option => ( + <div + key={option.value} + className='flex items-center px-2 py-1.5 h-7 rounded-lg cursor-pointer hover:bg-state-base-hover' + onClick={() => handleCheck(option.value)} + > + <Checkbox + className='mr-1' + checked={value.includes(option.value)} + /> + <div className='px-1 system-sm-medium text-text-secondary'> + {option.text} + </div> + </div> + )) + } + </div> + </div> + </PortalToFollowElemContent> + </PortalToFollowElem> + ) +} + +export default TagsFilter diff --git a/web/app/components/plugins/plugin-page/list/index.tsx b/web/app/components/plugins/plugin-page/list/index.tsx index 92b2a06805..0939c36ca7 100644 --- a/web/app/components/plugins/plugin-page/list/index.tsx +++ b/web/app/components/plugins/plugin-page/list/index.tsx @@ -1,12 +1,7 @@ -import { useTranslation } from 'react-i18next' -import { useContext } from 'use-context-selector' import PluginItem from '../../plugin-item' import { customTool, extensionDallE, modelGPT4, toolNotion } from '@/app/components/plugins/card/card-mock' -import I18n from '@/context/i18n' const PluginList = () => { - const { locale } = useContext(I18n) - const { t } = useTranslation() const pluginList = [toolNotion, extensionDallE, modelGPT4, customTool] return ( @@ -18,8 +13,7 @@ const PluginList = () => { key={index} payload={plugin as any} onDelete={() => {}} - pluginI8n={t} - locale={locale} + source={'debug'} /> ))} </div> diff --git a/web/app/components/plugins/plugin-page/plugins-panel.tsx b/web/app/components/plugins/plugin-page/plugins-panel.tsx index 81385bcb57..da36e6c424 100644 --- a/web/app/components/plugins/plugin-page/plugins-panel.tsx +++ b/web/app/components/plugins/plugin-page/plugins-panel.tsx @@ -1,18 +1,26 @@ 'use client' +import type { FilterState } from './filter-management' +import FilterManagement from './filter-management' import List from './list' const PluginsPanel = () => { + const handleFilterChange = (filters: FilterState) => { + // + } + return ( <> <div className='flex flex-col pt-1 pb-3 px-12 justify-center items-start gap-3 self-stretch'> <div className='h-px self-stretch bg-divider-subtle'></div> - <div className='flex items-center gap-2 self-stretch'> - {/* Filters go here */} - </div> + <FilterManagement + onFilterChange={handleFilterChange} + /> </div> <div className='flex px-12 items-start content-start gap-2 flex-grow self-stretch flex-wrap'> - <List /> + <div className='w-full'> + <List /> + </div> </div> </> ) From 0f60fe7f2ac8bde4eec3b4ebc56bcdcf24bdd148 Mon Sep 17 00:00:00 2001 From: Yi <yxiaoisme@gmail.com> Date: Fri, 18 Oct 2024 14:17:53 +0800 Subject: [PATCH 088/346] chore: update workspace name (truncated for long name) --- .../header/account-dropdown/workplace-selector/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/app/components/header/account-dropdown/workplace-selector/index.tsx b/web/app/components/header/account-dropdown/workplace-selector/index.tsx index b32cb13227..4d21ccdb59 100644 --- a/web/app/components/header/account-dropdown/workplace-selector/index.tsx +++ b/web/app/components/header/account-dropdown/workplace-selector/index.tsx @@ -41,7 +41,7 @@ const WorkplaceSelector = () => { `, )}> <div className='flex items-center justify-center w-7 h-7 bg-[#EFF4FF] rounded-md text-xs font-medium text-primary-600'>{currentWorkspace?.name[0].toLocaleUpperCase()}</div> - <div className={'truncate max-w-[80px] line-clamp-1 overflow-hidden text-text-secondary text-ellipsis system-sm-medium'}>{currentWorkspace?.name}</div> + <div className={'truncate max-w-[80px] text-text-secondary system-sm-medium'}>{currentWorkspace?.name}</div> <RiArrowDownSLine className='w-4 h-4 text-text-secondary' /> </Menu.Button> <Transition From bdb81fe20dafa7d5c9aa7c0e22862ccac7f5919e Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Fri, 18 Oct 2024 18:18:42 +0800 Subject: [PATCH 089/346] feat: choose tool sticky --- .../workflow/block-selector/all-tools.tsx | 25 ++++++++--- .../market-place-plugin/list.tsx | 44 +++++++++++++----- .../workflow/block-selector/tools.tsx | 2 +- .../block-selector/use-sticky-scroll.ts | 45 +++++++++++++++++++ 4 files changed, 98 insertions(+), 18 deletions(-) create mode 100644 web/app/components/workflow/block-selector/use-sticky-scroll.ts diff --git a/web/app/components/workflow/block-selector/all-tools.tsx b/web/app/components/workflow/block-selector/all-tools.tsx index 2f75f90fc3..a9a316b272 100644 --- a/web/app/components/workflow/block-selector/all-tools.tsx +++ b/web/app/components/workflow/block-selector/all-tools.tsx @@ -1,5 +1,6 @@ import { useMemo, + useRef, useState, } from 'react' import type { @@ -51,6 +52,10 @@ const AllTools = ({ }) }) }, [activeTab, buildInTools, customTools, workflowTools, searchText, language]) + + const pluginRef = useRef(null) + const wrapElemRef = useRef<HTMLDivElement>(null) + return ( <div> <div className='flex items-center justify-between px-3 bg-background-default-hover border-b-[0.5px] border-black/[0.08] shadow-xs'> @@ -73,13 +78,19 @@ const AllTools = ({ </div> <ViewTypeSelect viewType={activeView} onChange={setActiveView} /> </div> - <PluginList list={[toolNotion, extensionDallE, modelGPT4] as any} /> - <Tools - showWorkflowEmpty={activeTab === ToolTypeEnum.Workflow} - tools={tools} - onSelect={onSelect} - viewType={activeView} - /> + <div + ref={wrapElemRef} + className='max-h-[464px] overflow-y-auto' + onScroll={(pluginRef.current as any)?.handleScroll} + > + <Tools + showWorkflowEmpty={activeTab === ToolTypeEnum.Workflow} + tools={tools} + onSelect={onSelect} + viewType={activeView} + /> + <PluginList wrapElemRef={wrapElemRef} list={[toolNotion, extensionDallE, modelGPT4] as any} ref={pluginRef} /> + </div> </div> ) } diff --git a/web/app/components/workflow/block-selector/market-place-plugin/list.tsx b/web/app/components/workflow/block-selector/market-place-plugin/list.tsx index 33c00081c6..906f31657c 100644 --- a/web/app/components/workflow/block-selector/market-place-plugin/list.tsx +++ b/web/app/components/workflow/block-selector/market-place-plugin/list.tsx @@ -1,26 +1,50 @@ 'use client' -import type { FC } from 'react' -import React from 'react' +import React, { forwardRef, useImperativeHandle, useMemo, useRef } from 'react' import { useTranslation } from 'react-i18next' +import useStickyScroll, { ScrollPosition } from '../use-sticky-scroll' import Item from './item' import type { Plugin } from '@/app/components/plugins/types.ts' +import cn from '@/utils/classnames' type Props = { + wrapElemRef: React.RefObject<HTMLElement> list: Plugin[] - // onInstall: () => } -const List: FC<Props> = ({ +const List = ({ + wrapElemRef, list, -}) => { +}: Props, ref: any) => { const { t } = useTranslation() + const nextToStickyELemRef = useRef<HTMLDivElement>(null) + + const { handleScroll, scrollPosition } = useStickyScroll({ + wrapElemRef, + nextToStickyELemRef, + }) + + const stickyClassName = useMemo(() => { + switch (scrollPosition) { + case ScrollPosition.aboveTheWrap: + return 'top-0 shadow-md bg-white' + case ScrollPosition.showing: + return 'bottom-0' + case ScrollPosition.belowTheWrap: + return 'bottom-0 border-t border-gray-500 bg-white text-blue-500' + } + }, [scrollPosition]) + + useImperativeHandle(ref, () => ({ + handleScroll, + })) return ( - <div> - <div className='pt-3 px-4 py-1 text-text-primary system-sm-medium'> + <> + <div + className={cn('sticky z-10 pt-3 px-4 py-1 text-text-primary system-sm-medium', stickyClassName)}> {t('plugin.fromMarketplace')} </div> - <div className='p-1'> + <div className='p-1 pb-[500px]' ref={nextToStickyELemRef}> {list.map((item, index) => ( <Item key={index} @@ -29,7 +53,7 @@ const List: FC<Props> = ({ /> ))} </div> - </div> + </> ) } -export default React.memo(List) +export default forwardRef(List) diff --git a/web/app/components/workflow/block-selector/tools.tsx b/web/app/components/workflow/block-selector/tools.tsx index 43f44bf882..326ad1fde6 100644 --- a/web/app/components/workflow/block-selector/tools.tsx +++ b/web/app/components/workflow/block-selector/tools.tsx @@ -75,7 +75,7 @@ const Blocks = ({ } return ( - <div className='p-1 max-w-[320px] max-h-[464px] overflow-y-auto'> + <div className='p-1 max-w-[320px]'> { !tools.length && !showWorkflowEmpty && ( <div className='flex items-center px-3 h-[22px] text-xs font-medium text-gray-500'>{t('workflow.tabs.noResult')}</div> diff --git a/web/app/components/workflow/block-selector/use-sticky-scroll.ts b/web/app/components/workflow/block-selector/use-sticky-scroll.ts new file mode 100644 index 0000000000..405ecdba7e --- /dev/null +++ b/web/app/components/workflow/block-selector/use-sticky-scroll.ts @@ -0,0 +1,45 @@ +import React from 'react' +import { useThrottleFn } from 'ahooks' + +export enum ScrollPosition { + belowTheWrap = 'belowTheWrap', + showing = 'showing', + aboveTheWrap = 'aboveTheWrap', +} + +type Params = { + wrapElemRef: React.RefObject<HTMLElement> + nextToStickyELemRef: React.RefObject<HTMLElement> +} +const useStickyScroll = ({ + wrapElemRef, + nextToStickyELemRef, +}: Params) => { + const [scrollPosition, setScrollPosition] = React.useState<ScrollPosition>(ScrollPosition.belowTheWrap) + const { run: handleScroll } = useThrottleFn(() => { + const wrapDom = wrapElemRef.current + const stickyDOM = nextToStickyELemRef.current + if (!wrapDom || !stickyDOM) + return + const { height: wrapHeight, top: wrapTop } = wrapDom.getBoundingClientRect() + const { top: nextToStickyTop } = stickyDOM.getBoundingClientRect() + let scrollPositionNew = ScrollPosition.belowTheWrap + + if (nextToStickyTop - wrapTop >= wrapHeight) + scrollPositionNew = ScrollPosition.belowTheWrap + else if (nextToStickyTop <= wrapTop) + scrollPositionNew = ScrollPosition.aboveTheWrap + else + scrollPositionNew = ScrollPosition.showing + + if (scrollPosition !== scrollPositionNew) + setScrollPosition(scrollPositionNew) + }, { wait: 100 }) + + return { + handleScroll, + scrollPosition, + } +} + +export default useStickyScroll From 2eab8fcc3313882fa34d7bb3b5bf0eef2d2f5839 Mon Sep 17 00:00:00 2001 From: AkaraChen <akarachen@outlook.com> Date: Mon, 21 Oct 2024 09:39:41 +0800 Subject: [PATCH 090/346] build: switch to pnpm --- .devcontainer/post_create_command.sh | 7 +- .../translate-i18n-base-on-english.yml | 2 +- .gitignore | 5 +- web/.gitignore | 9 +- web/.husky/pre-commit | 2 +- web/README.md | 18 +- web/package.json | 3 +- web/pnpm-lock.yaml | 17061 ++++++++++++++++ web/yarn.lock | 14208 ------------- 9 files changed, 17084 insertions(+), 14231 deletions(-) create mode 100644 web/pnpm-lock.yaml delete mode 100644 web/yarn.lock diff --git a/.devcontainer/post_create_command.sh b/.devcontainer/post_create_command.sh index b0322dd2b2..79796393a2 100755 --- a/.devcontainer/post_create_command.sh +++ b/.devcontainer/post_create_command.sh @@ -1,11 +1,12 @@ #!/bin/bash -cd web && npm install +npm add -g pnpm@9.12.2 +cd web && pnpm install pipx install poetry echo 'alias start-api="cd /workspaces/dify/api && poetry run python -m flask run --host 0.0.0.0 --port=5001 --debug"' >> ~/.bashrc echo 'alias start-worker="cd /workspaces/dify/api && poetry run python -m celery -A app.celery worker -P gevent -c 1 --loglevel INFO -Q dataset,generation,mail,ops_trace,app_deletion"' >> ~/.bashrc -echo 'alias start-web="cd /workspaces/dify/web && npm run dev"' >> ~/.bashrc +echo 'alias start-web="cd /workspaces/dify/web && pnpm dev"' >> ~/.bashrc echo 'alias start-containers="cd /workspaces/dify/docker && docker-compose -f docker-compose.middleware.yaml -p dify up -d"' >> ~/.bashrc -source /home/vscode/.bashrc \ No newline at end of file +source /home/vscode/.bashrc diff --git a/.github/workflows/translate-i18n-base-on-english.yml b/.github/workflows/translate-i18n-base-on-english.yml index 3f51b3b2c7..c5183bceec 100644 --- a/.github/workflows/translate-i18n-base-on-english.yml +++ b/.github/workflows/translate-i18n-base-on-english.yml @@ -42,7 +42,7 @@ jobs: - name: Run npm script if: env.FILES_CHANGED == 'true' - run: npm run auto-gen-i18n + run: pnpm run auto-gen-i18n - name: Create Pull Request if: env.FILES_CHANGED == 'true' diff --git a/.gitignore b/.gitignore index 29374d13dc..53996f0c63 100644 --- a/.gitignore +++ b/.gitignore @@ -187,4 +187,7 @@ pyrightconfig.json api/.vscode .idea/ -.vscode \ No newline at end of file +.vscode + +# pnpm +/.pnpm-store diff --git a/web/.gitignore b/web/.gitignore index 71d6260ff5..efcbf2bfcd 100644 --- a/web/.gitignore +++ b/web/.gitignore @@ -44,10 +44,9 @@ package-lock.json .pnp.cjs .pnp.loader.mjs .yarn/ -.yarnrc.yml - -# pmpm -pnpm-lock.yaml .favorites.json -*storybook.log \ No newline at end of file + +# storybook +/storybook-static +*storybook.log diff --git a/web/.husky/pre-commit b/web/.husky/pre-commit index d9290e1853..1c80c8c20b 100755 --- a/web/.husky/pre-commit +++ b/web/.husky/pre-commit @@ -63,7 +63,7 @@ if $web_modified; then # check if the test file exists if [ -f "../$test_file" ]; then echo "Detected changes in $file, running corresponding unit tests..." - npm run test "../$test_file" + pnpm run test "../$test_file" if [ $? -ne 0 ]; then echo "Unit tests failed. Please fix the errors before committing." diff --git a/web/README.md b/web/README.md index ce5239e57f..64a460e355 100644 --- a/web/README.md +++ b/web/README.md @@ -6,14 +6,12 @@ This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next ### Run by source code -To start the web frontend service, you will need [Node.js v18.x (LTS)](https://nodejs.org/en) and [NPM version 8.x.x](https://www.npmjs.com/) or [Yarn](https://yarnpkg.com/). +To start the web frontend service, you will need [Node.js v18.x (LTS)](https://nodejs.org/en) and [pnpm version 9.12.2](https://pnpm.io). First, install the dependencies: ```bash -npm install -# or -yarn install --frozen-lockfile +pnpm install ``` Then, configure the environment variables. Create a file named `.env.local` in the current directory and copy the contents from `.env.example`. Modify the values of these environment variables according to your requirements: @@ -43,9 +41,7 @@ NEXT_PUBLIC_SENTRY_DSN= Finally, run the development server: ```bash -npm run dev -# or -yarn dev +pnpm run dev ``` Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. @@ -59,19 +55,19 @@ You can start editing the file under folder `app`. The page auto-updates as you First, build the app for production: ```bash -npm run build +pnpm run build ``` Then, start the server: ```bash -npm run start +pnpm run start ``` If you want to customize the host and port: ```bash -npm run start --port=3001 --host=0.0.0.0 +pnpm run start --port=3001 --host=0.0.0.0 ``` ## Storybook @@ -99,7 +95,7 @@ You can create a test file with a suffix of `.spec` beside the file that to be t Run test: ```bash -npm run test +pnpm run test ``` If you are not familiar with writing tests, here is some code to refer to: diff --git a/web/package.json b/web/package.json index 7c0977a44a..b8b57e42a4 100644 --- a/web/package.json +++ b/web/package.json @@ -20,7 +20,8 @@ "test": "jest", "test:watch": "jest --watch", "storybook": "storybook dev -p 6006", - "build-storybook": "storybook build" + "build-storybook": "storybook build", + "preinstall": "npx only-allow pnpm" }, "dependencies": { "@babel/runtime": "^7.22.3", diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml new file mode 100644 index 0000000000..d84b25948b --- /dev/null +++ b/web/pnpm-lock.yaml @@ -0,0 +1,17061 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +overrides: + '@types/react': ~18.2.0 + '@types/react-dom': ~18.2.0 + string-width: 4.2.3 + +importers: + + .: + dependencies: + '@babel/runtime': + specifier: ^7.22.3 + version: 7.25.7 + '@dagrejs/dagre': + specifier: ^1.1.2 + version: 1.1.4 + '@emoji-mart/data': + specifier: ^1.1.2 + version: 1.2.1 + '@floating-ui/react': + specifier: ^0.25.2 + version: 0.25.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@formatjs/intl-localematcher': + specifier: ^0.5.4 + version: 0.5.5 + '@headlessui/react': + specifier: ^1.7.13 + version: 1.7.19(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@heroicons/react': + specifier: ^2.0.16 + version: 2.1.5(react@18.2.0) + '@hookform/resolvers': + specifier: ^3.3.4 + version: 3.9.0(react-hook-form@7.53.1(react@18.2.0)) + '@lexical/react': + specifier: ^0.16.0 + version: 0.16.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(yjs@13.6.20) + '@mdx-js/loader': + specifier: ^2.3.0 + version: 2.3.0(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3)) + '@mdx-js/react': + specifier: ^2.3.0 + version: 2.3.0(react@18.2.0) + '@monaco-editor/react': + specifier: ^4.6.0 + version: 4.6.0(monaco-editor@0.52.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@next/mdx': + specifier: ^14.0.4 + version: 14.2.15(@mdx-js/loader@2.3.0(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3)))(@mdx-js/react@2.3.0(react@18.2.0)) + '@remixicon/react': + specifier: ^4.2.0 + version: 4.3.0(react@18.2.0) + '@sentry/react': + specifier: ^7.54.0 + version: 7.119.2(react@18.2.0) + '@sentry/utils': + specifier: ^7.54.0 + version: 7.119.2 + '@svgdotjs/svg.js': + specifier: ^3.2.4 + version: 3.2.4 + '@tailwindcss/line-clamp': + specifier: ^0.4.4 + version: 0.4.4(tailwindcss@3.4.14(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5))) + '@tailwindcss/typography': + specifier: ^0.5.9 + version: 0.5.15(tailwindcss@3.4.14(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5))) + ahooks: + specifier: ^3.7.5 + version: 3.8.1(react@18.2.0) + class-variance-authority: + specifier: ^0.7.0 + version: 0.7.0 + classnames: + specifier: ^2.3.2 + version: 2.5.1 + copy-to-clipboard: + specifier: ^3.3.3 + version: 3.3.3 + crypto-js: + specifier: ^4.2.0 + version: 4.2.0 + dayjs: + specifier: ^1.11.7 + version: 1.11.13 + echarts: + specifier: ^5.4.1 + version: 5.5.1 + echarts-for-react: + specifier: ^3.0.2 + version: 3.0.2(echarts@5.5.1)(react@18.2.0) + emoji-mart: + specifier: ^5.5.2 + version: 5.6.0 + fast-deep-equal: + specifier: ^3.1.3 + version: 3.1.3 + i18next: + specifier: ^22.4.13 + version: 22.5.1 + i18next-resources-to-backend: + specifier: ^1.1.3 + version: 1.2.1 + immer: + specifier: ^9.0.19 + version: 9.0.21 + js-audio-recorder: + specifier: ^1.0.7 + version: 1.0.7 + js-cookie: + specifier: ^3.0.1 + version: 3.0.5 + jwt-decode: + specifier: ^4.0.0 + version: 4.0.0 + katex: + specifier: ^0.16.10 + version: 0.16.11 + lamejs: + specifier: ^1.2.1 + version: 1.2.1 + lexical: + specifier: ^0.16.0 + version: 0.16.1 + lodash-es: + specifier: ^4.17.21 + version: 4.17.21 + mermaid: + specifier: 10.4.0 + version: 10.4.0 + negotiator: + specifier: ^0.6.3 + version: 0.6.4 + next: + specifier: ^14.1.1 + version: 14.2.15(@babel/core@7.25.8)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.80.3) + pinyin-pro: + specifier: ^3.23.0 + version: 3.25.0 + qrcode.react: + specifier: ^3.1.0 + version: 3.2.0(react@18.2.0) + qs: + specifier: ^6.11.1 + version: 6.13.0 + rc-textarea: + specifier: ^1.5.2 + version: 1.8.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + react: + specifier: ~18.2.0 + version: 18.2.0 + react-18-input-autosize: + specifier: ^3.0.0 + version: 3.0.0(react@18.2.0) + react-dom: + specifier: ~18.2.0 + version: 18.2.0(react@18.2.0) + react-easy-crop: + specifier: ^5.0.8 + version: 5.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + react-error-boundary: + specifier: ^4.0.2 + version: 4.1.2(react@18.2.0) + react-headless-pagination: + specifier: ^1.1.4 + version: 1.1.6(react@18.2.0) + react-hook-form: + specifier: ^7.51.4 + version: 7.53.1(react@18.2.0) + react-i18next: + specifier: ^12.2.0 + version: 12.3.1(i18next@22.5.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + react-infinite-scroll-component: + specifier: ^6.1.0 + version: 6.1.0(react@18.2.0) + react-markdown: + specifier: ^8.0.6 + version: 8.0.7(@types/react@18.2.79)(react@18.2.0) + react-multi-email: + specifier: ^1.0.14 + version: 1.0.25(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + react-papaparse: + specifier: ^4.1.0 + version: 4.4.0 + react-slider: + specifier: ^2.0.4 + version: 2.0.6(react@18.2.0) + react-sortablejs: + specifier: ^6.1.4 + version: 6.1.4(@types/sortablejs@1.15.8)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sortablejs@1.15.3) + react-syntax-highlighter: + specifier: ^15.5.0 + version: 15.6.1(react@18.2.0) + react-tooltip: + specifier: 5.8.3 + version: 5.8.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + react-window: + specifier: ^1.8.9 + version: 1.8.10(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + react-window-infinite-loader: + specifier: ^1.0.9 + version: 1.0.9(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + reactflow: + specifier: ^11.11.3 + version: 11.11.4(@types/react@18.2.79)(immer@9.0.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + recordrtc: + specifier: ^5.6.2 + version: 5.6.2 + rehype-katex: + specifier: ^6.0.2 + version: 6.0.3 + rehype-raw: + specifier: ^7.0.0 + version: 7.0.0 + remark-breaks: + specifier: ^3.0.2 + version: 3.0.3 + remark-gfm: + specifier: ^3.0.1 + version: 3.0.1 + remark-math: + specifier: ^5.1.1 + version: 5.1.1 + scheduler: + specifier: ^0.23.0 + version: 0.23.2 + server-only: + specifier: ^0.0.1 + version: 0.0.1 + sharp: + specifier: ^0.33.2 + version: 0.33.5 + sortablejs: + specifier: ^1.15.0 + version: 1.15.3 + swr: + specifier: ^2.1.0 + version: 2.2.5(react@18.2.0) + tailwind-merge: + specifier: ^2.4.0 + version: 2.5.4 + use-context-selector: + specifier: ^1.4.1 + version: 1.4.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(scheduler@0.23.2) + uuid: + specifier: ^9.0.1 + version: 9.0.1 + zod: + specifier: ^3.23.6 + version: 3.23.8 + zundo: + specifier: ^2.1.0 + version: 2.2.0(zustand@4.5.5(@types/react@18.2.79)(immer@9.0.21)(react@18.2.0)) + zustand: + specifier: ^4.5.2 + version: 4.5.5(@types/react@18.2.79)(immer@9.0.21)(react@18.2.0) + devDependencies: + '@antfu/eslint-config': + specifier: ^0.36.0 + version: 0.36.0(eslint@8.57.1)(jest@29.7.0(@types/node@18.15.0)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)))(typescript@4.9.5) + '@chromatic-com/storybook': + specifier: ^1.9.0 + version: 1.9.0(react@18.2.0) + '@faker-js/faker': + specifier: ^7.6.0 + version: 7.6.0 + '@rgrove/parse-xml': + specifier: ^4.1.0 + version: 4.1.0 + '@storybook/addon-essentials': + specifier: ^8.3.5 + version: 8.3.6(storybook@8.3.6)(webpack-sources@3.2.3) + '@storybook/addon-interactions': + specifier: ^8.3.5 + version: 8.3.6(storybook@8.3.6) + '@storybook/addon-links': + specifier: ^8.3.5 + version: 8.3.6(react@18.2.0)(storybook@8.3.6) + '@storybook/addon-onboarding': + specifier: ^8.3.5 + version: 8.3.6(react@18.2.0)(storybook@8.3.6) + '@storybook/addon-themes': + specifier: ^8.3.5 + version: 8.3.6(storybook@8.3.6) + '@storybook/blocks': + specifier: ^8.3.5 + version: 8.3.6(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(storybook@8.3.6) + '@storybook/nextjs': + specifier: ^8.3.5 + version: 8.3.6(esbuild@0.23.1)(next@14.2.15(@babel/core@7.25.8)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.80.3))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.80.3)(storybook@8.3.6)(type-fest@2.19.0)(typescript@4.9.5)(uglify-js@3.19.3)(webpack-hot-middleware@2.26.1)(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3)) + '@storybook/react': + specifier: ^8.3.5 + version: 8.3.6(@storybook/test@8.3.6(storybook@8.3.6))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(storybook@8.3.6)(typescript@4.9.5) + '@storybook/test': + specifier: ^8.3.5 + version: 8.3.6(storybook@8.3.6) + '@testing-library/dom': + specifier: ^10.3.2 + version: 10.4.0 + '@testing-library/jest-dom': + specifier: ^6.4.6 + version: 6.6.2 + '@testing-library/react': + specifier: ^16.0.0 + version: 16.0.1(@testing-library/dom@10.4.0)(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@types/crypto-js': + specifier: ^4.1.1 + version: 4.2.2 + '@types/dagre': + specifier: ^0.7.52 + version: 0.7.52 + '@types/jest': + specifier: ^29.5.12 + version: 29.5.13 + '@types/js-cookie': + specifier: ^3.0.3 + version: 3.0.6 + '@types/lodash-es': + specifier: ^4.17.7 + version: 4.17.12 + '@types/negotiator': + specifier: ^0.6.1 + version: 0.6.3 + '@types/node': + specifier: 18.15.0 + version: 18.15.0 + '@types/qs': + specifier: ^6.9.7 + version: 6.9.16 + '@types/react': + specifier: ~18.2.0 + version: 18.2.79 + '@types/react-dom': + specifier: ~18.2.0 + version: 18.2.25 + '@types/react-slider': + specifier: ^1.3.1 + version: 1.3.6 + '@types/react-syntax-highlighter': + specifier: ^15.5.6 + version: 15.5.13 + '@types/react-window': + specifier: ^1.8.5 + version: 1.8.8 + '@types/react-window-infinite-loader': + specifier: ^1.0.6 + version: 1.0.9 + '@types/recordrtc': + specifier: ^5.6.11 + version: 5.6.14 + '@types/sortablejs': + specifier: ^1.15.1 + version: 1.15.8 + '@types/uuid': + specifier: ^9.0.8 + version: 9.0.8 + autoprefixer: + specifier: ^10.4.14 + version: 10.4.20(postcss@8.4.47) + bing-translate-api: + specifier: ^4.0.2 + version: 4.0.2 + code-inspector-plugin: + specifier: ^0.13.0 + version: 0.13.0 + cross-env: + specifier: ^7.0.3 + version: 7.0.3 + eslint: + specifier: ^8.36.0 + version: 8.57.1 + eslint-config-next: + specifier: ^14.0.4 + version: 14.2.15(eslint@8.57.1)(typescript@4.9.5) + eslint-plugin-storybook: + specifier: ^0.9.0 + version: 0.9.0(eslint@8.57.1)(typescript@4.9.5) + husky: + specifier: ^8.0.3 + version: 8.0.3 + jest: + specifier: ^29.7.0 + version: 29.7.0(@types/node@18.15.0)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)) + jest-environment-jsdom: + specifier: ^29.7.0 + version: 29.7.0 + lint-staged: + specifier: ^13.2.2 + version: 13.3.0 + magicast: + specifier: ^0.3.4 + version: 0.3.5 + postcss: + specifier: ^8.4.31 + version: 8.4.47 + sass: + specifier: ^1.61.0 + version: 1.80.3 + storybook: + specifier: ^8.3.5 + version: 8.3.6 + tailwindcss: + specifier: ^3.4.4 + version: 3.4.14(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)) + ts-node: + specifier: ^10.9.2 + version: 10.9.2(@types/node@18.15.0)(typescript@4.9.5) + typescript: + specifier: 4.9.5 + version: 4.9.5 + uglify-js: + specifier: ^3.17.4 + version: 3.19.3 + +packages: + + '@adobe/css-tools@4.4.0': + resolution: {integrity: sha512-Ff9+ksdQQB3rMncgqDK78uLznstjyfIf2Arnh22pW8kBpLs6rpKDwgnZT46hin5Hl1WzazzK64DOrhSwYpS7bQ==} + + '@alloc/quick-lru@5.2.0': + resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} + engines: {node: '>=10'} + + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + + '@antfu/eslint-config-basic@0.36.0': + resolution: {integrity: sha512-2b3ZB7pO00nxAERDXo82iYPjLQ4l/AOMm0CTKmGmqWbN3RB33EIQWzYheZRboSbAVzWpI1/3rg/Gu+7xYVMYHA==} + peerDependencies: + eslint: '>=7.4.0' + + '@antfu/eslint-config-ts@0.36.0': + resolution: {integrity: sha512-I/h2ZOPBIqgnALG2fQp6lOBsOXk51QwLDumyEayt7GRnitdP4o9D8i+YAPowrMJ8M3kU7puQUyhWuJmZLgo57A==} + peerDependencies: + eslint: '>=7.4.0' + typescript: '>=3.9' + + '@antfu/eslint-config-vue@0.36.0': + resolution: {integrity: sha512-YuTcNlVlrEWX1ESOiPgr+e2Walfd6xt3Toa0kAKJxq2aBS1RWqIi1l3zIVGCHaX72lOrSXNmQ7bryaZyGADGDg==} + peerDependencies: + eslint: '>=7.4.0' + + '@antfu/eslint-config@0.36.0': + resolution: {integrity: sha512-otZ9PfKRT3gnGMMX1gS8URTNPMPCZ69K5jHZvLkYojru0gLBZ3IO5fCvjEZpWqOyIUHtAgg6NWELf1DbEF+NDw==} + peerDependencies: + eslint: '>=7.4.0' + + '@babel/code-frame@7.25.7': + resolution: {integrity: sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.25.8': + resolution: {integrity: sha512-ZsysZyXY4Tlx+Q53XdnOFmqwfB9QDTHYxaZYajWRoBLuLEAwI2UIbtxOjWh/cFaa9IKUlcB+DDuoskLuKu56JA==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.25.8': + resolution: {integrity: sha512-Oixnb+DzmRT30qu9d3tJSQkxuygWm32DFykT4bRoORPa9hZ/L4KhVB/XiRm6KG+roIEM7DBQlmg27kw2HZkdZg==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.25.7': + resolution: {integrity: sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-annotate-as-pure@7.25.7': + resolution: {integrity: sha512-4xwU8StnqnlIhhioZf1tqnVWeQ9pvH/ujS8hRfw/WOza+/a+1qv69BWNy+oY231maTCWgKWhfBU7kDpsds6zAA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-builder-binary-assignment-operator-visitor@7.25.7': + resolution: {integrity: sha512-12xfNeKNH7jubQNm7PAkzlLwEmCs1tfuX3UjIw6vP6QXi+leKh6+LyC/+Ed4EIQermwd58wsyh070yjDHFlNGg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.25.7': + resolution: {integrity: sha512-DniTEax0sv6isaw6qSQSfV4gVRNtw2rte8HHM45t9ZR0xILaufBRNkpMifCRiAPyvL4ACD6v0gfCwCmtOQaV4A==} + engines: {node: '>=6.9.0'} + + '@babel/helper-create-class-features-plugin@7.25.7': + resolution: {integrity: sha512-bD4WQhbkx80mAyj/WCm4ZHcF4rDxkoLFO6ph8/5/mQ3z4vAzltQXAmbc7GvVJx5H+lk5Mi5EmbTeox5nMGCsbw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-create-regexp-features-plugin@7.25.7': + resolution: {integrity: sha512-byHhumTj/X47wJ6C6eLpK7wW/WBEcnUeb7D0FNc/jFQnQVw7DOso3Zz5u9x/zLrFVkHa89ZGDbkAa1D54NdrCQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-define-polyfill-provider@0.6.2': + resolution: {integrity: sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + '@babel/helper-member-expression-to-functions@7.25.7': + resolution: {integrity: sha512-O31Ssjd5K6lPbTX9AAYpSKrZmLeagt9uwschJd+Ixo6QiRyfpvgtVQp8qrDR9UNFjZ8+DO34ZkdrN+BnPXemeA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.25.7': + resolution: {integrity: sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.25.7': + resolution: {integrity: sha512-k/6f8dKG3yDz/qCwSM+RKovjMix563SLxQFo0UhRNo239SP6n9u5/eLtKD6EAjwta2JHJ49CsD8pms2HdNiMMQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-optimise-call-expression@7.25.7': + resolution: {integrity: sha512-VAwcwuYhv/AT+Vfr28c9y6SHzTan1ryqrydSTFGjU0uDJHw3uZ+PduI8plCLkRsDnqK2DMEDmwrOQRsK/Ykjng==} + engines: {node: '>=6.9.0'} + + '@babel/helper-plugin-utils@7.25.7': + resolution: {integrity: sha512-eaPZai0PiqCi09pPs3pAFfl/zYgGaE6IdXtYvmf0qlcDTd3WCtO7JWCcRd64e0EQrcYgiHibEZnOGsSY4QSgaw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-remap-async-to-generator@7.25.7': + resolution: {integrity: sha512-kRGE89hLnPfcz6fTrlNU+uhgcwv0mBE4Gv3P9Ke9kLVJYpi4AMVVEElXvB5CabrPZW4nCM8P8UyyjrzCM0O2sw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-replace-supers@7.25.7': + resolution: {integrity: sha512-iy8JhqlUW9PtZkd4pHM96v6BdJ66Ba9yWSE4z0W4TvSZwLBPkyDsiIU3ENe4SmrzRBs76F7rQXTy1lYC49n6Lw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-simple-access@7.25.7': + resolution: {integrity: sha512-FPGAkJmyoChQeM+ruBGIDyrT2tKfZJO8NcxdC+CWNJi7N8/rZpSxK7yvBJ5O/nF1gfu5KzN7VKG3YVSLFfRSxQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-skip-transparent-expression-wrappers@7.25.7': + resolution: {integrity: sha512-pPbNbchZBkPMD50K0p3JGcFMNLVUCuU/ABybm/PGNj4JiHrpmNyqqCphBk4i19xXtNV0JhldQJJtbSW5aUvbyA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.25.7': + resolution: {integrity: sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.25.7': + resolution: {integrity: sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.25.7': + resolution: {integrity: sha512-ytbPLsm+GjArDYXJ8Ydr1c/KJuutjF2besPNbIZnZ6MKUxi/uTA22t2ymmA4WFjZFpjiAMO0xuuJPqK2nvDVfQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-wrap-function@7.25.7': + resolution: {integrity: sha512-MA0roW3JF2bD1ptAaJnvcabsVlNQShUaThyJbCDD4bCp8NEgiFvpoqRI2YS22hHlc2thjO/fTg2ShLMC3jygAg==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.25.7': + resolution: {integrity: sha512-Sv6pASx7Esm38KQpF/U/OXLwPPrdGHNKoeblRxgZRLXnAtnkEe4ptJPDtAZM7fBLadbc1Q07kQpSiGQ0Jg6tRA==} + engines: {node: '>=6.9.0'} + + '@babel/highlight@7.25.7': + resolution: {integrity: sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.25.8': + resolution: {integrity: sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.7': + resolution: {integrity: sha512-UV9Lg53zyebzD1DwQoT9mzkEKa922LNUp5YkTJ6Uta0RbyXaQNUgcvSt7qIu1PpPzVb6rd10OVNTzkyBGeVmxQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.25.7': + resolution: {integrity: sha512-GDDWeVLNxRIkQTnJn2pDOM1pkCgYdSqPeT1a9vh9yIqu2uzzgw1zcqEb+IJOhy+dTBMlNdThrDIksr2o09qrrQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.25.7': + resolution: {integrity: sha512-wxyWg2RYaSUYgmd9MR0FyRGyeOMQE/Uzr1wzd/g5cf5bwi9A4v6HFdDm7y1MgDtod/fLOSTZY6jDgV0xU9d5bA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.25.7': + resolution: {integrity: sha512-Xwg6tZpLxc4iQjorYsyGMyfJE7nP5MV8t/Ka58BgiA7Jw0fRqQNcANlLfdJ/yvBt9z9LD2We+BEkT7vLqZRWng==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.13.0 + + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.25.7': + resolution: {integrity: sha512-UVATLMidXrnH+GMUIuxq55nejlj02HP7F5ETyBONzP6G87fPBogG4CH6kxrSrdIuAjdwNO9VzyaYsrZPscWUrw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2': + resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-async-generators@7.8.4': + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-bigint@7.8.3': + resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-class-properties@7.12.13': + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-class-static-block@7.14.5': + resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-dynamic-import@7.8.3': + resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-assertions@7.25.7': + resolution: {integrity: sha512-ZvZQRmME0zfJnDQnVBKYzHxXT7lYBB3Revz1GuS7oLXWMgqUPX4G+DDbT30ICClht9WKV34QVrZhSw6WdklwZQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-attributes@7.25.7': + resolution: {integrity: sha512-AqVo+dguCgmpi/3mYBdu9lkngOBlQ2w2vnNpa6gfiCxQZLzV4ZbhsXitJ2Yblkoe1VQwtHSaNmIaGll/26YWRw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-meta@7.10.4': + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-json-strings@7.8.3': + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-jsx@7.25.7': + resolution: {integrity: sha512-ruZOnKO+ajVL/MVx+PwNBPOkrnXTXoWMtte1MBpegfCArhqOe3Bj52avVj1huLLxNKYKXYaSxZ2F+woK1ekXfw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-logical-assignment-operators@7.10.4': + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3': + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-numeric-separator@7.10.4': + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-object-rest-spread@7.8.3': + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-optional-catch-binding@7.8.3': + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-optional-chaining@7.8.3': + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-private-property-in-object@7.14.5': + resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-top-level-await@7.14.5': + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.25.7': + resolution: {integrity: sha512-rR+5FDjpCHqqZN2bzZm18bVYGaejGq5ZkpVCJLXor/+zlSrSoc4KWcHI0URVWjl/68Dyr1uwZUz/1njycEAv9g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-unicode-sets-regex@7.18.6': + resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-arrow-functions@7.25.7': + resolution: {integrity: sha512-EJN2mKxDwfOUCPxMO6MUI58RN3ganiRAG/MS/S3HfB6QFNjroAMelQo/gybyYq97WerCBAZoyrAoW8Tzdq2jWg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-async-generator-functions@7.25.8': + resolution: {integrity: sha512-9ypqkozyzpG+HxlH4o4gdctalFGIjjdufzo7I2XPda0iBnZ6a+FO0rIEQcdSPXp02CkvGsII1exJhmROPQd5oA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-async-to-generator@7.25.7': + resolution: {integrity: sha512-ZUCjAavsh5CESCmi/xCpX1qcCaAglzs/7tmuvoFnJgA1dM7gQplsguljoTg+Ru8WENpX89cQyAtWoaE0I3X3Pg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-block-scoped-functions@7.25.7': + resolution: {integrity: sha512-xHttvIM9fvqW+0a3tZlYcZYSBpSWzGBFIt/sYG3tcdSzBB8ZeVgz2gBP7Df+sM0N1850jrviYSSeUuc+135dmQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-block-scoping@7.25.7': + resolution: {integrity: sha512-ZEPJSkVZaeTFG/m2PARwLZQ+OG0vFIhPlKHK/JdIMy8DbRJ/htz6LRrTFtdzxi9EHmcwbNPAKDnadpNSIW+Aow==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-class-properties@7.25.7': + resolution: {integrity: sha512-mhyfEW4gufjIqYFo9krXHJ3ElbFLIze5IDp+wQTxoPd+mwFb1NxatNAwmv8Q8Iuxv7Zc+q8EkiMQwc9IhyGf4g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-class-static-block@7.25.8': + resolution: {integrity: sha512-e82gl3TCorath6YLf9xUwFehVvjvfqFhdOo4+0iVIVju+6XOi5XHkqB3P2AXnSwoeTX0HBoXq5gJFtvotJzFnQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.12.0 + + '@babel/plugin-transform-classes@7.25.7': + resolution: {integrity: sha512-9j9rnl+YCQY0IGoeipXvnk3niWicIB6kCsWRGLwX241qSXpbA4MKxtp/EdvFxsc4zI5vqfLxzOd0twIJ7I99zg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-computed-properties@7.25.7': + resolution: {integrity: sha512-QIv+imtM+EtNxg/XBKL3hiWjgdLjMOmZ+XzQwSgmBfKbfxUjBzGgVPklUuE55eq5/uVoh8gg3dqlrwR/jw3ZeA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-destructuring@7.25.7': + resolution: {integrity: sha512-xKcfLTlJYUczdaM1+epcdh1UGewJqr9zATgrNHcLBcV2QmfvPPEixo/sK/syql9cEmbr7ulu5HMFG5vbbt/sEA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-dotall-regex@7.25.7': + resolution: {integrity: sha512-kXzXMMRzAtJdDEgQBLF4oaiT6ZCU3oWHgpARnTKDAqPkDJ+bs3NrZb310YYevR5QlRo3Kn7dzzIdHbZm1VzJdQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-duplicate-keys@7.25.7': + resolution: {integrity: sha512-by+v2CjoL3aMnWDOyCIg+yxU9KXSRa9tN6MbqggH5xvymmr9p4AMjYkNlQy4brMceBnUyHZ9G8RnpvT8wP7Cfg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.25.7': + resolution: {integrity: sha512-HvS6JF66xSS5rNKXLqkk7L9c/jZ/cdIVIcoPVrnl8IsVpLggTjXs8OWekbLHs/VtYDDh5WXnQyeE3PPUGm22MA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-dynamic-import@7.25.8': + resolution: {integrity: sha512-gznWY+mr4ZQL/EWPcbBQUP3BXS5FwZp8RUOw06BaRn8tQLzN4XLIxXejpHN9Qo8x8jjBmAAKp6FoS51AgkSA/A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-exponentiation-operator@7.25.7': + resolution: {integrity: sha512-yjqtpstPfZ0h/y40fAXRv2snciYr0OAoMXY/0ClC7tm4C/nG5NJKmIItlaYlLbIVAWNfrYuy9dq1bE0SbX0PEg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-export-namespace-from@7.25.8': + resolution: {integrity: sha512-sPtYrduWINTQTW7FtOy99VCTWp4H23UX7vYcut7S4CIMEXU+54zKX9uCoGkLsWXteyaMXzVHgzWbLfQ1w4GZgw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-for-of@7.25.7': + resolution: {integrity: sha512-n/TaiBGJxYFWvpJDfsxSj9lEEE44BFM1EPGz4KEiTipTgkoFVVcCmzAL3qA7fdQU96dpo4gGf5HBx/KnDvqiHw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-function-name@7.25.7': + resolution: {integrity: sha512-5MCTNcjCMxQ63Tdu9rxyN6cAWurqfrDZ76qvVPrGYdBxIj+EawuuxTu/+dgJlhK5eRz3v1gLwp6XwS8XaX2NiQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-json-strings@7.25.8': + resolution: {integrity: sha512-4OMNv7eHTmJ2YXs3tvxAfa/I43di+VcF+M4Wt66c88EAED1RoGaf1D64cL5FkRpNL+Vx9Hds84lksWvd/wMIdA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-literals@7.25.7': + resolution: {integrity: sha512-fwzkLrSu2fESR/cm4t6vqd7ebNIopz2QHGtjoU+dswQo/P6lwAG04Q98lliE3jkz/XqnbGFLnUcE0q0CVUf92w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-logical-assignment-operators@7.25.8': + resolution: {integrity: sha512-f5W0AhSbbI+yY6VakT04jmxdxz+WsID0neG7+kQZbCOjuyJNdL5Nn4WIBm4hRpKnUcO9lP0eipUhFN12JpoH8g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-member-expression-literals@7.25.7': + resolution: {integrity: sha512-Std3kXwpXfRV0QtQy5JJcRpkqP8/wG4XL7hSKZmGlxPlDqmpXtEPRmhF7ztnlTCtUN3eXRUJp+sBEZjaIBVYaw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-amd@7.25.7': + resolution: {integrity: sha512-CgselSGCGzjQvKzghCvDTxKHP3iooenLpJDO842ehn5D2G5fJB222ptnDwQho0WjEvg7zyoxb9P+wiYxiJX5yA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-commonjs@7.25.7': + resolution: {integrity: sha512-L9Gcahi0kKFYXvweO6n0wc3ZG1ChpSFdgG+eV1WYZ3/dGbJK7vvk91FgGgak8YwRgrCuihF8tE/Xg07EkL5COg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-systemjs@7.25.7': + resolution: {integrity: sha512-t9jZIvBmOXJsiuyOwhrIGs8dVcD6jDyg2icw1VL4A/g+FnWyJKwUfSSU2nwJuMV2Zqui856El9u+ElB+j9fV1g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-umd@7.25.7': + resolution: {integrity: sha512-p88Jg6QqsaPh+EB7I9GJrIqi1Zt4ZBHUQtjw3z1bzEXcLh6GfPqzZJ6G+G1HBGKUNukT58MnKG7EN7zXQBCODw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-named-capturing-groups-regex@7.25.7': + resolution: {integrity: sha512-BtAT9LzCISKG3Dsdw5uso4oV1+v2NlVXIIomKJgQybotJY3OwCwJmkongjHgwGKoZXd0qG5UZ12JUlDQ07W6Ow==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-new-target@7.25.7': + resolution: {integrity: sha512-CfCS2jDsbcZaVYxRFo2qtavW8SpdzmBXC2LOI4oO0rP+JSRDxxF3inF4GcPsLgfb5FjkhXG5/yR/lxuRs2pySA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-nullish-coalescing-operator@7.25.8': + resolution: {integrity: sha512-Z7WJJWdQc8yCWgAmjI3hyC+5PXIubH9yRKzkl9ZEG647O9szl9zvmKLzpbItlijBnVhTUf1cpyWBsZ3+2wjWPQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-numeric-separator@7.25.8': + resolution: {integrity: sha512-rm9a5iEFPS4iMIy+/A/PiS0QN0UyjPIeVvbU5EMZFKJZHt8vQnasbpo3T3EFcxzCeYO0BHfc4RqooCZc51J86Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-object-rest-spread@7.25.8': + resolution: {integrity: sha512-LkUu0O2hnUKHKE7/zYOIjByMa4VRaV2CD/cdGz0AxU9we+VA3kDDggKEzI0Oz1IroG+6gUP6UmWEHBMWZU316g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-object-super@7.25.7': + resolution: {integrity: sha512-pWT6UXCEW3u1t2tcAGtE15ornCBvopHj9Bps9D2DsH15APgNVOTwwczGckX+WkAvBmuoYKRCFa4DK+jM8vh5AA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-optional-catch-binding@7.25.8': + resolution: {integrity: sha512-EbQYweoMAHOn7iJ9GgZo14ghhb9tTjgOc88xFgYngifx7Z9u580cENCV159M4xDh3q/irbhSjZVpuhpC2gKBbg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-optional-chaining@7.25.8': + resolution: {integrity: sha512-q05Bk7gXOxpTHoQ8RSzGSh/LHVB9JEIkKnk3myAWwZHnYiTGYtbdrYkIsS8Xyh4ltKf7GNUSgzs/6P2bJtBAQg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-parameters@7.25.7': + resolution: {integrity: sha512-FYiTvku63me9+1Nz7TOx4YMtW3tWXzfANZtrzHhUZrz4d47EEtMQhzFoZWESfXuAMMT5mwzD4+y1N8ONAX6lMQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-private-methods@7.25.7': + resolution: {integrity: sha512-KY0hh2FluNxMLwOCHbxVOKfdB5sjWG4M183885FmaqWWiGMhRZq4DQRKH6mHdEucbJnyDyYiZNwNG424RymJjA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-private-property-in-object@7.25.8': + resolution: {integrity: sha512-8Uh966svuB4V8RHHg0QJOB32QK287NBksJOByoKmHMp1TAobNniNalIkI2i5IPj5+S9NYCG4VIjbEuiSN8r+ow==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-property-literals@7.25.7': + resolution: {integrity: sha512-lQEeetGKfFi0wHbt8ClQrUSUMfEeI3MMm74Z73T9/kuz990yYVtfofjf3NuA42Jy3auFOpbjDyCSiIkTs1VIYw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-display-name@7.25.7': + resolution: {integrity: sha512-r0QY7NVU8OnrwE+w2IWiRom0wwsTbjx4+xH2RTd7AVdof3uurXOF+/mXHQDRk+2jIvWgSaCHKMgggfvM4dyUGA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx-development@7.25.7': + resolution: {integrity: sha512-5yd3lH1PWxzW6IZj+p+Y4OLQzz0/LzlOG8vGqonHfVR3euf1vyzyMUJk9Ac+m97BH46mFc/98t9PmYLyvgL3qg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx@7.25.7': + resolution: {integrity: sha512-vILAg5nwGlR9EXE8JIOX4NHXd49lrYbN8hnjffDtoULwpL9hUx/N55nqh2qd0q6FyNDfjl9V79ecKGvFbcSA0Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-pure-annotations@7.25.7': + resolution: {integrity: sha512-6YTHJ7yjjgYqGc8S+CbEXhLICODk0Tn92j+vNJo07HFk9t3bjFgAKxPLFhHwF2NjmQVSI1zBRfBWUeVBa2osfA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-regenerator@7.25.7': + resolution: {integrity: sha512-mgDoQCRjrY3XK95UuV60tZlFCQGXEtMg8H+IsW72ldw1ih1jZhzYXbJvghmAEpg5UVhhnCeia1CkGttUvCkiMQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-reserved-words@7.25.7': + resolution: {integrity: sha512-3OfyfRRqiGeOvIWSagcwUTVk2hXBsr/ww7bLn6TRTuXnexA+Udov2icFOxFX9abaj4l96ooYkcNN1qi2Zvqwng==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-runtime@7.25.7': + resolution: {integrity: sha512-Y9p487tyTzB0yDYQOtWnC+9HGOuogtP3/wNpun1xJXEEvI6vip59BSBTsHnekZLqxmPcgsrAKt46HAAb//xGhg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-shorthand-properties@7.25.7': + resolution: {integrity: sha512-uBbxNwimHi5Bv3hUccmOFlUy3ATO6WagTApenHz9KzoIdn0XeACdB12ZJ4cjhuB2WSi80Ez2FWzJnarccriJeA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-spread@7.25.7': + resolution: {integrity: sha512-Mm6aeymI0PBh44xNIv/qvo8nmbkpZze1KvR8MkEqbIREDxoiWTi18Zr2jryfRMwDfVZF9foKh060fWgni44luw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-sticky-regex@7.25.7': + resolution: {integrity: sha512-ZFAeNkpGuLnAQ/NCsXJ6xik7Id+tHuS+NT+ue/2+rn/31zcdnupCdmunOizEaP0JsUmTFSTOPoQY7PkK2pttXw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-template-literals@7.25.7': + resolution: {integrity: sha512-SI274k0nUsFFmyQupiO7+wKATAmMFf8iFgq2O+vVFXZ0SV9lNfT1NGzBEhjquFmD8I9sqHLguH+gZVN3vww2AA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typeof-symbol@7.25.7': + resolution: {integrity: sha512-OmWmQtTHnO8RSUbL0NTdtpbZHeNTnm68Gj5pA4Y2blFNh+V4iZR68V1qL9cI37J21ZN7AaCnkfdHtLExQPf2uA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typescript@7.25.7': + resolution: {integrity: sha512-VKlgy2vBzj8AmEzunocMun2fF06bsSWV+FvVXohtL6FGve/+L217qhHxRTVGHEDO/YR8IANcjzgJsd04J8ge5Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-escapes@7.25.7': + resolution: {integrity: sha512-BN87D7KpbdiABA+t3HbVqHzKWUDN3dymLaTnPFAMyc8lV+KN3+YzNhVRNdinaCPA4AUqx7ubXbQ9shRjYBl3SQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-property-regex@7.25.7': + resolution: {integrity: sha512-IWfR89zcEPQGB/iB408uGtSPlQd3Jpq11Im86vUgcmSTcoWAiQMCTOa2K2yNNqFJEBVICKhayctee65Ka8OB0w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-regex@7.25.7': + resolution: {integrity: sha512-8JKfg/hiuA3qXnlLx8qtv5HWRbgyFx2hMMtpDDuU2rTckpKkGu4ycK5yYHwuEa16/quXfoxHBIApEsNyMWnt0g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-sets-regex@7.25.7': + resolution: {integrity: sha512-YRW8o9vzImwmh4Q3Rffd09bH5/hvY0pxg+1H1i0f7APoUeg12G7+HhLj9ZFNIrYkgBXhIijPJ+IXypN0hLTIbw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/preset-env@7.25.8': + resolution: {integrity: sha512-58T2yulDHMN8YMUxiLq5YmWUnlDCyY1FsHM+v12VMx+1/FlrUj5tY50iDCpofFQEM8fMYOaY9YRvym2jcjn1Dg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/preset-modules@0.1.6-no-external-plugins': + resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==} + peerDependencies: + '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 + + '@babel/preset-react@7.25.7': + resolution: {integrity: sha512-GjV0/mUEEXpi1U5ZgDprMRRgajGMRW3G5FjMr5KLKD8nT2fTG8+h/klV3+6Dm5739QE+K5+2e91qFKAYI3pmRg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/preset-typescript@7.25.7': + resolution: {integrity: sha512-rkkpaXJZOFN45Fb+Gki0c+KMIglk4+zZXOoMJuyEK8y8Kkc8Jd3BDmP7qPsz0zQMJj+UD7EprF+AqAXcILnexw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/runtime@7.25.7': + resolution: {integrity: sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.25.7': + resolution: {integrity: sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.25.7': + resolution: {integrity: sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.25.8': + resolution: {integrity: sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg==} + engines: {node: '>=6.9.0'} + + '@base2/pretty-print-object@1.0.1': + resolution: {integrity: sha512-4iri8i1AqYHJE2DstZYkyEprg6Pq6sKx3xn5FpySk9sNhH7qN2LLlHJCfDTZRILNwQNPD7mATWM0TBui7uC1pA==} + + '@bcoe/v8-coverage@0.2.3': + resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + + '@braintree/sanitize-url@6.0.4': + resolution: {integrity: sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A==} + + '@chromatic-com/storybook@1.9.0': + resolution: {integrity: sha512-vYQ+TcfktEE3GHnLZXHCzXF/sN9dw+KivH8a5cmPyd9YtQs7fZtHrEgsIjWpYycXiweKMo1Lm1RZsjxk8DH3rA==} + engines: {node: '>=16.0.0', yarn: '>=1.22.18'} + + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + + '@dagrejs/dagre@1.1.4': + resolution: {integrity: sha512-QUTc54Cg/wvmlEUxB+uvoPVKFazM1H18kVHBQNmK2NbrDR5ihOCR6CXLnDSZzMcSQKJtabPUWridBOlJM3WkDg==} + + '@dagrejs/graphlib@2.2.4': + resolution: {integrity: sha512-mepCf/e9+SKYy1d02/UkvSy6+6MoyXhVxP8lLDfA7BPE1X1d4dR0sZznmbM8/XVJ1GPM+Svnx7Xj6ZweByWUkw==} + engines: {node: '>17.0.0'} + + '@emnapi/runtime@1.3.1': + resolution: {integrity: sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==} + + '@emoji-mart/data@1.2.1': + resolution: {integrity: sha512-no2pQMWiBy6gpBEiqGeU77/bFejDqUTRY7KX+0+iur13op3bqUsXdnwoZs6Xb1zbv0gAj5VvS1PWoUUckSr5Dw==} + + '@esbuild/aix-ppc64@0.23.1': + resolution: {integrity: sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.23.1': + resolution: {integrity: sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.23.1': + resolution: {integrity: sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.23.1': + resolution: {integrity: sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.23.1': + resolution: {integrity: sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.23.1': + resolution: {integrity: sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.23.1': + resolution: {integrity: sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.23.1': + resolution: {integrity: sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.23.1': + resolution: {integrity: sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.23.1': + resolution: {integrity: sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.23.1': + resolution: {integrity: sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.23.1': + resolution: {integrity: sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.23.1': + resolution: {integrity: sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.23.1': + resolution: {integrity: sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.23.1': + resolution: {integrity: sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.23.1': + resolution: {integrity: sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.23.1': + resolution: {integrity: sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.23.1': + resolution: {integrity: sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.23.1': + resolution: {integrity: sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.23.1': + resolution: {integrity: sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.23.1': + resolution: {integrity: sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.23.1': + resolution: {integrity: sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.23.1': + resolution: {integrity: sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.23.1': + resolution: {integrity: sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.4.0': + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.11.1': + resolution: {integrity: sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/eslintrc@2.1.4': + resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@eslint/js@8.57.1': + resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@faker-js/faker@7.6.0': + resolution: {integrity: sha512-XK6BTq1NDMo9Xqw/YkYyGjSsg44fbNwYRx7QK2CuoQgyy+f1rrTDHoExVM5PsyXCtfl2vs2vVJ0MN0yN6LppRw==} + engines: {node: '>=14.0.0', npm: '>=6.0.0'} + + '@floating-ui/core@1.6.8': + resolution: {integrity: sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==} + + '@floating-ui/dom@1.1.1': + resolution: {integrity: sha512-TpIO93+DIujg3g7SykEAGZMDtbJRrmnYRCNYSjJlvIbGhBjRSNTLVbNeDQBrzy9qDgUbiWdc7KA0uZHZ2tJmiw==} + + '@floating-ui/dom@1.6.11': + resolution: {integrity: sha512-qkMCxSR24v2vGkhYDo/UzxfJN3D4syqSjyuTFz6C7XcpU1pASPRieNI0Kj5VP3/503mOfYiGY891ugBX1GlABQ==} + + '@floating-ui/react-dom@2.1.2': + resolution: {integrity: sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@floating-ui/react@0.25.4': + resolution: {integrity: sha512-lWRQ/UiTvSIBxohn0/2HFHEmnmOVRjl7j6XcRJuLH0ls6f/9AyHMWVzkAJFuwx0n9gaEeCmg9VccCSCJzbEJig==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@floating-ui/utils@0.1.6': + resolution: {integrity: sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==} + + '@floating-ui/utils@0.2.8': + resolution: {integrity: sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==} + + '@formatjs/intl-localematcher@0.5.5': + resolution: {integrity: sha512-t5tOGMgZ/i5+ALl2/offNqAQq/lfUnKLEw0mXQI4N4bqpedhrSE+fyKLpwnd22sK0dif6AV+ufQcTsKShB9J1g==} + + '@headlessui/react@1.7.19': + resolution: {integrity: sha512-Ll+8q3OlMJfJbAKM/+/Y2q6PPYbryqNTXDbryx7SXLIDamkF6iQFbriYHga0dY44PvDhvvBWCx1Xj4U5+G4hOw==} + engines: {node: '>=10'} + peerDependencies: + react: ^16 || ^17 || ^18 + react-dom: ^16 || ^17 || ^18 + + '@heroicons/react@2.1.5': + resolution: {integrity: sha512-FuzFN+BsHa+7OxbvAERtgBTNeZpUjgM/MIizfVkSCL2/edriN0Hx/DWRCR//aPYwO5QX/YlgLGXk+E3PcfZwjA==} + peerDependencies: + react: '>= 16' + + '@hookform/resolvers@3.9.0': + resolution: {integrity: sha512-bU0Gr4EepJ/EQsH/IwEzYLsT/PEj5C0ynLQ4m+GSHS+xKH4TfSelhluTgOaoc4kA5s7eCsQbM4wvZLzELmWzUg==} + peerDependencies: + react-hook-form: ^7.0.0 + + '@humanwhocodes/config-array@0.13.0': + resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==} + engines: {node: '>=10.10.0'} + deprecated: Use @eslint/config-array instead + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/object-schema@2.0.3': + resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} + deprecated: Use @eslint/object-schema instead + + '@img/sharp-darwin-arm64@0.33.5': + resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.33.5': + resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.0.4': + resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.0.4': + resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.0.4': + resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linux-arm@1.0.5': + resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} + cpu: [arm] + os: [linux] + + '@img/sharp-libvips-linux-s390x@1.0.4': + resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} + cpu: [s390x] + os: [linux] + + '@img/sharp-libvips-linux-x64@1.0.4': + resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} + cpu: [x64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-x64@1.0.4': + resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} + cpu: [x64] + os: [linux] + + '@img/sharp-linux-arm64@0.33.5': + resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linux-arm@0.33.5': + resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + + '@img/sharp-linux-s390x@0.33.5': + resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + + '@img/sharp-linux-x64@0.33.5': + resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-linuxmusl-arm64@0.33.5': + resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linuxmusl-x64@0.33.5': + resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-wasm32@0.33.5': + resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + + '@img/sharp-win32-ia32@0.33.5': + resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.33.5': + resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@istanbuljs/load-nyc-config@1.1.0': + resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} + engines: {node: '>=8'} + + '@istanbuljs/schema@0.1.3': + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + + '@jest/console@29.7.0': + resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/core@29.7.0': + resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + '@jest/environment@29.7.0': + resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/expect-utils@29.7.0': + resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/expect@29.7.0': + resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/fake-timers@29.7.0': + resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/globals@29.7.0': + resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/reporters@29.7.0': + resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + '@jest/schemas@29.6.3': + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/source-map@29.6.3': + resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/test-result@29.7.0': + resolution: {integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/test-sequencer@29.7.0': + resolution: {integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/transform@29.7.0': + resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/types@29.6.3': + resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jridgewell/gen-mapping@0.3.5': + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + '@jridgewell/source-map@0.3.6': + resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + + '@jridgewell/trace-mapping@0.3.9': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + + '@lexical/clipboard@0.16.1': + resolution: {integrity: sha512-0dWs/SwKS5KPpuf6fUVVt9vSCl6HAqcDGhSITw/okv0rrIlXTUT6WhVsMJtXfFxTyVvwMeOecJHvQH3i/jRQtA==} + + '@lexical/code@0.16.1': + resolution: {integrity: sha512-pOC28rRZ2XkmI2nIJm50DbKaCJtk5D0o7r6nORYp4i0z+lxt5Sf2m82DL9ksUHJRqKy87pwJDpoWvJ2SAI0ohw==} + + '@lexical/devtools-core@0.16.1': + resolution: {integrity: sha512-8CvGERGL7ySDVGLU+YPeq+JupIXsOFlXa3EuJ88koLKqXxYenwMleZgGqayFp6lCP78xqPKnATVeoOZUt/NabQ==} + peerDependencies: + react: '>=17.x' + react-dom: '>=17.x' + + '@lexical/dragon@0.16.1': + resolution: {integrity: sha512-Rvd60GIYN5kpjjBumS34EnNbBaNsoseI0AlzOdtIV302jiHPCLH0noe9kxzu9nZy+MZmjZy8Dx2zTbQT2mueRw==} + + '@lexical/hashtag@0.16.1': + resolution: {integrity: sha512-G+YOxStAKs3q1utqm9KR4D4lCkwIH52Rctm4RgaVTI+4lvTaybeDRGFV75P/pI/qlF7/FvAYHTYEzCjtC3GNMQ==} + + '@lexical/history@0.16.1': + resolution: {integrity: sha512-WQhScx0TJeKSQAnEkRpIaWdUXqirrNrom2MxbBUc/32zEUMm9FzV7nRGknvUabEFUo7vZq6xTZpOExQJqHInQA==} + + '@lexical/html@0.16.1': + resolution: {integrity: sha512-vbtAdCvQ3PaAqa5mFmtmrvbiAvjCu1iXBAJ0bsHqFXCF2Sba5LwHVe8dUAOTpfEZEMbiHfjul6b5fj4vNPGF2A==} + + '@lexical/link@0.16.1': + resolution: {integrity: sha512-zG36gEnEqbIe6tK/MhXi7wn/XMY/zdivnPcOY5WyC3derkEezeLSSIFsC1u5UNeK5pbpNMSy4LDpLhi1Ww4Y5w==} + + '@lexical/list@0.16.1': + resolution: {integrity: sha512-i9YhLAh5N6YO9dP+R1SIL9WEdCKeTiQQYVUzj84vDvX5DIBxMPUjTmMn3LXu9T+QO3h1s2L/vJusZASrl45eAw==} + + '@lexical/mark@0.16.1': + resolution: {integrity: sha512-CZRGMLcxn5D+jzf1XnH+Z+uUugmpg1mBwTbGybCPm8UWpBrKDHkrscfMgWz62iRWz0cdVjM5+0zWpNElxFTRjQ==} + + '@lexical/markdown@0.16.1': + resolution: {integrity: sha512-0sBLttMvfQO/hVaIqpHdvDowpgV2CoRuWo2CNwvRLZPPWvPVjL4Nkb73wmi8zAZsAOTbX2aw+g4m/+k5oJqNig==} + + '@lexical/offset@0.16.1': + resolution: {integrity: sha512-/i2J04lQmFeydUZIF8tKXLQTXiJDTQ6GRnkfv1OpxU4amc0rwGa7+qAz/PuF1n58rP6InpLmSHxgY5JztXa2jw==} + + '@lexical/overflow@0.16.1': + resolution: {integrity: sha512-xh5YpoxwA7K4wgMQF/Sjl8sdjaxqesLCtH5ZrcMsaPlmucDIEEs+i8xxk+kDUTEY7y+3FvRxs4lGNgX8RVWkvQ==} + + '@lexical/plain-text@0.16.1': + resolution: {integrity: sha512-GjY4ylrBZIaAVIF8IFnmW0XGyHAuRmWA6gKB8iTTlsjgFrCHFIYC74EeJSp309O0Hflg9rRBnKoX1TYruFHVwA==} + + '@lexical/react@0.16.1': + resolution: {integrity: sha512-SsGgLt9iKfrrMRy9lFb6ROVPUYOgv6b+mCn9Al+TLqs/gBReDBi3msA7m526nrtBUKYUnjHdQ1QXIJzuKgOxcg==} + peerDependencies: + react: '>=17.x' + react-dom: '>=17.x' + + '@lexical/rich-text@0.16.1': + resolution: {integrity: sha512-4uEVXJur7tdSbqbmsToCW4YVm0AMh4y9LK077Yq2O9hSuA5dqpI8UbTDnxZN2D7RfahNvwlqp8eZKFB1yeiJGQ==} + + '@lexical/selection@0.16.1': + resolution: {integrity: sha512-+nK3RvXtyQvQDq7AZ46JpphmM33pwuulwiRfeXR5T9iFQTtgWOEjsAi/KKX7vGm70BxACfiSxy5QCOgBWFwVJg==} + + '@lexical/table@0.16.1': + resolution: {integrity: sha512-GWb0/MM1sVXpi1p2HWWOBldZXASMQ4c6WRNYnRmq7J/aB5N66HqQgJGKp3m66Kz4k1JjhmZfPs7F018qIBhnFQ==} + + '@lexical/text@0.16.1': + resolution: {integrity: sha512-Os/nKQegORTrKKN6vL3/FMVszyzyqaotlisPynvTaHTUC+yY4uyjM2hlF93i5a2ixxyiPLF9bDroxUP96TMPXg==} + + '@lexical/utils@0.16.1': + resolution: {integrity: sha512-BVyJxDQi/rIxFTDjf2zE7rMDKSuEaeJ4dybHRa/hRERt85gavGByQawSLeQlTjLaYLVsy+x7wCcqh2fNhlLf0g==} + + '@lexical/yjs@0.16.1': + resolution: {integrity: sha512-QHw1bmzB/IypIV1tRWMH4hhwE1xX7wV+HxbzBS8oJAkoU5AYXM/kyp/sQicgqiwVfpai1Px7zatOoUDFgbyzHQ==} + peerDependencies: + yjs: '>=13.5.22' + + '@mdx-js/loader@2.3.0': + resolution: {integrity: sha512-IqsscXh7Q3Rzb+f5DXYk0HU71PK+WuFsEhf+mSV3fOhpLcEpgsHvTQ2h0T6TlZ5gHOaBeFjkXwB52by7ypMyNg==} + peerDependencies: + webpack: '>=4' + + '@mdx-js/mdx@2.3.0': + resolution: {integrity: sha512-jLuwRlz8DQfQNiUCJR50Y09CGPq3fLtmtUQfVrj79E0JWu3dvsVcxVIcfhR5h0iXu+/z++zDrYeiJqifRynJkA==} + + '@mdx-js/react@2.3.0': + resolution: {integrity: sha512-zQH//gdOmuu7nt2oJR29vFhDv88oGPmVw6BggmrHeMI+xgEkp1B2dX9/bMBSYtK0dyLX/aOmesKS09g222K1/g==} + peerDependencies: + react: '>=16' + + '@mdx-js/react@3.1.0': + resolution: {integrity: sha512-QjHtSaoameoalGnKDT3FoIl4+9RwyTmo9ZJGBdLOks/YOiWHoRDI3PUwEzOE7kEmGcV3AFcp9K6dYu9rEuKLAQ==} + peerDependencies: + '@types/react': ~18.2.0 + react: '>=16' + + '@monaco-editor/loader@1.4.0': + resolution: {integrity: sha512-00ioBig0x642hytVspPl7DbQyaSWRaolYie/UFNjoTdvoKPzo6xrXLhTk9ixgIKcLH5b5vDOjVNiGyY+uDCUlg==} + peerDependencies: + monaco-editor: '>= 0.21.0 < 1' + + '@monaco-editor/react@4.6.0': + resolution: {integrity: sha512-RFkU9/i7cN2bsq/iTkurMWOEErmYcY6JiQI3Jn+WeR/FGISH8JbHERjpS9oRuSOPvDMJI0Z8nJeKkbOs9sBYQw==} + peerDependencies: + monaco-editor: '>= 0.25.0 < 1' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + + '@next/env@14.2.15': + resolution: {integrity: sha512-S1qaj25Wru2dUpcIZMjxeMVSwkt8BK4dmWHHiBuRstcIyOsMapqT4A4jSB6onvqeygkSSmOkyny9VVx8JIGamQ==} + + '@next/eslint-plugin-next@14.2.15': + resolution: {integrity: sha512-pKU0iqKRBlFB/ocOI1Ip2CkKePZpYpnw5bEItEkuZ/Nr9FQP1+p7VDWr4VfOdff4i9bFmrOaeaU1bFEyAcxiMQ==} + + '@next/mdx@14.2.15': + resolution: {integrity: sha512-OQWxKY5jWtHqPXdN3s5mj/LsD57pxt8CQsY4VQtTfQdQn6rNPd1bjN+kpbtezXdjgrKhvTJAb1yv1XGvzlh0uw==} + peerDependencies: + '@mdx-js/loader': '>=0.15.0' + '@mdx-js/react': '>=0.15.0' + peerDependenciesMeta: + '@mdx-js/loader': + optional: true + '@mdx-js/react': + optional: true + + '@next/swc-darwin-arm64@14.2.15': + resolution: {integrity: sha512-Rvh7KU9hOUBnZ9TJ28n2Oa7dD9cvDBKua9IKx7cfQQ0GoYUwg9ig31O2oMwH3wm+pE3IkAQ67ZobPfEgurPZIA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@next/swc-darwin-x64@14.2.15': + resolution: {integrity: sha512-5TGyjFcf8ampZP3e+FyCax5zFVHi+Oe7sZyaKOngsqyaNEpOgkKB3sqmymkZfowy3ufGA/tUgDPPxpQx931lHg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@next/swc-linux-arm64-gnu@14.2.15': + resolution: {integrity: sha512-3Bwv4oc08ONiQ3FiOLKT72Q+ndEMyLNsc/D3qnLMbtUYTQAmkx9E/JRu0DBpHxNddBmNT5hxz1mYBphJ3mfrrw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@next/swc-linux-arm64-musl@14.2.15': + resolution: {integrity: sha512-k5xf/tg1FBv/M4CMd8S+JL3uV9BnnRmoe7F+GWC3DxkTCD9aewFRH1s5rJ1zkzDa+Do4zyN8qD0N8c84Hu96FQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@next/swc-linux-x64-gnu@14.2.15': + resolution: {integrity: sha512-kE6q38hbrRbKEkkVn62reLXhThLRh6/TvgSP56GkFNhU22TbIrQDEMrO7j0IcQHcew2wfykq8lZyHFabz0oBrA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@next/swc-linux-x64-musl@14.2.15': + resolution: {integrity: sha512-PZ5YE9ouy/IdO7QVJeIcyLn/Rc4ml9M2G4y3kCM9MNf1YKvFY4heg3pVa/jQbMro+tP6yc4G2o9LjAz1zxD7tQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@next/swc-win32-arm64-msvc@14.2.15': + resolution: {integrity: sha512-2raR16703kBvYEQD9HNLyb0/394yfqzmIeyp2nDzcPV4yPjqNUG3ohX6jX00WryXz6s1FXpVhsCo3i+g4RUX+g==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@next/swc-win32-ia32-msvc@14.2.15': + resolution: {integrity: sha512-fyTE8cklgkyR1p03kJa5zXEaZ9El+kDNM5A+66+8evQS5e/6v0Gk28LqA0Jet8gKSOyP+OTm/tJHzMlGdQerdQ==} + engines: {node: '>= 10'} + cpu: [ia32] + os: [win32] + + '@next/swc-win32-x64-msvc@14.2.15': + resolution: {integrity: sha512-SzqGbsLsP9OwKNUG9nekShTwhj6JSB9ZLMWQ8g1gG6hdE5gQLncbnbymrwy2yVmH9nikSLYRYxYMFu78Ggp7/g==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@nolyfill/is-core-module@1.0.39': + resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==} + engines: {node: '>=12.4.0'} + + '@parcel/watcher-android-arm64@2.4.1': + resolution: {integrity: sha512-LOi/WTbbh3aTn2RYddrO8pnapixAziFl6SMxHM69r3tvdSm94JtCenaKgk1GRg5FJ5wpMCpHeW+7yqPlvZv7kg==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [android] + + '@parcel/watcher-darwin-arm64@2.4.1': + resolution: {integrity: sha512-ln41eihm5YXIY043vBrrHfn94SIBlqOWmoROhsMVTSXGh0QahKGy77tfEywQ7v3NywyxBBkGIfrWRHm0hsKtzA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [darwin] + + '@parcel/watcher-darwin-x64@2.4.1': + resolution: {integrity: sha512-yrw81BRLjjtHyDu7J61oPuSoeYWR3lDElcPGJyOvIXmor6DEo7/G2u1o7I38cwlcoBHQFULqF6nesIX3tsEXMg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [darwin] + + '@parcel/watcher-freebsd-x64@2.4.1': + resolution: {integrity: sha512-TJa3Pex/gX3CWIx/Co8k+ykNdDCLx+TuZj3f3h7eOjgpdKM+Mnix37RYsYU4LHhiYJz3DK5nFCCra81p6g050w==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [freebsd] + + '@parcel/watcher-linux-arm-glibc@2.4.1': + resolution: {integrity: sha512-4rVYDlsMEYfa537BRXxJ5UF4ddNwnr2/1O4MHM5PjI9cvV2qymvhwZSFgXqbS8YoTk5i/JR0L0JDs69BUn45YA==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + + '@parcel/watcher-linux-arm64-glibc@2.4.1': + resolution: {integrity: sha512-BJ7mH985OADVLpbrzCLgrJ3TOpiZggE9FMblfO65PlOCdG++xJpKUJ0Aol74ZUIYfb8WsRlUdgrZxKkz3zXWYA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + + '@parcel/watcher-linux-arm64-musl@2.4.1': + resolution: {integrity: sha512-p4Xb7JGq3MLgAfYhslU2SjoV9G0kI0Xry0kuxeG/41UfpjHGOhv7UoUDAz/jb1u2elbhazy4rRBL8PegPJFBhA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + + '@parcel/watcher-linux-x64-glibc@2.4.1': + resolution: {integrity: sha512-s9O3fByZ/2pyYDPoLM6zt92yu6P4E39a03zvO0qCHOTjxmt3GHRMLuRZEWhWLASTMSrrnVNWdVI/+pUElJBBBg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + + '@parcel/watcher-linux-x64-musl@2.4.1': + resolution: {integrity: sha512-L2nZTYR1myLNST0O632g0Dx9LyMNHrn6TOt76sYxWLdff3cB22/GZX2UPtJnaqQPdCRoszoY5rcOj4oMTtp5fQ==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + + '@parcel/watcher-win32-arm64@2.4.1': + resolution: {integrity: sha512-Uq2BPp5GWhrq/lcuItCHoqxjULU1QYEcyjSO5jqqOK8RNFDBQnenMMx4gAl3v8GiWa59E9+uDM7yZ6LxwUIfRg==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [win32] + + '@parcel/watcher-win32-ia32@2.4.1': + resolution: {integrity: sha512-maNRit5QQV2kgHFSYwftmPBxiuK5u4DXjbXx7q6eKjq5dsLXZ4FJiVvlcw35QXzk0KrUecJmuVFbj4uV9oYrcw==} + engines: {node: '>= 10.0.0'} + cpu: [ia32] + os: [win32] + + '@parcel/watcher-win32-x64@2.4.1': + resolution: {integrity: sha512-+DvS92F9ezicfswqrvIRM2njcYJbd5mb9CUgtrHCHmvn7pPPa+nMDRu1o1bYYz/l5IB2NVGNJWiH7h1E58IF2A==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [win32] + + '@parcel/watcher@2.4.1': + resolution: {integrity: sha512-HNjmfLQEVRZmHRET336f20H/8kOozUGwk7yajvsonjNxbj2wBTK1WsQuHkD5yYh9RxFGL2EyDHryOihOwUoKDA==} + engines: {node: '>= 10.0.0'} + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@pmmmwh/react-refresh-webpack-plugin@0.5.15': + resolution: {integrity: sha512-LFWllMA55pzB9D34w/wXUCf8+c+IYKuJDgxiZ3qMhl64KRMBHYM1I3VdGaD2BV5FNPV2/S2596bppxHbv2ZydQ==} + engines: {node: '>= 10.13'} + peerDependencies: + '@types/webpack': 4.x || 5.x + react-refresh: '>=0.10.0 <1.0.0' + sockjs-client: ^1.4.0 + type-fest: '>=0.17.0 <5.0.0' + webpack: '>=4.43.0 <6.0.0' + webpack-dev-server: 3.x || 4.x || 5.x + webpack-hot-middleware: 2.x + webpack-plugin-serve: 0.x || 1.x + peerDependenciesMeta: + '@types/webpack': + optional: true + sockjs-client: + optional: true + type-fest: + optional: true + webpack-dev-server: + optional: true + webpack-hot-middleware: + optional: true + webpack-plugin-serve: + optional: true + + '@reactflow/background@11.3.14': + resolution: {integrity: sha512-Gewd7blEVT5Lh6jqrvOgd4G6Qk17eGKQfsDXgyRSqM+CTwDqRldG2LsWN4sNeno6sbqVIC2fZ+rAUBFA9ZEUDA==} + peerDependencies: + react: '>=17' + react-dom: '>=17' + + '@reactflow/controls@11.2.14': + resolution: {integrity: sha512-MiJp5VldFD7FrqaBNIrQ85dxChrG6ivuZ+dcFhPQUwOK3HfYgX2RHdBua+gx+40p5Vw5It3dVNp/my4Z3jF0dw==} + peerDependencies: + react: '>=17' + react-dom: '>=17' + + '@reactflow/core@11.11.4': + resolution: {integrity: sha512-H4vODklsjAq3AMq6Np4LE12i1I4Ta9PrDHuBR9GmL8uzTt2l2jh4CiQbEMpvMDcp7xi4be0hgXj+Ysodde/i7Q==} + peerDependencies: + react: '>=17' + react-dom: '>=17' + + '@reactflow/minimap@11.7.14': + resolution: {integrity: sha512-mpwLKKrEAofgFJdkhwR5UQ1JYWlcAAL/ZU/bctBkuNTT1yqV+y0buoNVImsRehVYhJwffSWeSHaBR5/GJjlCSQ==} + peerDependencies: + react: '>=17' + react-dom: '>=17' + + '@reactflow/node-resizer@2.2.14': + resolution: {integrity: sha512-fwqnks83jUlYr6OHcdFEedumWKChTHRGw/kbCxj0oqBd+ekfs+SIp4ddyNU0pdx96JIm5iNFS0oNrmEiJbbSaA==} + peerDependencies: + react: '>=17' + react-dom: '>=17' + + '@reactflow/node-toolbar@1.3.14': + resolution: {integrity: sha512-rbynXQnH/xFNu4P9H+hVqlEUafDCkEoCy0Dg9mG22Sg+rY/0ck6KkrAQrYrTgXusd+cEJOMK0uOOFCK2/5rSGQ==} + peerDependencies: + react: '>=17' + react-dom: '>=17' + + '@remixicon/react@4.3.0': + resolution: {integrity: sha512-mAVDn8pAa9dURltGwiYrf7bPIqjG4ZAnCUHfjpgz3g+HLSDNXOaJ67Z5wmjVB5KMGpp9JbbTN5vsp2z+ajVLWg==} + peerDependencies: + react: '>=18.2.0' + + '@rgrove/parse-xml@4.1.0': + resolution: {integrity: sha512-pBiltENdy8SfI0AeR1e5TRpS9/9Gl0eiOEt6ful2jQfzsgvZYWqsKiBWaOCLdocQuk0wS7KOHI37n0C1pnKqTw==} + engines: {node: '>=14.0.0'} + + '@rtsao/scc@1.1.0': + resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} + + '@rushstack/eslint-patch@1.10.4': + resolution: {integrity: sha512-WJgX9nzTqknM393q1QJDJmoW28kUfEnybeTfVNcNAPnIx210RXm2DiXiHzfNPJNIUUb1tJnz/l4QGtJ30PgWmA==} + + '@sentry-internal/feedback@7.119.2': + resolution: {integrity: sha512-bnR1yJWVBZfXGx675nMXE8hCXsxluCBfIFy9GQT8PTN/urxpoS9cGz+5F7MA7Xe3Q06/7TT0Mz3fcDvjkqTu3Q==} + engines: {node: '>=12'} + + '@sentry-internal/replay-canvas@7.119.2': + resolution: {integrity: sha512-Lqo8IFyeKkdOrOGRqm9jCEqeBl8kINe5+c2VqULpkO/I6ql6ISwPSYnmG6yL8cCVIaT1893CLog/pS4FxCv8/Q==} + engines: {node: '>=12'} + + '@sentry-internal/tracing@7.119.2': + resolution: {integrity: sha512-V2W+STWrafyGJhQv3ulMFXYDwWHiU6wHQAQBShsHVACiFaDrJ2kPRet38FKv4dMLlLlP2xN+ss2e5zv3tYlTiQ==} + engines: {node: '>=8'} + + '@sentry/browser@7.119.2': + resolution: {integrity: sha512-Wb2RzCsJBTNCmS9KPmbVyV5GGzFXjFdUThAN9xlnN5GgemMBwdQjGu/tRYr8yJAVsRb0EOFH8IuJBNKKNnO49g==} + engines: {node: '>=8'} + + '@sentry/core@7.119.2': + resolution: {integrity: sha512-hQr3d2yWq/2lMvoyBPOwXw1IHqTrCjOsU1vYKhAa6w9vGbJZFGhKGGE2KEi/92c3gqGn+gW/PC7cV6waCTDuVA==} + engines: {node: '>=8'} + + '@sentry/integrations@7.119.2': + resolution: {integrity: sha512-dCuXKvbUE3gXVVa696SYMjlhSP6CxpMH/gl4Jk26naEB8Xjsn98z/hqEoXLg6Nab73rjR9c/9AdKqBbwVMHyrQ==} + engines: {node: '>=8'} + + '@sentry/react@7.119.2': + resolution: {integrity: sha512-fE48R/mtb/bpc4/YVvKurKSAZ0ueUI5Ma0cVSr/Fi09rFdGwLRMcweM1UydREO/ILiyt8FezyZg7L20VAp4/TQ==} + engines: {node: '>=8'} + peerDependencies: + react: 15.x || 16.x || 17.x || 18.x + + '@sentry/replay@7.119.2': + resolution: {integrity: sha512-nHDsBt0mlJXTWAHjzQdCzDbhV2fv8B62PPB5mu5SpI+G5h+ir3r5lR0lZZrMT8eurVowb/HnLXAs+XYVug3blg==} + engines: {node: '>=12'} + + '@sentry/types@7.119.2': + resolution: {integrity: sha512-ydq1tWsdG7QW+yFaTp0gFaowMLNVikIqM70wxWNK+u98QzKnVY/3XTixxNLsUtnAB4Y+isAzFhrc6Vb5GFdFeg==} + engines: {node: '>=8'} + + '@sentry/utils@7.119.2': + resolution: {integrity: sha512-TLdUCvcNgzKP0r9YD7tgCL1PEUp42TObISridsPJ5rhpVGQJvpr+Six0zIkfDUxerLYWZoK8QMm9KgFlPLNQzA==} + engines: {node: '>=8'} + + '@sinclair/typebox@0.27.8': + resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + + '@sindresorhus/is@4.6.0': + resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} + engines: {node: '>=10'} + + '@sinonjs/commons@3.0.1': + resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} + + '@sinonjs/fake-timers@10.3.0': + resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} + + '@storybook/addon-actions@8.3.6': + resolution: {integrity: sha512-nOqgl0WoZK2KwjaABaXMoIgrIHOQl9inOzJvqQau0HOtsvnXGXYfJXYnpjZenoZDoZXKbUDl0U2haDFx2a2fJw==} + peerDependencies: + storybook: ^8.3.6 + + '@storybook/addon-backgrounds@8.3.6': + resolution: {integrity: sha512-yBn+a8i5OJzJaX6Bx5MAkfei7c2nvq+RRmvuyvxw11rtDGR6Nz4OBBe56reWxo868wVUggpRTPJCMVe5tDYgVg==} + peerDependencies: + storybook: ^8.3.6 + + '@storybook/addon-controls@8.3.6': + resolution: {integrity: sha512-9IMLHgtWPuFoRCt3hDsIk1FbkK5SlCMDW1DDwtTBIeWYYZLvptS42+vGVTeQ8v5SejmVzZkzuUdzu3p4sb3IcA==} + peerDependencies: + storybook: ^8.3.6 + + '@storybook/addon-docs@8.3.6': + resolution: {integrity: sha512-31Rk1TOhDIzGM2wNCUIB1xKuWtArW0D2Puua9warEXlQ3FtvwmxnPrwbIzw6ufYZDWPwl9phDYTcRh8WqZIoGg==} + peerDependencies: + storybook: ^8.3.6 + + '@storybook/addon-essentials@8.3.6': + resolution: {integrity: sha512-MQPFvThlGU7wlda1xhBPQCmDh90cSSZ31OsVs1uC5kJh0aLbY2gYXPurq1G54kzrYo8SMfBxsXrCplz8Ir6UTg==} + peerDependencies: + storybook: ^8.3.6 + + '@storybook/addon-highlight@8.3.6': + resolution: {integrity: sha512-A7uU+1OPVXGpkklEUJjSl2VEEDLCSNvmffUJlvW1GjajsNFIHOW2CSD+KnfFlQyPxyVbnWAYLqUP4XJxoqrvDw==} + peerDependencies: + storybook: ^8.3.6 + + '@storybook/addon-interactions@8.3.6': + resolution: {integrity: sha512-Y0YUJj0oE1+6DFkaTPXM/8+dwTSoy0ltj2Sn2KOTJYzxKQYXBp8TlUv0QOQiGH7o/GKXIWek/VlTuvG/JEeiWw==} + peerDependencies: + storybook: ^8.3.6 + + '@storybook/addon-links@8.3.6': + resolution: {integrity: sha512-EGEH/kEjndEldbqyiJ8XSASkxqwzL/lgA/+6mHpa6Ljxhk1s5IMGcdA1ymJYJ2BpNdkUxRj/uxAa38eGcQiJ/g==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + storybook: ^8.3.6 + peerDependenciesMeta: + react: + optional: true + + '@storybook/addon-measure@8.3.6': + resolution: {integrity: sha512-VHWeGgYjhzhwb2WAqYW/qyEPqg5pwKR/XqFfd+3tEirUs/64olL1l3lzLwZ8Cm07cJ81T8Z4myywb9kObZfQlw==} + peerDependencies: + storybook: ^8.3.6 + + '@storybook/addon-onboarding@8.3.6': + resolution: {integrity: sha512-DvwtK3k5docaO7ZO0LRXL1myCwOnW2X+e9c383GEk9AykgL5otzkMjxRZ1rSAw39q/WIE9H0vBvUmzGVRpUm+A==} + peerDependencies: + storybook: ^8.3.6 + + '@storybook/addon-outline@8.3.6': + resolution: {integrity: sha512-+VXpM8SIHX2cn30qLlMvER9/6iioFRSn2sAfLniqy4RrcQmcMP+qgE7ZzbzExt7cneJh3VFsYqBS/HElu14Vgg==} + peerDependencies: + storybook: ^8.3.6 + + '@storybook/addon-themes@8.3.6': + resolution: {integrity: sha512-NX6zVWs0JVUg0xICL2v1zlb6eTAQYlE/vd6ATA4bNUNL5sabWGEd1w2ArQaHC9nTnfV60JuRQ8o3SvD7Gg0xMg==} + peerDependencies: + storybook: ^8.3.6 + + '@storybook/addon-toolbars@8.3.6': + resolution: {integrity: sha512-FJH+lRoZXENfpMR/G09ZqB0TmL/k6bv07GN1ysoVs420tKRgjfz6uXaZz5COrhcdISr5mTNmG+mw9x7xXTfX3Q==} + peerDependencies: + storybook: ^8.3.6 + + '@storybook/addon-viewport@8.3.6': + resolution: {integrity: sha512-bL51v837W1cng/+0pypkoLsWKWmvux96zLOzqLCpcWAQ4OSMhW3foIWpCiFwMG/KY+GanoOocTx6i7j5hLtuTA==} + peerDependencies: + storybook: ^8.3.6 + + '@storybook/blocks@8.3.6': + resolution: {integrity: sha512-Oc5jU6EzfsENjrd91KcKyEKBh60RT+8uyLi1RIrymC2C/mzZMTEoNIrbnQt0eIqbjlHxn6y9JMJxHu4NJ4EmZg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + storybook: ^8.3.6 + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + + '@storybook/builder-webpack5@8.3.6': + resolution: {integrity: sha512-Eqn2k8aA9f0o6IMQNAxGAMfSDeTP3YYCQAtOL5Gt5lgrqLV5JMTbZOfmaRBZ82ej/BBSAopnQKIJjQBBFx6kAQ==} + peerDependencies: + storybook: ^8.3.6 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@storybook/components@8.3.6': + resolution: {integrity: sha512-TXuoGZY7X3iixF45lXkYOFk8k2q9OHcqHyHyem1gATLLQXgyOvDgzm+VB7uKBNzssRQPEE+La70nfG8bq/viRw==} + peerDependencies: + storybook: ^8.3.6 + + '@storybook/core-webpack@8.3.6': + resolution: {integrity: sha512-ks306CFKD7FePQzRYyTjddiLsSriceblzv4rI+IjVtftkJvcEbxub2yWkV27kPP/e9kSd4Li3M34bX5mkiwkZA==} + peerDependencies: + storybook: ^8.3.6 + + '@storybook/core@8.3.6': + resolution: {integrity: sha512-frwfgf0EJ7QL29DWZ5bla/g0eOOWqJGd14t+VUBlpP920zB6sdDfo7+p9JoCjD9u08lGeFDqbPNKayUk+0qDag==} + + '@storybook/csf-plugin@8.3.6': + resolution: {integrity: sha512-TJyJPFejO6Gyr3+bXqE/+LomQbivvfHEbee/GwtlRj0XF4KQlqnvuEdEdcK25JbD0NXT8AbyncEUmjoxE7ojQw==} + peerDependencies: + storybook: ^8.3.6 + + '@storybook/csf@0.0.1': + resolution: {integrity: sha512-USTLkZze5gkel8MYCujSRBVIrUQ3YPBrLOx7GNk/0wttvVtlzWXAq9eLbQ4p/NicGxP+3T7KPEMVV//g+yubpw==} + + '@storybook/csf@0.1.11': + resolution: {integrity: sha512-dHYFQH3mA+EtnCkHXzicbLgsvzYjcDJ1JWsogbItZogkPHgSJM/Wr71uMkcvw8v9mmCyP4NpXJuu6bPoVsOnzg==} + + '@storybook/global@5.0.0': + resolution: {integrity: sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==} + + '@storybook/icons@1.2.12': + resolution: {integrity: sha512-UxgyK5W3/UV4VrI3dl6ajGfHM4aOqMAkFLWe2KibeQudLf6NJpDrDMSHwZj+3iKC4jFU7dkKbbtH2h/al4sW3Q==} + engines: {node: '>=14.0.0'} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + + '@storybook/instrumenter@8.3.6': + resolution: {integrity: sha512-0RowbKwoB/s7rtymlnKNiyWN1Z3ZK5mwgzVjlRmzxDL8hrdi5KDjTNExuJTRR3ZaBP2RR0/I3m/n0p9JhHAZvg==} + peerDependencies: + storybook: ^8.3.6 + + '@storybook/manager-api@8.3.6': + resolution: {integrity: sha512-Xt5VFZcL+G/9uzaHjzWFhxRNrP+4rPhSRKEvCZorAbC9+Hv+ZDs1JSZS5wMb4WKpXBZ0rwDVOLwngqbVtfRHuQ==} + peerDependencies: + storybook: ^8.3.6 + + '@storybook/nextjs@8.3.6': + resolution: {integrity: sha512-jNrEcS26OER645kJ3nMuSSgu8BWJhEY8MM9rDlE/133A/hojTBc2vZXwSfgZ22tAc7ckrbyw2gygEUPI2rHImA==} + engines: {node: '>=18.0.0'} + peerDependencies: + next: ^13.5.0 || ^14.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + storybook: ^8.3.6 + typescript: '*' + webpack: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + webpack: + optional: true + + '@storybook/preset-react-webpack@8.3.6': + resolution: {integrity: sha512-Ar0vhJITXa4xsXT3RdgYZ2mhXxE3jfUisQzsITey5a2RVgnSBIENggmRZ/6j1oVgEXFthbarNEsebGiA+2vDZg==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + storybook: ^8.3.6 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@storybook/preview-api@8.3.6': + resolution: {integrity: sha512-/Wxvb7wbI2O2iH63arRQQyyojA630vibdshkFjuC/u1nYdptEV1jkxa0OYmbZbKCn4/ze6uH4hfsKOpDPV9SWg==} + peerDependencies: + storybook: ^8.3.6 + + '@storybook/react-docgen-typescript-plugin@1.0.6--canary.9.0c3f3b7.0': + resolution: {integrity: sha512-KUqXC3oa9JuQ0kZJLBhVdS4lOneKTOopnNBK4tUAgoxWQ3u/IjzdueZjFr7gyBrXMoU6duutk3RQR9u8ZpYJ4Q==} + peerDependencies: + typescript: '>= 4.x' + webpack: '>= 4' + + '@storybook/react-dom-shim@8.3.6': + resolution: {integrity: sha512-9BO6VXIdli4GHSfiP/Z0gwAf7oQig3D/yWK2U1+91UWDV8nIAgnNBAi76U4ORC6MiK5MdkDfIikIxnLLeLnahA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + storybook: ^8.3.6 + + '@storybook/react@8.3.6': + resolution: {integrity: sha512-s3COryqIOYK7urgZaCPb77zlxGjPKr6dIsYmblQJcsFY2ZlG2x0Ysm8b5oRgD8Pv71hCJ0PKYA4RzDgBVYJS9A==} + engines: {node: '>=18.0.0'} + peerDependencies: + '@storybook/test': 8.3.6 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta + storybook: ^8.3.6 + typescript: '>= 4.2.x' + peerDependenciesMeta: + '@storybook/test': + optional: true + typescript: + optional: true + + '@storybook/test@8.3.6': + resolution: {integrity: sha512-WIc8LzK9jaEw+e3OiweEM2j3cppPzsWod59swuf6gDBf176EQLIyjtVc+Kh3qO4NNkcL+lwmqaLPjOxlBLaDbg==} + peerDependencies: + storybook: ^8.3.6 + + '@storybook/theming@8.3.6': + resolution: {integrity: sha512-LQjUk6GXRW9ELkoBKuqzQKFUW+ajfGPfVELcfs3/VQX61VhthJ4olov4bGPc04wsmmFMgN/qODxT485IwOHfPQ==} + peerDependencies: + storybook: ^8.3.6 + + '@svgdotjs/svg.js@3.2.4': + resolution: {integrity: sha512-BjJ/7vWNowlX3Z8O4ywT58DqbNRyYlkk6Yz/D13aB7hGmfQTvGX4Tkgtm/ApYlu9M7lCQi15xUEidqMUmdMYwg==} + + '@swc/counter@0.1.3': + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + + '@swc/helpers@0.5.5': + resolution: {integrity: sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==} + + '@szmarczak/http-timer@4.0.6': + resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} + engines: {node: '>=10'} + + '@tailwindcss/line-clamp@0.4.4': + resolution: {integrity: sha512-5U6SY5z8N42VtrCrKlsTAA35gy2VSyYtHWCsg1H87NU1SXnEfekTVlrga9fzUDrrHcGi2Lb5KenUWb4lRQT5/g==} + peerDependencies: + tailwindcss: '>=2.0.0 || >=3.0.0 || >=3.0.0-alpha.1' + + '@tailwindcss/typography@0.5.15': + resolution: {integrity: sha512-AqhlCXl+8grUz8uqExv5OTtgpjuVIwFTSXTrh8y9/pw6q2ek7fJ+Y8ZEVw7EB2DCcuCOtEjf9w3+J3rzts01uA==} + peerDependencies: + tailwindcss: '>=3.0.0 || insiders || >=4.0.0-alpha.20' + + '@tanstack/react-virtual@3.10.8': + resolution: {integrity: sha512-VbzbVGSsZlQktyLrP5nxE+vE1ZR+U0NFAWPbJLoG2+DKPwd2D7dVICTVIIaYlJqX1ZCEnYDbaOpmMwbsyhBoIA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + + '@tanstack/virtual-core@3.10.8': + resolution: {integrity: sha512-PBu00mtt95jbKFi6Llk9aik8bnR3tR/oQP1o3TSi+iG//+Q2RTIzCEgKkHG8BB86kxMNW6O8wku+Lmi+QFR6jA==} + + '@testing-library/dom@10.4.0': + resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==} + engines: {node: '>=18'} + + '@testing-library/jest-dom@6.5.0': + resolution: {integrity: sha512-xGGHpBXYSHUUr6XsKBfs85TWlYKpTc37cSBBVrXcib2MkHLboWlkClhWF37JKlDb9KEq3dHs+f2xR7XJEWGBxA==} + engines: {node: '>=14', npm: '>=6', yarn: '>=1'} + + '@testing-library/jest-dom@6.6.2': + resolution: {integrity: sha512-P6GJD4yqc9jZLbe98j/EkyQDTPgqftohZF5FBkHY5BUERZmcf4HeO2k0XaefEg329ux2p21i1A1DmyQ1kKw2Jw==} + engines: {node: '>=14', npm: '>=6', yarn: '>=1'} + + '@testing-library/react@16.0.1': + resolution: {integrity: sha512-dSmwJVtJXmku+iocRhWOUFbrERC76TX2Mnf0ATODz8brzAZrMBbzLwQixlBSanZxR6LddK3eiwpSFZgDET1URg==} + engines: {node: '>=18'} + peerDependencies: + '@testing-library/dom': ^10.0.0 + '@types/react': ~18.2.0 + '@types/react-dom': ~18.2.0 + react: ^18.0.0 + react-dom: ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@testing-library/user-event@14.5.2': + resolution: {integrity: sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==} + engines: {node: '>=12', npm: '>=6'} + peerDependencies: + '@testing-library/dom': '>=7.21.4' + + '@tootallnate/once@2.0.0': + resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} + engines: {node: '>= 10'} + + '@tsconfig/node10@1.0.11': + resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} + + '@tsconfig/node12@1.0.11': + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + + '@tsconfig/node14@1.0.3': + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + + '@tsconfig/node16@1.0.4': + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + + '@types/acorn@4.0.6': + resolution: {integrity: sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==} + + '@types/aria-query@5.0.4': + resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} + + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.6.8': + resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.20.6': + resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} + + '@types/body-parser@1.19.5': + resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} + + '@types/cacheable-request@6.0.3': + resolution: {integrity: sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==} + + '@types/connect@3.4.38': + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + + '@types/crypto-js@4.2.2': + resolution: {integrity: sha512-sDOLlVbHhXpAUAL0YHDUUwDZf3iN4Bwi4W6a0W0b+QcAezUbRtH4FVb+9J4h+XFPW7l/gQ9F8qC7P+Ec4k8QVQ==} + + '@types/d3-array@3.2.1': + resolution: {integrity: sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==} + + '@types/d3-axis@3.0.6': + resolution: {integrity: sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==} + + '@types/d3-brush@3.0.6': + resolution: {integrity: sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==} + + '@types/d3-chord@3.0.6': + resolution: {integrity: sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==} + + '@types/d3-color@3.1.3': + resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==} + + '@types/d3-contour@3.0.6': + resolution: {integrity: sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==} + + '@types/d3-delaunay@6.0.4': + resolution: {integrity: sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==} + + '@types/d3-dispatch@3.0.6': + resolution: {integrity: sha512-4fvZhzMeeuBJYZXRXrRIQnvUYfyXwYmLsdiN7XXmVNQKKw1cM8a5WdID0g1hVFZDqT9ZqZEY5pD44p24VS7iZQ==} + + '@types/d3-drag@3.0.7': + resolution: {integrity: sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==} + + '@types/d3-dsv@3.0.7': + resolution: {integrity: sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==} + + '@types/d3-ease@3.0.2': + resolution: {integrity: sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==} + + '@types/d3-fetch@3.0.7': + resolution: {integrity: sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==} + + '@types/d3-force@3.0.10': + resolution: {integrity: sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==} + + '@types/d3-format@3.0.4': + resolution: {integrity: sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==} + + '@types/d3-geo@3.1.0': + resolution: {integrity: sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==} + + '@types/d3-hierarchy@3.1.7': + resolution: {integrity: sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==} + + '@types/d3-interpolate@3.0.4': + resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==} + + '@types/d3-path@3.1.0': + resolution: {integrity: sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==} + + '@types/d3-polygon@3.0.2': + resolution: {integrity: sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==} + + '@types/d3-quadtree@3.0.6': + resolution: {integrity: sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==} + + '@types/d3-random@3.0.3': + resolution: {integrity: sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==} + + '@types/d3-scale-chromatic@3.0.3': + resolution: {integrity: sha512-laXM4+1o5ImZv3RpFAsTRn3TEkzqkytiOY0Dz0sq5cnd1dtNlk6sHLon4OvqaiJb28T0S/TdsBI3Sjsy+keJrw==} + + '@types/d3-scale@4.0.8': + resolution: {integrity: sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==} + + '@types/d3-selection@3.0.11': + resolution: {integrity: sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==} + + '@types/d3-shape@3.1.6': + resolution: {integrity: sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==} + + '@types/d3-time-format@4.0.3': + resolution: {integrity: sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==} + + '@types/d3-time@3.0.3': + resolution: {integrity: sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==} + + '@types/d3-timer@3.0.2': + resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==} + + '@types/d3-transition@3.0.9': + resolution: {integrity: sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==} + + '@types/d3-zoom@3.0.8': + resolution: {integrity: sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==} + + '@types/d3@7.4.3': + resolution: {integrity: sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==} + + '@types/dagre@0.7.52': + resolution: {integrity: sha512-XKJdy+OClLk3hketHi9Qg6gTfe1F3y+UFnHxKA2rn9Dw+oXa4Gb378Ztz9HlMgZKSxpPmn4BNVh9wgkpvrK1uw==} + + '@types/debug@4.1.12': + resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + + '@types/doctrine@0.0.9': + resolution: {integrity: sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA==} + + '@types/escodegen@0.0.6': + resolution: {integrity: sha512-AjwI4MvWx3HAOaZqYsjKWyEObT9lcVV0Y0V8nXo6cXzN8ZiMxVhf6F3d/UNvXVGKrEzL/Dluc5p+y9GkzlTWig==} + + '@types/estree-jsx@1.0.5': + resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} + + '@types/estree@0.0.51': + resolution: {integrity: sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==} + + '@types/estree@1.0.6': + resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + + '@types/express-serve-static-core@4.19.6': + resolution: {integrity: sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==} + + '@types/express@4.17.21': + resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==} + + '@types/geojson@7946.0.14': + resolution: {integrity: sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==} + + '@types/graceful-fs@4.1.9': + resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} + + '@types/hast@2.3.10': + resolution: {integrity: sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==} + + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + + '@types/html-minifier-terser@6.1.0': + resolution: {integrity: sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==} + + '@types/http-cache-semantics@4.0.4': + resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} + + '@types/http-errors@2.0.4': + resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} + + '@types/istanbul-lib-coverage@2.0.6': + resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} + + '@types/istanbul-lib-report@3.0.3': + resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} + + '@types/istanbul-reports@3.0.4': + resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} + + '@types/jest@29.5.13': + resolution: {integrity: sha512-wd+MVEZCHt23V0/L642O5APvspWply/rGY5BcW4SUETo2UzPU3Z26qr8jC2qxpimI2jjx9h7+2cj2FwIr01bXg==} + + '@types/js-cookie@3.0.6': + resolution: {integrity: sha512-wkw9yd1kEXOPnvEeEV1Go1MmxtBJL0RR79aOTAApecWFVu7w0NNXNqhcWgvw2YgZDYadliXkl14pa3WXw5jlCQ==} + + '@types/jsdom@20.0.1': + resolution: {integrity: sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/json5@0.0.29': + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + + '@types/katex@0.14.0': + resolution: {integrity: sha512-+2FW2CcT0K3P+JMR8YG846bmDwplKUTsWgT2ENwdQ1UdVfRk3GQrh6Mi4sTopy30gI8Uau5CEqHTDZ6YvWIUPA==} + + '@types/katex@0.16.7': + resolution: {integrity: sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==} + + '@types/keyv@3.1.4': + resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} + + '@types/lodash-es@4.17.12': + resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==} + + '@types/lodash@4.17.12': + resolution: {integrity: sha512-sviUmCE8AYdaF/KIHLDJBQgeYzPBI0vf/17NaYehBJfYD1j6/L95Slh07NlyK2iNyBNaEkb3En2jRt+a8y3xZQ==} + + '@types/mdast@3.0.15': + resolution: {integrity: sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==} + + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + + '@types/mdx@2.0.13': + resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==} + + '@types/mime@1.3.5': + resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} + + '@types/ms@0.7.34': + resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} + + '@types/negotiator@0.6.3': + resolution: {integrity: sha512-JkXTOdKs5MF086b/pt8C3+yVp3iDUwG635L7oCH6HvJvvr6lSUU5oe/gLXnPEfYRROHjJIPgCV6cuAg8gGkntQ==} + + '@types/node@18.15.0': + resolution: {integrity: sha512-z6nr0TTEOBGkzLGmbypWOGnpSpSIBorEhC4L+4HeQ2iezKCi4f77kyslRwvHeNitymGQ+oFyIWGP96l/DPSV9w==} + + '@types/node@22.7.7': + resolution: {integrity: sha512-SRxCrrg9CL/y54aiMCG3edPKdprgMVGDXjA3gB8UmmBW5TcXzRUYAh8EWzTnSJFAd1rgImPELza+A3bJ+qxz8Q==} + + '@types/normalize-package-data@2.4.4': + resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} + + '@types/papaparse@5.3.15': + resolution: {integrity: sha512-JHe6vF6x/8Z85nCX4yFdDslN11d+1pr12E526X8WAfhadOeaOTx5AuIkvDKIBopfvlzpzkdMx4YyvSKCM9oqtw==} + + '@types/parse-json@4.0.2': + resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} + + '@types/prop-types@15.7.13': + resolution: {integrity: sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==} + + '@types/qs@6.9.16': + resolution: {integrity: sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A==} + + '@types/range-parser@1.2.7': + resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} + + '@types/react-dom@18.2.25': + resolution: {integrity: sha512-o/V48vf4MQh7juIKZU2QGDfli6p1+OOi5oXx36Hffpc9adsHeXjVp8rHuPkjd8VT8sOJ2Zp05HR7CdpGTIUFUA==} + + '@types/react-slider@1.3.6': + resolution: {integrity: sha512-RS8XN5O159YQ6tu3tGZIQz1/9StMLTg/FCIPxwqh2gwVixJnlfIodtVx+fpXVMZHe7A58lAX1Q4XTgAGOQaCQg==} + + '@types/react-syntax-highlighter@15.5.13': + resolution: {integrity: sha512-uLGJ87j6Sz8UaBAooU0T6lWJ0dBmjZgN1PZTrj05TNql2/XpC6+4HhMT5syIdFUUt+FASfCeLLv4kBygNU+8qA==} + + '@types/react-window-infinite-loader@1.0.9': + resolution: {integrity: sha512-gEInTjQwURCnDOFyIEK2+fWB5gTjqwx30O62QfxA9stE5aiB6EWkGj4UMhc0axq7/FV++Gs/TGW8FtgEx0S6Tw==} + + '@types/react-window@1.8.8': + resolution: {integrity: sha512-8Ls660bHR1AUA2kuRvVG9D/4XpRC6wjAaPT9dil7Ckc76eP9TKWZwwmgfq8Q1LANX3QNDnoU4Zp48A3w+zK69Q==} + + '@types/react@18.2.79': + resolution: {integrity: sha512-RwGAGXPl9kSXwdNTafkOEuFrTBD5SA2B3iEB96xi8+xu5ddUa/cpvyVCSNn+asgLCTHkb5ZxN8gbuibYJi4s1w==} + + '@types/recordrtc@5.6.14': + resolution: {integrity: sha512-Reiy1sl11xP0r6w8DW3iQjc1BgXFyNC7aDuutysIjpFoqyftbQps9xPA2FoBkfVXpJM61betgYPNt+v65zvMhA==} + + '@types/resolve@1.20.6': + resolution: {integrity: sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ==} + + '@types/responselike@1.0.3': + resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==} + + '@types/semver@7.5.8': + resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} + + '@types/send@0.17.4': + resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} + + '@types/serve-static@1.15.7': + resolution: {integrity: sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==} + + '@types/sortablejs@1.15.8': + resolution: {integrity: sha512-b79830lW+RZfwaztgs1aVPgbasJ8e7AXtZYHTELNXZPsERt4ymJdjV4OccDbHQAvHrCcFpbF78jkm0R6h/pZVg==} + + '@types/stack-utils@2.0.3': + resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} + + '@types/tough-cookie@4.0.5': + resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} + + '@types/unist@2.0.11': + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} + + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + + '@types/uuid@9.0.8': + resolution: {integrity: sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==} + + '@types/yargs-parser@21.0.3': + resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} + + '@types/yargs@17.0.33': + resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==} + + '@typescript-eslint/eslint-plugin@5.62.0': + resolution: {integrity: sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + '@typescript-eslint/parser': ^5.0.0 + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/eslint-plugin@8.10.0': + resolution: {integrity: sha512-phuB3hoP7FFKbRXxjl+DRlQDuJqhpOnm5MmtROXyWi3uS/Xg2ZXqiQfcG2BJHiN4QKyzdOJi3NEn/qTnjUlkmQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/parser@5.62.0': + resolution: {integrity: sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/parser@8.10.0': + resolution: {integrity: sha512-E24l90SxuJhytWJ0pTQydFT46Nk0Z+bsLKo/L8rtQSL93rQ6byd1V/QbDpHUTdLPOMsBCcYXZweADNCfOCmOAg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/scope-manager@5.62.0': + resolution: {integrity: sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@typescript-eslint/scope-manager@8.10.0': + resolution: {integrity: sha512-AgCaEjhfql9MDKjMUxWvH7HjLeBqMCBfIaBbzzIcBbQPZE7CPh1m6FF+L75NUMJFMLYhCywJXIDEMa3//1A0dw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/type-utils@5.62.0': + resolution: {integrity: sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '*' + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/type-utils@8.10.0': + resolution: {integrity: sha512-PCpUOpyQSpxBn230yIcK+LeCQaXuxrgCm2Zk1S+PTIRJsEfU6nJ0TtwyH8pIwPK/vJoA+7TZtzyAJSGBz+s/dg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/types@5.62.0': + resolution: {integrity: sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@typescript-eslint/types@8.10.0': + resolution: {integrity: sha512-k/E48uzsfJCRRbGLapdZgrX52csmWJ2rcowwPvOZ8lwPUv3xW6CcFeJAXgx4uJm+Ge4+a4tFOkdYvSpxhRhg1w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@5.62.0': + resolution: {integrity: sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/typescript-estree@8.10.0': + resolution: {integrity: sha512-3OE0nlcOHaMvQ8Xu5gAfME3/tWVDpb/HxtpUZ1WeOAksZ/h/gwrBzCklaGzwZT97/lBbbxJ16dMA98JMEngW4w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/utils@5.62.0': + resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + + '@typescript-eslint/utils@8.10.0': + resolution: {integrity: sha512-Oq4uZ7JFr9d1ZunE/QKy5egcDRXT/FrS2z/nlxzPua2VHFtmMvFNDvpq1m/hq0ra+T52aUezfcjGRIB7vNJF9w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + + '@typescript-eslint/visitor-keys@5.62.0': + resolution: {integrity: sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@typescript-eslint/visitor-keys@8.10.0': + resolution: {integrity: sha512-k8nekgqwr7FadWk548Lfph6V3r9OVqjzAIVskE7orMZR23cGJjAOVazsZSJW+ElyjfTM4wx/1g88Mi70DDtG9A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@ungap/structured-clone@1.2.0': + resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + + '@vitest/expect@2.0.5': + resolution: {integrity: sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA==} + + '@vitest/pretty-format@2.0.5': + resolution: {integrity: sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ==} + + '@vitest/pretty-format@2.1.3': + resolution: {integrity: sha512-XH1XdtoLZCpqV59KRbPrIhFCOO0hErxrQCMcvnQete3Vibb9UeIOX02uFPfVn3Z9ZXsq78etlfyhnkmIZSzIwQ==} + + '@vitest/spy@2.0.5': + resolution: {integrity: sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA==} + + '@vitest/utils@2.0.5': + resolution: {integrity: sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ==} + + '@vitest/utils@2.1.3': + resolution: {integrity: sha512-xpiVfDSg1RrYT0tX6czgerkpcKFmFOF/gCr30+Mve5V2kewCy4Prn1/NDMSRwaSmT7PRaOF83wu+bEtsY1wrvA==} + + '@vue/compiler-core@3.5.12': + resolution: {integrity: sha512-ISyBTRMmMYagUxhcpyEH0hpXRd/KqDU4ymofPgl2XAkY9ZhQ+h0ovEZJIiPop13UmR/54oA2cgMDjgroRelaEw==} + + '@vue/compiler-dom@3.5.12': + resolution: {integrity: sha512-9G6PbJ03uwxLHKQ3P42cMTi85lDRvGLB2rSGOiQqtXELat6uI4n8cNz9yjfVHRPIu+MsK6TE418Giruvgptckg==} + + '@vue/shared@3.5.12': + resolution: {integrity: sha512-L2RPSAwUFbgZH20etwrXyVyCBu9OxRSi8T/38QsvnkJyvq2LufW2lDCOzm7t/U9C1mkhJGWYfCuFBCmIuNivrg==} + + '@webassemblyjs/ast@1.12.1': + resolution: {integrity: sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==} + + '@webassemblyjs/floating-point-hex-parser@1.11.6': + resolution: {integrity: sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==} + + '@webassemblyjs/helper-api-error@1.11.6': + resolution: {integrity: sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==} + + '@webassemblyjs/helper-buffer@1.12.1': + resolution: {integrity: sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==} + + '@webassemblyjs/helper-numbers@1.11.6': + resolution: {integrity: sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==} + + '@webassemblyjs/helper-wasm-bytecode@1.11.6': + resolution: {integrity: sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==} + + '@webassemblyjs/helper-wasm-section@1.12.1': + resolution: {integrity: sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==} + + '@webassemblyjs/ieee754@1.11.6': + resolution: {integrity: sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==} + + '@webassemblyjs/leb128@1.11.6': + resolution: {integrity: sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==} + + '@webassemblyjs/utf8@1.11.6': + resolution: {integrity: sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==} + + '@webassemblyjs/wasm-edit@1.12.1': + resolution: {integrity: sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==} + + '@webassemblyjs/wasm-gen@1.12.1': + resolution: {integrity: sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==} + + '@webassemblyjs/wasm-opt@1.12.1': + resolution: {integrity: sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==} + + '@webassemblyjs/wasm-parser@1.12.1': + resolution: {integrity: sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==} + + '@webassemblyjs/wast-printer@1.12.1': + resolution: {integrity: sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==} + + '@xtuc/ieee754@1.2.0': + resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} + + '@xtuc/long@4.2.2': + resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} + + abab@2.0.6: + resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==} + deprecated: Use your platform's native atob() and btoa() methods instead + + abort-controller@3.0.0: + resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} + engines: {node: '>=6.5'} + + accepts@1.3.8: + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} + + acorn-globals@7.0.1: + resolution: {integrity: sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==} + + acorn-import-attributes@1.9.5: + resolution: {integrity: sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==} + peerDependencies: + acorn: ^8 + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn-walk@7.2.0: + resolution: {integrity: sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==} + engines: {node: '>=0.4.0'} + + acorn-walk@8.3.4: + resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} + engines: {node: '>=0.4.0'} + + acorn@7.4.1: + resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} + engines: {node: '>=0.4.0'} + hasBin: true + + acorn@8.13.0: + resolution: {integrity: sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==} + engines: {node: '>=0.4.0'} + hasBin: true + + adjust-sourcemap-loader@4.0.0: + resolution: {integrity: sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==} + engines: {node: '>=8.9'} + + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + + ahooks@3.8.1: + resolution: {integrity: sha512-JoP9+/RWO7MnI/uSKdvQ8WB10Y3oo1PjLv+4Sv4Vpm19Z86VUMdXh+RhWvMGxZZs06sq2p0xVtFk8Oh5ZObsoA==} + engines: {node: '>=8.0.0'} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + + ajv-formats@2.1.1: + resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv-keywords@3.5.2: + resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} + peerDependencies: + ajv: ^6.9.1 + + ajv-keywords@5.1.0: + resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==} + peerDependencies: + ajv: ^8.8.2 + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + ajv@8.17.1: + resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + + ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + + ansi-escapes@5.0.0: + resolution: {integrity: sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==} + engines: {node: '>=12'} + + ansi-html-community@0.0.8: + resolution: {integrity: sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==} + engines: {'0': node >= 0.8.0} + hasBin: true + + ansi-html@0.0.9: + resolution: {integrity: sha512-ozbS3LuenHVxNRh/wdnN16QapUHzauqSomAl1jwwJRRsGwFwtj644lIhxfWu0Fy0acCij2+AEgHvjscq3dlVXg==} + engines: {'0': node >= 0.8.0} + hasBin: true + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} + engines: {node: '>=12'} + + ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + + arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + aria-query@5.1.3: + resolution: {integrity: sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==} + + aria-query@5.3.0: + resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + + aria-query@5.3.2: + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} + engines: {node: '>= 0.4'} + + array-buffer-byte-length@1.0.1: + resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} + engines: {node: '>= 0.4'} + + array-flatten@1.1.1: + resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + + array-includes@3.1.8: + resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==} + engines: {node: '>= 0.4'} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + array.prototype.findlast@1.2.5: + resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} + engines: {node: '>= 0.4'} + + array.prototype.findlastindex@1.2.5: + resolution: {integrity: sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==} + engines: {node: '>= 0.4'} + + array.prototype.flat@1.3.2: + resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==} + engines: {node: '>= 0.4'} + + array.prototype.flatmap@1.3.2: + resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==} + engines: {node: '>= 0.4'} + + array.prototype.tosorted@1.1.4: + resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==} + engines: {node: '>= 0.4'} + + arraybuffer.prototype.slice@1.0.3: + resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} + engines: {node: '>= 0.4'} + + asn1.js@4.10.1: + resolution: {integrity: sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==} + + assert@2.1.0: + resolution: {integrity: sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==} + + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + + ast-types-flow@0.0.8: + resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} + + ast-types@0.16.1: + resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==} + engines: {node: '>=4'} + + astring@1.9.0: + resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} + hasBin: true + + async@2.6.4: + resolution: {integrity: sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + autoprefixer@10.4.20: + resolution: {integrity: sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + axe-core@4.10.1: + resolution: {integrity: sha512-qPC9o+kD8Tir0lzNGLeghbOrWMr3ZJpaRlCIb6Uobt/7N4FiEDvqUMnxzCHRHmg8vOg14kr5gVNyScRmbMaJ9g==} + engines: {node: '>=4'} + + axobject-query@4.1.0: + resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} + engines: {node: '>= 0.4'} + + babel-jest@29.7.0: + resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.8.0 + + babel-loader@9.2.1: + resolution: {integrity: sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA==} + engines: {node: '>= 14.15.0'} + peerDependencies: + '@babel/core': ^7.12.0 + webpack: '>=5' + + babel-plugin-istanbul@6.1.1: + resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} + engines: {node: '>=8'} + + babel-plugin-jest-hoist@29.6.3: + resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + babel-plugin-polyfill-corejs2@0.4.11: + resolution: {integrity: sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + babel-plugin-polyfill-corejs3@0.10.6: + resolution: {integrity: sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + babel-plugin-polyfill-regenerator@0.6.2: + resolution: {integrity: sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + babel-preset-current-node-syntax@1.1.0: + resolution: {integrity: sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==} + peerDependencies: + '@babel/core': ^7.0.0 + + babel-preset-jest@29.6.3: + resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.0.0 + + bail@2.0.2: + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + better-opn@3.0.2: + resolution: {integrity: sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ==} + engines: {node: '>=12.0.0'} + + big.js@5.2.2: + resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + bing-translate-api@4.0.2: + resolution: {integrity: sha512-JJ8XUehnxzOhHU91oy86xEtp8OOMjVEjCZJX042fKxoO19NNvxJ5omeCcxQNFoPbDqVpBJwqiGVquL0oPdQm1Q==} + + bn.js@4.12.0: + resolution: {integrity: sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==} + + bn.js@5.2.1: + resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==} + + body-parser@1.20.3: + resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + brorand@1.1.0: + resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==} + + browser-assert@1.2.1: + resolution: {integrity: sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ==} + + browserify-aes@1.2.0: + resolution: {integrity: sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==} + + browserify-cipher@1.0.1: + resolution: {integrity: sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==} + + browserify-des@1.0.2: + resolution: {integrity: sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==} + + browserify-rsa@4.1.1: + resolution: {integrity: sha512-YBjSAiTqM04ZVei6sXighu679a3SqWORA3qZTEqZImnlkDIFtKc6pNutpjyZ8RJTjQtuYfeetkxM11GwoYXMIQ==} + engines: {node: '>= 0.10'} + + browserify-sign@4.2.3: + resolution: {integrity: sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw==} + engines: {node: '>= 0.12'} + + browserify-zlib@0.2.0: + resolution: {integrity: sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==} + + browserslist@4.24.0: + resolution: {integrity: sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + bser@2.1.1: + resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + buffer-xor@1.0.3: + resolution: {integrity: sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==} + + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + + builtin-modules@3.3.0: + resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} + engines: {node: '>=6'} + + builtin-status-codes@3.0.0: + resolution: {integrity: sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==} + + builtins@5.1.0: + resolution: {integrity: sha512-SW9lzGTLvWTP1AY8xeAMZimqDrIaSdLQUcVr9DMef51niJ022Ri87SwRRKYm4A6iHfkPaiVUu/Duw2Wc4J7kKg==} + + busboy@1.6.0: + resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} + engines: {node: '>=10.16.0'} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + cacheable-lookup@5.0.4: + resolution: {integrity: sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==} + engines: {node: '>=10.6.0'} + + cacheable-request@7.0.4: + resolution: {integrity: sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==} + engines: {node: '>=8'} + + call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + camel-case@4.1.2: + resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==} + + camelcase-css@2.0.1: + resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} + engines: {node: '>= 6'} + + camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + + caniuse-lite@1.0.30001669: + resolution: {integrity: sha512-DlWzFDJqstqtIVx1zeSpIMLjunf5SmwOw0N2Ck/QSQdS8PLS4+9HrLaYei4w8BIAL7IB/UEDu889d8vhCTPA0w==} + + case-sensitive-paths-webpack-plugin@2.4.0: + resolution: {integrity: sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==} + engines: {node: '>=4'} + + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + + chai@5.1.1: + resolution: {integrity: sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==} + engines: {node: '>=12'} + + chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + + chalk@3.0.0: + resolution: {integrity: sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==} + engines: {node: '>=8'} + + chalk@4.1.1: + resolution: {integrity: sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==} + engines: {node: '>=10'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chalk@5.3.0: + resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + char-regex@1.0.2: + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} + engines: {node: '>=10'} + + character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + + character-entities-legacy@1.1.4: + resolution: {integrity: sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==} + + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + + character-entities@1.2.4: + resolution: {integrity: sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==} + + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + + character-reference-invalid@1.1.4: + resolution: {integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==} + + character-reference-invalid@2.0.1: + resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + + check-error@2.1.1: + resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} + engines: {node: '>= 16'} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + chokidar@4.0.1: + resolution: {integrity: sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==} + engines: {node: '>= 14.16.0'} + + chromatic@11.12.6: + resolution: {integrity: sha512-lt6ekbx3LFLCwGheQrBZAkP2EhrXLPpESk7t45PrsV1DSpu0KOH2ZMN/G9QiF84ZGwj9RPC8BwWbnb2/kd66uA==} + hasBin: true + peerDependencies: + '@chromatic-com/cypress': ^0.*.* || ^1.0.0 + '@chromatic-com/playwright': ^0.*.* || ^1.0.0 + peerDependenciesMeta: + '@chromatic-com/cypress': + optional: true + '@chromatic-com/playwright': + optional: true + + chrome-trace-event@1.0.4: + resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} + engines: {node: '>=6.0'} + + ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} + engines: {node: '>=8'} + + cipher-base@1.0.4: + resolution: {integrity: sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==} + + cjs-module-lexer@1.4.1: + resolution: {integrity: sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==} + + class-variance-authority@0.7.0: + resolution: {integrity: sha512-jFI8IQw4hczaL4ALINxqLEXQbWcNjoSkloa4IaufXCJr6QawJyw7tuRysRsrE8w2p/4gGaxKIt/hX3qz/IbD1A==} + + classcat@5.0.5: + resolution: {integrity: sha512-JhZUT7JFcQy/EzW605k/ktHtncoo9vnyW/2GspNYwFlN1C/WmjuV/xtS04e9SOkL2sTdw0VAZ2UGCcQ9lR6p6w==} + + classnames@2.3.1: + resolution: {integrity: sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==} + + classnames@2.5.1: + resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==} + + clean-css@5.3.3: + resolution: {integrity: sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==} + engines: {node: '>= 10.0'} + + clean-regexp@1.0.0: + resolution: {integrity: sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==} + engines: {node: '>=4'} + + cli-cursor@4.0.0: + resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + cli-truncate@3.1.0: + resolution: {integrity: sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + client-only@0.0.1: + resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + clone-response@1.0.3: + resolution: {integrity: sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==} + + clsx@2.0.0: + resolution: {integrity: sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==} + engines: {node: '>=6'} + + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + + co@4.6.0: + resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} + engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} + + code-inspector-core@0.13.0: + resolution: {integrity: sha512-oYPNLdJjn3SY50YtF3IuxZOKLBNwzXSRPOqiXVnZFceMz9Ar6ugP3+zj7HszouxrsLFb2dVtlv//5wr4+cq62A==} + + code-inspector-plugin@0.13.0: + resolution: {integrity: sha512-v4mq5hhHkyMmutembTzREVsFeZ/+KsCwfx20+0gTqm1Il/M1T4d2BCv9mZ4ivie3GvvDMt/pVz1iBBVP3SuzJA==} + + collect-v8-coverage@1.0.2: + resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} + + color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + + color@4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} + + colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + comma-separated-tokens@1.0.8: + resolution: {integrity: sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==} + + comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + + commander@11.0.0: + resolution: {integrity: sha512-9HMlXtt/BNoYr8ooyjjNRdIilOTkVJXB+GhxMTtOKwk0R4j4lS4NpjuqmRxroBfnfTSHQIHQB7wryHhXarNjmQ==} + engines: {node: '>=16'} + + commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + + commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + + commander@7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + + commander@8.3.0: + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} + engines: {node: '>= 12'} + + common-path-prefix@3.0.0: + resolution: {integrity: sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==} + + commondir@1.0.1: + resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + console-browserify@1.2.0: + resolution: {integrity: sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==} + + constants-browserify@1.0.0: + resolution: {integrity: sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==} + + content-disposition@0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + convert-source-map@1.9.0: + resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cookie-signature@1.0.6: + resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + + cookie@0.7.1: + resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} + engines: {node: '>= 0.6'} + + copy-to-clipboard@3.3.3: + resolution: {integrity: sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==} + + core-js-compat@3.38.1: + resolution: {integrity: sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw==} + + core-js-pure@3.38.1: + resolution: {integrity: sha512-BY8Etc1FZqdw1glX0XNOq2FDwfrg/VGqoZOZCdaL+UmdaqDwQwYXkMJT4t6In+zfEfOJDcM9T0KdbBeJg8KKCQ==} + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + cose-base@1.0.3: + resolution: {integrity: sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==} + + cose-base@2.2.0: + resolution: {integrity: sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==} + + cosmiconfig@7.1.0: + resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==} + engines: {node: '>=10'} + + cosmiconfig@9.0.0: + resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true + + create-ecdh@4.0.4: + resolution: {integrity: sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==} + + create-hash@1.2.0: + resolution: {integrity: sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==} + + create-hmac@1.1.7: + resolution: {integrity: sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==} + + create-jest@29.7.0: + resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + + create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + + cross-env@7.0.3: + resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==} + engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'} + hasBin: true + + cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + + crypto-browserify@3.12.0: + resolution: {integrity: sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==} + + crypto-js@4.2.0: + resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==} + + css-loader@6.11.0: + resolution: {integrity: sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==} + engines: {node: '>= 12.13.0'} + peerDependencies: + '@rspack/core': 0.x || 1.x + webpack: ^5.0.0 + peerDependenciesMeta: + '@rspack/core': + optional: true + webpack: + optional: true + + css-select@4.3.0: + resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==} + + css-what@6.1.0: + resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} + engines: {node: '>= 6'} + + css.escape@1.5.1: + resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + cssom@0.3.8: + resolution: {integrity: sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==} + + cssom@0.5.0: + resolution: {integrity: sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==} + + cssstyle@2.3.0: + resolution: {integrity: sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==} + engines: {node: '>=8'} + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + cytoscape-cose-bilkent@4.1.0: + resolution: {integrity: sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==} + peerDependencies: + cytoscape: ^3.2.0 + + cytoscape-fcose@2.2.0: + resolution: {integrity: sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==} + peerDependencies: + cytoscape: ^3.2.0 + + cytoscape@3.30.2: + resolution: {integrity: sha512-oICxQsjW8uSaRmn4UK/jkczKOqTrVqt5/1WL0POiJUT2EKNc9STM4hYFHv917yu55aTBMFNRzymlJhVAiWPCxw==} + engines: {node: '>=0.10'} + + d3-array@2.12.1: + resolution: {integrity: sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==} + + d3-array@3.2.4: + resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} + engines: {node: '>=12'} + + d3-axis@3.0.0: + resolution: {integrity: sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==} + engines: {node: '>=12'} + + d3-brush@3.0.0: + resolution: {integrity: sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==} + engines: {node: '>=12'} + + d3-chord@3.0.1: + resolution: {integrity: sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==} + engines: {node: '>=12'} + + d3-color@3.1.0: + resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==} + engines: {node: '>=12'} + + d3-contour@4.0.2: + resolution: {integrity: sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==} + engines: {node: '>=12'} + + d3-delaunay@6.0.4: + resolution: {integrity: sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==} + engines: {node: '>=12'} + + d3-dispatch@3.0.1: + resolution: {integrity: sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==} + engines: {node: '>=12'} + + d3-drag@3.0.0: + resolution: {integrity: sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==} + engines: {node: '>=12'} + + d3-dsv@3.0.1: + resolution: {integrity: sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==} + engines: {node: '>=12'} + hasBin: true + + d3-ease@3.0.1: + resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==} + engines: {node: '>=12'} + + d3-fetch@3.0.1: + resolution: {integrity: sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==} + engines: {node: '>=12'} + + d3-force@3.0.0: + resolution: {integrity: sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==} + engines: {node: '>=12'} + + d3-format@3.1.0: + resolution: {integrity: sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==} + engines: {node: '>=12'} + + d3-geo@3.1.1: + resolution: {integrity: sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==} + engines: {node: '>=12'} + + d3-hierarchy@3.1.2: + resolution: {integrity: sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==} + engines: {node: '>=12'} + + d3-interpolate@3.0.1: + resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} + engines: {node: '>=12'} + + d3-path@1.0.9: + resolution: {integrity: sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==} + + d3-path@3.1.0: + resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==} + engines: {node: '>=12'} + + d3-polygon@3.0.1: + resolution: {integrity: sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==} + engines: {node: '>=12'} + + d3-quadtree@3.0.1: + resolution: {integrity: sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==} + engines: {node: '>=12'} + + d3-random@3.0.1: + resolution: {integrity: sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==} + engines: {node: '>=12'} + + d3-sankey@0.12.3: + resolution: {integrity: sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==} + + d3-scale-chromatic@3.1.0: + resolution: {integrity: sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==} + engines: {node: '>=12'} + + d3-scale@4.0.2: + resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} + engines: {node: '>=12'} + + d3-selection@3.0.0: + resolution: {integrity: sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==} + engines: {node: '>=12'} + + d3-shape@1.3.7: + resolution: {integrity: sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==} + + d3-shape@3.2.0: + resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==} + engines: {node: '>=12'} + + d3-time-format@4.1.0: + resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==} + engines: {node: '>=12'} + + d3-time@3.1.0: + resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==} + engines: {node: '>=12'} + + d3-timer@3.0.1: + resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} + engines: {node: '>=12'} + + d3-transition@3.0.1: + resolution: {integrity: sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==} + engines: {node: '>=12'} + peerDependencies: + d3-selection: 2 - 3 + + d3-zoom@3.0.0: + resolution: {integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==} + engines: {node: '>=12'} + + d3@7.9.0: + resolution: {integrity: sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==} + engines: {node: '>=12'} + + dagre-d3-es@7.0.10: + resolution: {integrity: sha512-qTCQmEhcynucuaZgY5/+ti3X/rnszKZhEQH/ZdWdtP1tA/y3VoHJzcVrO9pjjJCNpigfscAtoUB5ONcd2wNn0A==} + + damerau-levenshtein@1.0.8: + resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} + + data-urls@3.0.2: + resolution: {integrity: sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==} + engines: {node: '>=12'} + + data-view-buffer@1.0.1: + resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.1: + resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.0: + resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} + engines: {node: '>= 0.4'} + + dayjs@1.11.13: + resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} + + debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decimal.js@10.4.3: + resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==} + + decode-named-character-reference@1.0.2: + resolution: {integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==} + + decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + + dedent@0.7.0: + resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==} + + dedent@1.5.3: + resolution: {integrity: sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==} + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true + + deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} + engines: {node: '>=6'} + + deep-equal@2.2.3: + resolution: {integrity: sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==} + engines: {node: '>= 0.4'} + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + + defer-to-connect@2.0.1: + resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} + engines: {node: '>=10'} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-lazy-prop@2.0.0: + resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} + engines: {node: '>=8'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + delaunator@5.0.1: + resolution: {integrity: sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + des.js@1.1.0: + resolution: {integrity: sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==} + + destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + detect-libc@1.0.3: + resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==} + engines: {node: '>=0.10'} + hasBin: true + + detect-libc@2.0.3: + resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} + engines: {node: '>=8'} + + detect-newline@3.1.0: + resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} + engines: {node: '>=8'} + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + + didyoumean@1.2.2: + resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} + + diff-sequences@29.6.3: + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + + diff@5.2.0: + resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==} + engines: {node: '>=0.3.1'} + + diffie-hellman@5.0.3: + resolution: {integrity: sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + dlv@1.1.3: + resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + + doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + + doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + + dom-accessibility-api@0.5.16: + resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} + + dom-accessibility-api@0.6.3: + resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==} + + dom-converter@0.2.0: + resolution: {integrity: sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==} + + dom-serializer@1.4.1: + resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==} + + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + domain-browser@4.23.0: + resolution: {integrity: sha512-ArzcM/II1wCCujdCNyQjXrAFwS4mrLh4C7DZWlaI8mdh7h3BfKdNd3bKXITfl2PT9FtfQqaGvhi1vPRQPimjGA==} + engines: {node: '>=10'} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domexception@4.0.0: + resolution: {integrity: sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==} + engines: {node: '>=12'} + deprecated: Use your platform's native DOMException instead + + domhandler@4.3.1: + resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==} + engines: {node: '>= 4'} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + dompurify@3.1.7: + resolution: {integrity: sha512-VaTstWtsneJY8xzy7DekmYWEOZcmzIe3Qb3zPd4STve1OBTa+e+WmS1ITQec1fZYXI3HCsOZZiSMpG6oxoWMWQ==} + + domutils@2.8.0: + resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==} + + domutils@3.1.0: + resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==} + + dot-case@3.0.4: + resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} + + echarts-for-react@3.0.2: + resolution: {integrity: sha512-DRwIiTzx8JfwPOVgGttDytBqdp5VzCSyMRIxubgU/g2n9y3VLUmF2FK7Icmg/sNVkv4+rktmrLN9w22U2yy3fA==} + peerDependencies: + echarts: ^3.0.0 || ^4.0.0 || ^5.0.0 + react: ^15.0.0 || >=16.0.0 + + echarts@5.5.1: + resolution: {integrity: sha512-Fce8upazaAXUVUVsjgV6mBnGuqgO+JNDlcgF79Dksy4+wgGpQB2lmYoO4TSweFg/mZITdpGHomw/cNBJZj1icA==} + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + electron-to-chromium@1.5.41: + resolution: {integrity: sha512-dfdv/2xNjX0P8Vzme4cfzHqnPm5xsZXwsolTYr0eyW18IUmNyG08vL+fttvinTfhKfIKdRoqkDIC9e9iWQCNYQ==} + + elkjs@0.8.2: + resolution: {integrity: sha512-L6uRgvZTH+4OF5NE/MBbzQx/WYpru1xCBE9respNj6qznEewGUIfhzmm7horWWxbNO2M0WckQypGctR8lH79xQ==} + + elliptic@6.5.7: + resolution: {integrity: sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q==} + + emittery@0.13.1: + resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} + engines: {node: '>=12'} + + emoji-mart@5.6.0: + resolution: {integrity: sha512-eJp3QRe79pjwa+duv+n7+5YsNhRcMl812EcFVwrnRvYKoNPoQb5qxU8DG6Bgwji0akHdp6D4Ln6tYLG58MFSow==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + emojis-list@3.0.0: + resolution: {integrity: sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==} + engines: {node: '>= 4'} + + encodeurl@1.0.2: + resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} + engines: {node: '>= 0.8'} + + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + + end-of-stream@1.4.4: + resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + + endent@2.1.0: + resolution: {integrity: sha512-r8VyPX7XL8U01Xgnb1CjZ3XV+z90cXIJ9JPE/R9SEC9vpw2P6CfsRPJmp20DppC5N7ZAMCmjYkJIa744Iyg96w==} + + enhanced-resolve@5.17.1: + resolution: {integrity: sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==} + engines: {node: '>=10.13.0'} + + entities@2.2.0: + resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} + + error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + + error-stack-parser@2.1.4: + resolution: {integrity: sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==} + + es-abstract@1.23.3: + resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==} + engines: {node: '>= 0.4'} + + es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-get-iterator@1.1.3: + resolution: {integrity: sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==} + + es-iterator-helpers@1.1.0: + resolution: {integrity: sha512-/SurEfycdyssORP/E+bj4sEu1CWw4EmLDsHynHwSXQ7utgbrMRWW195pTrCjFgFCddf/UkYm3oqKPRq5i8bJbw==} + engines: {node: '>= 0.4'} + + es-module-lexer@1.5.4: + resolution: {integrity: sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==} + + es-object-atoms@1.0.0: + resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.0.3: + resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==} + engines: {node: '>= 0.4'} + + es-shim-unscopables@1.0.2: + resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==} + + es-to-primitive@1.2.1: + resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + engines: {node: '>= 0.4'} + + esbuild-register@3.6.0: + resolution: {integrity: sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==} + peerDependencies: + esbuild: '>=0.12 <1' + + esbuild@0.23.1: + resolution: {integrity: sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + escape-string-regexp@2.0.0: + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + + escodegen@2.1.0: + resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} + engines: {node: '>=6.0'} + hasBin: true + + eslint-compat-utils@0.5.1: + resolution: {integrity: sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==} + engines: {node: '>=12'} + peerDependencies: + eslint: '>=6.0.0' + + eslint-config-next@14.2.15: + resolution: {integrity: sha512-mKg+NC/8a4JKLZRIOBplxXNdStgxy7lzWuedUaCc8tev+Al9mwDUTujQH6W6qXDH9kycWiVo28tADWGvpBsZcQ==} + peerDependencies: + eslint: ^7.23.0 || ^8.0.0 + typescript: '>=3.3.1' + peerDependenciesMeta: + typescript: + optional: true + + eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + + eslint-import-resolver-typescript@3.6.3: + resolution: {integrity: sha512-ud9aw4szY9cCT1EWWdGv1L1XR6hh2PaRWif0j2QjQ0pgTY/69iw+W0Z4qZv5wHahOl8isEr+k/JnyAqNQkLkIA==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '*' + eslint-plugin-import: '*' + eslint-plugin-import-x: '*' + peerDependenciesMeta: + eslint-plugin-import: + optional: true + eslint-plugin-import-x: + optional: true + + eslint-module-utils@2.12.0: + resolution: {integrity: sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + + eslint-plugin-antfu@0.36.0: + resolution: {integrity: sha512-qLYtjZC2y6d1fvVtG4nvVGoBUDEuUwQsS4E1RwjoEZyONZAkHYDPfeoeULDlPS0IqumSW8uGR6zGSAXi5rrVMg==} + + eslint-plugin-es@4.1.0: + resolution: {integrity: sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ==} + engines: {node: '>=8.10.0'} + peerDependencies: + eslint: '>=4.19.1' + + eslint-plugin-eslint-comments@3.2.0: + resolution: {integrity: sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ==} + engines: {node: '>=6.5.0'} + peerDependencies: + eslint: '>=4.19.1' + + eslint-plugin-html@7.1.0: + resolution: {integrity: sha512-fNLRraV/e6j8e3XYOC9xgND4j+U7b1Rq+OygMlLcMg+wI/IpVbF+ubQa3R78EjKB9njT6TQOlcK5rFKBVVtdfg==} + + eslint-plugin-import@2.31.0: + resolution: {integrity: sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + + eslint-plugin-jest@27.9.0: + resolution: {integrity: sha512-QIT7FH7fNmd9n4se7FFKHbsLKGQiw885Ds6Y/sxKgCZ6natwCsXdgPOADnYVxN2QrRweF0FZWbJ6S7Rsn7llug==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@typescript-eslint/eslint-plugin': ^5.0.0 || ^6.0.0 || ^7.0.0 + eslint: ^7.0.0 || ^8.0.0 + jest: '*' + peerDependenciesMeta: + '@typescript-eslint/eslint-plugin': + optional: true + jest: + optional: true + + eslint-plugin-jsonc@2.16.0: + resolution: {integrity: sha512-Af/ZL5mgfb8FFNleH6KlO4/VdmDuTqmM+SPnWcdoWywTetv7kq+vQe99UyQb9XO3b0OWLVuTH7H0d/PXYCMdSg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '>=6.0.0' + + eslint-plugin-jsx-a11y@6.10.0: + resolution: {integrity: sha512-ySOHvXX8eSN6zz8Bywacm7CvGNhUtdjvqfQDVe6020TUK34Cywkw7m0KsCCk1Qtm9G1FayfTN1/7mMYnYO2Bhg==} + engines: {node: '>=4.0'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 + + eslint-plugin-markdown@3.0.1: + resolution: {integrity: sha512-8rqoc148DWdGdmYF6WSQFT3uQ6PO7zXYgeBpHAOAakX/zpq+NvFYbDA/H7PYzHajwtmaOzAwfxyl++x0g1/N9A==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + + eslint-plugin-n@15.7.0: + resolution: {integrity: sha512-jDex9s7D/Qial8AGVIHq4W7NswpUD5DPDL2RH8Lzd9EloWUuvUkHfv4FRLMipH5q2UtyurorBkPeNi1wVWNh3Q==} + engines: {node: '>=12.22.0'} + peerDependencies: + eslint: '>=7.0.0' + + eslint-plugin-no-only-tests@3.3.0: + resolution: {integrity: sha512-brcKcxGnISN2CcVhXJ/kEQlNa0MEfGRtwKtWA16SkqXHKitaKIMrfemJKLKX1YqDU5C/5JY3PvZXd5jEW04e0Q==} + engines: {node: '>=5.0.0'} + + eslint-plugin-promise@6.6.0: + resolution: {integrity: sha512-57Zzfw8G6+Gq7axm2Pdo3gW/Rx3h9Yywgn61uE/3elTCOePEHVrn2i5CdfBwA1BLK0Q0WqctICIUSqXZW/VprQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 + + eslint-plugin-react-hooks@5.0.0-canary-7118f5dd7-20230705: + resolution: {integrity: sha512-AZYbMo/NW9chdL7vk6HQzQhT+PvTAEVqWk9ziruUoW2kAOcN5qNyelv70e0F1VNQAbvutOC9oc+xfWycI9FxDw==} + engines: {node: '>=10'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 + + eslint-plugin-react@7.37.1: + resolution: {integrity: sha512-xwTnwDqzbDRA8uJ7BMxPs/EXRB3i8ZfnOIp8BsxEQkT0nHPp+WWceqGgo6rKb9ctNi8GJLDT4Go5HAWELa/WMg==} + engines: {node: '>=4'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 + + eslint-plugin-storybook@0.9.0: + resolution: {integrity: sha512-qOT/2vQBo0VqrG/BhZv8IdSsKQiyzJw+2Wqq+WFCiblI/PfxLSrGkF/buiXF+HumwfsCyBdaC94UhqhmYFmAvA==} + engines: {node: '>= 18'} + peerDependencies: + eslint: '>=6' + + eslint-plugin-unicorn@45.0.2: + resolution: {integrity: sha512-Y0WUDXRyGDMcKLiwgL3zSMpHrXI00xmdyixEGIg90gHnj0PcHY4moNv3Ppje/kDivdAy5vUeUr7z211ImPv2gw==} + engines: {node: '>=14.18'} + peerDependencies: + eslint: '>=8.28.0' + + eslint-plugin-unused-imports@2.0.0: + resolution: {integrity: sha512-3APeS/tQlTrFa167ThtP0Zm0vctjr4M44HMpeg1P4bK6wItarumq0Ma82xorMKdFsWpphQBlRPzw/pxiVELX1A==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + '@typescript-eslint/eslint-plugin': ^5.0.0 + eslint: ^8.0.0 + peerDependenciesMeta: + '@typescript-eslint/eslint-plugin': + optional: true + + eslint-plugin-vue@9.29.1: + resolution: {integrity: sha512-MH/MbVae4HV/tM8gKAVWMPJbYgW04CK7SuzYRrlNERpxbO0P3+Zdsa2oAcFBW6xNu7W6lIkGOsFAMCRTYmrlWQ==} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 + + eslint-plugin-yml@1.14.0: + resolution: {integrity: sha512-ESUpgYPOcAYQO9czugcX5OqRvn/ydDVwGCPXY4YjPqc09rHaUVUA6IE6HLQys4rXk/S+qx3EwTd1wHCwam/OWQ==} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '>=6.0.0' + + eslint-rule-composer@0.3.0: + resolution: {integrity: sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==} + engines: {node: '>=4.0.0'} + + eslint-scope@5.1.1: + resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} + engines: {node: '>=8.0.0'} + + eslint-scope@7.2.2: + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-utils@2.1.0: + resolution: {integrity: sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==} + engines: {node: '>=6'} + + eslint-utils@3.0.0: + resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} + engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} + peerDependencies: + eslint: '>=5' + + eslint-visitor-keys@1.3.0: + resolution: {integrity: sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==} + engines: {node: '>=4'} + + eslint-visitor-keys@2.1.0: + resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==} + engines: {node: '>=10'} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint@8.57.1: + resolution: {integrity: sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. + hasBin: true + + espree@9.6.1: + resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-util-attach-comments@2.1.1: + resolution: {integrity: sha512-+5Ba/xGGS6mnwFbXIuQiDPTbuTxuMCooq3arVv7gPZtYpjp+VXH/NkHAP35OOefPhNG/UGqU3vt/LTABwcHX0w==} + + estree-util-build-jsx@2.2.2: + resolution: {integrity: sha512-m56vOXcOBuaF+Igpb9OPAy7f9w9OIkb5yhjsZuaPm7HoGi4oTOQi0h2+yZ+AtKklYFZ+rPC4n0wYCJCEU1ONqg==} + + estree-util-is-identifier-name@2.1.0: + resolution: {integrity: sha512-bEN9VHRyXAUOjkKVQVvArFym08BTWB0aJPppZZr0UNyAqWsLaVfAqP7hbaTJjzHifmB5ebnR8Wm7r7yGN/HonQ==} + + estree-util-to-js@1.2.0: + resolution: {integrity: sha512-IzU74r1PK5IMMGZXUVZbmiu4A1uhiPgW5hm1GjcOfr4ZzHaMPpLNJjR7HjXiIOzi25nZDrgFTobHTkV5Q6ITjA==} + + estree-util-visit@1.2.1: + resolution: {integrity: sha512-xbgqcrkIVbIG+lI/gzbvd9SGTJL4zqJKBFttUl5pP27KhAjtMKbX/mQXJ7qgyXpMgVy/zvpm0xoQQaGL8OloOw==} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + event-target-shim@5.0.1: + resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} + engines: {node: '>=6'} + + eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + + evp_bytestokey@1.0.3: + resolution: {integrity: sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==} + + execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + + execa@7.2.0: + resolution: {integrity: sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==} + engines: {node: ^14.18.0 || ^16.14.0 || >=18.0.0} + + exit@0.1.2: + resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} + engines: {node: '>= 0.8.0'} + + expect@29.7.0: + resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + express@4.21.1: + resolution: {integrity: sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==} + engines: {node: '>= 0.10.0'} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + engines: {node: '>=8.6.0'} + + fast-json-parse@1.0.3: + resolution: {integrity: sha512-FRWsaZRWEJ1ESVNbDWmsAlqDk96gPQezzLghafp5J4GUKjbCz3OkAHuZs5TuPEtkbVQERysLp9xv6c24fBm8Aw==} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fast-uri@3.0.3: + resolution: {integrity: sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==} + + fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + + fault@1.0.4: + resolution: {integrity: sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==} + + fb-watchman@2.0.2: + resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} + + file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + + filesize@10.1.6: + resolution: {integrity: sha512-sJslQKU2uM33qH5nqewAwVB2QgR6w1aMNsYUp3aN5rMRyXEwJGmZvaWzeJFNTOXWlHQyBFCWrdj3fV/fsTOX8w==} + engines: {node: '>= 10.4.0'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + filter-obj@2.0.2: + resolution: {integrity: sha512-lO3ttPjHZRfjMcxWKb1j1eDhTFsu4meeR3lnMcnBFhk6RuLhvEiuALu2TlfL310ph4lCYYwgF/ElIjdP739tdg==} + engines: {node: '>=8'} + + finalhandler@1.3.1: + resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==} + engines: {node: '>= 0.8'} + + find-cache-dir@3.3.2: + resolution: {integrity: sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==} + engines: {node: '>=8'} + + find-cache-dir@4.0.0: + resolution: {integrity: sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==} + engines: {node: '>=14.16'} + + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + find-up@6.3.0: + resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + flat-cache@3.2.0: + resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} + engines: {node: ^10.12.0 || >=12.0.0} + + flatted@3.3.1: + resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} + + for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + + foreground-child@3.3.0: + resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} + engines: {node: '>=14'} + + fork-ts-checker-webpack-plugin@8.0.0: + resolution: {integrity: sha512-mX3qW3idpueT2klaQXBzrIM/pHw+T0B/V9KHEvNrqijTq9NFnMZU6oreVxDYcf33P8a5cW+67PjodNHthGnNVg==} + engines: {node: '>=12.13.0', yarn: '>=1.0.0'} + peerDependencies: + typescript: '>3.6.0' + webpack: ^5.11.0 + + form-data@4.0.1: + resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==} + engines: {node: '>= 6'} + + format@0.2.2: + resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==} + engines: {node: '>=0.4.x'} + + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + fraction.js@4.3.7: + resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} + + fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + + fs-extra@10.1.0: + resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} + engines: {node: '>=12'} + + fs-extra@11.2.0: + resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} + engines: {node: '>=14.14'} + + fs-monkey@1.0.6: + resolution: {integrity: sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + function.prototype.name@1.1.6: + resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} + engines: {node: '>= 0.4'} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + + get-package-type@0.1.0: + resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} + engines: {node: '>=8.0.0'} + + get-stream@5.2.0: + resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} + engines: {node: '>=8'} + + get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + + get-symbol-description@1.0.2: + resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} + engines: {node: '>= 0.4'} + + get-tsconfig@4.8.1: + resolution: {integrity: sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==} + + github-slugger@2.0.0: + resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + glob-to-regexp@0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + + glob@10.3.10: + resolution: {integrity: sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + + globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + + globals@13.24.0: + resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} + engines: {node: '>=8'} + + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + + gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + + got@11.8.6: + resolution: {integrity: sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==} + engines: {node: '>=10.19.0'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + + has-bigints@1.0.2: + resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + + has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + engines: {node: '>= 0.4'} + + has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hash-base@3.0.4: + resolution: {integrity: sha512-EeeoJKjTyt868liAlVmcv2ZsUfGHlE3Q+BICOXcZiwN3osr5Q/zFGYmTJpoIzuaSTAwndFy+GqhEwlU4L3j4Ow==} + engines: {node: '>=4'} + + hash-base@3.1.0: + resolution: {integrity: sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==} + engines: {node: '>=4'} + + hash.js@1.1.7: + resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + hast-util-from-dom@4.2.0: + resolution: {integrity: sha512-t1RJW/OpJbCAJQeKi3Qrj1cAOLA0+av/iPFori112+0X7R3wng+jxLA+kXec8K4szqPRGI8vPxbbpEYvvpwaeQ==} + + hast-util-from-html-isomorphic@1.0.0: + resolution: {integrity: sha512-Yu480AKeOEN/+l5LA674a+7BmIvtDj24GvOt7MtQWuhzUwlaaRWdEPXAh3Qm5vhuthpAipFb2vTetKXWOjmTvw==} + + hast-util-from-html@1.0.2: + resolution: {integrity: sha512-LhrTA2gfCbLOGJq2u/asp4kwuG0y6NhWTXiPKP+n0qNukKy7hc10whqqCFfyvIA1Q5U5d0sp9HhNim9gglEH4A==} + + hast-util-from-parse5@7.1.2: + resolution: {integrity: sha512-Nz7FfPBuljzsN3tCQ4kCBKqdNhQE2l0Tn+X1ubgKBPRoiDIu1mL08Cfw4k7q71+Duyaw7DXDN+VTAp4Vh3oCOw==} + + hast-util-from-parse5@8.0.1: + resolution: {integrity: sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ==} + + hast-util-heading-rank@3.0.0: + resolution: {integrity: sha512-EJKb8oMUXVHcWZTDepnr+WNbfnXKFNf9duMesmr4S8SXTJBJ9M4Yok08pu9vxdJwdlGRhVumk9mEhkEvKGifwA==} + + hast-util-is-element@2.1.3: + resolution: {integrity: sha512-O1bKah6mhgEq2WtVMk+Ta5K7pPMqsBBlmzysLdcwKVrqzZQ0CHqUPiIVspNhAG1rvxpvJjtGee17XfauZYKqVA==} + + hast-util-is-element@3.0.0: + resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==} + + hast-util-parse-selector@2.2.5: + resolution: {integrity: sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==} + + hast-util-parse-selector@3.1.1: + resolution: {integrity: sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA==} + + hast-util-parse-selector@4.0.0: + resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} + + hast-util-raw@9.0.4: + resolution: {integrity: sha512-LHE65TD2YiNsHD3YuXcKPHXPLuYh/gjp12mOfU8jxSrm1f/yJpsb0F/KKljS6U9LJoP0Ux+tCe8iJ2AsPzTdgA==} + + hast-util-to-estree@2.3.3: + resolution: {integrity: sha512-ihhPIUPxN0v0w6M5+IiAZZrn0LH2uZomeWwhn7uP7avZC6TE7lIiEh2yBMPr5+zi1aUCXq6VoYRgs2Bw9xmycQ==} + + hast-util-to-parse5@8.0.0: + resolution: {integrity: sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==} + + hast-util-to-string@3.0.1: + resolution: {integrity: sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==} + + hast-util-to-text@3.1.2: + resolution: {integrity: sha512-tcllLfp23dJJ+ju5wCCZHVpzsQQ43+moJbqVX3jNWPB7z/KFC4FyZD6R7y94cHL6MQ33YtMZL8Z0aIXXI4XFTw==} + + hast-util-whitespace@2.0.1: + resolution: {integrity: sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng==} + + hastscript@6.0.0: + resolution: {integrity: sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==} + + hastscript@7.2.0: + resolution: {integrity: sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw==} + + hastscript@8.0.0: + resolution: {integrity: sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==} + + he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + + highlight.js@10.7.3: + resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==} + + highlightjs-vue@1.0.0: + resolution: {integrity: sha512-PDEfEF102G23vHmPhLyPboFCD+BkMGu+GuJe2d9/eH4FsCwvgBpnc9n0pGE+ffKdph38s6foEZiEjdgHdzp+IA==} + + hmac-drbg@1.0.1: + resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} + + hoist-non-react-statics@3.3.2: + resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + + hosted-git-info@2.8.9: + resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + + html-encoding-sniffer@3.0.0: + resolution: {integrity: sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==} + engines: {node: '>=12'} + + html-entities@2.5.2: + resolution: {integrity: sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==} + + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + + html-minifier-terser@6.1.0: + resolution: {integrity: sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==} + engines: {node: '>=12'} + hasBin: true + + html-parse-stringify@3.0.1: + resolution: {integrity: sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==} + + html-tags@3.3.1: + resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==} + engines: {node: '>=8'} + + html-void-elements@3.0.0: + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + + html-webpack-plugin@5.6.2: + resolution: {integrity: sha512-q7xp/FO9RGBVoTKNItkdX1jKLscLFkgn/dLVFNYbHVbfHLBk6DYW5nsQ8kCzIWcgKP/kUBocetjvav6lD8YfCQ==} + engines: {node: '>=10.13.0'} + peerDependencies: + '@rspack/core': 0.x || 1.x + webpack: ^5.20.0 + peerDependenciesMeta: + '@rspack/core': + optional: true + webpack: + optional: true + + htmlparser2@6.1.0: + resolution: {integrity: sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==} + + htmlparser2@8.0.2: + resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} + + http-cache-semantics@4.1.1: + resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} + + http-errors@2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} + + http-proxy-agent@5.0.0: + resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} + engines: {node: '>= 6'} + + http2-wrapper@1.0.3: + resolution: {integrity: sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==} + engines: {node: '>=10.19.0'} + + https-browserify@1.0.0: + resolution: {integrity: sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==} + + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + + human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + + human-signals@4.3.1: + resolution: {integrity: sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==} + engines: {node: '>=14.18.0'} + + husky@8.0.3: + resolution: {integrity: sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==} + engines: {node: '>=14'} + hasBin: true + + i18next-resources-to-backend@1.2.1: + resolution: {integrity: sha512-okHbVA+HZ7n1/76MsfhPqDou0fptl2dAlhRDu2ideXloRRduzHsqDOznJBef+R3DFZnbvWoBW+KxJ7fnFjd6Yw==} + + i18next@22.5.1: + resolution: {integrity: sha512-8TGPgM3pAD+VRsMtUMNknRz3kzqwp/gPALrWMsDnmC1mKqJwpWyooQRLMcbTwq8z8YwSmuj+ZYvc+xCuEpkssA==} + + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + icss-utils@5.1.0: + resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + image-size@1.1.1: + resolution: {integrity: sha512-541xKlUw6jr/6gGuk92F+mYM5zaFAc5ahphvkqvNe2bQ6gVBkd6bfrmVJ2t4KDAfikAYZyIqTnktX3i6/aQDrQ==} + engines: {node: '>=16.x'} + hasBin: true + + immediate@3.0.6: + resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} + + immer@9.0.21: + resolution: {integrity: sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==} + + immutable@4.3.7: + resolution: {integrity: sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==} + + import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + + import-local@3.2.0: + resolution: {integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==} + engines: {node: '>=8'} + hasBin: true + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + inline-style-parser@0.1.1: + resolution: {integrity: sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==} + + internal-slot@1.0.7: + resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} + engines: {node: '>= 0.4'} + + internmap@1.0.1: + resolution: {integrity: sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==} + + internmap@2.0.3: + resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} + engines: {node: '>=12'} + + intersection-observer@0.12.2: + resolution: {integrity: sha512-7m1vEcPCxXYI8HqnL8CKI6siDyD+eIWSwgB3DZA+ZTogxk9I4CDnj4wilt9x/+/QbHI4YG5YZNmC6458/e9Ktg==} + + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + + is-absolute-url@4.0.1: + resolution: {integrity: sha512-/51/TKE88Lmm7Gc4/8btclNXWS+g50wXhYJq8HWIBAGUBnoAdRu1aXeh364t/O7wXDAcTJDP8PNuNKWUDWie+A==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + is-alphabetical@1.0.4: + resolution: {integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==} + + is-alphabetical@2.0.1: + resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} + + is-alphanumerical@1.0.4: + resolution: {integrity: sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==} + + is-alphanumerical@2.0.1: + resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + + is-arguments@1.1.1: + resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} + engines: {node: '>= 0.4'} + + is-array-buffer@3.0.4: + resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} + engines: {node: '>= 0.4'} + + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + is-arrayish@0.3.2: + resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + + is-async-function@2.0.0: + resolution: {integrity: sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==} + engines: {node: '>= 0.4'} + + is-bigint@1.0.4: + resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-boolean-object@1.1.2: + resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + engines: {node: '>= 0.4'} + + is-buffer@2.0.5: + resolution: {integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==} + engines: {node: '>=4'} + + is-builtin-module@3.2.1: + resolution: {integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==} + engines: {node: '>=6'} + + is-bun-module@1.2.1: + resolution: {integrity: sha512-AmidtEM6D6NmUiLOvvU7+IePxjEjOzra2h0pSrsfSAcXwl/83zLLXDByafUJy9k/rKK0pvXMLdwKwGHlX2Ke6Q==} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-core-module@2.15.1: + resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==} + engines: {node: '>= 0.4'} + + is-data-view@1.0.1: + resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==} + engines: {node: '>= 0.4'} + + is-date-object@1.0.5: + resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + engines: {node: '>= 0.4'} + + is-decimal@1.0.4: + resolution: {integrity: sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==} + + is-decimal@2.0.1: + resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} + + is-docker@2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-finalizationregistry@1.0.2: + resolution: {integrity: sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-fullwidth-code-point@4.0.0: + resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} + engines: {node: '>=12'} + + is-generator-fn@2.1.0: + resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} + engines: {node: '>=6'} + + is-generator-function@1.0.10: + resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} + engines: {node: '>= 0.4'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-hexadecimal@1.0.4: + resolution: {integrity: sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==} + + is-hexadecimal@2.0.1: + resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + + is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + + is-nan@1.3.2: + resolution: {integrity: sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==} + engines: {node: '>= 0.4'} + + is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + engines: {node: '>= 0.4'} + + is-number-object@1.0.7: + resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + engines: {node: '>= 0.4'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + + is-plain-object@5.0.0: + resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} + engines: {node: '>=0.10.0'} + + is-potential-custom-element-name@1.0.1: + resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + + is-reference@3.0.2: + resolution: {integrity: sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==} + + is-regex@1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.3: + resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} + engines: {node: '>= 0.4'} + + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + + is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + is-string@1.0.7: + resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + engines: {node: '>= 0.4'} + + is-symbol@1.0.4: + resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + engines: {node: '>= 0.4'} + + is-typed-array@1.1.13: + resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} + engines: {node: '>= 0.4'} + + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + + is-weakref@1.0.2: + resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + + is-weakset@2.0.3: + resolution: {integrity: sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==} + engines: {node: '>= 0.4'} + + is-wsl@2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + isomorphic.js@0.2.5: + resolution: {integrity: sha512-PIeMbHqMt4DnUP3MA/Flc0HElYjMXArsw1qwJZcm9sqR8mq3l8NYizFMty0pWwE/tzIGH3EKK5+jes5mAr85yw==} + + istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + + istanbul-lib-instrument@5.2.1: + resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} + engines: {node: '>=8'} + + istanbul-lib-instrument@6.0.3: + resolution: {integrity: sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==} + engines: {node: '>=10'} + + istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + + istanbul-lib-source-maps@4.0.1: + resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} + engines: {node: '>=10'} + + istanbul-reports@3.1.7: + resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} + engines: {node: '>=8'} + + iterator.prototype@1.1.3: + resolution: {integrity: sha512-FW5iMbeQ6rBGm/oKgzq2aW4KvAGpxPzYES8N4g4xNXUKpL1mclMvOe+76AcLDTvD+Ze+sOpVhgdAQEKF4L9iGQ==} + engines: {node: '>= 0.4'} + + jackspeak@2.3.6: + resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} + engines: {node: '>=14'} + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + jest-changed-files@29.7.0: + resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-circus@29.7.0: + resolution: {integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-cli@29.7.0: + resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + jest-config@29.7.0: + resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@types/node': '*' + ts-node: '>=9.0.0' + peerDependenciesMeta: + '@types/node': + optional: true + ts-node: + optional: true + + jest-diff@29.7.0: + resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-docblock@29.7.0: + resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-each@29.7.0: + resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-environment-jsdom@29.7.0: + resolution: {integrity: sha512-k9iQbsf9OyOfdzWH8HDmrRT0gSIcX+FLNW7IQq94tFX0gynPwqDTW0Ho6iMVNjGz/nb+l/vW3dWM2bbLLpkbXA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + canvas: ^2.5.0 + peerDependenciesMeta: + canvas: + optional: true + + jest-environment-node@29.7.0: + resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-get-type@29.6.3: + resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-haste-map@29.7.0: + resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-leak-detector@29.7.0: + resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-matcher-utils@29.7.0: + resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-message-util@29.7.0: + resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-mock@29.7.0: + resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-pnp-resolver@1.2.3: + resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} + engines: {node: '>=6'} + peerDependencies: + jest-resolve: '*' + peerDependenciesMeta: + jest-resolve: + optional: true + + jest-regex-util@29.6.3: + resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-resolve-dependencies@29.7.0: + resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-resolve@29.7.0: + resolution: {integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-runner@29.7.0: + resolution: {integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-runtime@29.7.0: + resolution: {integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-snapshot@29.7.0: + resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-util@29.7.0: + resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-validate@29.7.0: + resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-watcher@29.7.0: + resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-worker@27.5.1: + resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} + engines: {node: '>= 10.13.0'} + + jest-worker@29.7.0: + resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest@29.7.0: + resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + jiti@1.21.6: + resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==} + hasBin: true + + js-audio-recorder@1.0.7: + resolution: {integrity: sha512-JiDODCElVHGrFyjGYwYyNi7zCbKk9va9C77w+zCPMmi4C6ix7zsX2h3ddHugmo4dOTOTCym9++b/wVW9nC0IaA==} + + js-cookie@3.0.5: + resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==} + engines: {node: '>=14'} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + jsdoc-type-pratt-parser@4.1.0: + resolution: {integrity: sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==} + engines: {node: '>=12.0.0'} + + jsdom@20.0.3: + resolution: {integrity: sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==} + engines: {node: '>=14'} + peerDependencies: + canvas: ^2.5.0 + peerDependenciesMeta: + canvas: + optional: true + + jsesc@0.5.0: + resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} + hasBin: true + + jsesc@3.0.2: + resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} + engines: {node: '>=6'} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonc-eslint-parser@2.4.0: + resolution: {integrity: sha512-WYDyuc/uFcGp6YtM2H0uKmUwieOuzeE/5YocFJLnLfclZ4inf3mRn8ZVy1s7Hxji7Jxm6Ss8gqpexD/GlKoGgg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + + jsx-ast-utils@3.3.5: + resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} + engines: {node: '>=4.0'} + + jwt-decode@4.0.0: + resolution: {integrity: sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==} + engines: {node: '>=18'} + + katex@0.16.11: + resolution: {integrity: sha512-RQrI8rlHY92OLf3rho/Ts8i/XvjgguEjOkO1BEXcU3N8BqPpSzBNwV/G0Ukr+P/l3ivvJUE/Fa/CwbS6HesGNQ==} + hasBin: true + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + khroma@2.1.0: + resolution: {integrity: sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==} + + kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + + kleur@4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} + + lamejs@1.2.1: + resolution: {integrity: sha512-s7bxvjvYthw6oPLCm5pFxvA84wUROODB8jEO2+CE1adhKgrIvVOlmMgY8zyugxGrvRaDHNJanOiS21/emty6dQ==} + + language-subtag-registry@0.3.23: + resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} + + language-tags@1.0.9: + resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==} + engines: {node: '>=0.10'} + + layout-base@1.0.2: + resolution: {integrity: sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==} + + layout-base@2.0.1: + resolution: {integrity: sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==} + + leven@3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lexical@0.16.1: + resolution: {integrity: sha512-+R05d3+N945OY8pTUjTqQrWoApjC+ctzvjnmNETtx9WmVAaiW0tQVG+AYLt5pDGY8dQXtd4RPorvnxBTECt9SA==} + + lib0@0.2.98: + resolution: {integrity: sha512-XteTiNO0qEXqqweWx+b21p/fBnNHUA1NwAtJNJek1oPrewEZs2uiT4gWivHKr9GqCjDPAhchz0UQO8NwU3bBNA==} + engines: {node: '>=16'} + hasBin: true + + lie@3.1.1: + resolution: {integrity: sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==} + + lilconfig@2.1.0: + resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} + engines: {node: '>=10'} + + lilconfig@3.1.2: + resolution: {integrity: sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==} + engines: {node: '>=14'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + lint-staged@13.3.0: + resolution: {integrity: sha512-mPRtrYnipYYv1FEE134ufbWpeggNTo+O/UPzngoaKzbzHAthvR55am+8GfHTnqNRQVRRrYQLGW9ZyUoD7DsBHQ==} + engines: {node: ^16.14.0 || >=18.0.0} + hasBin: true + + listr2@6.6.1: + resolution: {integrity: sha512-+rAXGHh0fkEWdXBmX+L6mmfmXmXvDGEKzkjxO+8mP3+nI/r/CWznVBvsibXdxda9Zz0OW2e2ikphN3OwCT/jSg==} + engines: {node: '>=16.0.0'} + peerDependencies: + enquirer: '>= 2.3.0 < 3' + peerDependenciesMeta: + enquirer: + optional: true + + loader-runner@4.3.0: + resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==} + engines: {node: '>=6.11.5'} + + loader-utils@2.0.4: + resolution: {integrity: sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==} + engines: {node: '>=8.9.0'} + + loader-utils@3.3.1: + resolution: {integrity: sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==} + engines: {node: '>= 12.13.0'} + + local-pkg@0.4.3: + resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==} + engines: {node: '>=14'} + + localforage@1.10.0: + resolution: {integrity: sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==} + + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + locate-path@7.2.0: + resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + lodash-es@4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + + lodash.castarray@4.4.0: + resolution: {integrity: sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==} + + lodash.debounce@4.0.8: + resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} + + lodash.isplainobject@4.0.6: + resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + log-update@5.0.1: + resolution: {integrity: sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + loupe@3.1.2: + resolution: {integrity: sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==} + + lower-case@2.0.2: + resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + + lowercase-keys@2.0.0: + resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==} + engines: {node: '>=8'} + + lowlight@1.20.0: + resolution: {integrity: sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==} + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + lz-string@1.5.0: + resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} + hasBin: true + + magic-string@0.30.12: + resolution: {integrity: sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==} + + magicast@0.3.5: + resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==} + + make-dir@3.1.0: + resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} + engines: {node: '>=8'} + + make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + + make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + + makeerror@1.0.12: + resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + + map-or-similar@1.5.0: + resolution: {integrity: sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg==} + + markdown-extensions@1.1.1: + resolution: {integrity: sha512-WWC0ZuMzCyDHYCasEGs4IPvLyTGftYwh6wIEOULOF0HXcqZlhwRzrK0w2VUlxWA98xnvb/jszw4ZSkJ6ADpM6Q==} + engines: {node: '>=0.10.0'} + + markdown-table@3.0.3: + resolution: {integrity: sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==} + + markdown-to-jsx@7.5.0: + resolution: {integrity: sha512-RrBNcMHiFPcz/iqIj0n3wclzHXjwS7mzjBNWecKKVhNTIxQepIix6Il/wZCn2Cg5Y1ow2Qi84+eJrryFRWBEWw==} + engines: {node: '>= 10'} + peerDependencies: + react: '>= 0.14.0' + + md5.js@1.3.5: + resolution: {integrity: sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==} + + mdast-util-definitions@5.1.2: + resolution: {integrity: sha512-8SVPMuHqlPME/z3gqVwWY4zVXn8lqKv/pAhC57FuJ40ImXyBpmO5ukh98zB2v7Blql2FiHjHv9LVztSIqjY+MA==} + + mdast-util-find-and-replace@2.2.2: + resolution: {integrity: sha512-MTtdFRz/eMDHXzeK6W3dO7mXUlF82Gom4y0oOgvHhh/HXZAGvIQDUvQ0SuUx+j2tv44b8xTHOm8K/9OoRFnXKw==} + + mdast-util-from-markdown@0.8.5: + resolution: {integrity: sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==} + + mdast-util-from-markdown@1.3.1: + resolution: {integrity: sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==} + + mdast-util-gfm-autolink-literal@1.0.3: + resolution: {integrity: sha512-My8KJ57FYEy2W2LyNom4n3E7hKTuQk/0SES0u16tjA9Z3oFkF4RrC/hPAPgjlSpezsOvI8ObcXcElo92wn5IGA==} + + mdast-util-gfm-footnote@1.0.2: + resolution: {integrity: sha512-56D19KOGbE00uKVj3sgIykpwKL179QsVFwx/DCW0u/0+URsryacI4MAdNJl0dh+u2PSsD9FtxPFbHCzJ78qJFQ==} + + mdast-util-gfm-strikethrough@1.0.3: + resolution: {integrity: sha512-DAPhYzTYrRcXdMjUtUjKvW9z/FNAMTdU0ORyMcbmkwYNbKocDpdk+PX1L1dQgOID/+vVs1uBQ7ElrBQfZ0cuiQ==} + + mdast-util-gfm-table@1.0.7: + resolution: {integrity: sha512-jjcpmNnQvrmN5Vx7y7lEc2iIOEytYv7rTvu+MeyAsSHTASGCCRA79Igg2uKssgOs1i1po8s3plW0sTu1wkkLGg==} + + mdast-util-gfm-task-list-item@1.0.2: + resolution: {integrity: sha512-PFTA1gzfp1B1UaiJVyhJZA1rm0+Tzn690frc/L8vNX1Jop4STZgOE6bxUhnzdVSB+vm2GU1tIsuQcA9bxTQpMQ==} + + mdast-util-gfm@2.0.2: + resolution: {integrity: sha512-qvZ608nBppZ4icQlhQQIAdc6S3Ffj9RGmzwUKUWuEICFnd1LVkN3EktF7ZHAgfcEdvZB5owU9tQgt99e2TlLjg==} + + mdast-util-math@2.0.2: + resolution: {integrity: sha512-8gmkKVp9v6+Tgjtq6SYx9kGPpTf6FVYRa53/DLh479aldR9AyP48qeVOgNZ5X7QUK7nOy4yw7vg6mbiGcs9jWQ==} + + mdast-util-mdx-expression@1.3.2: + resolution: {integrity: sha512-xIPmR5ReJDu/DHH1OoIT1HkuybIfRGYRywC+gJtI7qHjCJp/M9jrmBEJW22O8lskDWm562BX2W8TiAwRTb0rKA==} + + mdast-util-mdx-jsx@2.1.4: + resolution: {integrity: sha512-DtMn9CmVhVzZx3f+optVDF8yFgQVt7FghCRNdlIaS3X5Bnym3hZwPbg/XW86vdpKjlc1PVj26SpnLGeJBXD3JA==} + + mdast-util-mdx@2.0.1: + resolution: {integrity: sha512-38w5y+r8nyKlGvNjSEqWrhG0w5PmnRA+wnBvm+ulYCct7nsGYhFVb0lljS9bQav4psDAS1eGkP2LMVcZBi/aqw==} + + mdast-util-mdxjs-esm@1.3.1: + resolution: {integrity: sha512-SXqglS0HrEvSdUEfoXFtcg7DRl7S2cwOXc7jkuusG472Mmjag34DUDeOJUZtl+BVnyeO1frIgVpHlNRWc2gk/w==} + + mdast-util-newline-to-break@1.0.0: + resolution: {integrity: sha512-491LcYv3gbGhhCrLoeALncQmega2xPh+m3gbsIhVsOX4sw85+ShLFPvPyibxc1Swx/6GtzxgVodq+cGa/47ULg==} + + mdast-util-phrasing@3.0.1: + resolution: {integrity: sha512-WmI1gTXUBJo4/ZmSk79Wcb2HcjPJBzM1nlI/OUWA8yk2X9ik3ffNbBGsU+09BFmXaL1IBb9fiuvq6/KMiNycSg==} + + mdast-util-to-hast@12.3.0: + resolution: {integrity: sha512-pits93r8PhnIoU4Vy9bjW39M2jJ6/tdHyja9rrot9uujkN7UTU9SDnE6WNJz/IGyQk3XHX6yNNtrBH6cQzm8Hw==} + + mdast-util-to-hast@13.2.0: + resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==} + + mdast-util-to-markdown@1.5.0: + resolution: {integrity: sha512-bbv7TPv/WC49thZPg3jXuqzuvI45IL2EVAr/KxF0BSdHsU0ceFHOmwQn6evxAh1GaoK/6GQ1wp4R4oW2+LFL/A==} + + mdast-util-to-string@2.0.0: + resolution: {integrity: sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==} + + mdast-util-to-string@3.2.0: + resolution: {integrity: sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==} + + media-typer@0.3.0: + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} + + memfs@3.5.3: + resolution: {integrity: sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==} + engines: {node: '>= 4.0.0'} + + memoize-one@5.2.1: + resolution: {integrity: sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==} + + memoizerific@1.11.3: + resolution: {integrity: sha512-/EuHYwAPdLtXwAwSZkh/Gutery6pD2KYd44oQLhAvQp/50mpyduZh8Q7PYHXTCJ+wuXxt7oij2LXyIJOOYFPog==} + + merge-descriptors@1.0.3: + resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + mermaid@10.4.0: + resolution: {integrity: sha512-4QCQLp79lvz7UZxow5HUX7uWTPJOaQBVExduo91tliXC7v78i6kssZOPHxLL+Xs30KU72cpPn3g3imw/xm/gaw==} + + methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + + micromark-core-commonmark@1.1.0: + resolution: {integrity: sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==} + + micromark-extension-gfm-autolink-literal@1.0.5: + resolution: {integrity: sha512-z3wJSLrDf8kRDOh2qBtoTRD53vJ+CWIyo7uyZuxf/JAbNJjiHsOpG1y5wxk8drtv3ETAHutCu6N3thkOOgueWg==} + + micromark-extension-gfm-footnote@1.1.2: + resolution: {integrity: sha512-Yxn7z7SxgyGWRNa4wzf8AhYYWNrwl5q1Z8ii+CSTTIqVkmGZF1CElX2JI8g5yGoM3GAman9/PVCUFUSJ0kB/8Q==} + + micromark-extension-gfm-strikethrough@1.0.7: + resolution: {integrity: sha512-sX0FawVE1o3abGk3vRjOH50L5TTLr3b5XMqnP9YDRb34M0v5OoZhG+OHFz1OffZ9dlwgpTBKaT4XW/AsUVnSDw==} + + micromark-extension-gfm-table@1.0.7: + resolution: {integrity: sha512-3ZORTHtcSnMQEKtAOsBQ9/oHp9096pI/UvdPtN7ehKvrmZZ2+bbWhi0ln+I9drmwXMt5boocn6OlwQzNXeVeqw==} + + micromark-extension-gfm-tagfilter@1.0.2: + resolution: {integrity: sha512-5XWB9GbAUSHTn8VPU8/1DBXMuKYT5uOgEjJb8gN3mW0PNW5OPHpSdojoqf+iq1xo7vWzw/P8bAHY0n6ijpXF7g==} + + micromark-extension-gfm-task-list-item@1.0.5: + resolution: {integrity: sha512-RMFXl2uQ0pNQy6Lun2YBYT9g9INXtWJULgbt01D/x8/6yJ2qpKyzdZD3pi6UIkzF++Da49xAelVKUeUMqd5eIQ==} + + micromark-extension-gfm@2.0.3: + resolution: {integrity: sha512-vb9OoHqrhCmbRidQv/2+Bc6pkP0FrtlhurxZofvOEy5o8RtuuvTq+RQ1Vw5ZDNrVraQZu3HixESqbG+0iKk/MQ==} + + micromark-extension-math@2.1.2: + resolution: {integrity: sha512-es0CcOV89VNS9wFmyn+wyFTKweXGW4CEvdaAca6SWRWPyYCbBisnjaHLjWO4Nszuiud84jCpkHsqAJoa768Pvg==} + + micromark-extension-mdx-expression@1.0.8: + resolution: {integrity: sha512-zZpeQtc5wfWKdzDsHRBY003H2Smg+PUi2REhqgIhdzAa5xonhP03FcXxqFSerFiNUr5AWmHpaNPQTBVOS4lrXw==} + + micromark-extension-mdx-jsx@1.0.5: + resolution: {integrity: sha512-gPH+9ZdmDflbu19Xkb8+gheqEDqkSpdCEubQyxuz/Hn8DOXiXvrXeikOoBA71+e8Pfi0/UYmU3wW3H58kr7akA==} + + micromark-extension-mdx-md@1.0.1: + resolution: {integrity: sha512-7MSuj2S7xjOQXAjjkbjBsHkMtb+mDGVW6uI2dBL9snOBCbZmoNgDAeZ0nSn9j3T42UE/g2xVNMn18PJxZvkBEA==} + + micromark-extension-mdxjs-esm@1.0.5: + resolution: {integrity: sha512-xNRBw4aoURcyz/S69B19WnZAkWJMxHMT5hE36GtDAyhoyn/8TuAeqjFJQlwk+MKQsUD7b3l7kFX+vlfVWgcX1w==} + + micromark-extension-mdxjs@1.0.1: + resolution: {integrity: sha512-7YA7hF6i5eKOfFUzZ+0z6avRG52GpWR8DL+kN47y3f2KhxbBZMhmxe7auOeaTBrW2DenbbZTf1ea9tA2hDpC2Q==} + + micromark-factory-destination@1.1.0: + resolution: {integrity: sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==} + + micromark-factory-label@1.1.0: + resolution: {integrity: sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==} + + micromark-factory-mdx-expression@1.0.9: + resolution: {integrity: sha512-jGIWzSmNfdnkJq05c7b0+Wv0Kfz3NJ3N4cBjnbO4zjXIlxJr+f8lk+5ZmwFvqdAbUy2q6B5rCY//g0QAAaXDWA==} + + micromark-factory-space@1.1.0: + resolution: {integrity: sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==} + + micromark-factory-title@1.1.0: + resolution: {integrity: sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==} + + micromark-factory-whitespace@1.1.0: + resolution: {integrity: sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==} + + micromark-util-character@1.2.0: + resolution: {integrity: sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==} + + micromark-util-character@2.1.0: + resolution: {integrity: sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==} + + micromark-util-chunked@1.1.0: + resolution: {integrity: sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==} + + micromark-util-classify-character@1.1.0: + resolution: {integrity: sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==} + + micromark-util-combine-extensions@1.1.0: + resolution: {integrity: sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==} + + micromark-util-decode-numeric-character-reference@1.1.0: + resolution: {integrity: sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==} + + micromark-util-decode-string@1.1.0: + resolution: {integrity: sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==} + + micromark-util-encode@1.1.0: + resolution: {integrity: sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==} + + micromark-util-encode@2.0.0: + resolution: {integrity: sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==} + + micromark-util-events-to-acorn@1.2.3: + resolution: {integrity: sha512-ij4X7Wuc4fED6UoLWkmo0xJQhsktfNh1J0m8g4PbIMPlx+ek/4YdW5mvbye8z/aZvAPUoxgXHrwVlXAPKMRp1w==} + + micromark-util-html-tag-name@1.2.0: + resolution: {integrity: sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==} + + micromark-util-normalize-identifier@1.1.0: + resolution: {integrity: sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==} + + micromark-util-resolve-all@1.1.0: + resolution: {integrity: sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==} + + micromark-util-sanitize-uri@1.2.0: + resolution: {integrity: sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==} + + micromark-util-sanitize-uri@2.0.0: + resolution: {integrity: sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==} + + micromark-util-subtokenize@1.1.0: + resolution: {integrity: sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==} + + micromark-util-symbol@1.1.0: + resolution: {integrity: sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==} + + micromark-util-symbol@2.0.0: + resolution: {integrity: sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==} + + micromark-util-types@1.1.0: + resolution: {integrity: sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==} + + micromark-util-types@2.0.0: + resolution: {integrity: sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==} + + micromark@2.11.4: + resolution: {integrity: sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==} + + micromark@3.2.0: + resolution: {integrity: sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==} + + micromatch@4.0.5: + resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + engines: {node: '>=8.6'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + miller-rabin@4.0.1: + resolution: {integrity: sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==} + hasBin: true + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + + mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + + mimic-response@1.0.1: + resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} + engines: {node: '>=4'} + + mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + + min-indent@1.0.1: + resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} + engines: {node: '>=4'} + + minimalistic-assert@1.0.1: + resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} + + minimalistic-crypto-utils@1.0.1: + resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + mkdirp@0.5.6: + resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true + + monaco-editor@0.52.0: + resolution: {integrity: sha512-OeWhNpABLCeTqubfqLMXGsqf6OmPU6pHM85kF3dhy6kq5hnhuVS1p3VrEW/XhWHc71P2tHyS5JFySD8mgs1crw==} + + mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + + ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + + nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + natural-compare-lite@1.4.0: + resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + + negotiator@0.6.4: + resolution: {integrity: sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==} + engines: {node: '>= 0.6'} + + neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + + next@14.2.15: + resolution: {integrity: sha512-h9ctmOokpoDphRvMGnwOJAedT6zKhwqyZML9mDtspgf4Rh3Pn7UTYKqePNoDvhsWBAO5GoPNYshnAUGIazVGmw==} + engines: {node: '>=18.17.0'} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.41.2 + react: ^18.2.0 + react-dom: ^18.2.0 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@playwright/test': + optional: true + sass: + optional: true + + no-case@3.0.4: + resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + + node-abort-controller@3.1.1: + resolution: {integrity: sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==} + + node-addon-api@7.1.1: + resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} + + node-int64@0.4.0: + resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} + + node-polyfill-webpack-plugin@2.0.1: + resolution: {integrity: sha512-ZUMiCnZkP1LF0Th2caY6J/eKKoA0TefpoVa68m/LQU1I/mE8rGt4fNYGgNuCcK+aG8P8P43nbeJ2RqJMOL/Y1A==} + engines: {node: '>=12'} + peerDependencies: + webpack: '>=5' + + node-releases@2.0.18: + resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} + + non-layered-tidy-tree-layout@2.0.2: + resolution: {integrity: sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw==} + + normalize-package-data@2.5.0: + resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + normalize-range@0.1.2: + resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} + engines: {node: '>=0.10.0'} + + normalize-url@6.1.0: + resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} + engines: {node: '>=10'} + + normalize-wheel@1.0.1: + resolution: {integrity: sha512-1OnlAPZ3zgrk8B91HyRj+eVv+kS5u+Z0SCsak6Xil/kmgEia50ga7zfkumayonZrImffAxPU/5WcyGhzetHNPA==} + + npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + + npm-run-path@5.3.0: + resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + nwsapi@2.2.13: + resolution: {integrity: sha512-cTGB9ptp9dY9A5VbMSe7fQBcl/tt22Vcqdq8+eN93rblOuE0aCFu4aZ2vMwct/2t+lFnosm8RkQW1I0Omb1UtQ==} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-hash@3.0.0: + resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} + engines: {node: '>= 6'} + + object-inspect@1.13.2: + resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==} + engines: {node: '>= 0.4'} + + object-is@1.1.6: + resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object.assign@4.1.5: + resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} + engines: {node: '>= 0.4'} + + object.entries@1.1.8: + resolution: {integrity: sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==} + engines: {node: '>= 0.4'} + + object.fromentries@2.0.8: + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} + engines: {node: '>= 0.4'} + + object.groupby@1.0.3: + resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} + engines: {node: '>= 0.4'} + + object.values@1.2.0: + resolution: {integrity: sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==} + engines: {node: '>= 0.4'} + + objectorarray@1.0.5: + resolution: {integrity: sha512-eJJDYkhJFFbBBAxeh8xW+weHlkI28n2ZdQV/J/DNfWfSKlGEf2xcfAbZTv3riEXHAhL9SVOTs2pRmXiSTf78xg==} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + + onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + + open@8.4.2: + resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} + engines: {node: '>=12'} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + os-browserify@0.3.0: + resolution: {integrity: sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==} + + p-cancelable@2.1.1: + resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==} + engines: {node: '>=8'} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-limit@4.0.0: + resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + p-locate@6.0.0: + resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + + pako@1.0.11: + resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + + papaparse@5.4.1: + resolution: {integrity: sha512-HipMsgJkZu8br23pW15uvo6sib6wne/4woLZPlFf3rpDyMe9ywEXUsuD7+6K9PRkJlVT51j/sCOYDKGGS3ZJrw==} + + param-case@3.0.4: + resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse-asn1@5.1.7: + resolution: {integrity: sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg==} + engines: {node: '>= 0.10'} + + parse-entities@2.0.0: + resolution: {integrity: sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==} + + parse-entities@4.0.1: + resolution: {integrity: sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==} + + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + + parse5@7.2.0: + resolution: {integrity: sha512-ZkDsAOcxsUMZ4Lz5fVciOehNcJ+Gb8gTzcA4yl3wnc273BAybYWrQ+Ks/OjCjSEpjvQkDSeZbybK9qj2VHHdGA==} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + pascal-case@3.1.2: + resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} + + path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-exists@5.0.0: + resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + path-to-regexp@0.1.10: + resolution: {integrity: sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + pathval@2.0.0: + resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} + engines: {node: '>= 14.16'} + + pbkdf2@3.1.2: + resolution: {integrity: sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==} + engines: {node: '>=0.12'} + + periscopic@3.1.0: + resolution: {integrity: sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + pidtree@0.6.0: + resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} + engines: {node: '>=0.10'} + hasBin: true + + pify@2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + + pinyin-pro@3.25.0: + resolution: {integrity: sha512-MpwQPa9Ry+1vVHrsRgfJTvbtoMn0Gk529OZEWqN+O/iiSOqnd2dbKrDMaX87n7YvVPhy2W1/sKakK9zheYNWeg==} + + pirates@4.0.6: + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + engines: {node: '>= 6'} + + pkg-dir@4.2.0: + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} + + pkg-dir@7.0.0: + resolution: {integrity: sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==} + engines: {node: '>=14.16'} + + pluralize@8.0.0: + resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} + engines: {node: '>=4'} + + pnp-webpack-plugin@1.7.0: + resolution: {integrity: sha512-2Rb3vm+EXble/sMXNSu6eoBx8e79gKqhNq9F5ZWW6ERNCTE/Q0wQNne5541tE5vKjfM8hpNCYL+LGc1YTfI0dg==} + engines: {node: '>=6'} + + polished@4.3.1: + resolution: {integrity: sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA==} + engines: {node: '>=10'} + + portfinder@1.0.32: + resolution: {integrity: sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==} + engines: {node: '>= 0.12.0'} + + possible-typed-array-names@1.0.0: + resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + engines: {node: '>= 0.4'} + + postcss-import@15.1.0: + resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} + engines: {node: '>=14.0.0'} + peerDependencies: + postcss: ^8.0.0 + + postcss-js@4.0.1: + resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} + engines: {node: ^12 || ^14 || >= 16} + peerDependencies: + postcss: ^8.4.21 + + postcss-load-config@4.0.2: + resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} + engines: {node: '>= 14'} + peerDependencies: + postcss: '>=8.0.9' + ts-node: '>=9.0.0' + peerDependenciesMeta: + postcss: + optional: true + ts-node: + optional: true + + postcss-loader@8.1.1: + resolution: {integrity: sha512-0IeqyAsG6tYiDRCYKQJLAmgQr47DX6N7sFSWvQxt6AcupX8DIdmykuk/o/tx0Lze3ErGHJEp5OSRxrelC6+NdQ==} + engines: {node: '>= 18.12.0'} + peerDependencies: + '@rspack/core': 0.x || 1.x + postcss: ^7.0.0 || ^8.0.1 + webpack: ^5.0.0 + peerDependenciesMeta: + '@rspack/core': + optional: true + webpack: + optional: true + + postcss-modules-extract-imports@3.1.0: + resolution: {integrity: sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-modules-local-by-default@4.0.5: + resolution: {integrity: sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-modules-scope@3.2.0: + resolution: {integrity: sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-modules-values@4.0.0: + resolution: {integrity: sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-nested@6.2.0: + resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.2.14 + + postcss-selector-parser@6.0.10: + resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==} + engines: {node: '>=4'} + + postcss-selector-parser@6.1.2: + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + engines: {node: '>=4'} + + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + + postcss@8.4.31: + resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} + engines: {node: ^10 || ^12 || >=14} + + postcss@8.4.47: + resolution: {integrity: sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==} + engines: {node: ^10 || ^12 || >=14} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + pretty-error@4.0.0: + resolution: {integrity: sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==} + + pretty-format@27.5.1: + resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + pretty-format@29.7.0: + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + prismjs@1.27.0: + resolution: {integrity: sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==} + engines: {node: '>=6'} + + prismjs@1.29.0: + resolution: {integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==} + engines: {node: '>=6'} + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + + prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + + prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + + property-information@5.6.0: + resolution: {integrity: sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==} + + property-information@6.5.0: + resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==} + + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + + psl@1.9.0: + resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} + + public-encrypt@4.0.3: + resolution: {integrity: sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==} + + pump@3.0.2: + resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==} + + punycode@1.4.1: + resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + pure-rand@6.1.0: + resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} + + qrcode.react@3.2.0: + resolution: {integrity: sha512-YietHHltOHA4+l5na1srdaMx4sVSOjV9tamHs+mwiLWAMr6QVACRUw1Neax5CptFILcNoITctJY0Ipyn5enQ8g==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + + qs@6.13.0: + resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} + engines: {node: '>=0.6'} + + querystring-es3@0.2.1: + resolution: {integrity: sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==} + engines: {node: '>=0.4.x'} + + querystringify@2.2.0: + resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + queue@6.0.2: + resolution: {integrity: sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==} + + quick-lru@5.1.1: + resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} + engines: {node: '>=10'} + + randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + + randomfill@1.0.4: + resolution: {integrity: sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==} + + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@2.5.2: + resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} + engines: {node: '>= 0.8'} + + rc-input@1.6.3: + resolution: {integrity: sha512-wI4NzuqBS8vvKr8cljsvnTUqItMfG1QbJoxovCgL+DX4eVUcHIjVwharwevIxyy7H/jbLryh+K7ysnJr23aWIA==} + peerDependencies: + react: '>=16.0.0' + react-dom: '>=16.0.0' + + rc-resize-observer@1.4.0: + resolution: {integrity: sha512-PnMVyRid9JLxFavTjeDXEXo65HCRqbmLBw9xX9gfC4BZiSzbLXKzW3jPz+J0P71pLbD5tBMTT+mkstV5gD0c9Q==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-textarea@1.8.2: + resolution: {integrity: sha512-UFAezAqltyR00a8Lf0IPAyTd29Jj9ee8wt8DqXyDMal7r/Cg/nDt3e1OOv3Th4W6mKaZijjgwuPXhAfVNTN8sw==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-util@5.43.0: + resolution: {integrity: sha512-AzC7KKOXFqAdIBqdGWepL9Xn7cm3vnAmjlHqUnoQaTMZYhM4VlXGLkkHHxj/BZ7Td0+SOPKB4RGPboBVKT9htw==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + react-18-input-autosize@3.0.0: + resolution: {integrity: sha512-7tsUc9PJWg6Vsp8qYuzlKKBf7hbCoTBdNfjYZSprEPbxf3meuhjklg9QPBe9rIyoR3uDAzmG7NpoJ1+kP5ns+w==} + peerDependencies: + react: ^16.3.0 || ^17.0.0 || ^18.0.0 + + react-colorful@5.6.1: + resolution: {integrity: sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + react-confetti@6.1.0: + resolution: {integrity: sha512-7Ypx4vz0+g8ECVxr88W9zhcQpbeujJAVqL14ZnXJ3I23mOI9/oBVTQ3dkJhUmB0D6XOtCZEM6N0Gm9PMngkORw==} + engines: {node: '>=10.18'} + peerDependencies: + react: ^16.3.0 || ^17.0.1 || ^18.0.0 + + react-docgen-typescript@2.2.2: + resolution: {integrity: sha512-tvg2ZtOpOi6QDwsb3GZhOjDkkX0h8Z2gipvTg6OVMUyoYoURhEiRNePT8NZItTVCDh39JJHnLdfCOkzoLbFnTg==} + peerDependencies: + typescript: '>= 4.3.x' + + react-docgen@7.1.0: + resolution: {integrity: sha512-APPU8HB2uZnpl6Vt/+0AFoVYgSRtfiP6FLrZgPPTDmqSb2R4qZRbgd0A3VzIFxDt5e+Fozjx79WjLWnF69DK8g==} + engines: {node: '>=16.14.0'} + + react-dom@18.2.0: + resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} + peerDependencies: + react: ^18.2.0 + + react-easy-crop@5.1.0: + resolution: {integrity: sha512-UsYeF/N7zoqtfOSD+2xSt1nRaoBYCI2YLkzmq+hi+aVepS4/bAMhbrLwJtDAP60jsVzWRiQCX7JG+ZtfWcHsiw==} + peerDependencies: + react: '>=16.4.0' + react-dom: '>=16.4.0' + + react-element-to-jsx-string@15.0.0: + resolution: {integrity: sha512-UDg4lXB6BzlobN60P8fHWVPX3Kyw8ORrTeBtClmIlGdkOOE+GYQSFvmEU5iLLpwp/6v42DINwNcwOhOLfQ//FQ==} + peerDependencies: + react: ^0.14.8 || ^15.0.1 || ^16.0.0 || ^17.0.1 || ^18.0.0 + react-dom: ^0.14.8 || ^15.0.1 || ^16.0.0 || ^17.0.1 || ^18.0.0 + + react-error-boundary@3.1.4: + resolution: {integrity: sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==} + engines: {node: '>=10', npm: '>=6'} + peerDependencies: + react: '>=16.13.1' + + react-error-boundary@4.1.2: + resolution: {integrity: sha512-GQDxZ5Jd+Aq/qUxbCm1UtzmL/s++V7zKgE8yMktJiCQXCCFZnMZh9ng+6/Ne6PjNSXH0L9CjeOEREfRnq6Duag==} + peerDependencies: + react: '>=16.13.1' + + react-fast-compare@3.2.2: + resolution: {integrity: sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==} + + react-headless-pagination@1.1.6: + resolution: {integrity: sha512-t7L/Q4xpyZszw8iC8ALERs/G2644JESmssahUkRp65WFWvw2k9HXVmfI6VbXvTXrqy+a8fbKT6BQ6SgS2ULNOA==} + engines: {node: '>=18.13'} + peerDependencies: + react: '>=16' + + react-hook-form@7.53.1: + resolution: {integrity: sha512-6aiQeBda4zjcuaugWvim9WsGqisoUk+etmFEsSUMm451/Ic8L/UAb7sRtMj3V+Hdzm6mMjU1VhiSzYUZeBm0Vg==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^16.8.0 || ^17 || ^18 || ^19 + + react-i18next@12.3.1: + resolution: {integrity: sha512-5v8E2XjZDFzK7K87eSwC7AJcAkcLt5xYZ4+yTPDAW1i7C93oOY1dnr4BaQM7un4Hm+GmghuiPvevWwlca5PwDA==} + peerDependencies: + i18next: '>= 19.0.0' + react: '>= 16.8.0' + react-dom: '*' + react-native: '*' + peerDependenciesMeta: + react-dom: + optional: true + react-native: + optional: true + + react-infinite-scroll-component@6.1.0: + resolution: {integrity: sha512-SQu5nCqy8DxQWpnUVLx7V7b7LcA37aM7tvoWjTLZp1dk6EJibM5/4EJKzOnl07/BsM1Y40sKLuqjCwwH/xV0TQ==} + peerDependencies: + react: '>=16.0.0' + + react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + + react-is@17.0.2: + resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + + react-is@18.1.0: + resolution: {integrity: sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg==} + + react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + + react-markdown@8.0.7: + resolution: {integrity: sha512-bvWbzG4MtOU62XqBx3Xx+zB2raaFFsq4mYiAzfjXJMEz2sixgeAfraA3tvzULF02ZdOMUOKTBFFaZJDDrq+BJQ==} + peerDependencies: + '@types/react': ~18.2.0 + react: '>=16' + + react-multi-email@1.0.25: + resolution: {integrity: sha512-Wmv28FvIk4nWgdpHzlIPonY4iSs7bPV35+fAiWYzSBhTo+vhXfglEhjY1WnjHQINW/Pibu2xlb/q1heVuytQHQ==} + peerDependencies: + react: ^18.2.0 + react-dom: ^18.2.0 + + react-papaparse@4.4.0: + resolution: {integrity: sha512-xTEwHZYJ+1dh9mQDQjjwJXmWyX20DdZ52u+ddw75V+Xm5qsjXSvWmC7c8K82vRwMjKAOH2S9uFyGpHEyEztkUQ==} + engines: {node: '>=8', npm: '>=5'} + + react-refresh@0.14.2: + resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} + engines: {node: '>=0.10.0'} + + react-slider@2.0.6: + resolution: {integrity: sha512-gJxG1HwmuMTJ+oWIRCmVWvgwotNCbByTwRkFZC6U4MBsHqJBmxwbYRJUmxy4Tke1ef8r9jfXjgkmY/uHOCEvbA==} + peerDependencies: + react: ^16 || ^17 || ^18 + + react-sortablejs@6.1.4: + resolution: {integrity: sha512-fc7cBosfhnbh53Mbm6a45W+F735jwZ1UFIYSrIqcO/gRIFoDyZeMtgKlpV4DdyQfbCzdh5LoALLTDRxhMpTyXQ==} + peerDependencies: + '@types/sortablejs': '1' + react: '>=16.9.0' + react-dom: '>=16.9.0' + sortablejs: '1' + + react-syntax-highlighter@15.6.1: + resolution: {integrity: sha512-OqJ2/vL7lEeV5zTJyG7kmARppUjiB9h9udl4qHQjjgEos66z00Ia0OckwYfRxCSFrW8RJIBnsBwQsHZbVPspqg==} + peerDependencies: + react: '>= 0.14.0' + + react-tooltip@5.8.3: + resolution: {integrity: sha512-h7maAlm2Xeymc14gWKhhrzsENeB83N65EzZ+AcQIGrOpNE0yefVRJIHhNcWHEJ0FEtf7VZXxtsj5glVXKxEtvA==} + peerDependencies: + react: '>=16.14.0' + react-dom: '>=16.14.0' + + react-window-infinite-loader@1.0.9: + resolution: {integrity: sha512-5Hg89IdU4Vrp0RT8kZYKeTIxWZYhNkVXeI1HbKo01Vm/Z7qztDvXljwx16sMzsa9yapRJQW3ODZfMUw38SOWHw==} + engines: {node: '>8.0.0'} + peerDependencies: + react: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0 + react-dom: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0 + + react-window@1.8.10: + resolution: {integrity: sha512-Y0Cx+dnU6NLa5/EvoHukUD0BklJ8qITCtVEPY1C/nL8wwoZ0b5aEw8Ff1dOVHw7fCzMt55XfJDd8S8W8LCaUCg==} + engines: {node: '>8.0.0'} + peerDependencies: + react: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 + react-dom: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 + + react@18.2.0: + resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} + engines: {node: '>=0.10.0'} + + reactflow@11.11.4: + resolution: {integrity: sha512-70FOtJkUWH3BAOsN+LU9lCrKoKbtOPnz2uq0CV2PLdNSwxTXOhCbsZr50GmZ+Rtw3jx8Uv7/vBFtCGixLfd4Og==} + peerDependencies: + react: '>=17' + react-dom: '>=17' + + read-cache@1.0.0: + resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} + + read-pkg-up@7.0.1: + resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} + engines: {node: '>=8'} + + read-pkg@5.2.0: + resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} + engines: {node: '>=8'} + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + readable-stream@4.5.2: + resolution: {integrity: sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + readdirp@4.0.2: + resolution: {integrity: sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==} + engines: {node: '>= 14.16.0'} + + recast@0.23.9: + resolution: {integrity: sha512-Hx/BGIbwj+Des3+xy5uAtAbdCyqK9y9wbBcDFDYanLS9JnMqf7OeF87HQwUimE87OEc72mr6tkKUKMBBL+hF9Q==} + engines: {node: '>= 4'} + + recordrtc@5.6.2: + resolution: {integrity: sha512-1QNKKNtl7+KcwD1lyOgP3ZlbiJ1d0HtXnypUy7yq49xEERxk31PHvE9RCciDrulPCY7WJ+oz0R9hpNxgsIurGQ==} + + redent@3.0.0: + resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} + engines: {node: '>=8'} + + reflect.getprototypeof@1.0.6: + resolution: {integrity: sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==} + engines: {node: '>= 0.4'} + + refractor@3.6.0: + resolution: {integrity: sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==} + + regenerate-unicode-properties@10.2.0: + resolution: {integrity: sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==} + engines: {node: '>=4'} + + regenerate@1.4.2: + resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} + + regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + + regenerator-transform@0.15.2: + resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==} + + regex-parser@2.3.0: + resolution: {integrity: sha512-TVILVSz2jY5D47F4mA4MppkBrafEaiUWJO/TcZHEIuI13AqoZMkK1WMA4Om1YkYbTx+9Ki1/tSUXbceyr9saRg==} + + regexp-tree@0.1.27: + resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==} + hasBin: true + + regexp.prototype.flags@1.5.3: + resolution: {integrity: sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==} + engines: {node: '>= 0.4'} + + regexpp@3.2.0: + resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==} + engines: {node: '>=8'} + + regexpu-core@6.1.1: + resolution: {integrity: sha512-k67Nb9jvwJcJmVpw0jPttR1/zVfnKf8Km0IPatrU/zJ5XeG3+Slx0xLXs9HByJSzXzrlz5EDvN6yLNMDc2qdnw==} + engines: {node: '>=4'} + + regjsgen@0.8.0: + resolution: {integrity: sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==} + + regjsparser@0.11.1: + resolution: {integrity: sha512-1DHODs4B8p/mQHU9kr+jv8+wIC9mtG4eBHxWxIq5mhjE3D5oORhCc6deRKzTjs9DcfRFmj9BHSDguZklqCGFWQ==} + hasBin: true + + regjsparser@0.9.1: + resolution: {integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==} + hasBin: true + + rehype-external-links@3.0.0: + resolution: {integrity: sha512-yp+e5N9V3C6bwBeAC4n796kc86M4gJCdlVhiMTxIrJG5UHDMh+PJANf9heqORJbt1nrCbDwIlAZKjANIaVBbvw==} + + rehype-katex@6.0.3: + resolution: {integrity: sha512-ByZlRwRUcWegNbF70CVRm2h/7xy7jQ3R9LaY4VVSvjnoVWwWVhNL60DiZsBpC5tSzYQOCvDbzncIpIjPZWodZA==} + + rehype-raw@7.0.0: + resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==} + + rehype-slug@6.0.0: + resolution: {integrity: sha512-lWyvf/jwu+oS5+hL5eClVd3hNdmwM1kAC0BUvEGD19pajQMIzcNUd/k9GsfQ+FfECvX+JE+e9/btsKH0EjJT6A==} + + relateurl@0.2.7: + resolution: {integrity: sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==} + engines: {node: '>= 0.10'} + + remark-breaks@3.0.3: + resolution: {integrity: sha512-C7VkvcUp1TPUc2eAYzsPdaUh8Xj4FSbQnYA5A9f80diApLZscTDeG7efiWP65W8hV2sEy3JuGVU0i6qr5D8Hug==} + + remark-gfm@3.0.1: + resolution: {integrity: sha512-lEFDoi2PICJyNrACFOfDD3JlLkuSbOa5Wd8EPt06HUdptv8Gn0bxYTdbU/XXQ3swAPkEaGxxPN9cbnMHvVu1Ig==} + + remark-math@5.1.1: + resolution: {integrity: sha512-cE5T2R/xLVtfFI4cCePtiRn+e6jKMtFDR3P8V3qpv8wpKjwvHoBA4eJzvX+nVrnlNy0911bdGmuspCSwetfYHw==} + + remark-mdx@2.3.0: + resolution: {integrity: sha512-g53hMkpM0I98MU266IzDFMrTD980gNF3BJnkyFcmN+dD873mQeD5rdMO3Y2X+x8umQfbSE0PcoEDl7ledSA+2g==} + + remark-parse@10.0.2: + resolution: {integrity: sha512-3ydxgHa/ZQzG8LvC7jTXccARYDcRld3VfcgIIFs7bI6vbRSxJJmzgLEIIoYKyrfhaY+ujuWaf/PJiMZXoiCXgw==} + + remark-rehype@10.1.0: + resolution: {integrity: sha512-EFmR5zppdBp0WQeDVZ/b66CWJipB2q2VLNFMabzDSGR66Z2fQii83G5gTBbgGEnEEA0QRussvrFHxk1HWGJskw==} + + renderkid@3.0.0: + resolution: {integrity: sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + requireindex@1.2.0: + resolution: {integrity: sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==} + engines: {node: '>=0.10.5'} + + requires-port@1.0.0: + resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + + resize-observer-polyfill@1.5.1: + resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==} + + resolve-alpn@1.2.1: + resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} + + resolve-cwd@3.0.0: + resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} + engines: {node: '>=8'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + resolve-url-loader@5.0.0: + resolution: {integrity: sha512-uZtduh8/8srhBoMx//5bwqjQ+rfYOUq8zC9NrMUGtjBiGTtFJM42s58/36+hTqeqINcnYe08Nj3LkK9lW4N8Xg==} + engines: {node: '>=12'} + + resolve.exports@2.0.2: + resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} + engines: {node: '>=10'} + + resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + hasBin: true + + resolve@2.0.0-next.5: + resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} + hasBin: true + + responselike@2.0.1: + resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==} + + restore-cursor@4.0.0: + resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rfdc@1.4.1: + resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + ripemd160@2.0.2: + resolution: {integrity: sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==} + + robust-predicates@3.0.2: + resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + rw@1.3.3: + resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} + + sade@1.8.1: + resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} + engines: {node: '>=6'} + + safe-array-concat@1.1.2: + resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} + engines: {node: '>=0.4'} + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safe-regex-test@1.0.3: + resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} + engines: {node: '>= 0.4'} + + safe-regex@2.1.1: + resolution: {integrity: sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + sass-loader@13.3.3: + resolution: {integrity: sha512-mt5YN2F1MOZr3d/wBRcZxeFgwgkH44wVc2zohO2YF6JiOMkiXe4BYRZpSu2sO1g71mo/j16txzUhsKZlqjVGzA==} + engines: {node: '>= 14.15.0'} + peerDependencies: + fibers: '>= 3.1.0' + node-sass: ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 + sass: ^1.3.0 + sass-embedded: '*' + webpack: ^5.0.0 + peerDependenciesMeta: + fibers: + optional: true + node-sass: + optional: true + sass: + optional: true + sass-embedded: + optional: true + + sass@1.80.3: + resolution: {integrity: sha512-ptDWyVmDMVielpz/oWy3YP3nfs7LpJTHIJZboMVs8GEC9eUmtZTZhMHlTW98wY4aEorDfjN38+Wr/XjskFWcfA==} + engines: {node: '>=14.0.0'} + hasBin: true + + saxes@6.0.0: + resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} + engines: {node: '>=v12.22.7'} + + scheduler@0.23.2: + resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + + schema-utils@3.3.0: + resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} + engines: {node: '>= 10.13.0'} + + schema-utils@4.2.0: + resolution: {integrity: sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==} + engines: {node: '>= 12.13.0'} + + screenfull@5.2.0: + resolution: {integrity: sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==} + engines: {node: '>=0.10.0'} + + semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + engines: {node: '>=10'} + hasBin: true + + send@0.19.0: + resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==} + engines: {node: '>= 0.8.0'} + + serialize-javascript@6.0.2: + resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + + serve-static@1.16.2: + resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==} + engines: {node: '>= 0.8.0'} + + server-only@0.0.1: + resolution: {integrity: sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + setimmediate@1.0.5: + resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + sha.js@2.4.11: + resolution: {integrity: sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==} + hasBin: true + + sharp@0.33.5: + resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + engines: {node: '>= 0.4'} + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + simple-swizzle@0.2.2: + resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + size-sensor@1.0.2: + resolution: {integrity: sha512-2NCmWxY7A9pYKGXNBfteo4hy14gWu47rg5692peVMst6lQLPKrVjhY+UTEsPI5ceFRJSl3gVgMYaUi/hKuaiKw==} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + slice-ansi@5.0.0: + resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} + engines: {node: '>=12'} + + sortablejs@1.15.3: + resolution: {integrity: sha512-zdK3/kwwAK1cJgy1rwl1YtNTbRmc8qW/+vgXf75A7NHag5of4pyI6uK86ktmQETyWRH7IGaE73uZOOBcGxgqZg==} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map-support@0.5.13: + resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + source-map@0.7.4: + resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} + engines: {node: '>= 8'} + + space-separated-tokens@1.1.5: + resolution: {integrity: sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==} + + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + + spdx-correct@3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + + spdx-exceptions@2.5.0: + resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} + + spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + + spdx-license-ids@3.0.20: + resolution: {integrity: sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + stack-utils@2.0.6: + resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} + engines: {node: '>=10'} + + stackframe@1.3.4: + resolution: {integrity: sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==} + + state-local@1.0.7: + resolution: {integrity: sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==} + + statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + + stop-iteration-iterator@1.0.0: + resolution: {integrity: sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==} + engines: {node: '>= 0.4'} + + storybook@8.3.6: + resolution: {integrity: sha512-9GVbtej6ZzPRUM7KRQ7848506FfHrUiJGqPuIQdoSJd09EmuEoLjmLAgEOmrHBQKgGYMaM7Vh9GsTLim6vwZTQ==} + hasBin: true + + stream-browserify@3.0.0: + resolution: {integrity: sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==} + + stream-http@3.2.0: + resolution: {integrity: sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==} + + streamsearch@1.1.0: + resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} + engines: {node: '>=10.0.0'} + + string-argv@0.3.2: + resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} + engines: {node: '>=0.6.19'} + + string-length@4.0.2: + resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} + engines: {node: '>=10'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string.prototype.includes@2.0.1: + resolution: {integrity: sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==} + engines: {node: '>= 0.4'} + + string.prototype.matchall@4.0.11: + resolution: {integrity: sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==} + engines: {node: '>= 0.4'} + + string.prototype.repeat@1.0.0: + resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==} + + string.prototype.trim@1.2.9: + resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.8: + resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==} + + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-bom@4.0.0: + resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} + engines: {node: '>=8'} + + strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + + strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + + strip-indent@3.0.0: + resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} + engines: {node: '>=8'} + + strip-indent@4.0.0: + resolution: {integrity: sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==} + engines: {node: '>=12'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + style-loader@3.3.4: + resolution: {integrity: sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w==} + engines: {node: '>= 12.13.0'} + peerDependencies: + webpack: ^5.0.0 + + style-to-object@0.4.4: + resolution: {integrity: sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==} + + styled-jsx@5.1.1: + resolution: {integrity: sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@babel/core': '*' + babel-plugin-macros: '*' + react: '>= 16.8.0 || 17.x.x || ^18.0.0-0' + peerDependenciesMeta: + '@babel/core': + optional: true + babel-plugin-macros: + optional: true + + styled-jsx@5.1.6: + resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@babel/core': '*' + babel-plugin-macros: '*' + react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0' + peerDependenciesMeta: + '@babel/core': + optional: true + babel-plugin-macros: + optional: true + + stylis@4.3.4: + resolution: {integrity: sha512-osIBl6BGUmSfDkyH2mB7EFvCJntXDrLhKjHTRj/rK6xLH0yuPrHULDRQzKokSOD4VoorhtKpfcfW1GAntu8now==} + + sucrase@3.35.0: + resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + + supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + swr@2.2.5: + resolution: {integrity: sha512-QtxqyclFeAsxEUeZIYmsaQ0UjimSq1RZ9Un7I68/0ClKK/U3LoyQunwkQfJZr2fc22DfIXLNDc2wFyTEikCUpg==} + peerDependencies: + react: ^16.11.0 || ^17.0.0 || ^18.0.0 + + symbol-tree@3.2.4: + resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + + synckit@0.6.2: + resolution: {integrity: sha512-Vhf+bUa//YSTYKseDiiEuQmhGCoIF3CVBhunm3r/DQnYiGT4JssmnKQc44BIyOZRK2pKjXXAgbhfmbeoC9CJpA==} + engines: {node: '>=12.20'} + + tabbable@6.2.0: + resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} + + tailwind-merge@2.5.4: + resolution: {integrity: sha512-0q8cfZHMu9nuYP/b5Shb7Y7Sh1B7Nnl5GqNr1U+n2p6+mybvRtayrQ+0042Z5byvTA8ihjlP8Odo8/VnHbZu4Q==} + + tailwindcss@3.4.14: + resolution: {integrity: sha512-IcSvOcTRcUtQQ7ILQL5quRDg7Xs93PdJEk1ZLbhhvJc7uj/OAhYOnruEiwnGgBvUtaUAJ8/mhSw1o8L2jCiENA==} + engines: {node: '>=14.0.0'} + hasBin: true + + tapable@2.2.1: + resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} + engines: {node: '>=6'} + + telejson@7.2.0: + resolution: {integrity: sha512-1QTEcJkJEhc8OnStBx/ILRu5J2p0GjvWsBx56bmZRqnrkdBMUe+nX92jxV+p3dB4CP6PZCdJMQJwCggkNBMzkQ==} + + terser-webpack-plugin@5.3.10: + resolution: {integrity: sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==} + engines: {node: '>= 10.13.0'} + peerDependencies: + '@swc/core': '*' + esbuild: '*' + uglify-js: '*' + webpack: ^5.1.0 + peerDependenciesMeta: + '@swc/core': + optional: true + esbuild: + optional: true + uglify-js: + optional: true + + terser@5.36.0: + resolution: {integrity: sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w==} + engines: {node: '>=10'} + hasBin: true + + test-exclude@6.0.0: + resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} + engines: {node: '>=8'} + + text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + + throttle-debounce@2.3.0: + resolution: {integrity: sha512-H7oLPV0P7+jgvrk+6mwwwBDmxTaxnu9HMXmloNLXwnNO0ZxZ31Orah2n8lU1eMPvsaowP2CX+USCgyovXfdOFQ==} + engines: {node: '>=8'} + + timers-browserify@2.0.12: + resolution: {integrity: sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==} + engines: {node: '>=0.6.0'} + + tiny-invariant@1.2.0: + resolution: {integrity: sha512-1Uhn/aqw5C6RI4KejVeTg6mIS7IqxnLJ8Mv2tV5rTc0qWobay7pDUz6Wi392Cnc8ak1H0F2cjoRzb2/AW4+Fvg==} + + tiny-invariant@1.3.3: + resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + + tinyrainbow@1.2.0: + resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} + engines: {node: '>=14.0.0'} + + tinyspy@3.0.2: + resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} + engines: {node: '>=14.0.0'} + + tmpl@1.0.5: + resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} + + to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + toggle-selection@1.0.6: + resolution: {integrity: sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + tough-cookie@4.1.4: + resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} + engines: {node: '>=6'} + + tr46@3.0.0: + resolution: {integrity: sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==} + engines: {node: '>=12'} + + trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + + trough@2.2.0: + resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + + ts-api-utils@1.3.0: + resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} + engines: {node: '>=16'} + peerDependencies: + typescript: '>=4.2.0' + + ts-dedent@2.2.0: + resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==} + engines: {node: '>=6.10'} + + ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + + ts-node@10.9.2: + resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + + ts-pnp@1.2.0: + resolution: {integrity: sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw==} + engines: {node: '>=6'} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + tsconfig-paths-webpack-plugin@4.1.0: + resolution: {integrity: sha512-xWFISjviPydmtmgeUAuXp4N1fky+VCtfhOkDUFIv5ea7p4wuTomI4QTrXvFBX2S4jZsmyTSrStQl+E+4w+RzxA==} + engines: {node: '>=10.13.0'} + + tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + + tsconfig-paths@4.2.0: + resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} + engines: {node: '>=6'} + + tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + + tslib@2.3.0: + resolution: {integrity: sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==} + + tslib@2.8.0: + resolution: {integrity: sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==} + + tsutils@3.21.0: + resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} + engines: {node: '>= 6'} + peerDependencies: + typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' + + tty-browserify@0.0.1: + resolution: {integrity: sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==} + + tween-functions@1.2.0: + resolution: {integrity: sha512-PZBtLYcCLtEcjL14Fzb1gSxPBeL7nWvGhO5ZFPGqziCcr8uvHp0NDmdjBchp6KHL+tExcg0m3NISmKxhU394dA==} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + type-detect@4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + + type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + + type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + + type-fest@0.6.0: + resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} + engines: {node: '>=8'} + + type-fest@0.8.1: + resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} + engines: {node: '>=8'} + + type-fest@1.4.0: + resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} + engines: {node: '>=10'} + + type-fest@2.19.0: + resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} + engines: {node: '>=12.20'} + + type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + + typed-array-buffer@1.0.2: + resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} + engines: {node: '>= 0.4'} + + typed-array-byte-length@1.0.1: + resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==} + engines: {node: '>= 0.4'} + + typed-array-byte-offset@1.0.2: + resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==} + engines: {node: '>= 0.4'} + + typed-array-length@1.0.6: + resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==} + engines: {node: '>= 0.4'} + + typescript@4.9.5: + resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} + engines: {node: '>=4.2.0'} + hasBin: true + + uglify-js@3.19.3: + resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} + engines: {node: '>=0.8.0'} + hasBin: true + + unbox-primitive@1.0.2: + resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + + undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + + unicode-canonical-property-names-ecmascript@2.0.1: + resolution: {integrity: sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==} + engines: {node: '>=4'} + + unicode-match-property-ecmascript@2.0.0: + resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} + engines: {node: '>=4'} + + unicode-match-property-value-ecmascript@2.2.0: + resolution: {integrity: sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==} + engines: {node: '>=4'} + + unicode-property-aliases-ecmascript@2.1.0: + resolution: {integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==} + engines: {node: '>=4'} + + unified@10.1.2: + resolution: {integrity: sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==} + + unist-util-find-after@4.0.1: + resolution: {integrity: sha512-QO/PuPMm2ERxC6vFXEPtmAutOopy5PknD+Oq64gGwxKtk4xwo9Z97t9Av1obPmGU0IyTa6EKYUfTrK2QJS3Ozw==} + + unist-util-generated@2.0.1: + resolution: {integrity: sha512-qF72kLmPxAw0oN2fwpWIqbXAVyEqUzDHMsbtPvOudIlUzXYFIeQIuxXQCRCFh22B7cixvU0MG7m3MW8FTq/S+A==} + + unist-util-is@5.2.1: + resolution: {integrity: sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==} + + unist-util-is@6.0.0: + resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==} + + unist-util-position-from-estree@1.1.2: + resolution: {integrity: sha512-poZa0eXpS+/XpoQwGwl79UUdea4ol2ZuCYguVaJS4qzIOMDzbqz8a3erUCOmubSZkaOuGamb3tX790iwOIROww==} + + unist-util-position@4.0.4: + resolution: {integrity: sha512-kUBE91efOWfIVBo8xzh/uZQ7p9ffYRtUbMRZBNFYwf0RK8koUMx6dGUfwylLOKmaT2cs4wSW96QoYUSXAyEtpg==} + + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + + unist-util-remove-position@4.0.2: + resolution: {integrity: sha512-TkBb0HABNmxzAcfLf4qsIbFbaPDvMO6wa3b3j4VcEzFVaw1LBKwnW4/sRJ/atSLSzoIg41JWEdnE7N6DIhGDGQ==} + + unist-util-stringify-position@2.0.3: + resolution: {integrity: sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==} + + unist-util-stringify-position@3.0.3: + resolution: {integrity: sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-parents@5.1.3: + resolution: {integrity: sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==} + + unist-util-visit-parents@6.0.1: + resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==} + + unist-util-visit@4.1.2: + resolution: {integrity: sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==} + + unist-util-visit@5.0.0: + resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} + + universalify@0.2.0: + resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} + engines: {node: '>= 4.0.0'} + + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + unplugin@1.14.1: + resolution: {integrity: sha512-lBlHbfSFPToDYp9pjXlUEFVxYLaue9f9T1HC+4OHlmj+HnMDdz9oZY+erXfoCe/5V/7gKUSY2jpXPb9S7f0f/w==} + engines: {node: '>=14.0.0'} + peerDependencies: + webpack-sources: ^3 + peerDependenciesMeta: + webpack-sources: + optional: true + + update-browserslist-db@1.1.1: + resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + url-parse@1.5.10: + resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + + url@0.11.4: + resolution: {integrity: sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==} + engines: {node: '>= 0.4'} + + use-context-selector@1.4.4: + resolution: {integrity: sha512-pS790zwGxxe59GoBha3QYOwk8AFGp4DN6DOtH+eoqVmgBBRXVx4IlPDhJmmMiNQAgUaLlP+58aqRC3A4rdaSjg==} + peerDependencies: + react: '>=16.8.0' + react-dom: '*' + react-native: '*' + scheduler: '>=0.19.0' + peerDependenciesMeta: + react-dom: + optional: true + react-native: + optional: true + + use-strict@1.0.1: + resolution: {integrity: sha512-IeiWvvEXfW5ltKVMkxq6FvNf2LojMKvB2OCeja6+ct24S1XOmQw2dGr2JyndwACWAGJva9B7yPHwAmeA9QCqAQ==} + + use-sync-external-store@1.2.2: + resolution: {integrity: sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + util@0.12.5: + resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} + + utila@0.4.0: + resolution: {integrity: sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==} + + utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + + uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + hasBin: true + + uvu@0.5.6: + resolution: {integrity: sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==} + engines: {node: '>=8'} + hasBin: true + + v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + + v8-to-istanbul@9.3.0: + resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} + engines: {node: '>=10.12.0'} + + validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + vfile-location@4.1.0: + resolution: {integrity: sha512-YF23YMyASIIJXpktBa4vIGLJ5Gs88UB/XePgqPmTa7cDA+JeO3yclbpheQYCHjVHBn/yePzrXuygIL+xbvRYHw==} + + vfile-location@5.0.3: + resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==} + + vfile-message@3.1.4: + resolution: {integrity: sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==} + + vfile-message@4.0.2: + resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==} + + vfile@5.3.7: + resolution: {integrity: sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + + vite-code-inspector-plugin@0.13.0: + resolution: {integrity: sha512-hvIn9G+IFzQHVVynWh2wGTBHo51CBJRqQBzYryeuuaL0BK0w8my2/tlpSAae5ofQxOBXBMhyXC2gWgYUJnNWrA==} + + vm-browserify@1.1.2: + resolution: {integrity: sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==} + + void-elements@3.1.0: + resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} + engines: {node: '>=0.10.0'} + + vue-eslint-parser@9.4.3: + resolution: {integrity: sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '>=6.0.0' + + w3c-xmlserializer@4.0.0: + resolution: {integrity: sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==} + engines: {node: '>=14'} + + walker@1.0.8: + resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} + + watchpack@2.4.2: + resolution: {integrity: sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==} + engines: {node: '>=10.13.0'} + + web-namespaces@2.0.1: + resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} + + web-worker@1.3.0: + resolution: {integrity: sha512-BSR9wyRsy/KOValMgd5kMyr3JzpdeoR9KVId8u5GVlTTAtNChlsE4yTxeY7zMdNSyOmoKBv8NH2qeRY9Tg+IaA==} + + webidl-conversions@7.0.0: + resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} + engines: {node: '>=12'} + + webpack-code-inspector-plugin@0.13.0: + resolution: {integrity: sha512-T3ZZ84NX0cVmwff5zyYhB9OuroZYsyaQpSgFicgiuYAWCsQePYApM/R3bHdvcECkBXO50hAVtr9SjWRTu1+Ntg==} + + webpack-dev-middleware@6.1.3: + resolution: {integrity: sha512-A4ChP0Qj8oGociTs6UdlRUGANIGrCDL3y+pmQMc+dSsraXHCatFpmMey4mYELA+juqwUqwQsUgJJISXl1KWmiw==} + engines: {node: '>= 14.15.0'} + peerDependencies: + webpack: ^5.0.0 + peerDependenciesMeta: + webpack: + optional: true + + webpack-hot-middleware@2.26.1: + resolution: {integrity: sha512-khZGfAeJx6I8K9zKohEWWYN6KDlVw2DHownoe+6Vtwj1LP9WFgegXnVMSkZ/dBEBtXFwrkkydsaPFlB7f8wU2A==} + + webpack-sources@3.2.3: + resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} + engines: {node: '>=10.13.0'} + + webpack-virtual-modules@0.6.2: + resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} + + webpack@5.95.0: + resolution: {integrity: sha512-2t3XstrKULz41MNMBF+cJ97TyHdyQ8HCt//pqErqDvNjU9YQBnZxIHa11VXsi7F3mb5/aO2tuDxdeTPdU7xu9Q==} + engines: {node: '>=10.13.0'} + hasBin: true + peerDependencies: + webpack-cli: '*' + peerDependenciesMeta: + webpack-cli: + optional: true + + whatwg-encoding@2.0.0: + resolution: {integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==} + engines: {node: '>=12'} + + whatwg-mimetype@3.0.0: + resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} + engines: {node: '>=12'} + + whatwg-url@11.0.0: + resolution: {integrity: sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==} + engines: {node: '>=12'} + + which-boxed-primitive@1.0.2: + resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + + which-builtin-type@1.1.4: + resolution: {integrity: sha512-bppkmBSsHFmIMSl8BO9TbsyzsvGjVoppt8xUiGzwiu/bhDCGxnpOKCxgqj6GuyHE0mINMDecBFPlOm2hzY084w==} + engines: {node: '>= 0.4'} + + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + + which-typed-array@1.1.15: + resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} + engines: {node: '>= 0.4'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + write-file-atomic@4.0.2: + resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + xml-name-validator@4.0.0: + resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} + engines: {node: '>=12'} + + xmlchars@2.2.0: + resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + + xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yaml-eslint-parser@1.2.3: + resolution: {integrity: sha512-4wZWvE398hCP7O8n3nXKu/vdq1HcH01ixYlCREaJL5NUMwQ0g3MaGFUBNSlmBtKmhbtVG/Cm6lyYmSVTEVil8A==} + engines: {node: ^14.17.0 || >=16.0.0} + + yaml@1.10.2: + resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} + engines: {node: '>= 6'} + + yaml@2.3.1: + resolution: {integrity: sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==} + engines: {node: '>= 14'} + + yaml@2.6.0: + resolution: {integrity: sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ==} + engines: {node: '>= 14'} + hasBin: true + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + yjs@13.6.20: + resolution: {integrity: sha512-Z2YZI+SYqK7XdWlloI3lhMiKnCdFCVC4PchpdO+mCYwtiTwncjUbnRK9R1JmkNfdmHyDXuWN3ibJAt0wsqTbLQ==} + engines: {node: '>=16.0.0', npm: '>=8.0.0'} + + yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + yocto-queue@1.1.1: + resolution: {integrity: sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==} + engines: {node: '>=12.20'} + + zod@3.23.8: + resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} + + zrender@5.6.0: + resolution: {integrity: sha512-uzgraf4njmmHAbEUxMJ8Oxg+P3fT04O+9p7gY+wJRVxo8Ge+KmYv0WJev945EH4wFuc4OY2NLXz46FZrWS9xJg==} + + zundo@2.2.0: + resolution: {integrity: sha512-WYCiSO3Uqm7TN9KtT3dpfhOuAS1t5CixjYJuPfVMKl88BZVpP449XtXeiuHWEtRAfYE3yFvRkFCgAThm7v3QuQ==} + peerDependencies: + zustand: ^4.3.0 + + zustand@4.5.5: + resolution: {integrity: sha512-+0PALYNJNgK6hldkgDq2vLrw5f6g/jCInz52n9RTpropGgeAf/ioFUCdtsjCqu4gNhW9D01rUQBROoRjdzyn2Q==} + engines: {node: '>=12.7.0'} + peerDependencies: + '@types/react': ~18.2.0 + immer: '>=9.0.6' + react: '>=16.8' + peerDependenciesMeta: + '@types/react': + optional: true + immer: + optional: true + react: + optional: true + + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + +snapshots: + + '@adobe/css-tools@4.4.0': {} + + '@alloc/quick-lru@5.2.0': {} + + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + + '@antfu/eslint-config-basic@0.36.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5)': + dependencies: + eslint: 8.57.1 + eslint-plugin-antfu: 0.36.0(eslint@8.57.1)(typescript@4.9.5) + eslint-plugin-eslint-comments: 3.2.0(eslint@8.57.1) + eslint-plugin-html: 7.1.0 + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1) + eslint-plugin-jsonc: 2.16.0(eslint@8.57.1) + eslint-plugin-markdown: 3.0.1(eslint@8.57.1) + eslint-plugin-n: 15.7.0(eslint@8.57.1) + eslint-plugin-no-only-tests: 3.3.0 + eslint-plugin-promise: 6.6.0(eslint@8.57.1) + eslint-plugin-unicorn: 45.0.2(eslint@8.57.1) + eslint-plugin-unused-imports: 2.0.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1) + eslint-plugin-yml: 1.14.0(eslint@8.57.1) + jsonc-eslint-parser: 2.4.0 + yaml-eslint-parser: 1.2.3 + transitivePeerDependencies: + - '@typescript-eslint/eslint-plugin' + - '@typescript-eslint/parser' + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + - typescript + + '@antfu/eslint-config-ts@0.36.0(eslint@8.57.1)(jest@29.7.0(@types/node@18.15.0)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)))(typescript@4.9.5)': + dependencies: + '@antfu/eslint-config-basic': 0.36.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@4.9.5) + eslint: 8.57.1 + eslint-plugin-jest: 27.9.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(jest@29.7.0(@types/node@18.15.0)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)))(typescript@4.9.5) + typescript: 4.9.5 + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - jest + - supports-color + + '@antfu/eslint-config-vue@0.36.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(jest@29.7.0(@types/node@18.15.0)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)))(typescript@4.9.5)': + dependencies: + '@antfu/eslint-config-basic': 0.36.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) + '@antfu/eslint-config-ts': 0.36.0(eslint@8.57.1)(jest@29.7.0(@types/node@18.15.0)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)))(typescript@4.9.5) + eslint: 8.57.1 + eslint-plugin-vue: 9.29.1(eslint@8.57.1) + local-pkg: 0.4.3 + transitivePeerDependencies: + - '@typescript-eslint/eslint-plugin' + - '@typescript-eslint/parser' + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - jest + - supports-color + - typescript + + '@antfu/eslint-config@0.36.0(eslint@8.57.1)(jest@29.7.0(@types/node@18.15.0)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)))(typescript@4.9.5)': + dependencies: + '@antfu/eslint-config-vue': 0.36.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(jest@29.7.0(@types/node@18.15.0)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)))(typescript@4.9.5) + '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@4.9.5) + eslint: 8.57.1 + eslint-plugin-eslint-comments: 3.2.0(eslint@8.57.1) + eslint-plugin-html: 7.1.0 + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1) + eslint-plugin-jsonc: 2.16.0(eslint@8.57.1) + eslint-plugin-n: 15.7.0(eslint@8.57.1) + eslint-plugin-promise: 6.6.0(eslint@8.57.1) + eslint-plugin-unicorn: 45.0.2(eslint@8.57.1) + eslint-plugin-vue: 9.29.1(eslint@8.57.1) + eslint-plugin-yml: 1.14.0(eslint@8.57.1) + jsonc-eslint-parser: 2.4.0 + yaml-eslint-parser: 1.2.3 + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - jest + - supports-color + - typescript + + '@babel/code-frame@7.25.7': + dependencies: + '@babel/highlight': 7.25.7 + picocolors: 1.1.1 + + '@babel/compat-data@7.25.8': {} + + '@babel/core@7.25.8': + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.25.7 + '@babel/generator': 7.25.7 + '@babel/helper-compilation-targets': 7.25.7 + '@babel/helper-module-transforms': 7.25.7(@babel/core@7.25.8) + '@babel/helpers': 7.25.7 + '@babel/parser': 7.25.8 + '@babel/template': 7.25.7 + '@babel/traverse': 7.25.7 + '@babel/types': 7.25.8 + convert-source-map: 2.0.0 + debug: 4.3.7 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.25.7': + dependencies: + '@babel/types': 7.25.8 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 3.0.2 + + '@babel/helper-annotate-as-pure@7.25.7': + dependencies: + '@babel/types': 7.25.8 + + '@babel/helper-builder-binary-assignment-operator-visitor@7.25.7': + dependencies: + '@babel/traverse': 7.25.7 + '@babel/types': 7.25.8 + transitivePeerDependencies: + - supports-color + + '@babel/helper-compilation-targets@7.25.7': + dependencies: + '@babel/compat-data': 7.25.8 + '@babel/helper-validator-option': 7.25.7 + browserslist: 4.24.0 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-create-class-features-plugin@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-annotate-as-pure': 7.25.7 + '@babel/helper-member-expression-to-functions': 7.25.7 + '@babel/helper-optimise-call-expression': 7.25.7 + '@babel/helper-replace-supers': 7.25.7(@babel/core@7.25.8) + '@babel/helper-skip-transparent-expression-wrappers': 7.25.7 + '@babel/traverse': 7.25.7 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-create-regexp-features-plugin@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-annotate-as-pure': 7.25.7 + regexpu-core: 6.1.1 + semver: 6.3.1 + + '@babel/helper-define-polyfill-provider@0.6.2(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-compilation-targets': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + debug: 4.3.7 + lodash.debounce: 4.0.8 + resolve: 1.22.8 + transitivePeerDependencies: + - supports-color + + '@babel/helper-member-expression-to-functions@7.25.7': + dependencies: + '@babel/traverse': 7.25.7 + '@babel/types': 7.25.8 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-imports@7.25.7': + dependencies: + '@babel/traverse': 7.25.7 + '@babel/types': 7.25.8 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-module-imports': 7.25.7 + '@babel/helper-simple-access': 7.25.7 + '@babel/helper-validator-identifier': 7.25.7 + '@babel/traverse': 7.25.7 + transitivePeerDependencies: + - supports-color + + '@babel/helper-optimise-call-expression@7.25.7': + dependencies: + '@babel/types': 7.25.8 + + '@babel/helper-plugin-utils@7.25.7': {} + + '@babel/helper-remap-async-to-generator@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-annotate-as-pure': 7.25.7 + '@babel/helper-wrap-function': 7.25.7 + '@babel/traverse': 7.25.7 + transitivePeerDependencies: + - supports-color + + '@babel/helper-replace-supers@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-member-expression-to-functions': 7.25.7 + '@babel/helper-optimise-call-expression': 7.25.7 + '@babel/traverse': 7.25.7 + transitivePeerDependencies: + - supports-color + + '@babel/helper-simple-access@7.25.7': + dependencies: + '@babel/traverse': 7.25.7 + '@babel/types': 7.25.8 + transitivePeerDependencies: + - supports-color + + '@babel/helper-skip-transparent-expression-wrappers@7.25.7': + dependencies: + '@babel/traverse': 7.25.7 + '@babel/types': 7.25.8 + transitivePeerDependencies: + - supports-color + + '@babel/helper-string-parser@7.25.7': {} + + '@babel/helper-validator-identifier@7.25.7': {} + + '@babel/helper-validator-option@7.25.7': {} + + '@babel/helper-wrap-function@7.25.7': + dependencies: + '@babel/template': 7.25.7 + '@babel/traverse': 7.25.7 + '@babel/types': 7.25.8 + transitivePeerDependencies: + - supports-color + + '@babel/helpers@7.25.7': + dependencies: + '@babel/template': 7.25.7 + '@babel/types': 7.25.8 + + '@babel/highlight@7.25.7': + dependencies: + '@babel/helper-validator-identifier': 7.25.7 + chalk: 2.4.2 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/parser@7.25.8': + dependencies: + '@babel/types': 7.25.8 + + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/traverse': 7.25.7 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/helper-skip-transparent-expression-wrappers': 7.25.7 + '@babel/plugin-transform-optional-chaining': 7.25.8(@babel/core@7.25.8) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/traverse': 7.25.7 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-syntax-import-assertions@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-syntax-import-attributes@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-syntax-jsx@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-syntax-typescript@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-create-regexp-features-plugin': 7.25.7(@babel/core@7.25.8) + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-transform-arrow-functions@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-transform-async-generator-functions@7.25.8(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/helper-remap-async-to-generator': 7.25.7(@babel/core@7.25.8) + '@babel/traverse': 7.25.7 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-async-to-generator@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-module-imports': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/helper-remap-async-to-generator': 7.25.7(@babel/core@7.25.8) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-block-scoped-functions@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-transform-block-scoping@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-transform-class-properties@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-create-class-features-plugin': 7.25.7(@babel/core@7.25.8) + '@babel/helper-plugin-utils': 7.25.7 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-class-static-block@7.25.8(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-create-class-features-plugin': 7.25.7(@babel/core@7.25.8) + '@babel/helper-plugin-utils': 7.25.7 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-classes@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-annotate-as-pure': 7.25.7 + '@babel/helper-compilation-targets': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/helper-replace-supers': 7.25.7(@babel/core@7.25.8) + '@babel/traverse': 7.25.7 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-computed-properties@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/template': 7.25.7 + + '@babel/plugin-transform-destructuring@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-transform-dotall-regex@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-create-regexp-features-plugin': 7.25.7(@babel/core@7.25.8) + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-transform-duplicate-keys@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-create-regexp-features-plugin': 7.25.7(@babel/core@7.25.8) + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-transform-dynamic-import@7.25.8(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-transform-exponentiation-operator@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-builder-binary-assignment-operator-visitor': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-export-namespace-from@7.25.8(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-transform-for-of@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/helper-skip-transparent-expression-wrappers': 7.25.7 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-function-name@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-compilation-targets': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/traverse': 7.25.7 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-json-strings@7.25.8(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-transform-literals@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-transform-logical-assignment-operators@7.25.8(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-transform-member-expression-literals@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-transform-modules-amd@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-module-transforms': 7.25.7(@babel/core@7.25.8) + '@babel/helper-plugin-utils': 7.25.7 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-commonjs@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-module-transforms': 7.25.7(@babel/core@7.25.8) + '@babel/helper-plugin-utils': 7.25.7 + '@babel/helper-simple-access': 7.25.7 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-systemjs@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-module-transforms': 7.25.7(@babel/core@7.25.8) + '@babel/helper-plugin-utils': 7.25.7 + '@babel/helper-validator-identifier': 7.25.7 + '@babel/traverse': 7.25.7 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-umd@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-module-transforms': 7.25.7(@babel/core@7.25.8) + '@babel/helper-plugin-utils': 7.25.7 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-named-capturing-groups-regex@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-create-regexp-features-plugin': 7.25.7(@babel/core@7.25.8) + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-transform-new-target@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-transform-nullish-coalescing-operator@7.25.8(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-transform-numeric-separator@7.25.8(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-transform-object-rest-spread@7.25.8(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-compilation-targets': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/plugin-transform-parameters': 7.25.7(@babel/core@7.25.8) + + '@babel/plugin-transform-object-super@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/helper-replace-supers': 7.25.7(@babel/core@7.25.8) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-optional-catch-binding@7.25.8(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-transform-optional-chaining@7.25.8(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/helper-skip-transparent-expression-wrappers': 7.25.7 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-parameters@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-transform-private-methods@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-create-class-features-plugin': 7.25.7(@babel/core@7.25.8) + '@babel/helper-plugin-utils': 7.25.7 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-private-property-in-object@7.25.8(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-annotate-as-pure': 7.25.7 + '@babel/helper-create-class-features-plugin': 7.25.7(@babel/core@7.25.8) + '@babel/helper-plugin-utils': 7.25.7 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-property-literals@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-transform-react-display-name@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-transform-react-jsx-development@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/plugin-transform-react-jsx': 7.25.7(@babel/core@7.25.8) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-react-jsx@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-annotate-as-pure': 7.25.7 + '@babel/helper-module-imports': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/plugin-syntax-jsx': 7.25.7(@babel/core@7.25.8) + '@babel/types': 7.25.8 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-react-pure-annotations@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-annotate-as-pure': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-transform-regenerator@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + regenerator-transform: 0.15.2 + + '@babel/plugin-transform-reserved-words@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-transform-runtime@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-module-imports': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + babel-plugin-polyfill-corejs2: 0.4.11(@babel/core@7.25.8) + babel-plugin-polyfill-corejs3: 0.10.6(@babel/core@7.25.8) + babel-plugin-polyfill-regenerator: 0.6.2(@babel/core@7.25.8) + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-shorthand-properties@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-transform-spread@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/helper-skip-transparent-expression-wrappers': 7.25.7 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-sticky-regex@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-transform-template-literals@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-transform-typeof-symbol@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-transform-typescript@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-annotate-as-pure': 7.25.7 + '@babel/helper-create-class-features-plugin': 7.25.7(@babel/core@7.25.8) + '@babel/helper-plugin-utils': 7.25.7 + '@babel/helper-skip-transparent-expression-wrappers': 7.25.7 + '@babel/plugin-syntax-typescript': 7.25.7(@babel/core@7.25.8) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-unicode-escapes@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-transform-unicode-property-regex@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-create-regexp-features-plugin': 7.25.7(@babel/core@7.25.8) + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-transform-unicode-regex@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-create-regexp-features-plugin': 7.25.7(@babel/core@7.25.8) + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/plugin-transform-unicode-sets-regex@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-create-regexp-features-plugin': 7.25.7(@babel/core@7.25.8) + '@babel/helper-plugin-utils': 7.25.7 + + '@babel/preset-env@7.25.8(@babel/core@7.25.8)': + dependencies: + '@babel/compat-data': 7.25.8 + '@babel/core': 7.25.8 + '@babel/helper-compilation-targets': 7.25.7 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/helper-validator-option': 7.25.7 + '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.25.8) + '@babel/plugin-syntax-import-assertions': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-syntax-import-attributes': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.25.8) + '@babel/plugin-transform-arrow-functions': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-async-generator-functions': 7.25.8(@babel/core@7.25.8) + '@babel/plugin-transform-async-to-generator': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-block-scoped-functions': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-block-scoping': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-class-properties': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-class-static-block': 7.25.8(@babel/core@7.25.8) + '@babel/plugin-transform-classes': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-computed-properties': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-destructuring': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-dotall-regex': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-duplicate-keys': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-dynamic-import': 7.25.8(@babel/core@7.25.8) + '@babel/plugin-transform-exponentiation-operator': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-export-namespace-from': 7.25.8(@babel/core@7.25.8) + '@babel/plugin-transform-for-of': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-function-name': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-json-strings': 7.25.8(@babel/core@7.25.8) + '@babel/plugin-transform-literals': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-logical-assignment-operators': 7.25.8(@babel/core@7.25.8) + '@babel/plugin-transform-member-expression-literals': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-modules-amd': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-modules-commonjs': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-modules-systemjs': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-modules-umd': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-named-capturing-groups-regex': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-new-target': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-nullish-coalescing-operator': 7.25.8(@babel/core@7.25.8) + '@babel/plugin-transform-numeric-separator': 7.25.8(@babel/core@7.25.8) + '@babel/plugin-transform-object-rest-spread': 7.25.8(@babel/core@7.25.8) + '@babel/plugin-transform-object-super': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-optional-catch-binding': 7.25.8(@babel/core@7.25.8) + '@babel/plugin-transform-optional-chaining': 7.25.8(@babel/core@7.25.8) + '@babel/plugin-transform-parameters': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-private-methods': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-private-property-in-object': 7.25.8(@babel/core@7.25.8) + '@babel/plugin-transform-property-literals': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-regenerator': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-reserved-words': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-shorthand-properties': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-spread': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-sticky-regex': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-template-literals': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-typeof-symbol': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-unicode-escapes': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-unicode-property-regex': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-unicode-regex': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-unicode-sets-regex': 7.25.7(@babel/core@7.25.8) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.25.8) + babel-plugin-polyfill-corejs2: 0.4.11(@babel/core@7.25.8) + babel-plugin-polyfill-corejs3: 0.10.6(@babel/core@7.25.8) + babel-plugin-polyfill-regenerator: 0.6.2(@babel/core@7.25.8) + core-js-compat: 3.38.1 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/types': 7.25.8 + esutils: 2.0.3 + + '@babel/preset-react@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/helper-validator-option': 7.25.7 + '@babel/plugin-transform-react-display-name': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-react-jsx': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-react-jsx-development': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-react-pure-annotations': 7.25.7(@babel/core@7.25.8) + transitivePeerDependencies: + - supports-color + + '@babel/preset-typescript@7.25.7(@babel/core@7.25.8)': + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-plugin-utils': 7.25.7 + '@babel/helper-validator-option': 7.25.7 + '@babel/plugin-syntax-jsx': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-modules-commonjs': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-typescript': 7.25.7(@babel/core@7.25.8) + transitivePeerDependencies: + - supports-color + + '@babel/runtime@7.25.7': + dependencies: + regenerator-runtime: 0.14.1 + + '@babel/template@7.25.7': + dependencies: + '@babel/code-frame': 7.25.7 + '@babel/parser': 7.25.8 + '@babel/types': 7.25.8 + + '@babel/traverse@7.25.7': + dependencies: + '@babel/code-frame': 7.25.7 + '@babel/generator': 7.25.7 + '@babel/parser': 7.25.8 + '@babel/template': 7.25.7 + '@babel/types': 7.25.8 + debug: 4.3.7 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.25.8': + dependencies: + '@babel/helper-string-parser': 7.25.7 + '@babel/helper-validator-identifier': 7.25.7 + to-fast-properties: 2.0.0 + + '@base2/pretty-print-object@1.0.1': {} + + '@bcoe/v8-coverage@0.2.3': {} + + '@braintree/sanitize-url@6.0.4': {} + + '@chromatic-com/storybook@1.9.0(react@18.2.0)': + dependencies: + chromatic: 11.12.6 + filesize: 10.1.6 + jsonfile: 6.1.0 + react-confetti: 6.1.0(react@18.2.0) + strip-ansi: 7.1.0 + transitivePeerDependencies: + - '@chromatic-com/cypress' + - '@chromatic-com/playwright' + - react + + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + + '@dagrejs/dagre@1.1.4': + dependencies: + '@dagrejs/graphlib': 2.2.4 + + '@dagrejs/graphlib@2.2.4': {} + + '@emnapi/runtime@1.3.1': + dependencies: + tslib: 2.8.0 + optional: true + + '@emoji-mart/data@1.2.1': {} + + '@esbuild/aix-ppc64@0.23.1': + optional: true + + '@esbuild/android-arm64@0.23.1': + optional: true + + '@esbuild/android-arm@0.23.1': + optional: true + + '@esbuild/android-x64@0.23.1': + optional: true + + '@esbuild/darwin-arm64@0.23.1': + optional: true + + '@esbuild/darwin-x64@0.23.1': + optional: true + + '@esbuild/freebsd-arm64@0.23.1': + optional: true + + '@esbuild/freebsd-x64@0.23.1': + optional: true + + '@esbuild/linux-arm64@0.23.1': + optional: true + + '@esbuild/linux-arm@0.23.1': + optional: true + + '@esbuild/linux-ia32@0.23.1': + optional: true + + '@esbuild/linux-loong64@0.23.1': + optional: true + + '@esbuild/linux-mips64el@0.23.1': + optional: true + + '@esbuild/linux-ppc64@0.23.1': + optional: true + + '@esbuild/linux-riscv64@0.23.1': + optional: true + + '@esbuild/linux-s390x@0.23.1': + optional: true + + '@esbuild/linux-x64@0.23.1': + optional: true + + '@esbuild/netbsd-x64@0.23.1': + optional: true + + '@esbuild/openbsd-arm64@0.23.1': + optional: true + + '@esbuild/openbsd-x64@0.23.1': + optional: true + + '@esbuild/sunos-x64@0.23.1': + optional: true + + '@esbuild/win32-arm64@0.23.1': + optional: true + + '@esbuild/win32-ia32@0.23.1': + optional: true + + '@esbuild/win32-x64@0.23.1': + optional: true + + '@eslint-community/eslint-utils@4.4.0(eslint@8.57.1)': + dependencies: + eslint: 8.57.1 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.11.1': {} + + '@eslint/eslintrc@2.1.4': + dependencies: + ajv: 6.12.6 + debug: 4.3.7 + espree: 9.6.1 + globals: 13.24.0 + ignore: 5.3.2 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@8.57.1': {} + + '@faker-js/faker@7.6.0': {} + + '@floating-ui/core@1.6.8': + dependencies: + '@floating-ui/utils': 0.2.8 + + '@floating-ui/dom@1.1.1': + dependencies: + '@floating-ui/core': 1.6.8 + + '@floating-ui/dom@1.6.11': + dependencies: + '@floating-ui/core': 1.6.8 + '@floating-ui/utils': 0.2.8 + + '@floating-ui/react-dom@2.1.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + dependencies: + '@floating-ui/dom': 1.6.11 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + + '@floating-ui/react@0.25.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + dependencies: + '@floating-ui/react-dom': 2.1.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@floating-ui/utils': 0.1.6 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + tabbable: 6.2.0 + + '@floating-ui/utils@0.1.6': {} + + '@floating-ui/utils@0.2.8': {} + + '@formatjs/intl-localematcher@0.5.5': + dependencies: + tslib: 2.8.0 + + '@headlessui/react@1.7.19(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + dependencies: + '@tanstack/react-virtual': 3.10.8(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + client-only: 0.0.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + + '@heroicons/react@2.1.5(react@18.2.0)': + dependencies: + react: 18.2.0 + + '@hookform/resolvers@3.9.0(react-hook-form@7.53.1(react@18.2.0))': + dependencies: + react-hook-form: 7.53.1(react@18.2.0) + + '@humanwhocodes/config-array@0.13.0': + dependencies: + '@humanwhocodes/object-schema': 2.0.3 + debug: 4.3.7 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/object-schema@2.0.3': {} + + '@img/sharp-darwin-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.0.4 + optional: true + + '@img/sharp-darwin-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.0.4 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-darwin-x64@1.0.4': + optional: true + + '@img/sharp-libvips-linux-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-linux-arm@1.0.5': + optional: true + + '@img/sharp-libvips-linux-s390x@1.0.4': + optional: true + + '@img/sharp-libvips-linux-x64@1.0.4': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.0.4': + optional: true + + '@img/sharp-linux-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.0.4 + optional: true + + '@img/sharp-linux-arm@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.0.5 + optional: true + + '@img/sharp-linux-s390x@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.0.4 + optional: true + + '@img/sharp-linux-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.0.4 + optional: true + + '@img/sharp-linuxmusl-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + optional: true + + '@img/sharp-linuxmusl-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + optional: true + + '@img/sharp-wasm32@0.33.5': + dependencies: + '@emnapi/runtime': 1.3.1 + optional: true + + '@img/sharp-win32-ia32@0.33.5': + optional: true + + '@img/sharp-win32-x64@0.33.5': + optional: true + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 4.2.3 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@istanbuljs/load-nyc-config@1.1.0': + dependencies: + camelcase: 5.3.1 + find-up: 4.1.0 + get-package-type: 0.1.0 + js-yaml: 3.14.1 + resolve-from: 5.0.0 + + '@istanbuljs/schema@0.1.3': {} + + '@jest/console@29.7.0': + dependencies: + '@jest/types': 29.6.3 + '@types/node': 18.15.0 + chalk: 4.1.2 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + slash: 3.0.0 + + '@jest/core@29.7.0(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5))': + dependencies: + '@jest/console': 29.7.0 + '@jest/reporters': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 18.15.0 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + ci-info: 3.9.0 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-changed-files: 29.7.0 + jest-config: 29.7.0(@types/node@18.15.0)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)) + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-resolve-dependencies: 29.7.0 + jest-runner: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + jest-watcher: 29.7.0 + micromatch: 4.0.8 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-ansi: 6.0.1 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + - ts-node + + '@jest/environment@29.7.0': + dependencies: + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 18.15.0 + jest-mock: 29.7.0 + + '@jest/expect-utils@29.7.0': + dependencies: + jest-get-type: 29.6.3 + + '@jest/expect@29.7.0': + dependencies: + expect: 29.7.0 + jest-snapshot: 29.7.0 + transitivePeerDependencies: + - supports-color + + '@jest/fake-timers@29.7.0': + dependencies: + '@jest/types': 29.6.3 + '@sinonjs/fake-timers': 10.3.0 + '@types/node': 18.15.0 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-util: 29.7.0 + + '@jest/globals@29.7.0': + dependencies: + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/types': 29.6.3 + jest-mock: 29.7.0 + transitivePeerDependencies: + - supports-color + + '@jest/reporters@29.7.0': + dependencies: + '@bcoe/v8-coverage': 0.2.3 + '@jest/console': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.25 + '@types/node': 18.15.0 + chalk: 4.1.2 + collect-v8-coverage: 1.0.2 + exit: 0.1.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-instrument: 6.0.3 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.1.7 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + jest-worker: 29.7.0 + slash: 3.0.0 + string-length: 4.0.2 + strip-ansi: 6.0.1 + v8-to-istanbul: 9.3.0 + transitivePeerDependencies: + - supports-color + + '@jest/schemas@29.6.3': + dependencies: + '@sinclair/typebox': 0.27.8 + + '@jest/source-map@29.6.3': + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + callsites: 3.1.0 + graceful-fs: 4.2.11 + + '@jest/test-result@29.7.0': + dependencies: + '@jest/console': 29.7.0 + '@jest/types': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + collect-v8-coverage: 1.0.2 + + '@jest/test-sequencer@29.7.0': + dependencies: + '@jest/test-result': 29.7.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + slash: 3.0.0 + + '@jest/transform@29.7.0': + dependencies: + '@babel/core': 7.25.8 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.25 + babel-plugin-istanbul: 6.1.1 + chalk: 4.1.2 + convert-source-map: 2.0.0 + fast-json-stable-stringify: 2.1.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + micromatch: 4.0.8 + pirates: 4.0.6 + slash: 3.0.0 + write-file-atomic: 4.0.2 + transitivePeerDependencies: + - supports-color + + '@jest/types@29.6.3': + dependencies: + '@jest/schemas': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 18.15.0 + '@types/yargs': 17.0.33 + chalk: 4.1.2 + + '@jridgewell/gen-mapping@0.3.5': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/source-map@0.3.6': + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@jridgewell/trace-mapping@0.3.9': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@lexical/clipboard@0.16.1': + dependencies: + '@lexical/html': 0.16.1 + '@lexical/list': 0.16.1 + '@lexical/selection': 0.16.1 + '@lexical/utils': 0.16.1 + lexical: 0.16.1 + + '@lexical/code@0.16.1': + dependencies: + '@lexical/utils': 0.16.1 + lexical: 0.16.1 + prismjs: 1.29.0 + + '@lexical/devtools-core@0.16.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + dependencies: + '@lexical/html': 0.16.1 + '@lexical/link': 0.16.1 + '@lexical/mark': 0.16.1 + '@lexical/table': 0.16.1 + '@lexical/utils': 0.16.1 + lexical: 0.16.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + + '@lexical/dragon@0.16.1': + dependencies: + lexical: 0.16.1 + + '@lexical/hashtag@0.16.1': + dependencies: + '@lexical/utils': 0.16.1 + lexical: 0.16.1 + + '@lexical/history@0.16.1': + dependencies: + '@lexical/utils': 0.16.1 + lexical: 0.16.1 + + '@lexical/html@0.16.1': + dependencies: + '@lexical/selection': 0.16.1 + '@lexical/utils': 0.16.1 + lexical: 0.16.1 + + '@lexical/link@0.16.1': + dependencies: + '@lexical/utils': 0.16.1 + lexical: 0.16.1 + + '@lexical/list@0.16.1': + dependencies: + '@lexical/utils': 0.16.1 + lexical: 0.16.1 + + '@lexical/mark@0.16.1': + dependencies: + '@lexical/utils': 0.16.1 + lexical: 0.16.1 + + '@lexical/markdown@0.16.1': + dependencies: + '@lexical/code': 0.16.1 + '@lexical/link': 0.16.1 + '@lexical/list': 0.16.1 + '@lexical/rich-text': 0.16.1 + '@lexical/text': 0.16.1 + '@lexical/utils': 0.16.1 + lexical: 0.16.1 + + '@lexical/offset@0.16.1': + dependencies: + lexical: 0.16.1 + + '@lexical/overflow@0.16.1': + dependencies: + lexical: 0.16.1 + + '@lexical/plain-text@0.16.1': + dependencies: + '@lexical/clipboard': 0.16.1 + '@lexical/selection': 0.16.1 + '@lexical/utils': 0.16.1 + lexical: 0.16.1 + + '@lexical/react@0.16.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(yjs@13.6.20)': + dependencies: + '@lexical/clipboard': 0.16.1 + '@lexical/code': 0.16.1 + '@lexical/devtools-core': 0.16.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@lexical/dragon': 0.16.1 + '@lexical/hashtag': 0.16.1 + '@lexical/history': 0.16.1 + '@lexical/link': 0.16.1 + '@lexical/list': 0.16.1 + '@lexical/mark': 0.16.1 + '@lexical/markdown': 0.16.1 + '@lexical/overflow': 0.16.1 + '@lexical/plain-text': 0.16.1 + '@lexical/rich-text': 0.16.1 + '@lexical/selection': 0.16.1 + '@lexical/table': 0.16.1 + '@lexical/text': 0.16.1 + '@lexical/utils': 0.16.1 + '@lexical/yjs': 0.16.1(yjs@13.6.20) + lexical: 0.16.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-error-boundary: 3.1.4(react@18.2.0) + transitivePeerDependencies: + - yjs + + '@lexical/rich-text@0.16.1': + dependencies: + '@lexical/clipboard': 0.16.1 + '@lexical/selection': 0.16.1 + '@lexical/utils': 0.16.1 + lexical: 0.16.1 + + '@lexical/selection@0.16.1': + dependencies: + lexical: 0.16.1 + + '@lexical/table@0.16.1': + dependencies: + '@lexical/utils': 0.16.1 + lexical: 0.16.1 + + '@lexical/text@0.16.1': + dependencies: + lexical: 0.16.1 + + '@lexical/utils@0.16.1': + dependencies: + '@lexical/list': 0.16.1 + '@lexical/selection': 0.16.1 + '@lexical/table': 0.16.1 + lexical: 0.16.1 + + '@lexical/yjs@0.16.1(yjs@13.6.20)': + dependencies: + '@lexical/offset': 0.16.1 + lexical: 0.16.1 + yjs: 13.6.20 + + '@mdx-js/loader@2.3.0(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3))': + dependencies: + '@mdx-js/mdx': 2.3.0 + source-map: 0.7.4 + webpack: 5.95.0(esbuild@0.23.1)(uglify-js@3.19.3) + transitivePeerDependencies: + - supports-color + + '@mdx-js/mdx@2.3.0': + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/mdx': 2.0.13 + estree-util-build-jsx: 2.2.2 + estree-util-is-identifier-name: 2.1.0 + estree-util-to-js: 1.2.0 + estree-walker: 3.0.3 + hast-util-to-estree: 2.3.3 + markdown-extensions: 1.1.1 + periscopic: 3.1.0 + remark-mdx: 2.3.0 + remark-parse: 10.0.2 + remark-rehype: 10.1.0 + unified: 10.1.2 + unist-util-position-from-estree: 1.1.2 + unist-util-stringify-position: 3.0.3 + unist-util-visit: 4.1.2 + vfile: 5.3.7 + transitivePeerDependencies: + - supports-color + + '@mdx-js/react@2.3.0(react@18.2.0)': + dependencies: + '@types/mdx': 2.0.13 + '@types/react': 18.2.79 + react: 18.2.0 + + '@mdx-js/react@3.1.0(@types/react@18.2.79)(react@18.2.0)': + dependencies: + '@types/mdx': 2.0.13 + '@types/react': 18.2.79 + react: 18.2.0 + + '@monaco-editor/loader@1.4.0(monaco-editor@0.52.0)': + dependencies: + monaco-editor: 0.52.0 + state-local: 1.0.7 + + '@monaco-editor/react@4.6.0(monaco-editor@0.52.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + dependencies: + '@monaco-editor/loader': 1.4.0(monaco-editor@0.52.0) + monaco-editor: 0.52.0 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + + '@next/env@14.2.15': {} + + '@next/eslint-plugin-next@14.2.15': + dependencies: + glob: 10.3.10 + + '@next/mdx@14.2.15(@mdx-js/loader@2.3.0(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3)))(@mdx-js/react@2.3.0(react@18.2.0))': + dependencies: + source-map: 0.7.4 + optionalDependencies: + '@mdx-js/loader': 2.3.0(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3)) + '@mdx-js/react': 2.3.0(react@18.2.0) + + '@next/swc-darwin-arm64@14.2.15': + optional: true + + '@next/swc-darwin-x64@14.2.15': + optional: true + + '@next/swc-linux-arm64-gnu@14.2.15': + optional: true + + '@next/swc-linux-arm64-musl@14.2.15': + optional: true + + '@next/swc-linux-x64-gnu@14.2.15': + optional: true + + '@next/swc-linux-x64-musl@14.2.15': + optional: true + + '@next/swc-win32-arm64-msvc@14.2.15': + optional: true + + '@next/swc-win32-ia32-msvc@14.2.15': + optional: true + + '@next/swc-win32-x64-msvc@14.2.15': + optional: true + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.17.1 + + '@nolyfill/is-core-module@1.0.39': {} + + '@parcel/watcher-android-arm64@2.4.1': + optional: true + + '@parcel/watcher-darwin-arm64@2.4.1': + optional: true + + '@parcel/watcher-darwin-x64@2.4.1': + optional: true + + '@parcel/watcher-freebsd-x64@2.4.1': + optional: true + + '@parcel/watcher-linux-arm-glibc@2.4.1': + optional: true + + '@parcel/watcher-linux-arm64-glibc@2.4.1': + optional: true + + '@parcel/watcher-linux-arm64-musl@2.4.1': + optional: true + + '@parcel/watcher-linux-x64-glibc@2.4.1': + optional: true + + '@parcel/watcher-linux-x64-musl@2.4.1': + optional: true + + '@parcel/watcher-win32-arm64@2.4.1': + optional: true + + '@parcel/watcher-win32-ia32@2.4.1': + optional: true + + '@parcel/watcher-win32-x64@2.4.1': + optional: true + + '@parcel/watcher@2.4.1': + dependencies: + detect-libc: 1.0.3 + is-glob: 4.0.3 + micromatch: 4.0.8 + node-addon-api: 7.1.1 + optionalDependencies: + '@parcel/watcher-android-arm64': 2.4.1 + '@parcel/watcher-darwin-arm64': 2.4.1 + '@parcel/watcher-darwin-x64': 2.4.1 + '@parcel/watcher-freebsd-x64': 2.4.1 + '@parcel/watcher-linux-arm-glibc': 2.4.1 + '@parcel/watcher-linux-arm64-glibc': 2.4.1 + '@parcel/watcher-linux-arm64-musl': 2.4.1 + '@parcel/watcher-linux-x64-glibc': 2.4.1 + '@parcel/watcher-linux-x64-musl': 2.4.1 + '@parcel/watcher-win32-arm64': 2.4.1 + '@parcel/watcher-win32-ia32': 2.4.1 + '@parcel/watcher-win32-x64': 2.4.1 + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@pmmmwh/react-refresh-webpack-plugin@0.5.15(react-refresh@0.14.2)(type-fest@2.19.0)(webpack-hot-middleware@2.26.1)(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3))': + dependencies: + ansi-html: 0.0.9 + core-js-pure: 3.38.1 + error-stack-parser: 2.1.4 + html-entities: 2.5.2 + loader-utils: 2.0.4 + react-refresh: 0.14.2 + schema-utils: 4.2.0 + source-map: 0.7.4 + webpack: 5.95.0(esbuild@0.23.1)(uglify-js@3.19.3) + optionalDependencies: + type-fest: 2.19.0 + webpack-hot-middleware: 2.26.1 + + '@reactflow/background@11.3.14(@types/react@18.2.79)(immer@9.0.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + dependencies: + '@reactflow/core': 11.11.4(@types/react@18.2.79)(immer@9.0.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + classcat: 5.0.5 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + zustand: 4.5.5(@types/react@18.2.79)(immer@9.0.21)(react@18.2.0) + transitivePeerDependencies: + - '@types/react' + - immer + + '@reactflow/controls@11.2.14(@types/react@18.2.79)(immer@9.0.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + dependencies: + '@reactflow/core': 11.11.4(@types/react@18.2.79)(immer@9.0.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + classcat: 5.0.5 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + zustand: 4.5.5(@types/react@18.2.79)(immer@9.0.21)(react@18.2.0) + transitivePeerDependencies: + - '@types/react' + - immer + + '@reactflow/core@11.11.4(@types/react@18.2.79)(immer@9.0.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + dependencies: + '@types/d3': 7.4.3 + '@types/d3-drag': 3.0.7 + '@types/d3-selection': 3.0.11 + '@types/d3-zoom': 3.0.8 + classcat: 5.0.5 + d3-drag: 3.0.0 + d3-selection: 3.0.0 + d3-zoom: 3.0.0 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + zustand: 4.5.5(@types/react@18.2.79)(immer@9.0.21)(react@18.2.0) + transitivePeerDependencies: + - '@types/react' + - immer + + '@reactflow/minimap@11.7.14(@types/react@18.2.79)(immer@9.0.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + dependencies: + '@reactflow/core': 11.11.4(@types/react@18.2.79)(immer@9.0.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@types/d3-selection': 3.0.11 + '@types/d3-zoom': 3.0.8 + classcat: 5.0.5 + d3-selection: 3.0.0 + d3-zoom: 3.0.0 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + zustand: 4.5.5(@types/react@18.2.79)(immer@9.0.21)(react@18.2.0) + transitivePeerDependencies: + - '@types/react' + - immer + + '@reactflow/node-resizer@2.2.14(@types/react@18.2.79)(immer@9.0.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + dependencies: + '@reactflow/core': 11.11.4(@types/react@18.2.79)(immer@9.0.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + classcat: 5.0.5 + d3-drag: 3.0.0 + d3-selection: 3.0.0 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + zustand: 4.5.5(@types/react@18.2.79)(immer@9.0.21)(react@18.2.0) + transitivePeerDependencies: + - '@types/react' + - immer + + '@reactflow/node-toolbar@1.3.14(@types/react@18.2.79)(immer@9.0.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + dependencies: + '@reactflow/core': 11.11.4(@types/react@18.2.79)(immer@9.0.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + classcat: 5.0.5 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + zustand: 4.5.5(@types/react@18.2.79)(immer@9.0.21)(react@18.2.0) + transitivePeerDependencies: + - '@types/react' + - immer + + '@remixicon/react@4.3.0(react@18.2.0)': + dependencies: + react: 18.2.0 + + '@rgrove/parse-xml@4.1.0': {} + + '@rtsao/scc@1.1.0': {} + + '@rushstack/eslint-patch@1.10.4': {} + + '@sentry-internal/feedback@7.119.2': + dependencies: + '@sentry/core': 7.119.2 + '@sentry/types': 7.119.2 + '@sentry/utils': 7.119.2 + + '@sentry-internal/replay-canvas@7.119.2': + dependencies: + '@sentry/core': 7.119.2 + '@sentry/replay': 7.119.2 + '@sentry/types': 7.119.2 + '@sentry/utils': 7.119.2 + + '@sentry-internal/tracing@7.119.2': + dependencies: + '@sentry/core': 7.119.2 + '@sentry/types': 7.119.2 + '@sentry/utils': 7.119.2 + + '@sentry/browser@7.119.2': + dependencies: + '@sentry-internal/feedback': 7.119.2 + '@sentry-internal/replay-canvas': 7.119.2 + '@sentry-internal/tracing': 7.119.2 + '@sentry/core': 7.119.2 + '@sentry/integrations': 7.119.2 + '@sentry/replay': 7.119.2 + '@sentry/types': 7.119.2 + '@sentry/utils': 7.119.2 + + '@sentry/core@7.119.2': + dependencies: + '@sentry/types': 7.119.2 + '@sentry/utils': 7.119.2 + + '@sentry/integrations@7.119.2': + dependencies: + '@sentry/core': 7.119.2 + '@sentry/types': 7.119.2 + '@sentry/utils': 7.119.2 + localforage: 1.10.0 + + '@sentry/react@7.119.2(react@18.2.0)': + dependencies: + '@sentry/browser': 7.119.2 + '@sentry/core': 7.119.2 + '@sentry/types': 7.119.2 + '@sentry/utils': 7.119.2 + hoist-non-react-statics: 3.3.2 + react: 18.2.0 + + '@sentry/replay@7.119.2': + dependencies: + '@sentry-internal/tracing': 7.119.2 + '@sentry/core': 7.119.2 + '@sentry/types': 7.119.2 + '@sentry/utils': 7.119.2 + + '@sentry/types@7.119.2': {} + + '@sentry/utils@7.119.2': + dependencies: + '@sentry/types': 7.119.2 + + '@sinclair/typebox@0.27.8': {} + + '@sindresorhus/is@4.6.0': {} + + '@sinonjs/commons@3.0.1': + dependencies: + type-detect: 4.0.8 + + '@sinonjs/fake-timers@10.3.0': + dependencies: + '@sinonjs/commons': 3.0.1 + + '@storybook/addon-actions@8.3.6(storybook@8.3.6)': + dependencies: + '@storybook/global': 5.0.0 + '@types/uuid': 9.0.8 + dequal: 2.0.3 + polished: 4.3.1 + storybook: 8.3.6 + uuid: 9.0.1 + + '@storybook/addon-backgrounds@8.3.6(storybook@8.3.6)': + dependencies: + '@storybook/global': 5.0.0 + memoizerific: 1.11.3 + storybook: 8.3.6 + ts-dedent: 2.2.0 + + '@storybook/addon-controls@8.3.6(storybook@8.3.6)': + dependencies: + '@storybook/global': 5.0.0 + dequal: 2.0.3 + lodash: 4.17.21 + storybook: 8.3.6 + ts-dedent: 2.2.0 + + '@storybook/addon-docs@8.3.6(storybook@8.3.6)(webpack-sources@3.2.3)': + dependencies: + '@mdx-js/react': 3.1.0(@types/react@18.2.79)(react@18.2.0) + '@storybook/blocks': 8.3.6(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(storybook@8.3.6) + '@storybook/csf-plugin': 8.3.6(storybook@8.3.6)(webpack-sources@3.2.3) + '@storybook/global': 5.0.0 + '@storybook/react-dom-shim': 8.3.6(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(storybook@8.3.6) + '@types/react': 18.2.79 + fs-extra: 11.2.0 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + rehype-external-links: 3.0.0 + rehype-slug: 6.0.0 + storybook: 8.3.6 + ts-dedent: 2.2.0 + transitivePeerDependencies: + - webpack-sources + + '@storybook/addon-essentials@8.3.6(storybook@8.3.6)(webpack-sources@3.2.3)': + dependencies: + '@storybook/addon-actions': 8.3.6(storybook@8.3.6) + '@storybook/addon-backgrounds': 8.3.6(storybook@8.3.6) + '@storybook/addon-controls': 8.3.6(storybook@8.3.6) + '@storybook/addon-docs': 8.3.6(storybook@8.3.6)(webpack-sources@3.2.3) + '@storybook/addon-highlight': 8.3.6(storybook@8.3.6) + '@storybook/addon-measure': 8.3.6(storybook@8.3.6) + '@storybook/addon-outline': 8.3.6(storybook@8.3.6) + '@storybook/addon-toolbars': 8.3.6(storybook@8.3.6) + '@storybook/addon-viewport': 8.3.6(storybook@8.3.6) + storybook: 8.3.6 + ts-dedent: 2.2.0 + transitivePeerDependencies: + - webpack-sources + + '@storybook/addon-highlight@8.3.6(storybook@8.3.6)': + dependencies: + '@storybook/global': 5.0.0 + storybook: 8.3.6 + + '@storybook/addon-interactions@8.3.6(storybook@8.3.6)': + dependencies: + '@storybook/global': 5.0.0 + '@storybook/instrumenter': 8.3.6(storybook@8.3.6) + '@storybook/test': 8.3.6(storybook@8.3.6) + polished: 4.3.1 + storybook: 8.3.6 + ts-dedent: 2.2.0 + + '@storybook/addon-links@8.3.6(react@18.2.0)(storybook@8.3.6)': + dependencies: + '@storybook/csf': 0.1.11 + '@storybook/global': 5.0.0 + storybook: 8.3.6 + ts-dedent: 2.2.0 + optionalDependencies: + react: 18.2.0 + + '@storybook/addon-measure@8.3.6(storybook@8.3.6)': + dependencies: + '@storybook/global': 5.0.0 + storybook: 8.3.6 + tiny-invariant: 1.3.3 + + '@storybook/addon-onboarding@8.3.6(react@18.2.0)(storybook@8.3.6)': + dependencies: + react-confetti: 6.1.0(react@18.2.0) + storybook: 8.3.6 + transitivePeerDependencies: + - react + + '@storybook/addon-outline@8.3.6(storybook@8.3.6)': + dependencies: + '@storybook/global': 5.0.0 + storybook: 8.3.6 + ts-dedent: 2.2.0 + + '@storybook/addon-themes@8.3.6(storybook@8.3.6)': + dependencies: + storybook: 8.3.6 + ts-dedent: 2.2.0 + + '@storybook/addon-toolbars@8.3.6(storybook@8.3.6)': + dependencies: + storybook: 8.3.6 + + '@storybook/addon-viewport@8.3.6(storybook@8.3.6)': + dependencies: + memoizerific: 1.11.3 + storybook: 8.3.6 + + '@storybook/blocks@8.3.6(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(storybook@8.3.6)': + dependencies: + '@storybook/csf': 0.1.11 + '@storybook/global': 5.0.0 + '@storybook/icons': 1.2.12(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@types/lodash': 4.17.12 + color-convert: 2.0.1 + dequal: 2.0.3 + lodash: 4.17.21 + markdown-to-jsx: 7.5.0(react@18.2.0) + memoizerific: 1.11.3 + polished: 4.3.1 + react-colorful: 5.6.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + storybook: 8.3.6 + telejson: 7.2.0 + ts-dedent: 2.2.0 + util-deprecate: 1.0.2 + optionalDependencies: + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + + '@storybook/builder-webpack5@8.3.6(esbuild@0.23.1)(storybook@8.3.6)(typescript@4.9.5)(uglify-js@3.19.3)': + dependencies: + '@storybook/core-webpack': 8.3.6(storybook@8.3.6) + '@types/node': 22.7.7 + '@types/semver': 7.5.8 + browser-assert: 1.2.1 + case-sensitive-paths-webpack-plugin: 2.4.0 + cjs-module-lexer: 1.4.1 + constants-browserify: 1.0.0 + css-loader: 6.11.0(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3)) + es-module-lexer: 1.5.4 + express: 4.21.1 + fork-ts-checker-webpack-plugin: 8.0.0(typescript@4.9.5)(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3)) + fs-extra: 11.2.0 + html-webpack-plugin: 5.6.2(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3)) + magic-string: 0.30.12 + path-browserify: 1.0.1 + process: 0.11.10 + semver: 7.6.3 + storybook: 8.3.6 + style-loader: 3.3.4(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3)) + terser-webpack-plugin: 5.3.10(esbuild@0.23.1)(uglify-js@3.19.3)(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3)) + ts-dedent: 2.2.0 + url: 0.11.4 + util: 0.12.5 + util-deprecate: 1.0.2 + webpack: 5.95.0(esbuild@0.23.1)(uglify-js@3.19.3) + webpack-dev-middleware: 6.1.3(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3)) + webpack-hot-middleware: 2.26.1 + webpack-virtual-modules: 0.6.2 + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - '@rspack/core' + - '@swc/core' + - esbuild + - supports-color + - uglify-js + - webpack-cli + + '@storybook/components@8.3.6(storybook@8.3.6)': + dependencies: + storybook: 8.3.6 + + '@storybook/core-webpack@8.3.6(storybook@8.3.6)': + dependencies: + '@types/node': 22.7.7 + storybook: 8.3.6 + ts-dedent: 2.2.0 + + '@storybook/core@8.3.6': + dependencies: + '@storybook/csf': 0.1.11 + '@types/express': 4.17.21 + better-opn: 3.0.2 + browser-assert: 1.2.1 + esbuild: 0.23.1 + esbuild-register: 3.6.0(esbuild@0.23.1) + express: 4.21.1 + jsdoc-type-pratt-parser: 4.1.0 + process: 0.11.10 + recast: 0.23.9 + semver: 7.6.3 + util: 0.12.5 + ws: 8.18.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@storybook/csf-plugin@8.3.6(storybook@8.3.6)(webpack-sources@3.2.3)': + dependencies: + storybook: 8.3.6 + unplugin: 1.14.1(webpack-sources@3.2.3) + transitivePeerDependencies: + - webpack-sources + + '@storybook/csf@0.0.1': + dependencies: + lodash: 4.17.21 + + '@storybook/csf@0.1.11': + dependencies: + type-fest: 2.19.0 + + '@storybook/global@5.0.0': {} + + '@storybook/icons@1.2.12(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + dependencies: + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + + '@storybook/instrumenter@8.3.6(storybook@8.3.6)': + dependencies: + '@storybook/global': 5.0.0 + '@vitest/utils': 2.1.3 + storybook: 8.3.6 + util: 0.12.5 + + '@storybook/manager-api@8.3.6(storybook@8.3.6)': + dependencies: + storybook: 8.3.6 + + '@storybook/nextjs@8.3.6(esbuild@0.23.1)(next@14.2.15(@babel/core@7.25.8)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.80.3))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.80.3)(storybook@8.3.6)(type-fest@2.19.0)(typescript@4.9.5)(uglify-js@3.19.3)(webpack-hot-middleware@2.26.1)(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3))': + dependencies: + '@babel/core': 7.25.8 + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.25.8) + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.25.8) + '@babel/plugin-syntax-import-assertions': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-class-properties': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-transform-export-namespace-from': 7.25.8(@babel/core@7.25.8) + '@babel/plugin-transform-numeric-separator': 7.25.8(@babel/core@7.25.8) + '@babel/plugin-transform-object-rest-spread': 7.25.8(@babel/core@7.25.8) + '@babel/plugin-transform-runtime': 7.25.7(@babel/core@7.25.8) + '@babel/preset-env': 7.25.8(@babel/core@7.25.8) + '@babel/preset-react': 7.25.7(@babel/core@7.25.8) + '@babel/preset-typescript': 7.25.7(@babel/core@7.25.8) + '@babel/runtime': 7.25.7 + '@pmmmwh/react-refresh-webpack-plugin': 0.5.15(react-refresh@0.14.2)(type-fest@2.19.0)(webpack-hot-middleware@2.26.1)(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3)) + '@storybook/builder-webpack5': 8.3.6(esbuild@0.23.1)(storybook@8.3.6)(typescript@4.9.5)(uglify-js@3.19.3) + '@storybook/preset-react-webpack': 8.3.6(@storybook/test@8.3.6(storybook@8.3.6))(esbuild@0.23.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(storybook@8.3.6)(typescript@4.9.5)(uglify-js@3.19.3) + '@storybook/react': 8.3.6(@storybook/test@8.3.6(storybook@8.3.6))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(storybook@8.3.6)(typescript@4.9.5) + '@storybook/test': 8.3.6(storybook@8.3.6) + '@types/node': 22.7.7 + '@types/semver': 7.5.8 + babel-loader: 9.2.1(@babel/core@7.25.8)(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3)) + css-loader: 6.11.0(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3)) + find-up: 5.0.0 + fs-extra: 11.2.0 + image-size: 1.1.1 + loader-utils: 3.3.1 + next: 14.2.15(@babel/core@7.25.8)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.80.3) + node-polyfill-webpack-plugin: 2.0.1(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3)) + pnp-webpack-plugin: 1.7.0(typescript@4.9.5) + postcss: 8.4.47 + postcss-loader: 8.1.1(postcss@8.4.47)(typescript@4.9.5)(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3)) + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-refresh: 0.14.2 + resolve-url-loader: 5.0.0 + sass-loader: 13.3.3(sass@1.80.3)(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3)) + semver: 7.6.3 + storybook: 8.3.6 + style-loader: 3.3.4(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3)) + styled-jsx: 5.1.6(@babel/core@7.25.8)(react@18.2.0) + ts-dedent: 2.2.0 + tsconfig-paths: 4.2.0 + tsconfig-paths-webpack-plugin: 4.1.0 + optionalDependencies: + sharp: 0.33.5 + typescript: 4.9.5 + webpack: 5.95.0(esbuild@0.23.1)(uglify-js@3.19.3) + transitivePeerDependencies: + - '@rspack/core' + - '@swc/core' + - '@types/webpack' + - babel-plugin-macros + - esbuild + - fibers + - node-sass + - sass + - sass-embedded + - sockjs-client + - supports-color + - type-fest + - uglify-js + - webpack-cli + - webpack-dev-server + - webpack-hot-middleware + - webpack-plugin-serve + + '@storybook/preset-react-webpack@8.3.6(@storybook/test@8.3.6(storybook@8.3.6))(esbuild@0.23.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(storybook@8.3.6)(typescript@4.9.5)(uglify-js@3.19.3)': + dependencies: + '@storybook/core-webpack': 8.3.6(storybook@8.3.6) + '@storybook/react': 8.3.6(@storybook/test@8.3.6(storybook@8.3.6))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(storybook@8.3.6)(typescript@4.9.5) + '@storybook/react-docgen-typescript-plugin': 1.0.6--canary.9.0c3f3b7.0(typescript@4.9.5)(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3)) + '@types/node': 22.7.7 + '@types/semver': 7.5.8 + find-up: 5.0.0 + fs-extra: 11.2.0 + magic-string: 0.30.12 + react: 18.2.0 + react-docgen: 7.1.0 + react-dom: 18.2.0(react@18.2.0) + resolve: 1.22.8 + semver: 7.6.3 + storybook: 8.3.6 + tsconfig-paths: 4.2.0 + webpack: 5.95.0(esbuild@0.23.1)(uglify-js@3.19.3) + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - '@storybook/test' + - '@swc/core' + - esbuild + - supports-color + - uglify-js + - webpack-cli + + '@storybook/preview-api@8.3.6(storybook@8.3.6)': + dependencies: + storybook: 8.3.6 + + '@storybook/react-docgen-typescript-plugin@1.0.6--canary.9.0c3f3b7.0(typescript@4.9.5)(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3))': + dependencies: + debug: 4.3.7 + endent: 2.1.0 + find-cache-dir: 3.3.2 + flat-cache: 3.2.0 + micromatch: 4.0.8 + react-docgen-typescript: 2.2.2(typescript@4.9.5) + tslib: 2.8.0 + typescript: 4.9.5 + webpack: 5.95.0(esbuild@0.23.1)(uglify-js@3.19.3) + transitivePeerDependencies: + - supports-color + + '@storybook/react-dom-shim@8.3.6(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(storybook@8.3.6)': + dependencies: + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + storybook: 8.3.6 + + '@storybook/react@8.3.6(@storybook/test@8.3.6(storybook@8.3.6))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(storybook@8.3.6)(typescript@4.9.5)': + dependencies: + '@storybook/components': 8.3.6(storybook@8.3.6) + '@storybook/global': 5.0.0 + '@storybook/manager-api': 8.3.6(storybook@8.3.6) + '@storybook/preview-api': 8.3.6(storybook@8.3.6) + '@storybook/react-dom-shim': 8.3.6(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(storybook@8.3.6) + '@storybook/theming': 8.3.6(storybook@8.3.6) + '@types/escodegen': 0.0.6 + '@types/estree': 0.0.51 + '@types/node': 22.7.7 + acorn: 7.4.1 + acorn-jsx: 5.3.2(acorn@7.4.1) + acorn-walk: 7.2.0 + escodegen: 2.1.0 + html-tags: 3.3.1 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-element-to-jsx-string: 15.0.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + semver: 7.6.3 + storybook: 8.3.6 + ts-dedent: 2.2.0 + type-fest: 2.19.0 + util-deprecate: 1.0.2 + optionalDependencies: + '@storybook/test': 8.3.6(storybook@8.3.6) + typescript: 4.9.5 + + '@storybook/test@8.3.6(storybook@8.3.6)': + dependencies: + '@storybook/csf': 0.1.11 + '@storybook/global': 5.0.0 + '@storybook/instrumenter': 8.3.6(storybook@8.3.6) + '@testing-library/dom': 10.4.0 + '@testing-library/jest-dom': 6.5.0 + '@testing-library/user-event': 14.5.2(@testing-library/dom@10.4.0) + '@vitest/expect': 2.0.5 + '@vitest/spy': 2.0.5 + storybook: 8.3.6 + util: 0.12.5 + + '@storybook/theming@8.3.6(storybook@8.3.6)': + dependencies: + storybook: 8.3.6 + + '@svgdotjs/svg.js@3.2.4': {} + + '@swc/counter@0.1.3': {} + + '@swc/helpers@0.5.5': + dependencies: + '@swc/counter': 0.1.3 + tslib: 2.8.0 + + '@szmarczak/http-timer@4.0.6': + dependencies: + defer-to-connect: 2.0.1 + + '@tailwindcss/line-clamp@0.4.4(tailwindcss@3.4.14(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)))': + dependencies: + tailwindcss: 3.4.14(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)) + + '@tailwindcss/typography@0.5.15(tailwindcss@3.4.14(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)))': + dependencies: + lodash.castarray: 4.4.0 + lodash.isplainobject: 4.0.6 + lodash.merge: 4.6.2 + postcss-selector-parser: 6.0.10 + tailwindcss: 3.4.14(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)) + + '@tanstack/react-virtual@3.10.8(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + dependencies: + '@tanstack/virtual-core': 3.10.8 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + + '@tanstack/virtual-core@3.10.8': {} + + '@testing-library/dom@10.4.0': + dependencies: + '@babel/code-frame': 7.25.7 + '@babel/runtime': 7.25.7 + '@types/aria-query': 5.0.4 + aria-query: 5.3.0 + chalk: 4.1.2 + dom-accessibility-api: 0.5.16 + lz-string: 1.5.0 + pretty-format: 27.5.1 + + '@testing-library/jest-dom@6.5.0': + dependencies: + '@adobe/css-tools': 4.4.0 + aria-query: 5.3.2 + chalk: 3.0.0 + css.escape: 1.5.1 + dom-accessibility-api: 0.6.3 + lodash: 4.17.21 + redent: 3.0.0 + + '@testing-library/jest-dom@6.6.2': + dependencies: + '@adobe/css-tools': 4.4.0 + aria-query: 5.3.2 + chalk: 3.0.0 + css.escape: 1.5.1 + dom-accessibility-api: 0.6.3 + lodash: 4.17.21 + redent: 3.0.0 + + '@testing-library/react@16.0.1(@testing-library/dom@10.4.0)(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + dependencies: + '@babel/runtime': 7.25.7 + '@testing-library/dom': 10.4.0 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + optionalDependencies: + '@types/react': 18.2.79 + '@types/react-dom': 18.2.25 + + '@testing-library/user-event@14.5.2(@testing-library/dom@10.4.0)': + dependencies: + '@testing-library/dom': 10.4.0 + + '@tootallnate/once@2.0.0': {} + + '@tsconfig/node10@1.0.11': {} + + '@tsconfig/node12@1.0.11': {} + + '@tsconfig/node14@1.0.3': {} + + '@tsconfig/node16@1.0.4': {} + + '@types/acorn@4.0.6': + dependencies: + '@types/estree': 1.0.6 + + '@types/aria-query@5.0.4': {} + + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.25.8 + '@babel/types': 7.25.8 + '@types/babel__generator': 7.6.8 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.20.6 + + '@types/babel__generator@7.6.8': + dependencies: + '@babel/types': 7.25.8 + + '@types/babel__template@7.4.4': + dependencies: + '@babel/parser': 7.25.8 + '@babel/types': 7.25.8 + + '@types/babel__traverse@7.20.6': + dependencies: + '@babel/types': 7.25.8 + + '@types/body-parser@1.19.5': + dependencies: + '@types/connect': 3.4.38 + '@types/node': 18.15.0 + + '@types/cacheable-request@6.0.3': + dependencies: + '@types/http-cache-semantics': 4.0.4 + '@types/keyv': 3.1.4 + '@types/node': 18.15.0 + '@types/responselike': 1.0.3 + + '@types/connect@3.4.38': + dependencies: + '@types/node': 18.15.0 + + '@types/crypto-js@4.2.2': {} + + '@types/d3-array@3.2.1': {} + + '@types/d3-axis@3.0.6': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-brush@3.0.6': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-chord@3.0.6': {} + + '@types/d3-color@3.1.3': {} + + '@types/d3-contour@3.0.6': + dependencies: + '@types/d3-array': 3.2.1 + '@types/geojson': 7946.0.14 + + '@types/d3-delaunay@6.0.4': {} + + '@types/d3-dispatch@3.0.6': {} + + '@types/d3-drag@3.0.7': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-dsv@3.0.7': {} + + '@types/d3-ease@3.0.2': {} + + '@types/d3-fetch@3.0.7': + dependencies: + '@types/d3-dsv': 3.0.7 + + '@types/d3-force@3.0.10': {} + + '@types/d3-format@3.0.4': {} + + '@types/d3-geo@3.1.0': + dependencies: + '@types/geojson': 7946.0.14 + + '@types/d3-hierarchy@3.1.7': {} + + '@types/d3-interpolate@3.0.4': + dependencies: + '@types/d3-color': 3.1.3 + + '@types/d3-path@3.1.0': {} + + '@types/d3-polygon@3.0.2': {} + + '@types/d3-quadtree@3.0.6': {} + + '@types/d3-random@3.0.3': {} + + '@types/d3-scale-chromatic@3.0.3': {} + + '@types/d3-scale@4.0.8': + dependencies: + '@types/d3-time': 3.0.3 + + '@types/d3-selection@3.0.11': {} + + '@types/d3-shape@3.1.6': + dependencies: + '@types/d3-path': 3.1.0 + + '@types/d3-time-format@4.0.3': {} + + '@types/d3-time@3.0.3': {} + + '@types/d3-timer@3.0.2': {} + + '@types/d3-transition@3.0.9': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-zoom@3.0.8': + dependencies: + '@types/d3-interpolate': 3.0.4 + '@types/d3-selection': 3.0.11 + + '@types/d3@7.4.3': + dependencies: + '@types/d3-array': 3.2.1 + '@types/d3-axis': 3.0.6 + '@types/d3-brush': 3.0.6 + '@types/d3-chord': 3.0.6 + '@types/d3-color': 3.1.3 + '@types/d3-contour': 3.0.6 + '@types/d3-delaunay': 6.0.4 + '@types/d3-dispatch': 3.0.6 + '@types/d3-drag': 3.0.7 + '@types/d3-dsv': 3.0.7 + '@types/d3-ease': 3.0.2 + '@types/d3-fetch': 3.0.7 + '@types/d3-force': 3.0.10 + '@types/d3-format': 3.0.4 + '@types/d3-geo': 3.1.0 + '@types/d3-hierarchy': 3.1.7 + '@types/d3-interpolate': 3.0.4 + '@types/d3-path': 3.1.0 + '@types/d3-polygon': 3.0.2 + '@types/d3-quadtree': 3.0.6 + '@types/d3-random': 3.0.3 + '@types/d3-scale': 4.0.8 + '@types/d3-scale-chromatic': 3.0.3 + '@types/d3-selection': 3.0.11 + '@types/d3-shape': 3.1.6 + '@types/d3-time': 3.0.3 + '@types/d3-time-format': 4.0.3 + '@types/d3-timer': 3.0.2 + '@types/d3-transition': 3.0.9 + '@types/d3-zoom': 3.0.8 + + '@types/dagre@0.7.52': {} + + '@types/debug@4.1.12': + dependencies: + '@types/ms': 0.7.34 + + '@types/doctrine@0.0.9': {} + + '@types/escodegen@0.0.6': {} + + '@types/estree-jsx@1.0.5': + dependencies: + '@types/estree': 1.0.6 + + '@types/estree@0.0.51': {} + + '@types/estree@1.0.6': {} + + '@types/express-serve-static-core@4.19.6': + dependencies: + '@types/node': 18.15.0 + '@types/qs': 6.9.16 + '@types/range-parser': 1.2.7 + '@types/send': 0.17.4 + + '@types/express@4.17.21': + dependencies: + '@types/body-parser': 1.19.5 + '@types/express-serve-static-core': 4.19.6 + '@types/qs': 6.9.16 + '@types/serve-static': 1.15.7 + + '@types/geojson@7946.0.14': {} + + '@types/graceful-fs@4.1.9': + dependencies: + '@types/node': 18.15.0 + + '@types/hast@2.3.10': + dependencies: + '@types/unist': 2.0.11 + + '@types/hast@3.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/html-minifier-terser@6.1.0': {} + + '@types/http-cache-semantics@4.0.4': {} + + '@types/http-errors@2.0.4': {} + + '@types/istanbul-lib-coverage@2.0.6': {} + + '@types/istanbul-lib-report@3.0.3': + dependencies: + '@types/istanbul-lib-coverage': 2.0.6 + + '@types/istanbul-reports@3.0.4': + dependencies: + '@types/istanbul-lib-report': 3.0.3 + + '@types/jest@29.5.13': + dependencies: + expect: 29.7.0 + pretty-format: 29.7.0 + + '@types/js-cookie@3.0.6': {} + + '@types/jsdom@20.0.1': + dependencies: + '@types/node': 18.15.0 + '@types/tough-cookie': 4.0.5 + parse5: 7.2.0 + + '@types/json-schema@7.0.15': {} + + '@types/json5@0.0.29': {} + + '@types/katex@0.14.0': {} + + '@types/katex@0.16.7': {} + + '@types/keyv@3.1.4': + dependencies: + '@types/node': 18.15.0 + + '@types/lodash-es@4.17.12': + dependencies: + '@types/lodash': 4.17.12 + + '@types/lodash@4.17.12': {} + + '@types/mdast@3.0.15': + dependencies: + '@types/unist': 2.0.11 + + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/mdx@2.0.13': {} + + '@types/mime@1.3.5': {} + + '@types/ms@0.7.34': {} + + '@types/negotiator@0.6.3': {} + + '@types/node@18.15.0': {} + + '@types/node@22.7.7': + dependencies: + undici-types: 6.19.8 + + '@types/normalize-package-data@2.4.4': {} + + '@types/papaparse@5.3.15': + dependencies: + '@types/node': 18.15.0 + + '@types/parse-json@4.0.2': {} + + '@types/prop-types@15.7.13': {} + + '@types/qs@6.9.16': {} + + '@types/range-parser@1.2.7': {} + + '@types/react-dom@18.2.25': + dependencies: + '@types/react': 18.2.79 + + '@types/react-slider@1.3.6': + dependencies: + '@types/react': 18.2.79 + + '@types/react-syntax-highlighter@15.5.13': + dependencies: + '@types/react': 18.2.79 + + '@types/react-window-infinite-loader@1.0.9': + dependencies: + '@types/react': 18.2.79 + '@types/react-window': 1.8.8 + + '@types/react-window@1.8.8': + dependencies: + '@types/react': 18.2.79 + + '@types/react@18.2.79': + dependencies: + '@types/prop-types': 15.7.13 + csstype: 3.1.3 + + '@types/recordrtc@5.6.14': {} + + '@types/resolve@1.20.6': {} + + '@types/responselike@1.0.3': + dependencies: + '@types/node': 18.15.0 + + '@types/semver@7.5.8': {} + + '@types/send@0.17.4': + dependencies: + '@types/mime': 1.3.5 + '@types/node': 18.15.0 + + '@types/serve-static@1.15.7': + dependencies: + '@types/http-errors': 2.0.4 + '@types/node': 18.15.0 + '@types/send': 0.17.4 + + '@types/sortablejs@1.15.8': {} + + '@types/stack-utils@2.0.3': {} + + '@types/tough-cookie@4.0.5': {} + + '@types/unist@2.0.11': {} + + '@types/unist@3.0.3': {} + + '@types/uuid@9.0.8': {} + + '@types/yargs-parser@21.0.3': {} + + '@types/yargs@17.0.33': + dependencies: + '@types/yargs-parser': 21.0.3 + + '@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5)': + dependencies: + '@eslint-community/regexpp': 4.11.1 + '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/type-utils': 5.62.0(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@4.9.5) + debug: 4.3.7 + eslint: 8.57.1 + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare-lite: 1.4.0 + semver: 7.6.3 + tsutils: 3.21.0(typescript@4.9.5) + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/eslint-plugin@8.10.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5)': + dependencies: + '@eslint-community/regexpp': 4.11.1 + '@typescript-eslint/parser': 8.10.0(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/scope-manager': 8.10.0 + '@typescript-eslint/type-utils': 8.10.0(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/utils': 8.10.0(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/visitor-keys': 8.10.0 + eslint: 8.57.1 + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare: 1.4.0 + ts-api-utils: 1.3.0(typescript@4.9.5) + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5)': + dependencies: + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5) + debug: 4.3.7 + eslint: 8.57.1 + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5)': + dependencies: + '@typescript-eslint/scope-manager': 8.10.0 + '@typescript-eslint/types': 8.10.0 + '@typescript-eslint/typescript-estree': 8.10.0(typescript@4.9.5) + '@typescript-eslint/visitor-keys': 8.10.0 + debug: 4.3.7 + eslint: 8.57.1 + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@5.62.0': + dependencies: + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/visitor-keys': 5.62.0 + + '@typescript-eslint/scope-manager@8.10.0': + dependencies: + '@typescript-eslint/types': 8.10.0 + '@typescript-eslint/visitor-keys': 8.10.0 + + '@typescript-eslint/type-utils@5.62.0(eslint@8.57.1)(typescript@4.9.5)': + dependencies: + '@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5) + '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@4.9.5) + debug: 4.3.7 + eslint: 8.57.1 + tsutils: 3.21.0(typescript@4.9.5) + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/type-utils@8.10.0(eslint@8.57.1)(typescript@4.9.5)': + dependencies: + '@typescript-eslint/typescript-estree': 8.10.0(typescript@4.9.5) + '@typescript-eslint/utils': 8.10.0(eslint@8.57.1)(typescript@4.9.5) + debug: 4.3.7 + ts-api-utils: 1.3.0(typescript@4.9.5) + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - eslint + - supports-color + + '@typescript-eslint/types@5.62.0': {} + + '@typescript-eslint/types@8.10.0': {} + + '@typescript-eslint/typescript-estree@5.62.0(typescript@4.9.5)': + dependencies: + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/visitor-keys': 5.62.0 + debug: 4.3.7 + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.6.3 + tsutils: 3.21.0(typescript@4.9.5) + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/typescript-estree@8.10.0(typescript@4.9.5)': + dependencies: + '@typescript-eslint/types': 8.10.0 + '@typescript-eslint/visitor-keys': 8.10.0 + debug: 4.3.7 + fast-glob: 3.3.2 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.6.3 + ts-api-utils: 1.3.0(typescript@4.9.5) + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@5.62.0(eslint@8.57.1)(typescript@4.9.5)': + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) + '@types/json-schema': 7.0.15 + '@types/semver': 7.5.8 + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5) + eslint: 8.57.1 + eslint-scope: 5.1.1 + semver: 7.6.3 + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/utils@8.10.0(eslint@8.57.1)(typescript@4.9.5)': + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) + '@typescript-eslint/scope-manager': 8.10.0 + '@typescript-eslint/types': 8.10.0 + '@typescript-eslint/typescript-estree': 8.10.0(typescript@4.9.5) + eslint: 8.57.1 + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/visitor-keys@5.62.0': + dependencies: + '@typescript-eslint/types': 5.62.0 + eslint-visitor-keys: 3.4.3 + + '@typescript-eslint/visitor-keys@8.10.0': + dependencies: + '@typescript-eslint/types': 8.10.0 + eslint-visitor-keys: 3.4.3 + + '@ungap/structured-clone@1.2.0': {} + + '@vitest/expect@2.0.5': + dependencies: + '@vitest/spy': 2.0.5 + '@vitest/utils': 2.0.5 + chai: 5.1.1 + tinyrainbow: 1.2.0 + + '@vitest/pretty-format@2.0.5': + dependencies: + tinyrainbow: 1.2.0 + + '@vitest/pretty-format@2.1.3': + dependencies: + tinyrainbow: 1.2.0 + + '@vitest/spy@2.0.5': + dependencies: + tinyspy: 3.0.2 + + '@vitest/utils@2.0.5': + dependencies: + '@vitest/pretty-format': 2.0.5 + estree-walker: 3.0.3 + loupe: 3.1.2 + tinyrainbow: 1.2.0 + + '@vitest/utils@2.1.3': + dependencies: + '@vitest/pretty-format': 2.1.3 + loupe: 3.1.2 + tinyrainbow: 1.2.0 + + '@vue/compiler-core@3.5.12': + dependencies: + '@babel/parser': 7.25.8 + '@vue/shared': 3.5.12 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + + '@vue/compiler-dom@3.5.12': + dependencies: + '@vue/compiler-core': 3.5.12 + '@vue/shared': 3.5.12 + + '@vue/shared@3.5.12': {} + + '@webassemblyjs/ast@1.12.1': + dependencies: + '@webassemblyjs/helper-numbers': 1.11.6 + '@webassemblyjs/helper-wasm-bytecode': 1.11.6 + + '@webassemblyjs/floating-point-hex-parser@1.11.6': {} + + '@webassemblyjs/helper-api-error@1.11.6': {} + + '@webassemblyjs/helper-buffer@1.12.1': {} + + '@webassemblyjs/helper-numbers@1.11.6': + dependencies: + '@webassemblyjs/floating-point-hex-parser': 1.11.6 + '@webassemblyjs/helper-api-error': 1.11.6 + '@xtuc/long': 4.2.2 + + '@webassemblyjs/helper-wasm-bytecode@1.11.6': {} + + '@webassemblyjs/helper-wasm-section@1.12.1': + dependencies: + '@webassemblyjs/ast': 1.12.1 + '@webassemblyjs/helper-buffer': 1.12.1 + '@webassemblyjs/helper-wasm-bytecode': 1.11.6 + '@webassemblyjs/wasm-gen': 1.12.1 + + '@webassemblyjs/ieee754@1.11.6': + dependencies: + '@xtuc/ieee754': 1.2.0 + + '@webassemblyjs/leb128@1.11.6': + dependencies: + '@xtuc/long': 4.2.2 + + '@webassemblyjs/utf8@1.11.6': {} + + '@webassemblyjs/wasm-edit@1.12.1': + dependencies: + '@webassemblyjs/ast': 1.12.1 + '@webassemblyjs/helper-buffer': 1.12.1 + '@webassemblyjs/helper-wasm-bytecode': 1.11.6 + '@webassemblyjs/helper-wasm-section': 1.12.1 + '@webassemblyjs/wasm-gen': 1.12.1 + '@webassemblyjs/wasm-opt': 1.12.1 + '@webassemblyjs/wasm-parser': 1.12.1 + '@webassemblyjs/wast-printer': 1.12.1 + + '@webassemblyjs/wasm-gen@1.12.1': + dependencies: + '@webassemblyjs/ast': 1.12.1 + '@webassemblyjs/helper-wasm-bytecode': 1.11.6 + '@webassemblyjs/ieee754': 1.11.6 + '@webassemblyjs/leb128': 1.11.6 + '@webassemblyjs/utf8': 1.11.6 + + '@webassemblyjs/wasm-opt@1.12.1': + dependencies: + '@webassemblyjs/ast': 1.12.1 + '@webassemblyjs/helper-buffer': 1.12.1 + '@webassemblyjs/wasm-gen': 1.12.1 + '@webassemblyjs/wasm-parser': 1.12.1 + + '@webassemblyjs/wasm-parser@1.12.1': + dependencies: + '@webassemblyjs/ast': 1.12.1 + '@webassemblyjs/helper-api-error': 1.11.6 + '@webassemblyjs/helper-wasm-bytecode': 1.11.6 + '@webassemblyjs/ieee754': 1.11.6 + '@webassemblyjs/leb128': 1.11.6 + '@webassemblyjs/utf8': 1.11.6 + + '@webassemblyjs/wast-printer@1.12.1': + dependencies: + '@webassemblyjs/ast': 1.12.1 + '@xtuc/long': 4.2.2 + + '@xtuc/ieee754@1.2.0': {} + + '@xtuc/long@4.2.2': {} + + abab@2.0.6: {} + + abort-controller@3.0.0: + dependencies: + event-target-shim: 5.0.1 + + accepts@1.3.8: + dependencies: + mime-types: 2.1.35 + negotiator: 0.6.3 + + acorn-globals@7.0.1: + dependencies: + acorn: 8.13.0 + acorn-walk: 8.3.4 + + acorn-import-attributes@1.9.5(acorn@8.13.0): + dependencies: + acorn: 8.13.0 + + acorn-jsx@5.3.2(acorn@7.4.1): + dependencies: + acorn: 7.4.1 + + acorn-jsx@5.3.2(acorn@8.13.0): + dependencies: + acorn: 8.13.0 + + acorn-walk@7.2.0: {} + + acorn-walk@8.3.4: + dependencies: + acorn: 8.13.0 + + acorn@7.4.1: {} + + acorn@8.13.0: {} + + adjust-sourcemap-loader@4.0.0: + dependencies: + loader-utils: 2.0.4 + regex-parser: 2.3.0 + + agent-base@6.0.2: + dependencies: + debug: 4.3.7 + transitivePeerDependencies: + - supports-color + + ahooks@3.8.1(react@18.2.0): + dependencies: + '@babel/runtime': 7.25.7 + dayjs: 1.11.13 + intersection-observer: 0.12.2 + js-cookie: 3.0.5 + lodash: 4.17.21 + react: 18.2.0 + react-fast-compare: 3.2.2 + resize-observer-polyfill: 1.5.1 + screenfull: 5.2.0 + tslib: 2.8.0 + + ajv-formats@2.1.1(ajv@8.17.1): + optionalDependencies: + ajv: 8.17.1 + + ajv-keywords@3.5.2(ajv@6.12.6): + dependencies: + ajv: 6.12.6 + + ajv-keywords@5.1.0(ajv@8.17.1): + dependencies: + ajv: 8.17.1 + fast-deep-equal: 3.1.3 + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ajv@8.17.1: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.0.3 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + + ansi-escapes@4.3.2: + dependencies: + type-fest: 0.21.3 + + ansi-escapes@5.0.0: + dependencies: + type-fest: 1.4.0 + + ansi-html-community@0.0.8: {} + + ansi-html@0.0.9: {} + + ansi-regex@5.0.1: {} + + ansi-regex@6.1.0: {} + + ansi-styles@3.2.1: + dependencies: + color-convert: 1.9.3 + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@5.2.0: {} + + ansi-styles@6.2.1: {} + + any-promise@1.3.0: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + arg@4.1.3: {} + + arg@5.0.2: {} + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + argparse@2.0.1: {} + + aria-query@5.1.3: + dependencies: + deep-equal: 2.2.3 + + aria-query@5.3.0: + dependencies: + dequal: 2.0.3 + + aria-query@5.3.2: {} + + array-buffer-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + is-array-buffer: 3.0.4 + + array-flatten@1.1.1: {} + + array-includes@3.1.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + get-intrinsic: 1.2.4 + is-string: 1.0.7 + + array-union@2.1.0: {} + + array.prototype.findlast@1.2.5: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-shim-unscopables: 1.0.2 + + array.prototype.findlastindex@1.2.5: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-shim-unscopables: 1.0.2 + + array.prototype.flat@1.3.2: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-shim-unscopables: 1.0.2 + + array.prototype.flatmap@1.3.2: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-shim-unscopables: 1.0.2 + + array.prototype.tosorted@1.1.4: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-shim-unscopables: 1.0.2 + + arraybuffer.prototype.slice@1.0.3: + dependencies: + array-buffer-byte-length: 1.0.1 + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + is-array-buffer: 3.0.4 + is-shared-array-buffer: 1.0.3 + + asn1.js@4.10.1: + dependencies: + bn.js: 4.12.0 + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + + assert@2.1.0: + dependencies: + call-bind: 1.0.7 + is-nan: 1.3.2 + object-is: 1.1.6 + object.assign: 4.1.5 + util: 0.12.5 + + assertion-error@2.0.1: {} + + ast-types-flow@0.0.8: {} + + ast-types@0.16.1: + dependencies: + tslib: 2.8.0 + + astring@1.9.0: {} + + async@2.6.4: + dependencies: + lodash: 4.17.21 + + asynckit@0.4.0: {} + + autoprefixer@10.4.20(postcss@8.4.47): + dependencies: + browserslist: 4.24.0 + caniuse-lite: 1.0.30001669 + fraction.js: 4.3.7 + normalize-range: 0.1.2 + picocolors: 1.1.1 + postcss: 8.4.47 + postcss-value-parser: 4.2.0 + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.0.0 + + axe-core@4.10.1: {} + + axobject-query@4.1.0: {} + + babel-jest@29.7.0(@babel/core@7.25.8): + dependencies: + '@babel/core': 7.25.8 + '@jest/transform': 29.7.0 + '@types/babel__core': 7.20.5 + babel-plugin-istanbul: 6.1.1 + babel-preset-jest: 29.6.3(@babel/core@7.25.8) + chalk: 4.1.2 + graceful-fs: 4.2.11 + slash: 3.0.0 + transitivePeerDependencies: + - supports-color + + babel-loader@9.2.1(@babel/core@7.25.8)(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3)): + dependencies: + '@babel/core': 7.25.8 + find-cache-dir: 4.0.0 + schema-utils: 4.2.0 + webpack: 5.95.0(esbuild@0.23.1)(uglify-js@3.19.3) + + babel-plugin-istanbul@6.1.1: + dependencies: + '@babel/helper-plugin-utils': 7.25.7 + '@istanbuljs/load-nyc-config': 1.1.0 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-instrument: 5.2.1 + test-exclude: 6.0.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-jest-hoist@29.6.3: + dependencies: + '@babel/template': 7.25.7 + '@babel/types': 7.25.8 + '@types/babel__core': 7.20.5 + '@types/babel__traverse': 7.20.6 + + babel-plugin-polyfill-corejs2@0.4.11(@babel/core@7.25.8): + dependencies: + '@babel/compat-data': 7.25.8 + '@babel/core': 7.25.8 + '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.25.8) + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + babel-plugin-polyfill-corejs3@0.10.6(@babel/core@7.25.8): + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.25.8) + core-js-compat: 3.38.1 + transitivePeerDependencies: + - supports-color + + babel-plugin-polyfill-regenerator@0.6.2(@babel/core@7.25.8): + dependencies: + '@babel/core': 7.25.8 + '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.25.8) + transitivePeerDependencies: + - supports-color + + babel-preset-current-node-syntax@1.1.0(@babel/core@7.25.8): + dependencies: + '@babel/core': 7.25.8 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.25.8) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.25.8) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.25.8) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.25.8) + '@babel/plugin-syntax-import-attributes': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.25.8) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.25.8) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.25.8) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.25.8) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.25.8) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.25.8) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.25.8) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.25.8) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.25.8) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.25.8) + + babel-preset-jest@29.6.3(@babel/core@7.25.8): + dependencies: + '@babel/core': 7.25.8 + babel-plugin-jest-hoist: 29.6.3 + babel-preset-current-node-syntax: 1.1.0(@babel/core@7.25.8) + + bail@2.0.2: {} + + balanced-match@1.0.2: {} + + base64-js@1.5.1: {} + + better-opn@3.0.2: + dependencies: + open: 8.4.2 + + big.js@5.2.2: {} + + binary-extensions@2.3.0: {} + + bing-translate-api@4.0.2: + dependencies: + got: 11.8.6 + + bn.js@4.12.0: {} + + bn.js@5.2.1: {} + + body-parser@1.20.3: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + on-finished: 2.4.1 + qs: 6.13.0 + raw-body: 2.5.2 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + boolbase@1.0.0: {} + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + brorand@1.1.0: {} + + browser-assert@1.2.1: {} + + browserify-aes@1.2.0: + dependencies: + buffer-xor: 1.0.3 + cipher-base: 1.0.4 + create-hash: 1.2.0 + evp_bytestokey: 1.0.3 + inherits: 2.0.4 + safe-buffer: 5.2.1 + + browserify-cipher@1.0.1: + dependencies: + browserify-aes: 1.2.0 + browserify-des: 1.0.2 + evp_bytestokey: 1.0.3 + + browserify-des@1.0.2: + dependencies: + cipher-base: 1.0.4 + des.js: 1.1.0 + inherits: 2.0.4 + safe-buffer: 5.2.1 + + browserify-rsa@4.1.1: + dependencies: + bn.js: 5.2.1 + randombytes: 2.1.0 + safe-buffer: 5.2.1 + + browserify-sign@4.2.3: + dependencies: + bn.js: 5.2.1 + browserify-rsa: 4.1.1 + create-hash: 1.2.0 + create-hmac: 1.1.7 + elliptic: 6.5.7 + hash-base: 3.0.4 + inherits: 2.0.4 + parse-asn1: 5.1.7 + readable-stream: 2.3.8 + safe-buffer: 5.2.1 + + browserify-zlib@0.2.0: + dependencies: + pako: 1.0.11 + + browserslist@4.24.0: + dependencies: + caniuse-lite: 1.0.30001669 + electron-to-chromium: 1.5.41 + node-releases: 2.0.18 + update-browserslist-db: 1.1.1(browserslist@4.24.0) + + bser@2.1.1: + dependencies: + node-int64: 0.4.0 + + buffer-from@1.1.2: {} + + buffer-xor@1.0.3: {} + + buffer@6.0.3: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + builtin-modules@3.3.0: {} + + builtin-status-codes@3.0.0: {} + + builtins@5.1.0: + dependencies: + semver: 7.6.3 + + busboy@1.6.0: + dependencies: + streamsearch: 1.1.0 + + bytes@3.1.2: {} + + cacheable-lookup@5.0.4: {} + + cacheable-request@7.0.4: + dependencies: + clone-response: 1.0.3 + get-stream: 5.2.0 + http-cache-semantics: 4.1.1 + keyv: 4.5.4 + lowercase-keys: 2.0.0 + normalize-url: 6.1.0 + responselike: 2.0.1 + + call-bind@1.0.7: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + set-function-length: 1.2.2 + + callsites@3.1.0: {} + + camel-case@4.1.2: + dependencies: + pascal-case: 3.1.2 + tslib: 2.8.0 + + camelcase-css@2.0.1: {} + + camelcase@5.3.1: {} + + camelcase@6.3.0: {} + + caniuse-lite@1.0.30001669: {} + + case-sensitive-paths-webpack-plugin@2.4.0: {} + + ccount@2.0.1: {} + + chai@5.1.1: + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.1 + deep-eql: 5.0.2 + loupe: 3.1.2 + pathval: 2.0.0 + + chalk@2.4.2: + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + + chalk@3.0.0: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chalk@4.1.1: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chalk@5.3.0: {} + + char-regex@1.0.2: {} + + character-entities-html4@2.1.0: {} + + character-entities-legacy@1.1.4: {} + + character-entities-legacy@3.0.0: {} + + character-entities@1.2.4: {} + + character-entities@2.0.2: {} + + character-reference-invalid@1.1.4: {} + + character-reference-invalid@2.0.1: {} + + check-error@2.1.1: {} + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chokidar@4.0.1: + dependencies: + readdirp: 4.0.2 + + chromatic@11.12.6: {} + + chrome-trace-event@1.0.4: {} + + ci-info@3.9.0: {} + + cipher-base@1.0.4: + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + + cjs-module-lexer@1.4.1: {} + + class-variance-authority@0.7.0: + dependencies: + clsx: 2.0.0 + + classcat@5.0.5: {} + + classnames@2.3.1: {} + + classnames@2.5.1: {} + + clean-css@5.3.3: + dependencies: + source-map: 0.6.1 + + clean-regexp@1.0.0: + dependencies: + escape-string-regexp: 1.0.5 + + cli-cursor@4.0.0: + dependencies: + restore-cursor: 4.0.0 + + cli-truncate@3.1.0: + dependencies: + slice-ansi: 5.0.0 + string-width: 4.2.3 + + client-only@0.0.1: {} + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + clone-response@1.0.3: + dependencies: + mimic-response: 1.0.1 + + clsx@2.0.0: {} + + clsx@2.1.1: {} + + co@4.6.0: {} + + code-inspector-core@0.13.0: + dependencies: + '@vue/compiler-dom': 3.5.12 + chalk: 4.1.1 + portfinder: 1.0.32 + transitivePeerDependencies: + - supports-color + + code-inspector-plugin@0.13.0: + dependencies: + chalk: 4.1.1 + code-inspector-core: 0.13.0 + vite-code-inspector-plugin: 0.13.0 + webpack-code-inspector-plugin: 0.13.0 + transitivePeerDependencies: + - supports-color + + collect-v8-coverage@1.0.2: {} + + color-convert@1.9.3: + dependencies: + color-name: 1.1.3 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.3: {} + + color-name@1.1.4: {} + + color-string@1.9.1: + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.2 + + color@4.2.3: + dependencies: + color-convert: 2.0.1 + color-string: 1.9.1 + + colorette@2.0.20: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + comma-separated-tokens@1.0.8: {} + + comma-separated-tokens@2.0.3: {} + + commander@11.0.0: {} + + commander@2.20.3: {} + + commander@4.1.1: {} + + commander@7.2.0: {} + + commander@8.3.0: {} + + common-path-prefix@3.0.0: {} + + commondir@1.0.1: {} + + concat-map@0.0.1: {} + + console-browserify@1.2.0: {} + + constants-browserify@1.0.0: {} + + content-disposition@0.5.4: + dependencies: + safe-buffer: 5.2.1 + + content-type@1.0.5: {} + + convert-source-map@1.9.0: {} + + convert-source-map@2.0.0: {} + + cookie-signature@1.0.6: {} + + cookie@0.7.1: {} + + copy-to-clipboard@3.3.3: + dependencies: + toggle-selection: 1.0.6 + + core-js-compat@3.38.1: + dependencies: + browserslist: 4.24.0 + + core-js-pure@3.38.1: {} + + core-util-is@1.0.3: {} + + cose-base@1.0.3: + dependencies: + layout-base: 1.0.2 + + cose-base@2.2.0: + dependencies: + layout-base: 2.0.1 + + cosmiconfig@7.1.0: + dependencies: + '@types/parse-json': 4.0.2 + import-fresh: 3.3.0 + parse-json: 5.2.0 + path-type: 4.0.0 + yaml: 1.10.2 + + cosmiconfig@9.0.0(typescript@4.9.5): + dependencies: + env-paths: 2.2.1 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + parse-json: 5.2.0 + optionalDependencies: + typescript: 4.9.5 + + create-ecdh@4.0.4: + dependencies: + bn.js: 4.12.0 + elliptic: 6.5.7 + + create-hash@1.2.0: + dependencies: + cipher-base: 1.0.4 + inherits: 2.0.4 + md5.js: 1.3.5 + ripemd160: 2.0.2 + sha.js: 2.4.11 + + create-hmac@1.1.7: + dependencies: + cipher-base: 1.0.4 + create-hash: 1.2.0 + inherits: 2.0.4 + ripemd160: 2.0.2 + safe-buffer: 5.2.1 + sha.js: 2.4.11 + + create-jest@29.7.0(@types/node@18.15.0)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)): + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-config: 29.7.0(@types/node@18.15.0)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)) + jest-util: 29.7.0 + prompts: 2.4.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + + create-require@1.1.1: {} + + cross-env@7.0.3: + dependencies: + cross-spawn: 7.0.3 + + cross-spawn@7.0.3: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + crypto-browserify@3.12.0: + dependencies: + browserify-cipher: 1.0.1 + browserify-sign: 4.2.3 + create-ecdh: 4.0.4 + create-hash: 1.2.0 + create-hmac: 1.1.7 + diffie-hellman: 5.0.3 + inherits: 2.0.4 + pbkdf2: 3.1.2 + public-encrypt: 4.0.3 + randombytes: 2.1.0 + randomfill: 1.0.4 + + crypto-js@4.2.0: {} + + css-loader@6.11.0(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3)): + dependencies: + icss-utils: 5.1.0(postcss@8.4.47) + postcss: 8.4.47 + postcss-modules-extract-imports: 3.1.0(postcss@8.4.47) + postcss-modules-local-by-default: 4.0.5(postcss@8.4.47) + postcss-modules-scope: 3.2.0(postcss@8.4.47) + postcss-modules-values: 4.0.0(postcss@8.4.47) + postcss-value-parser: 4.2.0 + semver: 7.6.3 + optionalDependencies: + webpack: 5.95.0(esbuild@0.23.1)(uglify-js@3.19.3) + + css-select@4.3.0: + dependencies: + boolbase: 1.0.0 + css-what: 6.1.0 + domhandler: 4.3.1 + domutils: 2.8.0 + nth-check: 2.1.1 + + css-what@6.1.0: {} + + css.escape@1.5.1: {} + + cssesc@3.0.0: {} + + cssom@0.3.8: {} + + cssom@0.5.0: {} + + cssstyle@2.3.0: + dependencies: + cssom: 0.3.8 + + csstype@3.1.3: {} + + cytoscape-cose-bilkent@4.1.0(cytoscape@3.30.2): + dependencies: + cose-base: 1.0.3 + cytoscape: 3.30.2 + + cytoscape-fcose@2.2.0(cytoscape@3.30.2): + dependencies: + cose-base: 2.2.0 + cytoscape: 3.30.2 + + cytoscape@3.30.2: {} + + d3-array@2.12.1: + dependencies: + internmap: 1.0.1 + + d3-array@3.2.4: + dependencies: + internmap: 2.0.3 + + d3-axis@3.0.0: {} + + d3-brush@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + + d3-chord@3.0.1: + dependencies: + d3-path: 3.1.0 + + d3-color@3.1.0: {} + + d3-contour@4.0.2: + dependencies: + d3-array: 3.2.4 + + d3-delaunay@6.0.4: + dependencies: + delaunator: 5.0.1 + + d3-dispatch@3.0.1: {} + + d3-drag@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-selection: 3.0.0 + + d3-dsv@3.0.1: + dependencies: + commander: 7.2.0 + iconv-lite: 0.6.3 + rw: 1.3.3 + + d3-ease@3.0.1: {} + + d3-fetch@3.0.1: + dependencies: + d3-dsv: 3.0.1 + + d3-force@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-quadtree: 3.0.1 + d3-timer: 3.0.1 + + d3-format@3.1.0: {} + + d3-geo@3.1.1: + dependencies: + d3-array: 3.2.4 + + d3-hierarchy@3.1.2: {} + + d3-interpolate@3.0.1: + dependencies: + d3-color: 3.1.0 + + d3-path@1.0.9: {} + + d3-path@3.1.0: {} + + d3-polygon@3.0.1: {} + + d3-quadtree@3.0.1: {} + + d3-random@3.0.1: {} + + d3-sankey@0.12.3: + dependencies: + d3-array: 2.12.1 + d3-shape: 1.3.7 + + d3-scale-chromatic@3.1.0: + dependencies: + d3-color: 3.1.0 + d3-interpolate: 3.0.1 + + d3-scale@4.0.2: + dependencies: + d3-array: 3.2.4 + d3-format: 3.1.0 + d3-interpolate: 3.0.1 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + + d3-selection@3.0.0: {} + + d3-shape@1.3.7: + dependencies: + d3-path: 1.0.9 + + d3-shape@3.2.0: + dependencies: + d3-path: 3.1.0 + + d3-time-format@4.1.0: + dependencies: + d3-time: 3.1.0 + + d3-time@3.1.0: + dependencies: + d3-array: 3.2.4 + + d3-timer@3.0.1: {} + + d3-transition@3.0.1(d3-selection@3.0.0): + dependencies: + d3-color: 3.1.0 + d3-dispatch: 3.0.1 + d3-ease: 3.0.1 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-timer: 3.0.1 + + d3-zoom@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + + d3@7.9.0: + dependencies: + d3-array: 3.2.4 + d3-axis: 3.0.0 + d3-brush: 3.0.0 + d3-chord: 3.0.1 + d3-color: 3.1.0 + d3-contour: 4.0.2 + d3-delaunay: 6.0.4 + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-dsv: 3.0.1 + d3-ease: 3.0.1 + d3-fetch: 3.0.1 + d3-force: 3.0.0 + d3-format: 3.1.0 + d3-geo: 3.1.1 + d3-hierarchy: 3.1.2 + d3-interpolate: 3.0.1 + d3-path: 3.1.0 + d3-polygon: 3.0.1 + d3-quadtree: 3.0.1 + d3-random: 3.0.1 + d3-scale: 4.0.2 + d3-scale-chromatic: 3.1.0 + d3-selection: 3.0.0 + d3-shape: 3.2.0 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + d3-timer: 3.0.1 + d3-transition: 3.0.1(d3-selection@3.0.0) + d3-zoom: 3.0.0 + + dagre-d3-es@7.0.10: + dependencies: + d3: 7.9.0 + lodash-es: 4.17.21 + + damerau-levenshtein@1.0.8: {} + + data-urls@3.0.2: + dependencies: + abab: 2.0.6 + whatwg-mimetype: 3.0.0 + whatwg-url: 11.0.0 + + data-view-buffer@1.0.1: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + data-view-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + data-view-byte-offset@1.0.0: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + dayjs@1.11.13: {} + + debug@2.6.9: + dependencies: + ms: 2.0.0 + + debug@3.2.7: + dependencies: + ms: 2.1.3 + + debug@4.3.4: + dependencies: + ms: 2.1.2 + + debug@4.3.7: + dependencies: + ms: 2.1.3 + + decimal.js@10.4.3: {} + + decode-named-character-reference@1.0.2: + dependencies: + character-entities: 2.0.2 + + decompress-response@6.0.0: + dependencies: + mimic-response: 3.1.0 + + dedent@0.7.0: {} + + dedent@1.5.3: {} + + deep-eql@5.0.2: {} + + deep-equal@2.2.3: + dependencies: + array-buffer-byte-length: 1.0.1 + call-bind: 1.0.7 + es-get-iterator: 1.1.3 + get-intrinsic: 1.2.4 + is-arguments: 1.1.1 + is-array-buffer: 3.0.4 + is-date-object: 1.0.5 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.3 + isarray: 2.0.5 + object-is: 1.1.6 + object-keys: 1.1.1 + object.assign: 4.1.5 + regexp.prototype.flags: 1.5.3 + side-channel: 1.0.6 + which-boxed-primitive: 1.0.2 + which-collection: 1.0.2 + which-typed-array: 1.1.15 + + deep-is@0.1.4: {} + + deepmerge@4.3.1: {} + + defer-to-connect@2.0.1: {} + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + gopd: 1.0.1 + + define-lazy-prop@2.0.0: {} + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + delaunator@5.0.1: + dependencies: + robust-predicates: 3.0.2 + + delayed-stream@1.0.0: {} + + depd@2.0.0: {} + + dequal@2.0.3: {} + + des.js@1.1.0: + dependencies: + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + + destroy@1.2.0: {} + + detect-libc@1.0.3: {} + + detect-libc@2.0.3: {} + + detect-newline@3.1.0: {} + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + + didyoumean@1.2.2: {} + + diff-sequences@29.6.3: {} + + diff@4.0.2: {} + + diff@5.2.0: {} + + diffie-hellman@5.0.3: + dependencies: + bn.js: 4.12.0 + miller-rabin: 4.0.1 + randombytes: 2.1.0 + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + dlv@1.1.3: {} + + doctrine@2.1.0: + dependencies: + esutils: 2.0.3 + + doctrine@3.0.0: + dependencies: + esutils: 2.0.3 + + dom-accessibility-api@0.5.16: {} + + dom-accessibility-api@0.6.3: {} + + dom-converter@0.2.0: + dependencies: + utila: 0.4.0 + + dom-serializer@1.4.1: + dependencies: + domelementtype: 2.3.0 + domhandler: 4.3.1 + entities: 2.2.0 + + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domain-browser@4.23.0: {} + + domelementtype@2.3.0: {} + + domexception@4.0.0: + dependencies: + webidl-conversions: 7.0.0 + + domhandler@4.3.1: + dependencies: + domelementtype: 2.3.0 + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + dompurify@3.1.7: {} + + domutils@2.8.0: + dependencies: + dom-serializer: 1.4.1 + domelementtype: 2.3.0 + domhandler: 4.3.1 + + domutils@3.1.0: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + + dot-case@3.0.4: + dependencies: + no-case: 3.0.4 + tslib: 2.8.0 + + echarts-for-react@3.0.2(echarts@5.5.1)(react@18.2.0): + dependencies: + echarts: 5.5.1 + fast-deep-equal: 3.1.3 + react: 18.2.0 + size-sensor: 1.0.2 + + echarts@5.5.1: + dependencies: + tslib: 2.3.0 + zrender: 5.6.0 + + ee-first@1.1.1: {} + + electron-to-chromium@1.5.41: {} + + elkjs@0.8.2: {} + + elliptic@6.5.7: + dependencies: + bn.js: 4.12.0 + brorand: 1.1.0 + hash.js: 1.1.7 + hmac-drbg: 1.0.1 + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 + + emittery@0.13.1: {} + + emoji-mart@5.6.0: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + emojis-list@3.0.0: {} + + encodeurl@1.0.2: {} + + encodeurl@2.0.0: {} + + end-of-stream@1.4.4: + dependencies: + once: 1.4.0 + + endent@2.1.0: + dependencies: + dedent: 0.7.0 + fast-json-parse: 1.0.3 + objectorarray: 1.0.5 + + enhanced-resolve@5.17.1: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.1 + + entities@2.2.0: {} + + entities@4.5.0: {} + + env-paths@2.2.1: {} + + error-ex@1.3.2: + dependencies: + is-arrayish: 0.2.1 + + error-stack-parser@2.1.4: + dependencies: + stackframe: 1.3.4 + + es-abstract@1.23.3: + dependencies: + array-buffer-byte-length: 1.0.1 + arraybuffer.prototype.slice: 1.0.3 + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + data-view-buffer: 1.0.1 + data-view-byte-length: 1.0.1 + data-view-byte-offset: 1.0.0 + es-define-property: 1.0.0 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-set-tostringtag: 2.0.3 + es-to-primitive: 1.2.1 + function.prototype.name: 1.1.6 + get-intrinsic: 1.2.4 + get-symbol-description: 1.0.2 + globalthis: 1.0.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + internal-slot: 1.0.7 + is-array-buffer: 3.0.4 + is-callable: 1.2.7 + is-data-view: 1.0.1 + is-negative-zero: 2.0.3 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.3 + is-string: 1.0.7 + is-typed-array: 1.1.13 + is-weakref: 1.0.2 + object-inspect: 1.13.2 + object-keys: 1.1.1 + object.assign: 4.1.5 + regexp.prototype.flags: 1.5.3 + safe-array-concat: 1.1.2 + safe-regex-test: 1.0.3 + string.prototype.trim: 1.2.9 + string.prototype.trimend: 1.0.8 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.2 + typed-array-byte-length: 1.0.1 + typed-array-byte-offset: 1.0.2 + typed-array-length: 1.0.6 + unbox-primitive: 1.0.2 + which-typed-array: 1.1.15 + + es-define-property@1.0.0: + dependencies: + get-intrinsic: 1.2.4 + + es-errors@1.3.0: {} + + es-get-iterator@1.1.3: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + has-symbols: 1.0.3 + is-arguments: 1.1.1 + is-map: 2.0.3 + is-set: 2.0.3 + is-string: 1.0.7 + isarray: 2.0.5 + stop-iteration-iterator: 1.0.0 + + es-iterator-helpers@1.1.0: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-set-tostringtag: 2.0.3 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + globalthis: 1.0.4 + has-property-descriptors: 1.0.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + internal-slot: 1.0.7 + iterator.prototype: 1.1.3 + safe-array-concat: 1.1.2 + + es-module-lexer@1.5.4: {} + + es-object-atoms@1.0.0: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.0.3: + dependencies: + get-intrinsic: 1.2.4 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + es-shim-unscopables@1.0.2: + dependencies: + hasown: 2.0.2 + + es-to-primitive@1.2.1: + dependencies: + is-callable: 1.2.7 + is-date-object: 1.0.5 + is-symbol: 1.0.4 + + esbuild-register@3.6.0(esbuild@0.23.1): + dependencies: + debug: 4.3.7 + esbuild: 0.23.1 + transitivePeerDependencies: + - supports-color + + esbuild@0.23.1: + optionalDependencies: + '@esbuild/aix-ppc64': 0.23.1 + '@esbuild/android-arm': 0.23.1 + '@esbuild/android-arm64': 0.23.1 + '@esbuild/android-x64': 0.23.1 + '@esbuild/darwin-arm64': 0.23.1 + '@esbuild/darwin-x64': 0.23.1 + '@esbuild/freebsd-arm64': 0.23.1 + '@esbuild/freebsd-x64': 0.23.1 + '@esbuild/linux-arm': 0.23.1 + '@esbuild/linux-arm64': 0.23.1 + '@esbuild/linux-ia32': 0.23.1 + '@esbuild/linux-loong64': 0.23.1 + '@esbuild/linux-mips64el': 0.23.1 + '@esbuild/linux-ppc64': 0.23.1 + '@esbuild/linux-riscv64': 0.23.1 + '@esbuild/linux-s390x': 0.23.1 + '@esbuild/linux-x64': 0.23.1 + '@esbuild/netbsd-x64': 0.23.1 + '@esbuild/openbsd-arm64': 0.23.1 + '@esbuild/openbsd-x64': 0.23.1 + '@esbuild/sunos-x64': 0.23.1 + '@esbuild/win32-arm64': 0.23.1 + '@esbuild/win32-ia32': 0.23.1 + '@esbuild/win32-x64': 0.23.1 + + escalade@3.2.0: {} + + escape-html@1.0.3: {} + + escape-string-regexp@1.0.5: {} + + escape-string-regexp@2.0.0: {} + + escape-string-regexp@4.0.0: {} + + escape-string-regexp@5.0.0: {} + + escodegen@2.1.0: + dependencies: + esprima: 4.0.1 + estraverse: 5.3.0 + esutils: 2.0.3 + optionalDependencies: + source-map: 0.6.1 + + eslint-compat-utils@0.5.1(eslint@8.57.1): + dependencies: + eslint: 8.57.1 + semver: 7.6.3 + + eslint-config-next@14.2.15(eslint@8.57.1)(typescript@4.9.5): + dependencies: + '@next/eslint-plugin-next': 14.2.15 + '@rushstack/eslint-patch': 1.10.4 + '@typescript-eslint/eslint-plugin': 8.10.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/parser': 8.10.0(eslint@8.57.1)(typescript@4.9.5) + eslint: 8.57.1 + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1))(eslint@8.57.1) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) + eslint-plugin-jsx-a11y: 6.10.0(eslint@8.57.1) + eslint-plugin-react: 7.37.1(eslint@8.57.1) + eslint-plugin-react-hooks: 5.0.0-canary-7118f5dd7-20230705(eslint@8.57.1) + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - eslint-import-resolver-webpack + - eslint-plugin-import-x + - supports-color + + eslint-import-resolver-node@0.3.9: + dependencies: + debug: 3.2.7 + is-core-module: 2.15.1 + resolve: 1.22.8 + transitivePeerDependencies: + - supports-color + + eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1))(eslint@8.57.1): + dependencies: + '@nolyfill/is-core-module': 1.0.39 + debug: 4.3.7 + enhanced-resolve: 5.17.1 + eslint: 8.57.1 + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + fast-glob: 3.3.2 + get-tsconfig: 4.8.1 + is-bun-module: 1.2.1 + is-glob: 4.0.3 + optionalDependencies: + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) + transitivePeerDependencies: + - '@typescript-eslint/parser' + - eslint-import-resolver-node + - eslint-import-resolver-webpack + - supports-color + + eslint-module-utils@2.12.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@4.9.5) + eslint: 8.57.1 + eslint-import-resolver-node: 0.3.9 + transitivePeerDependencies: + - supports-color + + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 8.10.0(eslint@8.57.1)(typescript@4.9.5) + eslint: 8.57.1 + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1))(eslint@8.57.1) + transitivePeerDependencies: + - supports-color + + eslint-plugin-antfu@0.36.0(eslint@8.57.1)(typescript@4.9.5): + dependencies: + '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@4.9.5) + transitivePeerDependencies: + - eslint + - supports-color + - typescript + + eslint-plugin-es@4.1.0(eslint@8.57.1): + dependencies: + eslint: 8.57.1 + eslint-utils: 2.1.0 + regexpp: 3.2.0 + + eslint-plugin-eslint-comments@3.2.0(eslint@8.57.1): + dependencies: + escape-string-regexp: 1.0.5 + eslint: 8.57.1 + ignore: 5.3.2 + + eslint-plugin-html@7.1.0: + dependencies: + htmlparser2: 8.0.2 + + eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1): + dependencies: + '@rtsao/scc': 1.1.0 + array-includes: 3.1.8 + array.prototype.findlastindex: 1.2.5 + array.prototype.flat: 1.3.2 + array.prototype.flatmap: 1.3.2 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 8.57.1 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.12.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1) + hasown: 2.0.2 + is-core-module: 2.15.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.0 + semver: 6.3.1 + string.prototype.trimend: 1.0.8 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@4.9.5) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + + eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1): + dependencies: + '@rtsao/scc': 1.1.0 + array-includes: 3.1.8 + array.prototype.findlastindex: 1.2.5 + array.prototype.flat: 1.3.2 + array.prototype.flatmap: 1.3.2 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 8.57.1 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + hasown: 2.0.2 + is-core-module: 2.15.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.0 + semver: 6.3.1 + string.prototype.trimend: 1.0.8 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 8.10.0(eslint@8.57.1)(typescript@4.9.5) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + + eslint-plugin-jest@27.9.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(jest@29.7.0(@types/node@18.15.0)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)))(typescript@4.9.5): + dependencies: + '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@4.9.5) + eslint: 8.57.1 + optionalDependencies: + '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) + jest: 29.7.0(@types/node@18.15.0)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)) + transitivePeerDependencies: + - supports-color + - typescript + + eslint-plugin-jsonc@2.16.0(eslint@8.57.1): + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) + eslint: 8.57.1 + eslint-compat-utils: 0.5.1(eslint@8.57.1) + espree: 9.6.1 + graphemer: 1.4.0 + jsonc-eslint-parser: 2.4.0 + natural-compare: 1.4.0 + synckit: 0.6.2 + + eslint-plugin-jsx-a11y@6.10.0(eslint@8.57.1): + dependencies: + aria-query: 5.1.3 + array-includes: 3.1.8 + array.prototype.flatmap: 1.3.2 + ast-types-flow: 0.0.8 + axe-core: 4.10.1 + axobject-query: 4.1.0 + damerau-levenshtein: 1.0.8 + emoji-regex: 9.2.2 + es-iterator-helpers: 1.1.0 + eslint: 8.57.1 + hasown: 2.0.2 + jsx-ast-utils: 3.3.5 + language-tags: 1.0.9 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + safe-regex-test: 1.0.3 + string.prototype.includes: 2.0.1 + + eslint-plugin-markdown@3.0.1(eslint@8.57.1): + dependencies: + eslint: 8.57.1 + mdast-util-from-markdown: 0.8.5 + transitivePeerDependencies: + - supports-color + + eslint-plugin-n@15.7.0(eslint@8.57.1): + dependencies: + builtins: 5.1.0 + eslint: 8.57.1 + eslint-plugin-es: 4.1.0(eslint@8.57.1) + eslint-utils: 3.0.0(eslint@8.57.1) + ignore: 5.3.2 + is-core-module: 2.15.1 + minimatch: 3.1.2 + resolve: 1.22.8 + semver: 7.6.3 + + eslint-plugin-no-only-tests@3.3.0: {} + + eslint-plugin-promise@6.6.0(eslint@8.57.1): + dependencies: + eslint: 8.57.1 + + eslint-plugin-react-hooks@5.0.0-canary-7118f5dd7-20230705(eslint@8.57.1): + dependencies: + eslint: 8.57.1 + + eslint-plugin-react@7.37.1(eslint@8.57.1): + dependencies: + array-includes: 3.1.8 + array.prototype.findlast: 1.2.5 + array.prototype.flatmap: 1.3.2 + array.prototype.tosorted: 1.1.4 + doctrine: 2.1.0 + es-iterator-helpers: 1.1.0 + eslint: 8.57.1 + estraverse: 5.3.0 + hasown: 2.0.2 + jsx-ast-utils: 3.3.5 + minimatch: 3.1.2 + object.entries: 1.1.8 + object.fromentries: 2.0.8 + object.values: 1.2.0 + prop-types: 15.8.1 + resolve: 2.0.0-next.5 + semver: 6.3.1 + string.prototype.matchall: 4.0.11 + string.prototype.repeat: 1.0.0 + + eslint-plugin-storybook@0.9.0(eslint@8.57.1)(typescript@4.9.5): + dependencies: + '@storybook/csf': 0.0.1 + '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@4.9.5) + eslint: 8.57.1 + requireindex: 1.2.0 + ts-dedent: 2.2.0 + transitivePeerDependencies: + - supports-color + - typescript + + eslint-plugin-unicorn@45.0.2(eslint@8.57.1): + dependencies: + '@babel/helper-validator-identifier': 7.25.7 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) + ci-info: 3.9.0 + clean-regexp: 1.0.0 + eslint: 8.57.1 + esquery: 1.6.0 + indent-string: 4.0.0 + is-builtin-module: 3.2.1 + jsesc: 3.0.2 + lodash: 4.17.21 + pluralize: 8.0.0 + read-pkg-up: 7.0.1 + regexp-tree: 0.1.27 + regjsparser: 0.9.1 + safe-regex: 2.1.1 + semver: 7.6.3 + strip-indent: 3.0.0 + + eslint-plugin-unused-imports@2.0.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1): + dependencies: + eslint: 8.57.1 + eslint-rule-composer: 0.3.0 + optionalDependencies: + '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) + + eslint-plugin-vue@9.29.1(eslint@8.57.1): + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) + eslint: 8.57.1 + globals: 13.24.0 + natural-compare: 1.4.0 + nth-check: 2.1.1 + postcss-selector-parser: 6.1.2 + semver: 7.6.3 + vue-eslint-parser: 9.4.3(eslint@8.57.1) + xml-name-validator: 4.0.0 + transitivePeerDependencies: + - supports-color + + eslint-plugin-yml@1.14.0(eslint@8.57.1): + dependencies: + debug: 4.3.7 + eslint: 8.57.1 + eslint-compat-utils: 0.5.1(eslint@8.57.1) + lodash: 4.17.21 + natural-compare: 1.4.0 + yaml-eslint-parser: 1.2.3 + transitivePeerDependencies: + - supports-color + + eslint-rule-composer@0.3.0: {} + + eslint-scope@5.1.1: + dependencies: + esrecurse: 4.3.0 + estraverse: 4.3.0 + + eslint-scope@7.2.2: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-utils@2.1.0: + dependencies: + eslint-visitor-keys: 1.3.0 + + eslint-utils@3.0.0(eslint@8.57.1): + dependencies: + eslint: 8.57.1 + eslint-visitor-keys: 2.1.0 + + eslint-visitor-keys@1.3.0: {} + + eslint-visitor-keys@2.1.0: {} + + eslint-visitor-keys@3.4.3: {} + + eslint@8.57.1: + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) + '@eslint-community/regexpp': 4.11.1 + '@eslint/eslintrc': 2.1.4 + '@eslint/js': 8.57.1 + '@humanwhocodes/config-array': 0.13.0 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + '@ungap/structured-clone': 1.2.0 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.7 + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + glob-parent: 6.0.2 + globals: 13.24.0 + graphemer: 1.4.0 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-yaml: 4.1.0 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + strip-ansi: 6.0.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + + espree@9.6.1: + dependencies: + acorn: 8.13.0 + acorn-jsx: 5.3.2(acorn@8.13.0) + eslint-visitor-keys: 3.4.3 + + esprima@4.0.1: {} + + esquery@1.6.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@4.3.0: {} + + estraverse@5.3.0: {} + + estree-util-attach-comments@2.1.1: + dependencies: + '@types/estree': 1.0.6 + + estree-util-build-jsx@2.2.2: + dependencies: + '@types/estree-jsx': 1.0.5 + estree-util-is-identifier-name: 2.1.0 + estree-walker: 3.0.3 + + estree-util-is-identifier-name@2.1.0: {} + + estree-util-to-js@1.2.0: + dependencies: + '@types/estree-jsx': 1.0.5 + astring: 1.9.0 + source-map: 0.7.4 + + estree-util-visit@1.2.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/unist': 2.0.11 + + estree-walker@2.0.2: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.6 + + esutils@2.0.3: {} + + etag@1.8.1: {} + + event-target-shim@5.0.1: {} + + eventemitter3@5.0.1: {} + + events@3.3.0: {} + + evp_bytestokey@1.0.3: + dependencies: + md5.js: 1.3.5 + safe-buffer: 5.2.1 + + execa@5.1.1: + dependencies: + cross-spawn: 7.0.3 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + + execa@7.2.0: + dependencies: + cross-spawn: 7.0.3 + get-stream: 6.0.1 + human-signals: 4.3.1 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.3.0 + onetime: 6.0.0 + signal-exit: 3.0.7 + strip-final-newline: 3.0.0 + + exit@0.1.2: {} + + expect@29.7.0: + dependencies: + '@jest/expect-utils': 29.7.0 + jest-get-type: 29.6.3 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + + express@4.21.1: + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.3 + content-disposition: 0.5.4 + content-type: 1.0.5 + cookie: 0.7.1 + cookie-signature: 1.0.6 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.3.1 + fresh: 0.5.2 + http-errors: 2.0.0 + merge-descriptors: 1.0.3 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.10 + proxy-addr: 2.0.7 + qs: 6.13.0 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.19.0 + serve-static: 1.16.2 + setprototypeof: 1.2.0 + statuses: 2.0.1 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + extend@3.0.2: {} + + fast-deep-equal@3.1.3: {} + + fast-glob@3.3.2: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-parse@1.0.3: {} + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fast-uri@3.0.3: {} + + fastq@1.17.1: + dependencies: + reusify: 1.0.4 + + fault@1.0.4: + dependencies: + format: 0.2.2 + + fb-watchman@2.0.2: + dependencies: + bser: 2.1.1 + + file-entry-cache@6.0.1: + dependencies: + flat-cache: 3.2.0 + + filesize@10.1.6: {} + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + filter-obj@2.0.2: {} + + finalhandler@1.3.1: + dependencies: + debug: 2.6.9 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.1 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + find-cache-dir@3.3.2: + dependencies: + commondir: 1.0.1 + make-dir: 3.1.0 + pkg-dir: 4.2.0 + + find-cache-dir@4.0.0: + dependencies: + common-path-prefix: 3.0.0 + pkg-dir: 7.0.0 + + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + find-up@6.3.0: + dependencies: + locate-path: 7.2.0 + path-exists: 5.0.0 + + flat-cache@3.2.0: + dependencies: + flatted: 3.3.1 + keyv: 4.5.4 + rimraf: 3.0.2 + + flatted@3.3.1: {} + + for-each@0.3.3: + dependencies: + is-callable: 1.2.7 + + foreground-child@3.3.0: + dependencies: + cross-spawn: 7.0.3 + signal-exit: 4.1.0 + + fork-ts-checker-webpack-plugin@8.0.0(typescript@4.9.5)(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3)): + dependencies: + '@babel/code-frame': 7.25.7 + chalk: 4.1.2 + chokidar: 3.6.0 + cosmiconfig: 7.1.0 + deepmerge: 4.3.1 + fs-extra: 10.1.0 + memfs: 3.5.3 + minimatch: 3.1.2 + node-abort-controller: 3.1.1 + schema-utils: 3.3.0 + semver: 7.6.3 + tapable: 2.2.1 + typescript: 4.9.5 + webpack: 5.95.0(esbuild@0.23.1)(uglify-js@3.19.3) + + form-data@4.0.1: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + + format@0.2.2: {} + + forwarded@0.2.0: {} + + fraction.js@4.3.7: {} + + fresh@0.5.2: {} + + fs-extra@10.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + + fs-extra@11.2.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + + fs-monkey@1.0.6: {} + + fs.realpath@1.0.0: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + function.prototype.name@1.1.6: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + functions-have-names: 1.2.3 + + functions-have-names@1.2.3: {} + + gensync@1.0.0-beta.2: {} + + get-caller-file@2.0.5: {} + + get-intrinsic@1.2.4: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + + get-package-type@0.1.0: {} + + get-stream@5.2.0: + dependencies: + pump: 3.0.2 + + get-stream@6.0.1: {} + + get-symbol-description@1.0.2: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + + get-tsconfig@4.8.1: + dependencies: + resolve-pkg-maps: 1.0.0 + + github-slugger@2.0.0: {} + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + glob-to-regexp@0.4.1: {} + + glob@10.3.10: + dependencies: + foreground-child: 3.3.0 + jackspeak: 2.3.6 + minimatch: 9.0.5 + minipass: 7.1.2 + path-scurry: 1.11.1 + + glob@10.4.5: + dependencies: + foreground-child: 3.3.0 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + globals@11.12.0: {} + + globals@13.24.0: + dependencies: + type-fest: 0.20.2 + + globalthis@1.0.4: + dependencies: + define-properties: 1.2.1 + gopd: 1.0.1 + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.2 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 + + gopd@1.0.1: + dependencies: + get-intrinsic: 1.2.4 + + got@11.8.6: + dependencies: + '@sindresorhus/is': 4.6.0 + '@szmarczak/http-timer': 4.0.6 + '@types/cacheable-request': 6.0.3 + '@types/responselike': 1.0.3 + cacheable-lookup: 5.0.4 + cacheable-request: 7.0.4 + decompress-response: 6.0.0 + http2-wrapper: 1.0.3 + lowercase-keys: 2.0.0 + p-cancelable: 2.1.1 + responselike: 2.0.1 + + graceful-fs@4.2.11: {} + + graphemer@1.4.0: {} + + has-bigints@1.0.2: {} + + has-flag@3.0.0: {} + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.0 + + has-proto@1.0.3: {} + + has-symbols@1.0.3: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.0.3 + + hash-base@3.0.4: + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + + hash-base@3.1.0: + dependencies: + inherits: 2.0.4 + readable-stream: 3.6.2 + safe-buffer: 5.2.1 + + hash.js@1.1.7: + dependencies: + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + hast-util-from-dom@4.2.0: + dependencies: + hastscript: 7.2.0 + web-namespaces: 2.0.1 + + hast-util-from-html-isomorphic@1.0.0: + dependencies: + '@types/hast': 2.3.10 + hast-util-from-dom: 4.2.0 + hast-util-from-html: 1.0.2 + unist-util-remove-position: 4.0.2 + + hast-util-from-html@1.0.2: + dependencies: + '@types/hast': 2.3.10 + hast-util-from-parse5: 7.1.2 + parse5: 7.2.0 + vfile: 5.3.7 + vfile-message: 3.1.4 + + hast-util-from-parse5@7.1.2: + dependencies: + '@types/hast': 2.3.10 + '@types/unist': 2.0.11 + hastscript: 7.2.0 + property-information: 6.5.0 + vfile: 5.3.7 + vfile-location: 4.1.0 + web-namespaces: 2.0.1 + + hast-util-from-parse5@8.0.1: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + devlop: 1.1.0 + hastscript: 8.0.0 + property-information: 6.5.0 + vfile: 6.0.3 + vfile-location: 5.0.3 + web-namespaces: 2.0.1 + + hast-util-heading-rank@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast-util-is-element@2.1.3: + dependencies: + '@types/hast': 2.3.10 + '@types/unist': 2.0.11 + + hast-util-is-element@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast-util-parse-selector@2.2.5: {} + + hast-util-parse-selector@3.1.1: + dependencies: + '@types/hast': 2.3.10 + + hast-util-parse-selector@4.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast-util-raw@9.0.4: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + '@ungap/structured-clone': 1.2.0 + hast-util-from-parse5: 8.0.1 + hast-util-to-parse5: 8.0.0 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.0 + parse5: 7.2.0 + unist-util-position: 5.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + web-namespaces: 2.0.1 + zwitch: 2.0.4 + + hast-util-to-estree@2.3.3: + dependencies: + '@types/estree': 1.0.6 + '@types/estree-jsx': 1.0.5 + '@types/hast': 2.3.10 + '@types/unist': 2.0.11 + comma-separated-tokens: 2.0.3 + estree-util-attach-comments: 2.1.1 + estree-util-is-identifier-name: 2.1.0 + hast-util-whitespace: 2.0.1 + mdast-util-mdx-expression: 1.3.2 + mdast-util-mdxjs-esm: 1.3.1 + property-information: 6.5.0 + space-separated-tokens: 2.0.2 + style-to-object: 0.4.4 + unist-util-position: 4.0.4 + zwitch: 2.0.4 + transitivePeerDependencies: + - supports-color + + hast-util-to-parse5@8.0.0: + dependencies: + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + property-information: 6.5.0 + space-separated-tokens: 2.0.2 + web-namespaces: 2.0.1 + zwitch: 2.0.4 + + hast-util-to-string@3.0.1: + dependencies: + '@types/hast': 3.0.4 + + hast-util-to-text@3.1.2: + dependencies: + '@types/hast': 2.3.10 + '@types/unist': 2.0.11 + hast-util-is-element: 2.1.3 + unist-util-find-after: 4.0.1 + + hast-util-whitespace@2.0.1: {} + + hastscript@6.0.0: + dependencies: + '@types/hast': 2.3.10 + comma-separated-tokens: 1.0.8 + hast-util-parse-selector: 2.2.5 + property-information: 5.6.0 + space-separated-tokens: 1.1.5 + + hastscript@7.2.0: + dependencies: + '@types/hast': 2.3.10 + comma-separated-tokens: 2.0.3 + hast-util-parse-selector: 3.1.1 + property-information: 6.5.0 + space-separated-tokens: 2.0.2 + + hastscript@8.0.0: + dependencies: + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + hast-util-parse-selector: 4.0.0 + property-information: 6.5.0 + space-separated-tokens: 2.0.2 + + he@1.2.0: {} + + highlight.js@10.7.3: {} + + highlightjs-vue@1.0.0: {} + + hmac-drbg@1.0.1: + dependencies: + hash.js: 1.1.7 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 + + hoist-non-react-statics@3.3.2: + dependencies: + react-is: 16.13.1 + + hosted-git-info@2.8.9: {} + + html-encoding-sniffer@3.0.0: + dependencies: + whatwg-encoding: 2.0.0 + + html-entities@2.5.2: {} + + html-escaper@2.0.2: {} + + html-minifier-terser@6.1.0: + dependencies: + camel-case: 4.1.2 + clean-css: 5.3.3 + commander: 8.3.0 + he: 1.2.0 + param-case: 3.0.4 + relateurl: 0.2.7 + terser: 5.36.0 + + html-parse-stringify@3.0.1: + dependencies: + void-elements: 3.1.0 + + html-tags@3.3.1: {} + + html-void-elements@3.0.0: {} + + html-webpack-plugin@5.6.2(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3)): + dependencies: + '@types/html-minifier-terser': 6.1.0 + html-minifier-terser: 6.1.0 + lodash: 4.17.21 + pretty-error: 4.0.0 + tapable: 2.2.1 + optionalDependencies: + webpack: 5.95.0(esbuild@0.23.1)(uglify-js@3.19.3) + + htmlparser2@6.1.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 4.3.1 + domutils: 2.8.0 + entities: 2.2.0 + + htmlparser2@8.0.2: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.1.0 + entities: 4.5.0 + + http-cache-semantics@4.1.1: {} + + http-errors@2.0.0: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.1 + toidentifier: 1.0.1 + + http-proxy-agent@5.0.0: + dependencies: + '@tootallnate/once': 2.0.0 + agent-base: 6.0.2 + debug: 4.3.7 + transitivePeerDependencies: + - supports-color + + http2-wrapper@1.0.3: + dependencies: + quick-lru: 5.1.1 + resolve-alpn: 1.2.1 + + https-browserify@1.0.0: {} + + https-proxy-agent@5.0.1: + dependencies: + agent-base: 6.0.2 + debug: 4.3.7 + transitivePeerDependencies: + - supports-color + + human-signals@2.1.0: {} + + human-signals@4.3.1: {} + + husky@8.0.3: {} + + i18next-resources-to-backend@1.2.1: + dependencies: + '@babel/runtime': 7.25.7 + + i18next@22.5.1: + dependencies: + '@babel/runtime': 7.25.7 + + iconv-lite@0.4.24: + dependencies: + safer-buffer: 2.1.2 + + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + + icss-utils@5.1.0(postcss@8.4.47): + dependencies: + postcss: 8.4.47 + + ieee754@1.2.1: {} + + ignore@5.3.2: {} + + image-size@1.1.1: + dependencies: + queue: 6.0.2 + + immediate@3.0.6: {} + + immer@9.0.21: {} + + immutable@4.3.7: {} + + import-fresh@3.3.0: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + import-local@3.2.0: + dependencies: + pkg-dir: 4.2.0 + resolve-cwd: 3.0.0 + + imurmurhash@0.1.4: {} + + indent-string@4.0.0: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + inline-style-parser@0.1.1: {} + + internal-slot@1.0.7: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.0.6 + + internmap@1.0.1: {} + + internmap@2.0.3: {} + + intersection-observer@0.12.2: {} + + ipaddr.js@1.9.1: {} + + is-absolute-url@4.0.1: {} + + is-alphabetical@1.0.4: {} + + is-alphabetical@2.0.1: {} + + is-alphanumerical@1.0.4: + dependencies: + is-alphabetical: 1.0.4 + is-decimal: 1.0.4 + + is-alphanumerical@2.0.1: + dependencies: + is-alphabetical: 2.0.1 + is-decimal: 2.0.1 + + is-arguments@1.1.1: + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + + is-array-buffer@3.0.4: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + + is-arrayish@0.2.1: {} + + is-arrayish@0.3.2: {} + + is-async-function@2.0.0: + dependencies: + has-tostringtag: 1.0.2 + + is-bigint@1.0.4: + dependencies: + has-bigints: 1.0.2 + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-boolean-object@1.1.2: + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + + is-buffer@2.0.5: {} + + is-builtin-module@3.2.1: + dependencies: + builtin-modules: 3.3.0 + + is-bun-module@1.2.1: + dependencies: + semver: 7.6.3 + + is-callable@1.2.7: {} + + is-core-module@2.15.1: + dependencies: + hasown: 2.0.2 + + is-data-view@1.0.1: + dependencies: + is-typed-array: 1.1.13 + + is-date-object@1.0.5: + dependencies: + has-tostringtag: 1.0.2 + + is-decimal@1.0.4: {} + + is-decimal@2.0.1: {} + + is-docker@2.2.1: {} + + is-extglob@2.1.1: {} + + is-finalizationregistry@1.0.2: + dependencies: + call-bind: 1.0.7 + + is-fullwidth-code-point@3.0.0: {} + + is-fullwidth-code-point@4.0.0: {} + + is-generator-fn@2.1.0: {} + + is-generator-function@1.0.10: + dependencies: + has-tostringtag: 1.0.2 + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-hexadecimal@1.0.4: {} + + is-hexadecimal@2.0.1: {} + + is-map@2.0.3: {} + + is-nan@1.3.2: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + + is-negative-zero@2.0.3: {} + + is-number-object@1.0.7: + dependencies: + has-tostringtag: 1.0.2 + + is-number@7.0.0: {} + + is-path-inside@3.0.3: {} + + is-plain-obj@4.1.0: {} + + is-plain-object@5.0.0: {} + + is-potential-custom-element-name@1.0.1: {} + + is-reference@3.0.2: + dependencies: + '@types/estree': 1.0.6 + + is-regex@1.1.4: + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + + is-set@2.0.3: {} + + is-shared-array-buffer@1.0.3: + dependencies: + call-bind: 1.0.7 + + is-stream@2.0.1: {} + + is-stream@3.0.0: {} + + is-string@1.0.7: + dependencies: + has-tostringtag: 1.0.2 + + is-symbol@1.0.4: + dependencies: + has-symbols: 1.0.3 + + is-typed-array@1.1.13: + dependencies: + which-typed-array: 1.1.15 + + is-weakmap@2.0.2: {} + + is-weakref@1.0.2: + dependencies: + call-bind: 1.0.7 + + is-weakset@2.0.3: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + + is-wsl@2.2.0: + dependencies: + is-docker: 2.2.1 + + isarray@1.0.0: {} + + isarray@2.0.5: {} + + isexe@2.0.0: {} + + isomorphic.js@0.2.5: {} + + istanbul-lib-coverage@3.2.2: {} + + istanbul-lib-instrument@5.2.1: + dependencies: + '@babel/core': 7.25.8 + '@babel/parser': 7.25.8 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + istanbul-lib-instrument@6.0.3: + dependencies: + '@babel/core': 7.25.8 + '@babel/parser': 7.25.8 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 7.6.3 + transitivePeerDependencies: + - supports-color + + istanbul-lib-report@3.0.1: + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + + istanbul-lib-source-maps@4.0.1: + dependencies: + debug: 4.3.7 + istanbul-lib-coverage: 3.2.2 + source-map: 0.6.1 + transitivePeerDependencies: + - supports-color + + istanbul-reports@3.1.7: + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + + iterator.prototype@1.1.3: + dependencies: + define-properties: 1.2.1 + get-intrinsic: 1.2.4 + has-symbols: 1.0.3 + reflect.getprototypeof: 1.0.6 + set-function-name: 2.0.2 + + jackspeak@2.3.6: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + jest-changed-files@29.7.0: + dependencies: + execa: 5.1.1 + jest-util: 29.7.0 + p-limit: 3.1.0 + + jest-circus@29.7.0: + dependencies: + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 18.15.0 + chalk: 4.1.2 + co: 4.6.0 + dedent: 1.5.3 + is-generator-fn: 2.1.0 + jest-each: 29.7.0 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + p-limit: 3.1.0 + pretty-format: 29.7.0 + pure-rand: 6.1.0 + slash: 3.0.0 + stack-utils: 2.0.6 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + + jest-cli@29.7.0(@types/node@18.15.0)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)): + dependencies: + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)) + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + chalk: 4.1.2 + create-jest: 29.7.0(@types/node@18.15.0)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)) + exit: 0.1.2 + import-local: 3.2.0 + jest-config: 29.7.0(@types/node@18.15.0)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)) + jest-util: 29.7.0 + jest-validate: 29.7.0 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + + jest-config@29.7.0(@types/node@18.15.0)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)): + dependencies: + '@babel/core': 7.25.8 + '@jest/test-sequencer': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.25.8) + chalk: 4.1.2 + ci-info: 3.9.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.7.0 + jest-environment-node: 29.7.0 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-runner: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + micromatch: 4.0.8 + parse-json: 5.2.0 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 + optionalDependencies: + '@types/node': 18.15.0 + ts-node: 10.9.2(@types/node@18.15.0)(typescript@4.9.5) + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + + jest-diff@29.7.0: + dependencies: + chalk: 4.1.2 + diff-sequences: 29.6.3 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + jest-docblock@29.7.0: + dependencies: + detect-newline: 3.1.0 + + jest-each@29.7.0: + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + jest-get-type: 29.6.3 + jest-util: 29.7.0 + pretty-format: 29.7.0 + + jest-environment-jsdom@29.7.0: + dependencies: + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/jsdom': 20.0.1 + '@types/node': 18.15.0 + jest-mock: 29.7.0 + jest-util: 29.7.0 + jsdom: 20.0.3 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + jest-environment-node@29.7.0: + dependencies: + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 18.15.0 + jest-mock: 29.7.0 + jest-util: 29.7.0 + + jest-get-type@29.6.3: {} + + jest-haste-map@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/graceful-fs': 4.1.9 + '@types/node': 18.15.0 + anymatch: 3.1.3 + fb-watchman: 2.0.2 + graceful-fs: 4.2.11 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + jest-worker: 29.7.0 + micromatch: 4.0.8 + walker: 1.0.8 + optionalDependencies: + fsevents: 2.3.3 + + jest-leak-detector@29.7.0: + dependencies: + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + jest-matcher-utils@29.7.0: + dependencies: + chalk: 4.1.2 + jest-diff: 29.7.0 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + jest-message-util@29.7.0: + dependencies: + '@babel/code-frame': 7.25.7 + '@jest/types': 29.6.3 + '@types/stack-utils': 2.0.3 + chalk: 4.1.2 + graceful-fs: 4.2.11 + micromatch: 4.0.8 + pretty-format: 29.7.0 + slash: 3.0.0 + stack-utils: 2.0.6 + + jest-mock@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/node': 18.15.0 + jest-util: 29.7.0 + + jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): + optionalDependencies: + jest-resolve: 29.7.0 + + jest-regex-util@29.6.3: {} + + jest-resolve-dependencies@29.7.0: + dependencies: + jest-regex-util: 29.6.3 + jest-snapshot: 29.7.0 + transitivePeerDependencies: + - supports-color + + jest-resolve@29.7.0: + dependencies: + chalk: 4.1.2 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-pnp-resolver: 1.2.3(jest-resolve@29.7.0) + jest-util: 29.7.0 + jest-validate: 29.7.0 + resolve: 1.22.8 + resolve.exports: 2.0.2 + slash: 3.0.0 + + jest-runner@29.7.0: + dependencies: + '@jest/console': 29.7.0 + '@jest/environment': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 18.15.0 + chalk: 4.1.2 + emittery: 0.13.1 + graceful-fs: 4.2.11 + jest-docblock: 29.7.0 + jest-environment-node: 29.7.0 + jest-haste-map: 29.7.0 + jest-leak-detector: 29.7.0 + jest-message-util: 29.7.0 + jest-resolve: 29.7.0 + jest-runtime: 29.7.0 + jest-util: 29.7.0 + jest-watcher: 29.7.0 + jest-worker: 29.7.0 + p-limit: 3.1.0 + source-map-support: 0.5.13 + transitivePeerDependencies: + - supports-color + + jest-runtime@29.7.0: + dependencies: + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/globals': 29.7.0 + '@jest/source-map': 29.6.3 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 18.15.0 + chalk: 4.1.2 + cjs-module-lexer: 1.4.1 + collect-v8-coverage: 1.0.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + slash: 3.0.0 + strip-bom: 4.0.0 + transitivePeerDependencies: + - supports-color + + jest-snapshot@29.7.0: + dependencies: + '@babel/core': 7.25.8 + '@babel/generator': 7.25.7 + '@babel/plugin-syntax-jsx': 7.25.7(@babel/core@7.25.8) + '@babel/plugin-syntax-typescript': 7.25.7(@babel/core@7.25.8) + '@babel/types': 7.25.8 + '@jest/expect-utils': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + babel-preset-current-node-syntax: 1.1.0(@babel/core@7.25.8) + chalk: 4.1.2 + expect: 29.7.0 + graceful-fs: 4.2.11 + jest-diff: 29.7.0 + jest-get-type: 29.6.3 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + natural-compare: 1.4.0 + pretty-format: 29.7.0 + semver: 7.6.3 + transitivePeerDependencies: + - supports-color + + jest-util@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/node': 18.15.0 + chalk: 4.1.2 + ci-info: 3.9.0 + graceful-fs: 4.2.11 + picomatch: 2.3.1 + + jest-validate@29.7.0: + dependencies: + '@jest/types': 29.6.3 + camelcase: 6.3.0 + chalk: 4.1.2 + jest-get-type: 29.6.3 + leven: 3.1.0 + pretty-format: 29.7.0 + + jest-watcher@29.7.0: + dependencies: + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 18.15.0 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + emittery: 0.13.1 + jest-util: 29.7.0 + string-length: 4.0.2 + + jest-worker@27.5.1: + dependencies: + '@types/node': 18.15.0 + merge-stream: 2.0.0 + supports-color: 8.1.1 + + jest-worker@29.7.0: + dependencies: + '@types/node': 18.15.0 + jest-util: 29.7.0 + merge-stream: 2.0.0 + supports-color: 8.1.1 + + jest@29.7.0(@types/node@18.15.0)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)): + dependencies: + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)) + '@jest/types': 29.6.3 + import-local: 3.2.0 + jest-cli: 29.7.0(@types/node@18.15.0)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)) + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + + jiti@1.21.6: {} + + js-audio-recorder@1.0.7: {} + + js-cookie@3.0.5: {} + + js-tokens@4.0.0: {} + + js-yaml@3.14.1: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + jsdoc-type-pratt-parser@4.1.0: {} + + jsdom@20.0.3: + dependencies: + abab: 2.0.6 + acorn: 8.13.0 + acorn-globals: 7.0.1 + cssom: 0.5.0 + cssstyle: 2.3.0 + data-urls: 3.0.2 + decimal.js: 10.4.3 + domexception: 4.0.0 + escodegen: 2.1.0 + form-data: 4.0.1 + html-encoding-sniffer: 3.0.0 + http-proxy-agent: 5.0.0 + https-proxy-agent: 5.0.1 + is-potential-custom-element-name: 1.0.1 + nwsapi: 2.2.13 + parse5: 7.2.0 + saxes: 6.0.0 + symbol-tree: 3.2.4 + tough-cookie: 4.1.4 + w3c-xmlserializer: 4.0.0 + webidl-conversions: 7.0.0 + whatwg-encoding: 2.0.0 + whatwg-mimetype: 3.0.0 + whatwg-url: 11.0.0 + ws: 8.18.0 + xml-name-validator: 4.0.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + jsesc@0.5.0: {} + + jsesc@3.0.2: {} + + json-buffer@3.0.1: {} + + json-parse-even-better-errors@2.3.1: {} + + json-schema-traverse@0.4.1: {} + + json-schema-traverse@1.0.0: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@1.0.2: + dependencies: + minimist: 1.2.8 + + json5@2.2.3: {} + + jsonc-eslint-parser@2.4.0: + dependencies: + acorn: 8.13.0 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + semver: 7.6.3 + + jsonfile@6.1.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + jsx-ast-utils@3.3.5: + dependencies: + array-includes: 3.1.8 + array.prototype.flat: 1.3.2 + object.assign: 4.1.5 + object.values: 1.2.0 + + jwt-decode@4.0.0: {} + + katex@0.16.11: + dependencies: + commander: 8.3.0 + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + khroma@2.1.0: {} + + kleur@3.0.3: {} + + kleur@4.1.5: {} + + lamejs@1.2.1: + dependencies: + use-strict: 1.0.1 + + language-subtag-registry@0.3.23: {} + + language-tags@1.0.9: + dependencies: + language-subtag-registry: 0.3.23 + + layout-base@1.0.2: {} + + layout-base@2.0.1: {} + + leven@3.1.0: {} + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lexical@0.16.1: {} + + lib0@0.2.98: + dependencies: + isomorphic.js: 0.2.5 + + lie@3.1.1: + dependencies: + immediate: 3.0.6 + + lilconfig@2.1.0: {} + + lilconfig@3.1.2: {} + + lines-and-columns@1.2.4: {} + + lint-staged@13.3.0: + dependencies: + chalk: 5.3.0 + commander: 11.0.0 + debug: 4.3.4 + execa: 7.2.0 + lilconfig: 2.1.0 + listr2: 6.6.1 + micromatch: 4.0.5 + pidtree: 0.6.0 + string-argv: 0.3.2 + yaml: 2.3.1 + transitivePeerDependencies: + - enquirer + - supports-color + + listr2@6.6.1: + dependencies: + cli-truncate: 3.1.0 + colorette: 2.0.20 + eventemitter3: 5.0.1 + log-update: 5.0.1 + rfdc: 1.4.1 + wrap-ansi: 8.1.0 + + loader-runner@4.3.0: {} + + loader-utils@2.0.4: + dependencies: + big.js: 5.2.2 + emojis-list: 3.0.0 + json5: 2.2.3 + + loader-utils@3.3.1: {} + + local-pkg@0.4.3: {} + + localforage@1.10.0: + dependencies: + lie: 3.1.1 + + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + locate-path@7.2.0: + dependencies: + p-locate: 6.0.0 + + lodash-es@4.17.21: {} + + lodash.castarray@4.4.0: {} + + lodash.debounce@4.0.8: {} + + lodash.isplainobject@4.0.6: {} + + lodash.merge@4.6.2: {} + + lodash@4.17.21: {} + + log-update@5.0.1: + dependencies: + ansi-escapes: 5.0.0 + cli-cursor: 4.0.0 + slice-ansi: 5.0.0 + strip-ansi: 7.1.0 + wrap-ansi: 8.1.0 + + longest-streak@3.1.0: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + loupe@3.1.2: {} + + lower-case@2.0.2: + dependencies: + tslib: 2.8.0 + + lowercase-keys@2.0.0: {} + + lowlight@1.20.0: + dependencies: + fault: 1.0.4 + highlight.js: 10.7.3 + + lru-cache@10.4.3: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + lz-string@1.5.0: {} + + magic-string@0.30.12: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + magicast@0.3.5: + dependencies: + '@babel/parser': 7.25.8 + '@babel/types': 7.25.8 + source-map-js: 1.2.1 + + make-dir@3.1.0: + dependencies: + semver: 6.3.1 + + make-dir@4.0.0: + dependencies: + semver: 7.6.3 + + make-error@1.3.6: {} + + makeerror@1.0.12: + dependencies: + tmpl: 1.0.5 + + map-or-similar@1.5.0: {} + + markdown-extensions@1.1.1: {} + + markdown-table@3.0.3: {} + + markdown-to-jsx@7.5.0(react@18.2.0): + dependencies: + react: 18.2.0 + + md5.js@1.3.5: + dependencies: + hash-base: 3.1.0 + inherits: 2.0.4 + safe-buffer: 5.2.1 + + mdast-util-definitions@5.1.2: + dependencies: + '@types/mdast': 3.0.15 + '@types/unist': 2.0.11 + unist-util-visit: 4.1.2 + + mdast-util-find-and-replace@2.2.2: + dependencies: + '@types/mdast': 3.0.15 + escape-string-regexp: 5.0.0 + unist-util-is: 5.2.1 + unist-util-visit-parents: 5.1.3 + + mdast-util-from-markdown@0.8.5: + dependencies: + '@types/mdast': 3.0.15 + mdast-util-to-string: 2.0.0 + micromark: 2.11.4 + parse-entities: 2.0.0 + unist-util-stringify-position: 2.0.3 + transitivePeerDependencies: + - supports-color + + mdast-util-from-markdown@1.3.1: + dependencies: + '@types/mdast': 3.0.15 + '@types/unist': 2.0.11 + decode-named-character-reference: 1.0.2 + mdast-util-to-string: 3.2.0 + micromark: 3.2.0 + micromark-util-decode-numeric-character-reference: 1.1.0 + micromark-util-decode-string: 1.1.0 + micromark-util-normalize-identifier: 1.1.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + unist-util-stringify-position: 3.0.3 + uvu: 0.5.6 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-autolink-literal@1.0.3: + dependencies: + '@types/mdast': 3.0.15 + ccount: 2.0.1 + mdast-util-find-and-replace: 2.2.2 + micromark-util-character: 1.2.0 + + mdast-util-gfm-footnote@1.0.2: + dependencies: + '@types/mdast': 3.0.15 + mdast-util-to-markdown: 1.5.0 + micromark-util-normalize-identifier: 1.1.0 + + mdast-util-gfm-strikethrough@1.0.3: + dependencies: + '@types/mdast': 3.0.15 + mdast-util-to-markdown: 1.5.0 + + mdast-util-gfm-table@1.0.7: + dependencies: + '@types/mdast': 3.0.15 + markdown-table: 3.0.3 + mdast-util-from-markdown: 1.3.1 + mdast-util-to-markdown: 1.5.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-task-list-item@1.0.2: + dependencies: + '@types/mdast': 3.0.15 + mdast-util-to-markdown: 1.5.0 + + mdast-util-gfm@2.0.2: + dependencies: + mdast-util-from-markdown: 1.3.1 + mdast-util-gfm-autolink-literal: 1.0.3 + mdast-util-gfm-footnote: 1.0.2 + mdast-util-gfm-strikethrough: 1.0.3 + mdast-util-gfm-table: 1.0.7 + mdast-util-gfm-task-list-item: 1.0.2 + mdast-util-to-markdown: 1.5.0 + transitivePeerDependencies: + - supports-color + + mdast-util-math@2.0.2: + dependencies: + '@types/mdast': 3.0.15 + longest-streak: 3.1.0 + mdast-util-to-markdown: 1.5.0 + + mdast-util-mdx-expression@1.3.2: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 2.3.10 + '@types/mdast': 3.0.15 + mdast-util-from-markdown: 1.3.1 + mdast-util-to-markdown: 1.5.0 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-jsx@2.1.4: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 2.3.10 + '@types/mdast': 3.0.15 + '@types/unist': 2.0.11 + ccount: 2.0.1 + mdast-util-from-markdown: 1.3.1 + mdast-util-to-markdown: 1.5.0 + parse-entities: 4.0.1 + stringify-entities: 4.0.4 + unist-util-remove-position: 4.0.2 + unist-util-stringify-position: 3.0.3 + vfile-message: 3.1.4 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx@2.0.1: + dependencies: + mdast-util-from-markdown: 1.3.1 + mdast-util-mdx-expression: 1.3.2 + mdast-util-mdx-jsx: 2.1.4 + mdast-util-mdxjs-esm: 1.3.1 + mdast-util-to-markdown: 1.5.0 + transitivePeerDependencies: + - supports-color + + mdast-util-mdxjs-esm@1.3.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 2.3.10 + '@types/mdast': 3.0.15 + mdast-util-from-markdown: 1.3.1 + mdast-util-to-markdown: 1.5.0 + transitivePeerDependencies: + - supports-color + + mdast-util-newline-to-break@1.0.0: + dependencies: + '@types/mdast': 3.0.15 + mdast-util-find-and-replace: 2.2.2 + + mdast-util-phrasing@3.0.1: + dependencies: + '@types/mdast': 3.0.15 + unist-util-is: 5.2.1 + + mdast-util-to-hast@12.3.0: + dependencies: + '@types/hast': 2.3.10 + '@types/mdast': 3.0.15 + mdast-util-definitions: 5.1.2 + micromark-util-sanitize-uri: 1.2.0 + trim-lines: 3.0.1 + unist-util-generated: 2.0.1 + unist-util-position: 4.0.4 + unist-util-visit: 4.1.2 + + mdast-util-to-hast@13.2.0: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.2.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.0 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + + mdast-util-to-markdown@1.5.0: + dependencies: + '@types/mdast': 3.0.15 + '@types/unist': 2.0.11 + longest-streak: 3.1.0 + mdast-util-phrasing: 3.0.1 + mdast-util-to-string: 3.2.0 + micromark-util-decode-string: 1.1.0 + unist-util-visit: 4.1.2 + zwitch: 2.0.4 + + mdast-util-to-string@2.0.0: {} + + mdast-util-to-string@3.2.0: + dependencies: + '@types/mdast': 3.0.15 + + media-typer@0.3.0: {} + + memfs@3.5.3: + dependencies: + fs-monkey: 1.0.6 + + memoize-one@5.2.1: {} + + memoizerific@1.11.3: + dependencies: + map-or-similar: 1.5.0 + + merge-descriptors@1.0.3: {} + + merge-stream@2.0.0: {} + + merge2@1.4.1: {} + + mermaid@10.4.0: + dependencies: + '@braintree/sanitize-url': 6.0.4 + '@types/d3-scale': 4.0.8 + '@types/d3-scale-chromatic': 3.0.3 + cytoscape: 3.30.2 + cytoscape-cose-bilkent: 4.1.0(cytoscape@3.30.2) + cytoscape-fcose: 2.2.0(cytoscape@3.30.2) + d3: 7.9.0 + d3-sankey: 0.12.3 + dagre-d3-es: 7.0.10 + dayjs: 1.11.13 + dompurify: 3.1.7 + elkjs: 0.8.2 + khroma: 2.1.0 + lodash-es: 4.17.21 + mdast-util-from-markdown: 1.3.1 + non-layered-tidy-tree-layout: 2.0.2 + stylis: 4.3.4 + ts-dedent: 2.2.0 + uuid: 9.0.1 + web-worker: 1.3.0 + transitivePeerDependencies: + - supports-color + + methods@1.1.2: {} + + micromark-core-commonmark@1.1.0: + dependencies: + decode-named-character-reference: 1.0.2 + micromark-factory-destination: 1.1.0 + micromark-factory-label: 1.1.0 + micromark-factory-space: 1.1.0 + micromark-factory-title: 1.1.0 + micromark-factory-whitespace: 1.1.0 + micromark-util-character: 1.2.0 + micromark-util-chunked: 1.1.0 + micromark-util-classify-character: 1.1.0 + micromark-util-html-tag-name: 1.2.0 + micromark-util-normalize-identifier: 1.1.0 + micromark-util-resolve-all: 1.1.0 + micromark-util-subtokenize: 1.1.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + uvu: 0.5.6 + + micromark-extension-gfm-autolink-literal@1.0.5: + dependencies: + micromark-util-character: 1.2.0 + micromark-util-sanitize-uri: 1.2.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + + micromark-extension-gfm-footnote@1.1.2: + dependencies: + micromark-core-commonmark: 1.1.0 + micromark-factory-space: 1.1.0 + micromark-util-character: 1.2.0 + micromark-util-normalize-identifier: 1.1.0 + micromark-util-sanitize-uri: 1.2.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + uvu: 0.5.6 + + micromark-extension-gfm-strikethrough@1.0.7: + dependencies: + micromark-util-chunked: 1.1.0 + micromark-util-classify-character: 1.1.0 + micromark-util-resolve-all: 1.1.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + uvu: 0.5.6 + + micromark-extension-gfm-table@1.0.7: + dependencies: + micromark-factory-space: 1.1.0 + micromark-util-character: 1.2.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + uvu: 0.5.6 + + micromark-extension-gfm-tagfilter@1.0.2: + dependencies: + micromark-util-types: 1.1.0 + + micromark-extension-gfm-task-list-item@1.0.5: + dependencies: + micromark-factory-space: 1.1.0 + micromark-util-character: 1.2.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + uvu: 0.5.6 + + micromark-extension-gfm@2.0.3: + dependencies: + micromark-extension-gfm-autolink-literal: 1.0.5 + micromark-extension-gfm-footnote: 1.1.2 + micromark-extension-gfm-strikethrough: 1.0.7 + micromark-extension-gfm-table: 1.0.7 + micromark-extension-gfm-tagfilter: 1.0.2 + micromark-extension-gfm-task-list-item: 1.0.5 + micromark-util-combine-extensions: 1.1.0 + micromark-util-types: 1.1.0 + + micromark-extension-math@2.1.2: + dependencies: + '@types/katex': 0.16.7 + katex: 0.16.11 + micromark-factory-space: 1.1.0 + micromark-util-character: 1.2.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + uvu: 0.5.6 + + micromark-extension-mdx-expression@1.0.8: + dependencies: + '@types/estree': 1.0.6 + micromark-factory-mdx-expression: 1.0.9 + micromark-factory-space: 1.1.0 + micromark-util-character: 1.2.0 + micromark-util-events-to-acorn: 1.2.3 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + uvu: 0.5.6 + + micromark-extension-mdx-jsx@1.0.5: + dependencies: + '@types/acorn': 4.0.6 + '@types/estree': 1.0.6 + estree-util-is-identifier-name: 2.1.0 + micromark-factory-mdx-expression: 1.0.9 + micromark-factory-space: 1.1.0 + micromark-util-character: 1.2.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + uvu: 0.5.6 + vfile-message: 3.1.4 + + micromark-extension-mdx-md@1.0.1: + dependencies: + micromark-util-types: 1.1.0 + + micromark-extension-mdxjs-esm@1.0.5: + dependencies: + '@types/estree': 1.0.6 + micromark-core-commonmark: 1.1.0 + micromark-util-character: 1.2.0 + micromark-util-events-to-acorn: 1.2.3 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + unist-util-position-from-estree: 1.1.2 + uvu: 0.5.6 + vfile-message: 3.1.4 + + micromark-extension-mdxjs@1.0.1: + dependencies: + acorn: 8.13.0 + acorn-jsx: 5.3.2(acorn@8.13.0) + micromark-extension-mdx-expression: 1.0.8 + micromark-extension-mdx-jsx: 1.0.5 + micromark-extension-mdx-md: 1.0.1 + micromark-extension-mdxjs-esm: 1.0.5 + micromark-util-combine-extensions: 1.1.0 + micromark-util-types: 1.1.0 + + micromark-factory-destination@1.1.0: + dependencies: + micromark-util-character: 1.2.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + + micromark-factory-label@1.1.0: + dependencies: + micromark-util-character: 1.2.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + uvu: 0.5.6 + + micromark-factory-mdx-expression@1.0.9: + dependencies: + '@types/estree': 1.0.6 + micromark-util-character: 1.2.0 + micromark-util-events-to-acorn: 1.2.3 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + unist-util-position-from-estree: 1.1.2 + uvu: 0.5.6 + vfile-message: 3.1.4 + + micromark-factory-space@1.1.0: + dependencies: + micromark-util-character: 1.2.0 + micromark-util-types: 1.1.0 + + micromark-factory-title@1.1.0: + dependencies: + micromark-factory-space: 1.1.0 + micromark-util-character: 1.2.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + + micromark-factory-whitespace@1.1.0: + dependencies: + micromark-factory-space: 1.1.0 + micromark-util-character: 1.2.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + + micromark-util-character@1.2.0: + dependencies: + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + + micromark-util-character@2.1.0: + dependencies: + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + + micromark-util-chunked@1.1.0: + dependencies: + micromark-util-symbol: 1.1.0 + + micromark-util-classify-character@1.1.0: + dependencies: + micromark-util-character: 1.2.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + + micromark-util-combine-extensions@1.1.0: + dependencies: + micromark-util-chunked: 1.1.0 + micromark-util-types: 1.1.0 + + micromark-util-decode-numeric-character-reference@1.1.0: + dependencies: + micromark-util-symbol: 1.1.0 + + micromark-util-decode-string@1.1.0: + dependencies: + decode-named-character-reference: 1.0.2 + micromark-util-character: 1.2.0 + micromark-util-decode-numeric-character-reference: 1.1.0 + micromark-util-symbol: 1.1.0 + + micromark-util-encode@1.1.0: {} + + micromark-util-encode@2.0.0: {} + + micromark-util-events-to-acorn@1.2.3: + dependencies: + '@types/acorn': 4.0.6 + '@types/estree': 1.0.6 + '@types/unist': 2.0.11 + estree-util-visit: 1.2.1 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + uvu: 0.5.6 + vfile-message: 3.1.4 + + micromark-util-html-tag-name@1.2.0: {} + + micromark-util-normalize-identifier@1.1.0: + dependencies: + micromark-util-symbol: 1.1.0 + + micromark-util-resolve-all@1.1.0: + dependencies: + micromark-util-types: 1.1.0 + + micromark-util-sanitize-uri@1.2.0: + dependencies: + micromark-util-character: 1.2.0 + micromark-util-encode: 1.1.0 + micromark-util-symbol: 1.1.0 + + micromark-util-sanitize-uri@2.0.0: + dependencies: + micromark-util-character: 2.1.0 + micromark-util-encode: 2.0.0 + micromark-util-symbol: 2.0.0 + + micromark-util-subtokenize@1.1.0: + dependencies: + micromark-util-chunked: 1.1.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + uvu: 0.5.6 + + micromark-util-symbol@1.1.0: {} + + micromark-util-symbol@2.0.0: {} + + micromark-util-types@1.1.0: {} + + micromark-util-types@2.0.0: {} + + micromark@2.11.4: + dependencies: + debug: 4.3.7 + parse-entities: 2.0.0 + transitivePeerDependencies: + - supports-color + + micromark@3.2.0: + dependencies: + '@types/debug': 4.1.12 + debug: 4.3.7 + decode-named-character-reference: 1.0.2 + micromark-core-commonmark: 1.1.0 + micromark-factory-space: 1.1.0 + micromark-util-character: 1.2.0 + micromark-util-chunked: 1.1.0 + micromark-util-combine-extensions: 1.1.0 + micromark-util-decode-numeric-character-reference: 1.1.0 + micromark-util-encode: 1.1.0 + micromark-util-normalize-identifier: 1.1.0 + micromark-util-resolve-all: 1.1.0 + micromark-util-sanitize-uri: 1.2.0 + micromark-util-subtokenize: 1.1.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + uvu: 0.5.6 + transitivePeerDependencies: + - supports-color + + micromatch@4.0.5: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + miller-rabin@4.0.1: + dependencies: + bn.js: 4.12.0 + brorand: 1.1.0 + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mime@1.6.0: {} + + mimic-fn@2.1.0: {} + + mimic-fn@4.0.0: {} + + mimic-response@1.0.1: {} + + mimic-response@3.1.0: {} + + min-indent@1.0.1: {} + + minimalistic-assert@1.0.1: {} + + minimalistic-crypto-utils@1.0.1: {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + minimist@1.2.8: {} + + minipass@7.1.2: {} + + mkdirp@0.5.6: + dependencies: + minimist: 1.2.8 + + monaco-editor@0.52.0: {} + + mri@1.2.0: {} + + ms@2.0.0: {} + + ms@2.1.2: {} + + ms@2.1.3: {} + + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + + nanoid@3.3.7: {} + + natural-compare-lite@1.4.0: {} + + natural-compare@1.4.0: {} + + negotiator@0.6.3: {} + + negotiator@0.6.4: {} + + neo-async@2.6.2: {} + + next@14.2.15(@babel/core@7.25.8)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.80.3): + dependencies: + '@next/env': 14.2.15 + '@swc/helpers': 0.5.5 + busboy: 1.6.0 + caniuse-lite: 1.0.30001669 + graceful-fs: 4.2.11 + postcss: 8.4.31 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + styled-jsx: 5.1.1(@babel/core@7.25.8)(react@18.2.0) + optionalDependencies: + '@next/swc-darwin-arm64': 14.2.15 + '@next/swc-darwin-x64': 14.2.15 + '@next/swc-linux-arm64-gnu': 14.2.15 + '@next/swc-linux-arm64-musl': 14.2.15 + '@next/swc-linux-x64-gnu': 14.2.15 + '@next/swc-linux-x64-musl': 14.2.15 + '@next/swc-win32-arm64-msvc': 14.2.15 + '@next/swc-win32-ia32-msvc': 14.2.15 + '@next/swc-win32-x64-msvc': 14.2.15 + sass: 1.80.3 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + + no-case@3.0.4: + dependencies: + lower-case: 2.0.2 + tslib: 2.8.0 + + node-abort-controller@3.1.1: {} + + node-addon-api@7.1.1: {} + + node-int64@0.4.0: {} + + node-polyfill-webpack-plugin@2.0.1(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3)): + dependencies: + assert: 2.1.0 + browserify-zlib: 0.2.0 + buffer: 6.0.3 + console-browserify: 1.2.0 + constants-browserify: 1.0.0 + crypto-browserify: 3.12.0 + domain-browser: 4.23.0 + events: 3.3.0 + filter-obj: 2.0.2 + https-browserify: 1.0.0 + os-browserify: 0.3.0 + path-browserify: 1.0.1 + process: 0.11.10 + punycode: 2.3.1 + querystring-es3: 0.2.1 + readable-stream: 4.5.2 + stream-browserify: 3.0.0 + stream-http: 3.2.0 + string_decoder: 1.3.0 + timers-browserify: 2.0.12 + tty-browserify: 0.0.1 + type-fest: 2.19.0 + url: 0.11.4 + util: 0.12.5 + vm-browserify: 1.1.2 + webpack: 5.95.0(esbuild@0.23.1)(uglify-js@3.19.3) + + node-releases@2.0.18: {} + + non-layered-tidy-tree-layout@2.0.2: {} + + normalize-package-data@2.5.0: + dependencies: + hosted-git-info: 2.8.9 + resolve: 1.22.8 + semver: 5.7.2 + validate-npm-package-license: 3.0.4 + + normalize-path@3.0.0: {} + + normalize-range@0.1.2: {} + + normalize-url@6.1.0: {} + + normalize-wheel@1.0.1: {} + + npm-run-path@4.0.1: + dependencies: + path-key: 3.1.1 + + npm-run-path@5.3.0: + dependencies: + path-key: 4.0.0 + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + nwsapi@2.2.13: {} + + object-assign@4.1.1: {} + + object-hash@3.0.0: {} + + object-inspect@1.13.2: {} + + object-is@1.1.6: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + + object-keys@1.1.1: {} + + object.assign@4.1.5: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + has-symbols: 1.0.3 + object-keys: 1.1.1 + + object.entries@1.1.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + + object.fromentries@2.0.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + + object.groupby@1.0.3: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + + object.values@1.2.0: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + + objectorarray@1.0.5: {} + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + onetime@5.1.2: + dependencies: + mimic-fn: 2.1.0 + + onetime@6.0.0: + dependencies: + mimic-fn: 4.0.0 + + open@8.4.2: + dependencies: + define-lazy-prop: 2.0.0 + is-docker: 2.2.1 + is-wsl: 2.2.0 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + os-browserify@0.3.0: {} + + p-cancelable@2.1.1: {} + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-limit@4.0.0: + dependencies: + yocto-queue: 1.1.1 + + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + p-locate@6.0.0: + dependencies: + p-limit: 4.0.0 + + p-try@2.2.0: {} + + package-json-from-dist@1.0.1: {} + + pako@1.0.11: {} + + papaparse@5.4.1: {} + + param-case@3.0.4: + dependencies: + dot-case: 3.0.4 + tslib: 2.8.0 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parse-asn1@5.1.7: + dependencies: + asn1.js: 4.10.1 + browserify-aes: 1.2.0 + evp_bytestokey: 1.0.3 + hash-base: 3.0.4 + pbkdf2: 3.1.2 + safe-buffer: 5.2.1 + + parse-entities@2.0.0: + dependencies: + character-entities: 1.2.4 + character-entities-legacy: 1.1.4 + character-reference-invalid: 1.1.4 + is-alphanumerical: 1.0.4 + is-decimal: 1.0.4 + is-hexadecimal: 1.0.4 + + parse-entities@4.0.1: + dependencies: + '@types/unist': 2.0.11 + character-entities: 2.0.2 + character-entities-legacy: 3.0.0 + character-reference-invalid: 2.0.1 + decode-named-character-reference: 1.0.2 + is-alphanumerical: 2.0.1 + is-decimal: 2.0.1 + is-hexadecimal: 2.0.1 + + parse-json@5.2.0: + dependencies: + '@babel/code-frame': 7.25.7 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + + parse5@7.2.0: + dependencies: + entities: 4.5.0 + + parseurl@1.3.3: {} + + pascal-case@3.1.2: + dependencies: + no-case: 3.0.4 + tslib: 2.8.0 + + path-browserify@1.0.1: {} + + path-exists@4.0.0: {} + + path-exists@5.0.0: {} + + path-is-absolute@1.0.1: {} + + path-key@3.1.1: {} + + path-key@4.0.0: {} + + path-parse@1.0.7: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + + path-to-regexp@0.1.10: {} + + path-type@4.0.0: {} + + pathval@2.0.0: {} + + pbkdf2@3.1.2: + dependencies: + create-hash: 1.2.0 + create-hmac: 1.1.7 + ripemd160: 2.0.2 + safe-buffer: 5.2.1 + sha.js: 2.4.11 + + periscopic@3.1.0: + dependencies: + '@types/estree': 1.0.6 + estree-walker: 3.0.3 + is-reference: 3.0.2 + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + pidtree@0.6.0: {} + + pify@2.3.0: {} + + pinyin-pro@3.25.0: {} + + pirates@4.0.6: {} + + pkg-dir@4.2.0: + dependencies: + find-up: 4.1.0 + + pkg-dir@7.0.0: + dependencies: + find-up: 6.3.0 + + pluralize@8.0.0: {} + + pnp-webpack-plugin@1.7.0(typescript@4.9.5): + dependencies: + ts-pnp: 1.2.0(typescript@4.9.5) + transitivePeerDependencies: + - typescript + + polished@4.3.1: + dependencies: + '@babel/runtime': 7.25.7 + + portfinder@1.0.32: + dependencies: + async: 2.6.4 + debug: 3.2.7 + mkdirp: 0.5.6 + transitivePeerDependencies: + - supports-color + + possible-typed-array-names@1.0.0: {} + + postcss-import@15.1.0(postcss@8.4.47): + dependencies: + postcss: 8.4.47 + postcss-value-parser: 4.2.0 + read-cache: 1.0.0 + resolve: 1.22.8 + + postcss-js@4.0.1(postcss@8.4.47): + dependencies: + camelcase-css: 2.0.1 + postcss: 8.4.47 + + postcss-load-config@4.0.2(postcss@8.4.47)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)): + dependencies: + lilconfig: 3.1.2 + yaml: 2.6.0 + optionalDependencies: + postcss: 8.4.47 + ts-node: 10.9.2(@types/node@18.15.0)(typescript@4.9.5) + + postcss-loader@8.1.1(postcss@8.4.47)(typescript@4.9.5)(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3)): + dependencies: + cosmiconfig: 9.0.0(typescript@4.9.5) + jiti: 1.21.6 + postcss: 8.4.47 + semver: 7.6.3 + optionalDependencies: + webpack: 5.95.0(esbuild@0.23.1)(uglify-js@3.19.3) + transitivePeerDependencies: + - typescript + + postcss-modules-extract-imports@3.1.0(postcss@8.4.47): + dependencies: + postcss: 8.4.47 + + postcss-modules-local-by-default@4.0.5(postcss@8.4.47): + dependencies: + icss-utils: 5.1.0(postcss@8.4.47) + postcss: 8.4.47 + postcss-selector-parser: 6.1.2 + postcss-value-parser: 4.2.0 + + postcss-modules-scope@3.2.0(postcss@8.4.47): + dependencies: + postcss: 8.4.47 + postcss-selector-parser: 6.1.2 + + postcss-modules-values@4.0.0(postcss@8.4.47): + dependencies: + icss-utils: 5.1.0(postcss@8.4.47) + postcss: 8.4.47 + + postcss-nested@6.2.0(postcss@8.4.47): + dependencies: + postcss: 8.4.47 + postcss-selector-parser: 6.1.2 + + postcss-selector-parser@6.0.10: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-selector-parser@6.1.2: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-value-parser@4.2.0: {} + + postcss@8.4.31: + dependencies: + nanoid: 3.3.7 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + postcss@8.4.47: + dependencies: + nanoid: 3.3.7 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prelude-ls@1.2.1: {} + + pretty-error@4.0.0: + dependencies: + lodash: 4.17.21 + renderkid: 3.0.0 + + pretty-format@27.5.1: + dependencies: + ansi-regex: 5.0.1 + ansi-styles: 5.2.0 + react-is: 17.0.2 + + pretty-format@29.7.0: + dependencies: + '@jest/schemas': 29.6.3 + ansi-styles: 5.2.0 + react-is: 18.3.1 + + prismjs@1.27.0: {} + + prismjs@1.29.0: {} + + process-nextick-args@2.0.1: {} + + process@0.11.10: {} + + prompts@2.4.2: + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + + prop-types@15.8.1: + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + + property-information@5.6.0: + dependencies: + xtend: 4.0.2 + + property-information@6.5.0: {} + + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + psl@1.9.0: {} + + public-encrypt@4.0.3: + dependencies: + bn.js: 4.12.0 + browserify-rsa: 4.1.1 + create-hash: 1.2.0 + parse-asn1: 5.1.7 + randombytes: 2.1.0 + safe-buffer: 5.2.1 + + pump@3.0.2: + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + + punycode@1.4.1: {} + + punycode@2.3.1: {} + + pure-rand@6.1.0: {} + + qrcode.react@3.2.0(react@18.2.0): + dependencies: + react: 18.2.0 + + qs@6.13.0: + dependencies: + side-channel: 1.0.6 + + querystring-es3@0.2.1: {} + + querystringify@2.2.0: {} + + queue-microtask@1.2.3: {} + + queue@6.0.2: + dependencies: + inherits: 2.0.4 + + quick-lru@5.1.1: {} + + randombytes@2.1.0: + dependencies: + safe-buffer: 5.2.1 + + randomfill@1.0.4: + dependencies: + randombytes: 2.1.0 + safe-buffer: 5.2.1 + + range-parser@1.2.1: {} + + raw-body@2.5.2: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + + rc-input@1.6.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + dependencies: + '@babel/runtime': 7.25.7 + classnames: 2.5.1 + rc-util: 5.43.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + + rc-resize-observer@1.4.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + dependencies: + '@babel/runtime': 7.25.7 + classnames: 2.5.1 + rc-util: 5.43.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + resize-observer-polyfill: 1.5.1 + + rc-textarea@1.8.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + dependencies: + '@babel/runtime': 7.25.7 + classnames: 2.5.1 + rc-input: 1.6.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + rc-resize-observer: 1.4.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + rc-util: 5.43.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + + rc-util@5.43.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + dependencies: + '@babel/runtime': 7.25.7 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-is: 18.3.1 + + react-18-input-autosize@3.0.0(react@18.2.0): + dependencies: + prop-types: 15.8.1 + react: 18.2.0 + + react-colorful@5.6.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + dependencies: + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + + react-confetti@6.1.0(react@18.2.0): + dependencies: + react: 18.2.0 + tween-functions: 1.2.0 + + react-docgen-typescript@2.2.2(typescript@4.9.5): + dependencies: + typescript: 4.9.5 + + react-docgen@7.1.0: + dependencies: + '@babel/core': 7.25.8 + '@babel/traverse': 7.25.7 + '@babel/types': 7.25.8 + '@types/babel__core': 7.20.5 + '@types/babel__traverse': 7.20.6 + '@types/doctrine': 0.0.9 + '@types/resolve': 1.20.6 + doctrine: 3.0.0 + resolve: 1.22.8 + strip-indent: 4.0.0 + transitivePeerDependencies: + - supports-color + + react-dom@18.2.0(react@18.2.0): + dependencies: + loose-envify: 1.4.0 + react: 18.2.0 + scheduler: 0.23.2 + + react-easy-crop@5.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + dependencies: + normalize-wheel: 1.0.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + tslib: 2.8.0 + + react-element-to-jsx-string@15.0.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + dependencies: + '@base2/pretty-print-object': 1.0.1 + is-plain-object: 5.0.0 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-is: 18.1.0 + + react-error-boundary@3.1.4(react@18.2.0): + dependencies: + '@babel/runtime': 7.25.7 + react: 18.2.0 + + react-error-boundary@4.1.2(react@18.2.0): + dependencies: + '@babel/runtime': 7.25.7 + react: 18.2.0 + + react-fast-compare@3.2.2: {} + + react-headless-pagination@1.1.6(react@18.2.0): + dependencies: + clsx: 2.1.1 + react: 18.2.0 + + react-hook-form@7.53.1(react@18.2.0): + dependencies: + react: 18.2.0 + + react-i18next@12.3.1(i18next@22.5.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + dependencies: + '@babel/runtime': 7.25.7 + html-parse-stringify: 3.0.1 + i18next: 22.5.1 + react: 18.2.0 + optionalDependencies: + react-dom: 18.2.0(react@18.2.0) + + react-infinite-scroll-component@6.1.0(react@18.2.0): + dependencies: + react: 18.2.0 + throttle-debounce: 2.3.0 + + react-is@16.13.1: {} + + react-is@17.0.2: {} + + react-is@18.1.0: {} + + react-is@18.3.1: {} + + react-markdown@8.0.7(@types/react@18.2.79)(react@18.2.0): + dependencies: + '@types/hast': 2.3.10 + '@types/prop-types': 15.7.13 + '@types/react': 18.2.79 + '@types/unist': 2.0.11 + comma-separated-tokens: 2.0.3 + hast-util-whitespace: 2.0.1 + prop-types: 15.8.1 + property-information: 6.5.0 + react: 18.2.0 + react-is: 18.3.1 + remark-parse: 10.0.2 + remark-rehype: 10.1.0 + space-separated-tokens: 2.0.2 + style-to-object: 0.4.4 + unified: 10.1.2 + unist-util-visit: 4.1.2 + vfile: 5.3.7 + transitivePeerDependencies: + - supports-color + + react-multi-email@1.0.25(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + dependencies: + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + + react-papaparse@4.4.0: + dependencies: + '@types/papaparse': 5.3.15 + papaparse: 5.4.1 + + react-refresh@0.14.2: {} + + react-slider@2.0.6(react@18.2.0): + dependencies: + prop-types: 15.8.1 + react: 18.2.0 + + react-sortablejs@6.1.4(@types/sortablejs@1.15.8)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sortablejs@1.15.3): + dependencies: + '@types/sortablejs': 1.15.8 + classnames: 2.3.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + sortablejs: 1.15.3 + tiny-invariant: 1.2.0 + + react-syntax-highlighter@15.6.1(react@18.2.0): + dependencies: + '@babel/runtime': 7.25.7 + highlight.js: 10.7.3 + highlightjs-vue: 1.0.0 + lowlight: 1.20.0 + prismjs: 1.29.0 + react: 18.2.0 + refractor: 3.6.0 + + react-tooltip@5.8.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + dependencies: + '@floating-ui/dom': 1.1.1 + classnames: 2.5.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + + react-window-infinite-loader@1.0.9(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + dependencies: + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + + react-window@1.8.10(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + dependencies: + '@babel/runtime': 7.25.7 + memoize-one: 5.2.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + + react@18.2.0: + dependencies: + loose-envify: 1.4.0 + + reactflow@11.11.4(@types/react@18.2.79)(immer@9.0.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + dependencies: + '@reactflow/background': 11.3.14(@types/react@18.2.79)(immer@9.0.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@reactflow/controls': 11.2.14(@types/react@18.2.79)(immer@9.0.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@reactflow/core': 11.11.4(@types/react@18.2.79)(immer@9.0.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@reactflow/minimap': 11.7.14(@types/react@18.2.79)(immer@9.0.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@reactflow/node-resizer': 2.2.14(@types/react@18.2.79)(immer@9.0.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@reactflow/node-toolbar': 1.3.14(@types/react@18.2.79)(immer@9.0.21)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + transitivePeerDependencies: + - '@types/react' + - immer + + read-cache@1.0.0: + dependencies: + pify: 2.3.0 + + read-pkg-up@7.0.1: + dependencies: + find-up: 4.1.0 + read-pkg: 5.2.0 + type-fest: 0.8.1 + + read-pkg@5.2.0: + dependencies: + '@types/normalize-package-data': 2.4.4 + normalize-package-data: 2.5.0 + parse-json: 5.2.0 + type-fest: 0.6.0 + + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + readable-stream@4.5.2: + dependencies: + abort-controller: 3.0.0 + buffer: 6.0.3 + events: 3.3.0 + process: 0.11.10 + string_decoder: 1.3.0 + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + readdirp@4.0.2: {} + + recast@0.23.9: + dependencies: + ast-types: 0.16.1 + esprima: 4.0.1 + source-map: 0.6.1 + tiny-invariant: 1.3.3 + tslib: 2.8.0 + + recordrtc@5.6.2: {} + + redent@3.0.0: + dependencies: + indent-string: 4.0.0 + strip-indent: 3.0.0 + + reflect.getprototypeof@1.0.6: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + globalthis: 1.0.4 + which-builtin-type: 1.1.4 + + refractor@3.6.0: + dependencies: + hastscript: 6.0.0 + parse-entities: 2.0.0 + prismjs: 1.27.0 + + regenerate-unicode-properties@10.2.0: + dependencies: + regenerate: 1.4.2 + + regenerate@1.4.2: {} + + regenerator-runtime@0.14.1: {} + + regenerator-transform@0.15.2: + dependencies: + '@babel/runtime': 7.25.7 + + regex-parser@2.3.0: {} + + regexp-tree@0.1.27: {} + + regexp.prototype.flags@1.5.3: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-errors: 1.3.0 + set-function-name: 2.0.2 + + regexpp@3.2.0: {} + + regexpu-core@6.1.1: + dependencies: + regenerate: 1.4.2 + regenerate-unicode-properties: 10.2.0 + regjsgen: 0.8.0 + regjsparser: 0.11.1 + unicode-match-property-ecmascript: 2.0.0 + unicode-match-property-value-ecmascript: 2.2.0 + + regjsgen@0.8.0: {} + + regjsparser@0.11.1: + dependencies: + jsesc: 3.0.2 + + regjsparser@0.9.1: + dependencies: + jsesc: 0.5.0 + + rehype-external-links@3.0.0: + dependencies: + '@types/hast': 3.0.4 + '@ungap/structured-clone': 1.2.0 + hast-util-is-element: 3.0.0 + is-absolute-url: 4.0.1 + space-separated-tokens: 2.0.2 + unist-util-visit: 5.0.0 + + rehype-katex@6.0.3: + dependencies: + '@types/hast': 2.3.10 + '@types/katex': 0.14.0 + hast-util-from-html-isomorphic: 1.0.0 + hast-util-to-text: 3.1.2 + katex: 0.16.11 + unist-util-visit: 4.1.2 + + rehype-raw@7.0.0: + dependencies: + '@types/hast': 3.0.4 + hast-util-raw: 9.0.4 + vfile: 6.0.3 + + rehype-slug@6.0.0: + dependencies: + '@types/hast': 3.0.4 + github-slugger: 2.0.0 + hast-util-heading-rank: 3.0.0 + hast-util-to-string: 3.0.1 + unist-util-visit: 5.0.0 + + relateurl@0.2.7: {} + + remark-breaks@3.0.3: + dependencies: + '@types/mdast': 3.0.15 + mdast-util-newline-to-break: 1.0.0 + unified: 10.1.2 + + remark-gfm@3.0.1: + dependencies: + '@types/mdast': 3.0.15 + mdast-util-gfm: 2.0.2 + micromark-extension-gfm: 2.0.3 + unified: 10.1.2 + transitivePeerDependencies: + - supports-color + + remark-math@5.1.1: + dependencies: + '@types/mdast': 3.0.15 + mdast-util-math: 2.0.2 + micromark-extension-math: 2.1.2 + unified: 10.1.2 + + remark-mdx@2.3.0: + dependencies: + mdast-util-mdx: 2.0.1 + micromark-extension-mdxjs: 1.0.1 + transitivePeerDependencies: + - supports-color + + remark-parse@10.0.2: + dependencies: + '@types/mdast': 3.0.15 + mdast-util-from-markdown: 1.3.1 + unified: 10.1.2 + transitivePeerDependencies: + - supports-color + + remark-rehype@10.1.0: + dependencies: + '@types/hast': 2.3.10 + '@types/mdast': 3.0.15 + mdast-util-to-hast: 12.3.0 + unified: 10.1.2 + + renderkid@3.0.0: + dependencies: + css-select: 4.3.0 + dom-converter: 0.2.0 + htmlparser2: 6.1.0 + lodash: 4.17.21 + strip-ansi: 6.0.1 + + require-directory@2.1.1: {} + + require-from-string@2.0.2: {} + + requireindex@1.2.0: {} + + requires-port@1.0.0: {} + + resize-observer-polyfill@1.5.1: {} + + resolve-alpn@1.2.1: {} + + resolve-cwd@3.0.0: + dependencies: + resolve-from: 5.0.0 + + resolve-from@4.0.0: {} + + resolve-from@5.0.0: {} + + resolve-pkg-maps@1.0.0: {} + + resolve-url-loader@5.0.0: + dependencies: + adjust-sourcemap-loader: 4.0.0 + convert-source-map: 1.9.0 + loader-utils: 2.0.4 + postcss: 8.4.47 + source-map: 0.6.1 + + resolve.exports@2.0.2: {} + + resolve@1.22.8: + dependencies: + is-core-module: 2.15.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + resolve@2.0.0-next.5: + dependencies: + is-core-module: 2.15.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + responselike@2.0.1: + dependencies: + lowercase-keys: 2.0.0 + + restore-cursor@4.0.0: + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + + reusify@1.0.4: {} + + rfdc@1.4.1: {} + + rimraf@3.0.2: + dependencies: + glob: 7.2.3 + + ripemd160@2.0.2: + dependencies: + hash-base: 3.1.0 + inherits: 2.0.4 + + robust-predicates@3.0.2: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + rw@1.3.3: {} + + sade@1.8.1: + dependencies: + mri: 1.2.0 + + safe-array-concat@1.1.2: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + has-symbols: 1.0.3 + isarray: 2.0.5 + + safe-buffer@5.1.2: {} + + safe-buffer@5.2.1: {} + + safe-regex-test@1.0.3: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-regex: 1.1.4 + + safe-regex@2.1.1: + dependencies: + regexp-tree: 0.1.27 + + safer-buffer@2.1.2: {} + + sass-loader@13.3.3(sass@1.80.3)(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3)): + dependencies: + neo-async: 2.6.2 + webpack: 5.95.0(esbuild@0.23.1)(uglify-js@3.19.3) + optionalDependencies: + sass: 1.80.3 + + sass@1.80.3: + dependencies: + '@parcel/watcher': 2.4.1 + chokidar: 4.0.1 + immutable: 4.3.7 + source-map-js: 1.2.1 + + saxes@6.0.0: + dependencies: + xmlchars: 2.2.0 + + scheduler@0.23.2: + dependencies: + loose-envify: 1.4.0 + + schema-utils@3.3.0: + dependencies: + '@types/json-schema': 7.0.15 + ajv: 6.12.6 + ajv-keywords: 3.5.2(ajv@6.12.6) + + schema-utils@4.2.0: + dependencies: + '@types/json-schema': 7.0.15 + ajv: 8.17.1 + ajv-formats: 2.1.1(ajv@8.17.1) + ajv-keywords: 5.1.0(ajv@8.17.1) + + screenfull@5.2.0: {} + + semver@5.7.2: {} + + semver@6.3.1: {} + + semver@7.6.3: {} + + send@0.19.0: + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.0 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + + serialize-javascript@6.0.2: + dependencies: + randombytes: 2.1.0 + + serve-static@1.16.2: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.19.0 + transitivePeerDependencies: + - supports-color + + server-only@0.0.1: {} + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + setimmediate@1.0.5: {} + + setprototypeof@1.2.0: {} + + sha.js@2.4.11: + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + + sharp@0.33.5: + dependencies: + color: 4.2.3 + detect-libc: 2.0.3 + semver: 7.6.3 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.33.5 + '@img/sharp-darwin-x64': 0.33.5 + '@img/sharp-libvips-darwin-arm64': 1.0.4 + '@img/sharp-libvips-darwin-x64': 1.0.4 + '@img/sharp-libvips-linux-arm': 1.0.5 + '@img/sharp-libvips-linux-arm64': 1.0.4 + '@img/sharp-libvips-linux-s390x': 1.0.4 + '@img/sharp-libvips-linux-x64': 1.0.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + '@img/sharp-linux-arm': 0.33.5 + '@img/sharp-linux-arm64': 0.33.5 + '@img/sharp-linux-s390x': 0.33.5 + '@img/sharp-linux-x64': 0.33.5 + '@img/sharp-linuxmusl-arm64': 0.33.5 + '@img/sharp-linuxmusl-x64': 0.33.5 + '@img/sharp-wasm32': 0.33.5 + '@img/sharp-win32-ia32': 0.33.5 + '@img/sharp-win32-x64': 0.33.5 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + side-channel@1.0.6: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + object-inspect: 1.13.2 + + signal-exit@3.0.7: {} + + signal-exit@4.1.0: {} + + simple-swizzle@0.2.2: + dependencies: + is-arrayish: 0.3.2 + + sisteransi@1.0.5: {} + + size-sensor@1.0.2: {} + + slash@3.0.0: {} + + slice-ansi@5.0.0: + dependencies: + ansi-styles: 6.2.1 + is-fullwidth-code-point: 4.0.0 + + sortablejs@1.15.3: {} + + source-map-js@1.2.1: {} + + source-map-support@0.5.13: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map@0.6.1: {} + + source-map@0.7.4: {} + + space-separated-tokens@1.1.5: {} + + space-separated-tokens@2.0.2: {} + + spdx-correct@3.2.0: + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.20 + + spdx-exceptions@2.5.0: {} + + spdx-expression-parse@3.0.1: + dependencies: + spdx-exceptions: 2.5.0 + spdx-license-ids: 3.0.20 + + spdx-license-ids@3.0.20: {} + + sprintf-js@1.0.3: {} + + stack-utils@2.0.6: + dependencies: + escape-string-regexp: 2.0.0 + + stackframe@1.3.4: {} + + state-local@1.0.7: {} + + statuses@2.0.1: {} + + stop-iteration-iterator@1.0.0: + dependencies: + internal-slot: 1.0.7 + + storybook@8.3.6: + dependencies: + '@storybook/core': 8.3.6 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + stream-browserify@3.0.0: + dependencies: + inherits: 2.0.4 + readable-stream: 3.6.2 + + stream-http@3.2.0: + dependencies: + builtin-status-codes: 3.0.0 + inherits: 2.0.4 + readable-stream: 3.6.2 + xtend: 4.0.2 + + streamsearch@1.1.0: {} + + string-argv@0.3.2: {} + + string-length@4.0.2: + dependencies: + char-regex: 1.0.2 + strip-ansi: 6.0.1 + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string.prototype.includes@2.0.1: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + + string.prototype.matchall@4.0.11: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-symbols: 1.0.3 + internal-slot: 1.0.7 + regexp.prototype.flags: 1.5.3 + set-function-name: 2.0.2 + side-channel: 1.0.6 + + string.prototype.repeat@1.0.0: + dependencies: + define-properties: 1.2.1 + es-abstract: 1.23.3 + + string.prototype.trim@1.2.9: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + + string.prototype.trimend@1.0.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + + string.prototype.trimstart@1.0.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + stringify-entities@4.0.4: + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.1.0 + + strip-bom@3.0.0: {} + + strip-bom@4.0.0: {} + + strip-final-newline@2.0.0: {} + + strip-final-newline@3.0.0: {} + + strip-indent@3.0.0: + dependencies: + min-indent: 1.0.1 + + strip-indent@4.0.0: + dependencies: + min-indent: 1.0.1 + + strip-json-comments@3.1.1: {} + + style-loader@3.3.4(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3)): + dependencies: + webpack: 5.95.0(esbuild@0.23.1)(uglify-js@3.19.3) + + style-to-object@0.4.4: + dependencies: + inline-style-parser: 0.1.1 + + styled-jsx@5.1.1(@babel/core@7.25.8)(react@18.2.0): + dependencies: + client-only: 0.0.1 + react: 18.2.0 + optionalDependencies: + '@babel/core': 7.25.8 + + styled-jsx@5.1.6(@babel/core@7.25.8)(react@18.2.0): + dependencies: + client-only: 0.0.1 + react: 18.2.0 + optionalDependencies: + '@babel/core': 7.25.8 + + stylis@4.3.4: {} + + sucrase@3.35.0: + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + commander: 4.1.1 + glob: 10.4.5 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.6 + ts-interface-checker: 0.1.13 + + supports-color@5.5.0: + dependencies: + has-flag: 3.0.0 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-color@8.1.1: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + swr@2.2.5(react@18.2.0): + dependencies: + client-only: 0.0.1 + react: 18.2.0 + use-sync-external-store: 1.2.2(react@18.2.0) + + symbol-tree@3.2.4: {} + + synckit@0.6.2: + dependencies: + tslib: 2.8.0 + + tabbable@6.2.0: {} + + tailwind-merge@2.5.4: {} + + tailwindcss@3.4.14(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)): + dependencies: + '@alloc/quick-lru': 5.2.0 + arg: 5.0.2 + chokidar: 3.6.0 + didyoumean: 1.2.2 + dlv: 1.1.3 + fast-glob: 3.3.2 + glob-parent: 6.0.2 + is-glob: 4.0.3 + jiti: 1.21.6 + lilconfig: 2.1.0 + micromatch: 4.0.8 + normalize-path: 3.0.0 + object-hash: 3.0.0 + picocolors: 1.1.1 + postcss: 8.4.47 + postcss-import: 15.1.0(postcss@8.4.47) + postcss-js: 4.0.1(postcss@8.4.47) + postcss-load-config: 4.0.2(postcss@8.4.47)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)) + postcss-nested: 6.2.0(postcss@8.4.47) + postcss-selector-parser: 6.1.2 + resolve: 1.22.8 + sucrase: 3.35.0 + transitivePeerDependencies: + - ts-node + + tapable@2.2.1: {} + + telejson@7.2.0: + dependencies: + memoizerific: 1.11.3 + + terser-webpack-plugin@5.3.10(esbuild@0.23.1)(uglify-js@3.19.3)(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3)): + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + jest-worker: 27.5.1 + schema-utils: 3.3.0 + serialize-javascript: 6.0.2 + terser: 5.36.0 + webpack: 5.95.0(esbuild@0.23.1)(uglify-js@3.19.3) + optionalDependencies: + esbuild: 0.23.1 + uglify-js: 3.19.3 + + terser@5.36.0: + dependencies: + '@jridgewell/source-map': 0.3.6 + acorn: 8.13.0 + commander: 2.20.3 + source-map-support: 0.5.21 + + test-exclude@6.0.0: + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 7.2.3 + minimatch: 3.1.2 + + text-table@0.2.0: {} + + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + + throttle-debounce@2.3.0: {} + + timers-browserify@2.0.12: + dependencies: + setimmediate: 1.0.5 + + tiny-invariant@1.2.0: {} + + tiny-invariant@1.3.3: {} + + tinyrainbow@1.2.0: {} + + tinyspy@3.0.2: {} + + tmpl@1.0.5: {} + + to-fast-properties@2.0.0: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + toggle-selection@1.0.6: {} + + toidentifier@1.0.1: {} + + tough-cookie@4.1.4: + dependencies: + psl: 1.9.0 + punycode: 2.3.1 + universalify: 0.2.0 + url-parse: 1.5.10 + + tr46@3.0.0: + dependencies: + punycode: 2.3.1 + + trim-lines@3.0.1: {} + + trough@2.2.0: {} + + ts-api-utils@1.3.0(typescript@4.9.5): + dependencies: + typescript: 4.9.5 + + ts-dedent@2.2.0: {} + + ts-interface-checker@0.1.13: {} + + ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.11 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 18.15.0 + acorn: 8.13.0 + acorn-walk: 8.3.4 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 4.9.5 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + + ts-pnp@1.2.0(typescript@4.9.5): + optionalDependencies: + typescript: 4.9.5 + + tsconfig-paths-webpack-plugin@4.1.0: + dependencies: + chalk: 4.1.2 + enhanced-resolve: 5.17.1 + tsconfig-paths: 4.2.0 + + tsconfig-paths@3.15.0: + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + + tsconfig-paths@4.2.0: + dependencies: + json5: 2.2.3 + minimist: 1.2.8 + strip-bom: 3.0.0 + + tslib@1.14.1: {} + + tslib@2.3.0: {} + + tslib@2.8.0: {} + + tsutils@3.21.0(typescript@4.9.5): + dependencies: + tslib: 1.14.1 + typescript: 4.9.5 + + tty-browserify@0.0.1: {} + + tween-functions@1.2.0: {} + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + type-detect@4.0.8: {} + + type-fest@0.20.2: {} + + type-fest@0.21.3: {} + + type-fest@0.6.0: {} + + type-fest@0.8.1: {} + + type-fest@1.4.0: {} + + type-fest@2.19.0: {} + + type-is@1.6.18: + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + + typed-array-buffer@1.0.2: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-typed-array: 1.1.13 + + typed-array-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + + typed-array-byte-offset@1.0.2: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + + typed-array-length@1.0.6: + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + possible-typed-array-names: 1.0.0 + + typescript@4.9.5: {} + + uglify-js@3.19.3: {} + + unbox-primitive@1.0.2: + dependencies: + call-bind: 1.0.7 + has-bigints: 1.0.2 + has-symbols: 1.0.3 + which-boxed-primitive: 1.0.2 + + undici-types@6.19.8: {} + + unicode-canonical-property-names-ecmascript@2.0.1: {} + + unicode-match-property-ecmascript@2.0.0: + dependencies: + unicode-canonical-property-names-ecmascript: 2.0.1 + unicode-property-aliases-ecmascript: 2.1.0 + + unicode-match-property-value-ecmascript@2.2.0: {} + + unicode-property-aliases-ecmascript@2.1.0: {} + + unified@10.1.2: + dependencies: + '@types/unist': 2.0.11 + bail: 2.0.2 + extend: 3.0.2 + is-buffer: 2.0.5 + is-plain-obj: 4.1.0 + trough: 2.2.0 + vfile: 5.3.7 + + unist-util-find-after@4.0.1: + dependencies: + '@types/unist': 2.0.11 + unist-util-is: 5.2.1 + + unist-util-generated@2.0.1: {} + + unist-util-is@5.2.1: + dependencies: + '@types/unist': 2.0.11 + + unist-util-is@6.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position-from-estree@1.1.2: + dependencies: + '@types/unist': 2.0.11 + + unist-util-position@4.0.4: + dependencies: + '@types/unist': 2.0.11 + + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-remove-position@4.0.2: + dependencies: + '@types/unist': 2.0.11 + unist-util-visit: 4.1.2 + + unist-util-stringify-position@2.0.3: + dependencies: + '@types/unist': 2.0.11 + + unist-util-stringify-position@3.0.3: + dependencies: + '@types/unist': 2.0.11 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-parents@5.1.3: + dependencies: + '@types/unist': 2.0.11 + unist-util-is: 5.2.1 + + unist-util-visit-parents@6.0.1: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.0 + + unist-util-visit@4.1.2: + dependencies: + '@types/unist': 2.0.11 + unist-util-is: 5.2.1 + unist-util-visit-parents: 5.1.3 + + unist-util-visit@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.0 + unist-util-visit-parents: 6.0.1 + + universalify@0.2.0: {} + + universalify@2.0.1: {} + + unpipe@1.0.0: {} + + unplugin@1.14.1(webpack-sources@3.2.3): + dependencies: + acorn: 8.13.0 + webpack-virtual-modules: 0.6.2 + optionalDependencies: + webpack-sources: 3.2.3 + + update-browserslist-db@1.1.1(browserslist@4.24.0): + dependencies: + browserslist: 4.24.0 + escalade: 3.2.0 + picocolors: 1.1.1 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + url-parse@1.5.10: + dependencies: + querystringify: 2.2.0 + requires-port: 1.0.0 + + url@0.11.4: + dependencies: + punycode: 1.4.1 + qs: 6.13.0 + + use-context-selector@1.4.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(scheduler@0.23.2): + dependencies: + react: 18.2.0 + scheduler: 0.23.2 + optionalDependencies: + react-dom: 18.2.0(react@18.2.0) + + use-strict@1.0.1: {} + + use-sync-external-store@1.2.2(react@18.2.0): + dependencies: + react: 18.2.0 + + util-deprecate@1.0.2: {} + + util@0.12.5: + dependencies: + inherits: 2.0.4 + is-arguments: 1.1.1 + is-generator-function: 1.0.10 + is-typed-array: 1.1.13 + which-typed-array: 1.1.15 + + utila@0.4.0: {} + + utils-merge@1.0.1: {} + + uuid@9.0.1: {} + + uvu@0.5.6: + dependencies: + dequal: 2.0.3 + diff: 5.2.0 + kleur: 4.1.5 + sade: 1.8.1 + + v8-compile-cache-lib@3.0.1: {} + + v8-to-istanbul@9.3.0: + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + '@types/istanbul-lib-coverage': 2.0.6 + convert-source-map: 2.0.0 + + validate-npm-package-license@3.0.4: + dependencies: + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + + vary@1.1.2: {} + + vfile-location@4.1.0: + dependencies: + '@types/unist': 2.0.11 + vfile: 5.3.7 + + vfile-location@5.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile: 6.0.3 + + vfile-message@3.1.4: + dependencies: + '@types/unist': 2.0.11 + unist-util-stringify-position: 3.0.3 + + vfile-message@4.0.2: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + + vfile@5.3.7: + dependencies: + '@types/unist': 2.0.11 + is-buffer: 2.0.5 + unist-util-stringify-position: 3.0.3 + vfile-message: 3.1.4 + + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.2 + + vite-code-inspector-plugin@0.13.0: + dependencies: + code-inspector-core: 0.13.0 + transitivePeerDependencies: + - supports-color + + vm-browserify@1.1.2: {} + + void-elements@3.1.0: {} + + vue-eslint-parser@9.4.3(eslint@8.57.1): + dependencies: + debug: 4.3.7 + eslint: 8.57.1 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.6.0 + lodash: 4.17.21 + semver: 7.6.3 + transitivePeerDependencies: + - supports-color + + w3c-xmlserializer@4.0.0: + dependencies: + xml-name-validator: 4.0.0 + + walker@1.0.8: + dependencies: + makeerror: 1.0.12 + + watchpack@2.4.2: + dependencies: + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + + web-namespaces@2.0.1: {} + + web-worker@1.3.0: {} + + webidl-conversions@7.0.0: {} + + webpack-code-inspector-plugin@0.13.0: + dependencies: + code-inspector-core: 0.13.0 + transitivePeerDependencies: + - supports-color + + webpack-dev-middleware@6.1.3(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3)): + dependencies: + colorette: 2.0.20 + memfs: 3.5.3 + mime-types: 2.1.35 + range-parser: 1.2.1 + schema-utils: 4.2.0 + optionalDependencies: + webpack: 5.95.0(esbuild@0.23.1)(uglify-js@3.19.3) + + webpack-hot-middleware@2.26.1: + dependencies: + ansi-html-community: 0.0.8 + html-entities: 2.5.2 + strip-ansi: 6.0.1 + + webpack-sources@3.2.3: {} + + webpack-virtual-modules@0.6.2: {} + + webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3): + dependencies: + '@types/estree': 1.0.6 + '@webassemblyjs/ast': 1.12.1 + '@webassemblyjs/wasm-edit': 1.12.1 + '@webassemblyjs/wasm-parser': 1.12.1 + acorn: 8.13.0 + acorn-import-attributes: 1.9.5(acorn@8.13.0) + browserslist: 4.24.0 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.17.1 + es-module-lexer: 1.5.4 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + json-parse-even-better-errors: 2.3.1 + loader-runner: 4.3.0 + mime-types: 2.1.35 + neo-async: 2.6.2 + schema-utils: 3.3.0 + tapable: 2.2.1 + terser-webpack-plugin: 5.3.10(esbuild@0.23.1)(uglify-js@3.19.3)(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3)) + watchpack: 2.4.2 + webpack-sources: 3.2.3 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - uglify-js + + whatwg-encoding@2.0.0: + dependencies: + iconv-lite: 0.6.3 + + whatwg-mimetype@3.0.0: {} + + whatwg-url@11.0.0: + dependencies: + tr46: 3.0.0 + webidl-conversions: 7.0.0 + + which-boxed-primitive@1.0.2: + dependencies: + is-bigint: 1.0.4 + is-boolean-object: 1.1.2 + is-number-object: 1.0.7 + is-string: 1.0.7 + is-symbol: 1.0.4 + + which-builtin-type@1.1.4: + dependencies: + function.prototype.name: 1.1.6 + has-tostringtag: 1.0.2 + is-async-function: 2.0.0 + is-date-object: 1.0.5 + is-finalizationregistry: 1.0.2 + is-generator-function: 1.0.10 + is-regex: 1.1.4 + is-weakref: 1.0.2 + isarray: 2.0.5 + which-boxed-primitive: 1.0.2 + which-collection: 1.0.2 + which-typed-array: 1.1.15 + + which-collection@1.0.2: + dependencies: + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.3 + + which-typed-array@1.1.15: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.2 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + word-wrap@1.2.5: {} + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 4.2.3 + strip-ansi: 7.1.0 + + wrappy@1.0.2: {} + + write-file-atomic@4.0.2: + dependencies: + imurmurhash: 0.1.4 + signal-exit: 3.0.7 + + ws@8.18.0: {} + + xml-name-validator@4.0.0: {} + + xmlchars@2.2.0: {} + + xtend@4.0.2: {} + + y18n@5.0.8: {} + + yallist@3.1.1: {} + + yaml-eslint-parser@1.2.3: + dependencies: + eslint-visitor-keys: 3.4.3 + lodash: 4.17.21 + yaml: 2.6.0 + + yaml@1.10.2: {} + + yaml@2.3.1: {} + + yaml@2.6.0: {} + + yargs-parser@21.1.1: {} + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + yjs@13.6.20: + dependencies: + lib0: 0.2.98 + + yn@3.1.1: {} + + yocto-queue@0.1.0: {} + + yocto-queue@1.1.1: {} + + zod@3.23.8: {} + + zrender@5.6.0: + dependencies: + tslib: 2.3.0 + + zundo@2.2.0(zustand@4.5.5(@types/react@18.2.79)(immer@9.0.21)(react@18.2.0)): + dependencies: + zustand: 4.5.5(@types/react@18.2.79)(immer@9.0.21)(react@18.2.0) + + zustand@4.5.5(@types/react@18.2.79)(immer@9.0.21)(react@18.2.0): + dependencies: + use-sync-external-store: 1.2.2(react@18.2.0) + optionalDependencies: + '@types/react': 18.2.79 + immer: 9.0.21 + react: 18.2.0 + + zwitch@2.0.4: {} diff --git a/web/yarn.lock b/web/yarn.lock deleted file mode 100644 index bf731b0ffa..0000000000 --- a/web/yarn.lock +++ /dev/null @@ -1,14208 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@adobe/css-tools@^4.4.0": - version "4.4.0" - resolved "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.0.tgz#728c484f4e10df03d5a3acd0d8adcbbebff8ad63" - integrity sha512-Ff9+ksdQQB3rMncgqDK78uLznstjyfIf2Arnh22pW8kBpLs6rpKDwgnZT46hin5Hl1WzazzK64DOrhSwYpS7bQ== - -"@alloc/quick-lru@^5.2.0": - version "5.2.0" - resolved "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz" - integrity sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw== - -"@ampproject/remapping@^2.2.0": - version "2.3.0" - resolved "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz#ed441b6fa600072520ce18b43d2c8cc8caecc7f4" - integrity sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw== - dependencies: - "@jridgewell/gen-mapping" "^0.3.5" - "@jridgewell/trace-mapping" "^0.3.24" - -"@antfu/eslint-config-basic@0.36.0": - version "0.36.0" - resolved "https://registry.npmjs.org/@antfu/eslint-config-basic/-/eslint-config-basic-0.36.0.tgz" - integrity sha512-2b3ZB7pO00nxAERDXo82iYPjLQ4l/AOMm0CTKmGmqWbN3RB33EIQWzYheZRboSbAVzWpI1/3rg/Gu+7xYVMYHA== - dependencies: - eslint-plugin-antfu "0.36.0" - eslint-plugin-eslint-comments "^3.2.0" - eslint-plugin-html "^7.1.0" - eslint-plugin-import "^2.27.5" - eslint-plugin-jsonc "^2.6.0" - eslint-plugin-markdown "^3.0.0" - eslint-plugin-n "^15.6.1" - eslint-plugin-no-only-tests "^3.1.0" - eslint-plugin-promise "^6.1.1" - eslint-plugin-unicorn "^45.0.2" - eslint-plugin-unused-imports "^2.0.0" - eslint-plugin-yml "^1.5.0" - jsonc-eslint-parser "^2.1.0" - yaml-eslint-parser "^1.1.0" - -"@antfu/eslint-config-ts@0.36.0": - version "0.36.0" - resolved "https://registry.npmjs.org/@antfu/eslint-config-ts/-/eslint-config-ts-0.36.0.tgz" - integrity sha512-I/h2ZOPBIqgnALG2fQp6lOBsOXk51QwLDumyEayt7GRnitdP4o9D8i+YAPowrMJ8M3kU7puQUyhWuJmZLgo57A== - dependencies: - "@antfu/eslint-config-basic" "0.36.0" - "@typescript-eslint/eslint-plugin" "^5.53.0" - "@typescript-eslint/parser" "^5.53.0" - eslint-plugin-jest "^27.2.1" - -"@antfu/eslint-config-vue@0.36.0": - version "0.36.0" - resolved "https://registry.npmjs.org/@antfu/eslint-config-vue/-/eslint-config-vue-0.36.0.tgz" - integrity sha512-YuTcNlVlrEWX1ESOiPgr+e2Walfd6xt3Toa0kAKJxq2aBS1RWqIi1l3zIVGCHaX72lOrSXNmQ7bryaZyGADGDg== - dependencies: - "@antfu/eslint-config-basic" "0.36.0" - "@antfu/eslint-config-ts" "0.36.0" - eslint-plugin-vue "^9.9.0" - local-pkg "^0.4.3" - -"@antfu/eslint-config@^0.36.0": - version "0.36.0" - resolved "https://registry.npmjs.org/@antfu/eslint-config/-/eslint-config-0.36.0.tgz" - integrity sha512-otZ9PfKRT3gnGMMX1gS8URTNPMPCZ69K5jHZvLkYojru0gLBZ3IO5fCvjEZpWqOyIUHtAgg6NWELf1DbEF+NDw== - dependencies: - "@antfu/eslint-config-vue" "0.36.0" - "@typescript-eslint/eslint-plugin" "^5.53.0" - "@typescript-eslint/parser" "^5.53.0" - eslint-plugin-eslint-comments "^3.2.0" - eslint-plugin-html "^7.1.0" - eslint-plugin-import "^2.27.5" - eslint-plugin-jsonc "^2.6.0" - eslint-plugin-n "^15.6.1" - eslint-plugin-promise "^6.1.1" - eslint-plugin-unicorn "^45.0.2" - eslint-plugin-vue "^9.9.0" - eslint-plugin-yml "^1.5.0" - jsonc-eslint-parser "^2.1.0" - yaml-eslint-parser "^1.1.0" - -"@babel/code-frame@^7.0.0": - version "7.21.4" - resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz" - integrity sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g== - dependencies: - "@babel/highlight" "^7.18.6" - -"@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.24.7": - version "7.24.7" - resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz#882fd9e09e8ee324e496bd040401c6f046ef4465" - integrity sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA== - dependencies: - "@babel/highlight" "^7.24.7" - picocolors "^1.0.0" - -"@babel/code-frame@^7.16.7", "@babel/code-frame@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.25.7.tgz#438f2c524071531d643c6f0188e1e28f130cebc7" - integrity sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g== - dependencies: - "@babel/highlight" "^7.25.7" - picocolors "^1.0.0" - -"@babel/compat-data@^7.22.6", "@babel/compat-data@^7.25.7", "@babel/compat-data@^7.25.8": - version "7.25.8" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.25.8.tgz#0376e83df5ab0eb0da18885c0140041f0747a402" - integrity sha512-ZsysZyXY4Tlx+Q53XdnOFmqwfB9QDTHYxaZYajWRoBLuLEAwI2UIbtxOjWh/cFaa9IKUlcB+DDuoskLuKu56JA== - -"@babel/compat-data@^7.24.8": - version "7.24.9" - resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.9.tgz#53eee4e68f1c1d0282aa0eb05ddb02d033fc43a0" - integrity sha512-e701mcfApCJqMMueQI0Fb68Amflj83+dvAvHawoBpAz+GDjCIyGHzNwnefjsWJ3xiYAqqiQFoWbspGYBdb2/ng== - -"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.23.9": - version "7.24.9" - resolved "https://registry.npmjs.org/@babel/core/-/core-7.24.9.tgz#dc07c9d307162c97fa9484ea997ade65841c7c82" - integrity sha512-5e3FI4Q3M3Pbr21+5xJwCv6ZT6KmGkI0vw3Tozy5ODAQFTIWe37iT8Cr7Ice2Ntb+M3iSKCEWMB1MBgKrW3whg== - dependencies: - "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.24.7" - "@babel/generator" "^7.24.9" - "@babel/helper-compilation-targets" "^7.24.8" - "@babel/helper-module-transforms" "^7.24.9" - "@babel/helpers" "^7.24.8" - "@babel/parser" "^7.24.8" - "@babel/template" "^7.24.7" - "@babel/traverse" "^7.24.8" - "@babel/types" "^7.24.9" - convert-source-map "^2.0.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.2.3" - semver "^6.3.1" - -"@babel/core@^7.18.9", "@babel/core@^7.24.4": - version "7.25.8" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.25.8.tgz#a57137d2a51bbcffcfaeba43cb4dd33ae3e0e1c6" - integrity sha512-Oixnb+DzmRT30qu9d3tJSQkxuygWm32DFykT4bRoORPa9hZ/L4KhVB/XiRm6KG+roIEM7DBQlmg27kw2HZkdZg== - dependencies: - "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.25.7" - "@babel/generator" "^7.25.7" - "@babel/helper-compilation-targets" "^7.25.7" - "@babel/helper-module-transforms" "^7.25.7" - "@babel/helpers" "^7.25.7" - "@babel/parser" "^7.25.8" - "@babel/template" "^7.25.7" - "@babel/traverse" "^7.25.7" - "@babel/types" "^7.25.8" - convert-source-map "^2.0.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.2.3" - semver "^6.3.1" - -"@babel/generator@^7.24.8", "@babel/generator@^7.24.9", "@babel/generator@^7.7.2": - version "7.24.10" - resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.24.10.tgz#a4ab681ec2a78bbb9ba22a3941195e28a81d8e76" - integrity sha512-o9HBZL1G2129luEUlG1hB4N/nlYNWHnpwlND9eOMclRqqu1YDy2sSYVCFUZwl8I1Gxh+QSRrP2vD7EpUmFVXxg== - dependencies: - "@babel/types" "^7.24.9" - "@jridgewell/gen-mapping" "^0.3.5" - "@jridgewell/trace-mapping" "^0.3.25" - jsesc "^2.5.1" - -"@babel/generator@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.25.7.tgz#de86acbeb975a3e11ee92dd52223e6b03b479c56" - integrity sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA== - dependencies: - "@babel/types" "^7.25.7" - "@jridgewell/gen-mapping" "^0.3.5" - "@jridgewell/trace-mapping" "^0.3.25" - jsesc "^3.0.2" - -"@babel/helper-annotate-as-pure@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.7.tgz#63f02dbfa1f7cb75a9bdb832f300582f30bb8972" - integrity sha512-4xwU8StnqnlIhhioZf1tqnVWeQ9pvH/ujS8hRfw/WOza+/a+1qv69BWNy+oY231maTCWgKWhfBU7kDpsds6zAA== - dependencies: - "@babel/types" "^7.25.7" - -"@babel/helper-builder-binary-assignment-operator-visitor@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.25.7.tgz#d721650c1f595371e0a23ee816f1c3c488c0d622" - integrity sha512-12xfNeKNH7jubQNm7PAkzlLwEmCs1tfuX3UjIw6vP6QXi+leKh6+LyC/+Ed4EIQermwd58wsyh070yjDHFlNGg== - dependencies: - "@babel/traverse" "^7.25.7" - "@babel/types" "^7.25.7" - -"@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.7.tgz#11260ac3322dda0ef53edfae6e97b961449f5fa4" - integrity sha512-DniTEax0sv6isaw6qSQSfV4gVRNtw2rte8HHM45t9ZR0xILaufBRNkpMifCRiAPyvL4ACD6v0gfCwCmtOQaV4A== - dependencies: - "@babel/compat-data" "^7.25.7" - "@babel/helper-validator-option" "^7.25.7" - browserslist "^4.24.0" - lru-cache "^5.1.1" - semver "^6.3.1" - -"@babel/helper-compilation-targets@^7.24.8": - version "7.24.8" - resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.8.tgz#b607c3161cd9d1744977d4f97139572fe778c271" - integrity sha512-oU+UoqCHdp+nWVDkpldqIQL/i/bvAv53tRqLG/s+cOXxe66zOYLU7ar/Xs3LdmBihrUMEUhwu6dMZwbNOYDwvw== - dependencies: - "@babel/compat-data" "^7.24.8" - "@babel/helper-validator-option" "^7.24.8" - browserslist "^4.23.1" - lru-cache "^5.1.1" - semver "^6.3.1" - -"@babel/helper-create-class-features-plugin@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.7.tgz#5d65074c76cae75607421c00d6bd517fe1892d6b" - integrity sha512-bD4WQhbkx80mAyj/WCm4ZHcF4rDxkoLFO6ph8/5/mQ3z4vAzltQXAmbc7GvVJx5H+lk5Mi5EmbTeox5nMGCsbw== - dependencies: - "@babel/helper-annotate-as-pure" "^7.25.7" - "@babel/helper-member-expression-to-functions" "^7.25.7" - "@babel/helper-optimise-call-expression" "^7.25.7" - "@babel/helper-replace-supers" "^7.25.7" - "@babel/helper-skip-transparent-expression-wrappers" "^7.25.7" - "@babel/traverse" "^7.25.7" - semver "^6.3.1" - -"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.7.tgz#dcb464f0e2cdfe0c25cc2a0a59c37ab940ce894e" - integrity sha512-byHhumTj/X47wJ6C6eLpK7wW/WBEcnUeb7D0FNc/jFQnQVw7DOso3Zz5u9x/zLrFVkHa89ZGDbkAa1D54NdrCQ== - dependencies: - "@babel/helper-annotate-as-pure" "^7.25.7" - regexpu-core "^6.1.1" - semver "^6.3.1" - -"@babel/helper-define-polyfill-provider@^0.6.2": - version "0.6.2" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz#18594f789c3594acb24cfdb4a7f7b7d2e8bd912d" - integrity sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ== - dependencies: - "@babel/helper-compilation-targets" "^7.22.6" - "@babel/helper-plugin-utils" "^7.22.5" - debug "^4.1.1" - lodash.debounce "^4.0.8" - resolve "^1.14.2" - -"@babel/helper-environment-visitor@^7.24.7": - version "7.24.7" - resolved "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz#4b31ba9551d1f90781ba83491dd59cf9b269f7d9" - integrity sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ== - dependencies: - "@babel/types" "^7.24.7" - -"@babel/helper-function-name@^7.24.7": - version "7.24.7" - resolved "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz#75f1e1725742f39ac6584ee0b16d94513da38dd2" - integrity sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA== - dependencies: - "@babel/template" "^7.24.7" - "@babel/types" "^7.24.7" - -"@babel/helper-hoist-variables@^7.24.7": - version "7.24.7" - resolved "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz#b4ede1cde2fd89436397f30dc9376ee06b0f25ee" - integrity sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ== - dependencies: - "@babel/types" "^7.24.7" - -"@babel/helper-member-expression-to-functions@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.7.tgz#541a33b071f0355a63a0fa4bdf9ac360116b8574" - integrity sha512-O31Ssjd5K6lPbTX9AAYpSKrZmLeagt9uwschJd+Ixo6QiRyfpvgtVQp8qrDR9UNFjZ8+DO34ZkdrN+BnPXemeA== - dependencies: - "@babel/traverse" "^7.25.7" - "@babel/types" "^7.25.7" - -"@babel/helper-module-imports@^7.24.7": - version "7.24.7" - resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz#f2f980392de5b84c3328fc71d38bd81bbb83042b" - integrity sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA== - dependencies: - "@babel/traverse" "^7.24.7" - "@babel/types" "^7.24.7" - -"@babel/helper-module-imports@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.25.7.tgz#dba00d9523539152906ba49263e36d7261040472" - integrity sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw== - dependencies: - "@babel/traverse" "^7.25.7" - "@babel/types" "^7.25.7" - -"@babel/helper-module-transforms@^7.24.9": - version "7.24.9" - resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.9.tgz#e13d26306b89eea569180868e652e7f514de9d29" - integrity sha512-oYbh+rtFKj/HwBQkFlUzvcybzklmVdVV3UU+mN7n2t/q3yGHbuVdNxyFvSBO1tfvjyArpHNcWMAzsSPdyI46hw== - dependencies: - "@babel/helper-environment-visitor" "^7.24.7" - "@babel/helper-module-imports" "^7.24.7" - "@babel/helper-simple-access" "^7.24.7" - "@babel/helper-split-export-declaration" "^7.24.7" - "@babel/helper-validator-identifier" "^7.24.7" - -"@babel/helper-module-transforms@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.25.7.tgz#2ac9372c5e001b19bc62f1fe7d96a18cb0901d1a" - integrity sha512-k/6f8dKG3yDz/qCwSM+RKovjMix563SLxQFo0UhRNo239SP6n9u5/eLtKD6EAjwta2JHJ49CsD8pms2HdNiMMQ== - dependencies: - "@babel/helper-module-imports" "^7.25.7" - "@babel/helper-simple-access" "^7.25.7" - "@babel/helper-validator-identifier" "^7.25.7" - "@babel/traverse" "^7.25.7" - -"@babel/helper-optimise-call-expression@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.7.tgz#1de1b99688e987af723eed44fa7fc0ee7b97d77a" - integrity sha512-VAwcwuYhv/AT+Vfr28c9y6SHzTan1ryqrydSTFGjU0uDJHw3uZ+PduI8plCLkRsDnqK2DMEDmwrOQRsK/Ykjng== - dependencies: - "@babel/types" "^7.25.7" - -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.24.7", "@babel/helper-plugin-utils@^7.8.0": - version "7.24.8" - resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz#94ee67e8ec0e5d44ea7baeb51e571bd26af07878" - integrity sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg== - -"@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.7.tgz#8ec5b21812d992e1ef88a9b068260537b6f0e36c" - integrity sha512-eaPZai0PiqCi09pPs3pAFfl/zYgGaE6IdXtYvmf0qlcDTd3WCtO7JWCcRd64e0EQrcYgiHibEZnOGsSY4QSgaw== - -"@babel/helper-remap-async-to-generator@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.7.tgz#9efdc39df5f489bcd15533c912b6c723a0a65021" - integrity sha512-kRGE89hLnPfcz6fTrlNU+uhgcwv0mBE4Gv3P9Ke9kLVJYpi4AMVVEElXvB5CabrPZW4nCM8P8UyyjrzCM0O2sw== - dependencies: - "@babel/helper-annotate-as-pure" "^7.25.7" - "@babel/helper-wrap-function" "^7.25.7" - "@babel/traverse" "^7.25.7" - -"@babel/helper-replace-supers@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.25.7.tgz#38cfda3b6e990879c71d08d0fef9236b62bd75f5" - integrity sha512-iy8JhqlUW9PtZkd4pHM96v6BdJ66Ba9yWSE4z0W4TvSZwLBPkyDsiIU3ENe4SmrzRBs76F7rQXTy1lYC49n6Lw== - dependencies: - "@babel/helper-member-expression-to-functions" "^7.25.7" - "@babel/helper-optimise-call-expression" "^7.25.7" - "@babel/traverse" "^7.25.7" - -"@babel/helper-simple-access@^7.24.7": - version "7.24.7" - resolved "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz#bcade8da3aec8ed16b9c4953b74e506b51b5edb3" - integrity sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg== - dependencies: - "@babel/traverse" "^7.24.7" - "@babel/types" "^7.24.7" - -"@babel/helper-simple-access@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.25.7.tgz#5eb9f6a60c5d6b2e0f76057004f8dacbddfae1c0" - integrity sha512-FPGAkJmyoChQeM+ruBGIDyrT2tKfZJO8NcxdC+CWNJi7N8/rZpSxK7yvBJ5O/nF1gfu5KzN7VKG3YVSLFfRSxQ== - dependencies: - "@babel/traverse" "^7.25.7" - "@babel/types" "^7.25.7" - -"@babel/helper-skip-transparent-expression-wrappers@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.7.tgz#382831c91038b1a6d32643f5f49505b8442cb87c" - integrity sha512-pPbNbchZBkPMD50K0p3JGcFMNLVUCuU/ABybm/PGNj4JiHrpmNyqqCphBk4i19xXtNV0JhldQJJtbSW5aUvbyA== - dependencies: - "@babel/traverse" "^7.25.7" - "@babel/types" "^7.25.7" - -"@babel/helper-split-export-declaration@^7.24.7": - version "7.24.7" - resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz#83949436890e07fa3d6873c61a96e3bbf692d856" - integrity sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA== - dependencies: - "@babel/types" "^7.24.7" - -"@babel/helper-string-parser@^7.24.8": - version "7.24.8" - resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz#5b3329c9a58803d5df425e5785865881a81ca48d" - integrity sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ== - -"@babel/helper-string-parser@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.25.7.tgz#d50e8d37b1176207b4fe9acedec386c565a44a54" - integrity sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g== - -"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": - version "7.19.1" - resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz" - integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== - -"@babel/helper-validator-identifier@^7.24.7": - version "7.24.7" - resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz#75b889cfaf9e35c2aaf42cf0d72c8e91719251db" - integrity sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w== - -"@babel/helper-validator-identifier@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.7.tgz#77b7f60c40b15c97df735b38a66ba1d7c3e93da5" - integrity sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg== - -"@babel/helper-validator-option@^7.24.8": - version "7.24.8" - resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz#3725cdeea8b480e86d34df15304806a06975e33d" - integrity sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q== - -"@babel/helper-validator-option@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.25.7.tgz#97d1d684448228b30b506d90cace495d6f492729" - integrity sha512-ytbPLsm+GjArDYXJ8Ydr1c/KJuutjF2besPNbIZnZ6MKUxi/uTA22t2ymmA4WFjZFpjiAMO0xuuJPqK2nvDVfQ== - -"@babel/helper-wrap-function@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.25.7.tgz#9f6021dd1c4fdf4ad515c809967fc4bac9a70fe7" - integrity sha512-MA0roW3JF2bD1ptAaJnvcabsVlNQShUaThyJbCDD4bCp8NEgiFvpoqRI2YS22hHlc2thjO/fTg2ShLMC3jygAg== - dependencies: - "@babel/template" "^7.25.7" - "@babel/traverse" "^7.25.7" - "@babel/types" "^7.25.7" - -"@babel/helpers@^7.24.8": - version "7.24.8" - resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.8.tgz#2820d64d5d6686cca8789dd15b074cd862795873" - integrity sha512-gV2265Nkcz7weJJfvDoAEVzC1e2OTDpkGbEsebse8koXUJUXPsCMi7sRo/+SPMuMZ9MtUPnGwITTnQnU5YjyaQ== - dependencies: - "@babel/template" "^7.24.7" - "@babel/types" "^7.24.8" - -"@babel/helpers@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.25.7.tgz#091b52cb697a171fe0136ab62e54e407211f09c2" - integrity sha512-Sv6pASx7Esm38KQpF/U/OXLwPPrdGHNKoeblRxgZRLXnAtnkEe4ptJPDtAZM7fBLadbc1Q07kQpSiGQ0Jg6tRA== - dependencies: - "@babel/template" "^7.25.7" - "@babel/types" "^7.25.7" - -"@babel/highlight@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz" - integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== - dependencies: - "@babel/helper-validator-identifier" "^7.18.6" - chalk "^2.0.0" - js-tokens "^4.0.0" - -"@babel/highlight@^7.24.7": - version "7.24.7" - resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz#a05ab1df134b286558aae0ed41e6c5f731bf409d" - integrity sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw== - dependencies: - "@babel/helper-validator-identifier" "^7.24.7" - chalk "^2.4.2" - js-tokens "^4.0.0" - picocolors "^1.0.0" - -"@babel/highlight@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.25.7.tgz#20383b5f442aa606e7b5e3043b0b1aafe9f37de5" - integrity sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw== - dependencies: - "@babel/helper-validator-identifier" "^7.25.7" - chalk "^2.4.2" - js-tokens "^4.0.0" - picocolors "^1.0.0" - -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.24.7", "@babel/parser@^7.24.8": - version "7.24.8" - resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.24.8.tgz#58a4dbbcad7eb1d48930524a3fd93d93e9084c6f" - integrity sha512-WzfbgXOkGzZiXXCqk43kKwZjzwx4oulxZi3nq2TYL9mOjQv6kYwul9mz6ID36njuL7Xkp6nJEfok848Zj10j/w== - -"@babel/parser@^7.24.4": - version "7.24.4" - resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.24.4.tgz" - integrity sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg== - -"@babel/parser@^7.25.4": - version "7.25.6" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.25.6.tgz#85660c5ef388cbbf6e3d2a694ee97a38f18afe2f" - integrity sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q== - dependencies: - "@babel/types" "^7.25.6" - -"@babel/parser@^7.25.7", "@babel/parser@^7.25.8": - version "7.25.8" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.25.8.tgz#f6aaf38e80c36129460c1657c0762db584c9d5e2" - integrity sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ== - dependencies: - "@babel/types" "^7.25.8" - -"@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.7.tgz#93969ac50ef4d68b2504b01b758af714e4cbdd64" - integrity sha512-UV9Lg53zyebzD1DwQoT9mzkEKa922LNUp5YkTJ6Uta0RbyXaQNUgcvSt7qIu1PpPzVb6rd10OVNTzkyBGeVmxQ== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - "@babel/traverse" "^7.25.7" - -"@babel/plugin-bugfix-safari-class-field-initializer-scope@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.7.tgz#a338d611adb9dcd599b8b1efa200c88ebeffe046" - integrity sha512-GDDWeVLNxRIkQTnJn2pDOM1pkCgYdSqPeT1a9vh9yIqu2uzzgw1zcqEb+IJOhy+dTBMlNdThrDIksr2o09qrrQ== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.7.tgz#c5f755e911dfac7ef6957300c0f9c4a8c18c06f4" - integrity sha512-wxyWg2RYaSUYgmd9MR0FyRGyeOMQE/Uzr1wzd/g5cf5bwi9A4v6HFdDm7y1MgDtod/fLOSTZY6jDgV0xU9d5bA== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.7.tgz#3b7ea04492ded990978b6deaa1dfca120ad4455a" - integrity sha512-Xwg6tZpLxc4iQjorYsyGMyfJE7nP5MV8t/Ka58BgiA7Jw0fRqQNcANlLfdJ/yvBt9z9LD2We+BEkT7vLqZRWng== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - "@babel/helper-skip-transparent-expression-wrappers" "^7.25.7" - "@babel/plugin-transform-optional-chaining" "^7.25.7" - -"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.7.tgz#9622b1d597a703aa3a921e6f58c9c2d9a028d2c5" - integrity sha512-UVATLMidXrnH+GMUIuxq55nejlj02HP7F5ETyBONzP6G87fPBogG4CH6kxrSrdIuAjdwNO9VzyaYsrZPscWUrw== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - "@babel/traverse" "^7.25.7" - -"@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2": - version "7.21.0-placeholder-for-preset-env.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz#7844f9289546efa9febac2de4cfe358a050bd703" - integrity sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w== - -"@babel/plugin-syntax-async-generators@^7.8.4": - version "7.8.4" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" - integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-bigint@^7.8.3": - version "7.8.3" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" - integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-class-properties@^7.8.3": - version "7.12.13" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" - integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== - dependencies: - "@babel/helper-plugin-utils" "^7.12.13" - -"@babel/plugin-syntax-dynamic-import@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" - integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-import-assertions@^7.24.1", "@babel/plugin-syntax-import-assertions@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.25.7.tgz#8ce248f9f4ed4b7ed4cb2e0eb4ed9efd9f52921f" - integrity sha512-ZvZQRmME0zfJnDQnVBKYzHxXT7lYBB3Revz1GuS7oLXWMgqUPX4G+DDbT30ICClht9WKV34QVrZhSw6WdklwZQ== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-syntax-import-attributes@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.25.7.tgz#d78dd0499d30df19a598e63ab895e21b909bc43f" - integrity sha512-AqVo+dguCgmpi/3mYBdu9lkngOBlQ2w2vnNpa6gfiCxQZLzV4ZbhsXitJ2Yblkoe1VQwtHSaNmIaGll/26YWRw== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-syntax-import-meta@^7.8.3": - version "7.10.4" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" - integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-json-strings@^7.8.3": - version "7.8.3" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" - integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-jsx@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.7.tgz#5352d398d11ea5e7ef330c854dea1dae0bf18165" - integrity sha512-ruZOnKO+ajVL/MVx+PwNBPOkrnXTXoWMtte1MBpegfCArhqOe3Bj52avVj1huLLxNKYKXYaSxZ2F+woK1ekXfw== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-syntax-jsx@^7.7.2": - version "7.24.7" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz#39a1fa4a7e3d3d7f34e2acc6be585b718d30e02d" - integrity sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ== - dependencies: - "@babel/helper-plugin-utils" "^7.24.7" - -"@babel/plugin-syntax-logical-assignment-operators@^7.8.3": - version "7.10.4" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" - integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": - version "7.8.3" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" - integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-numeric-separator@^7.8.3": - version "7.10.4" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" - integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-object-rest-spread@^7.8.3": - version "7.8.3" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" - integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-optional-catch-binding@^7.8.3": - version "7.8.3" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" - integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-optional-chaining@^7.8.3": - version "7.8.3" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" - integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-top-level-await@^7.8.3": - version "7.14.5" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" - integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-syntax-typescript@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.7.tgz#bfc05b0cc31ebd8af09964650cee723bb228108b" - integrity sha512-rR+5FDjpCHqqZN2bzZm18bVYGaejGq5ZkpVCJLXor/+zlSrSoc4KWcHI0URVWjl/68Dyr1uwZUz/1njycEAv9g== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-syntax-typescript@^7.7.2": - version "7.24.7" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.7.tgz#58d458271b4d3b6bb27ee6ac9525acbb259bad1c" - integrity sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA== - dependencies: - "@babel/helper-plugin-utils" "^7.24.7" - -"@babel/plugin-syntax-unicode-sets-regex@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz#d49a3b3e6b52e5be6740022317580234a6a47357" - integrity sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-transform-arrow-functions@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.7.tgz#1b9ed22e6890a0e9ff470371c73b8c749bcec386" - integrity sha512-EJN2mKxDwfOUCPxMO6MUI58RN3ganiRAG/MS/S3HfB6QFNjroAMelQo/gybyYq97WerCBAZoyrAoW8Tzdq2jWg== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-transform-async-generator-functions@^7.25.8": - version "7.25.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.8.tgz#3331de02f52cc1f2c75b396bec52188c85b0b1ec" - integrity sha512-9ypqkozyzpG+HxlH4o4gdctalFGIjjdufzo7I2XPda0iBnZ6a+FO0rIEQcdSPXp02CkvGsII1exJhmROPQd5oA== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - "@babel/helper-remap-async-to-generator" "^7.25.7" - "@babel/traverse" "^7.25.7" - -"@babel/plugin-transform-async-to-generator@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.7.tgz#a44c7323f8d4285a6c568dd43c5c361d6367ec52" - integrity sha512-ZUCjAavsh5CESCmi/xCpX1qcCaAglzs/7tmuvoFnJgA1dM7gQplsguljoTg+Ru8WENpX89cQyAtWoaE0I3X3Pg== - dependencies: - "@babel/helper-module-imports" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" - "@babel/helper-remap-async-to-generator" "^7.25.7" - -"@babel/plugin-transform-block-scoped-functions@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.25.7.tgz#e0b8843d5571719a2f1bf7e284117a3379fcc17c" - integrity sha512-xHttvIM9fvqW+0a3tZlYcZYSBpSWzGBFIt/sYG3tcdSzBB8ZeVgz2gBP7Df+sM0N1850jrviYSSeUuc+135dmQ== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-transform-block-scoping@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.7.tgz#6dab95e98adf780ceef1b1c3ab0e55cd20dd410a" - integrity sha512-ZEPJSkVZaeTFG/m2PARwLZQ+OG0vFIhPlKHK/JdIMy8DbRJ/htz6LRrTFtdzxi9EHmcwbNPAKDnadpNSIW+Aow== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-transform-class-properties@^7.24.1", "@babel/plugin-transform-class-properties@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.7.tgz#a389cfca7a10ac80e3ff4c75fca08bd097ad1523" - integrity sha512-mhyfEW4gufjIqYFo9krXHJ3ElbFLIze5IDp+wQTxoPd+mwFb1NxatNAwmv8Q8Iuxv7Zc+q8EkiMQwc9IhyGf4g== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-transform-class-static-block@^7.25.8": - version "7.25.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.25.8.tgz#a8af22028920fe404668031eceb4c3aadccb5262" - integrity sha512-e82gl3TCorath6YLf9xUwFehVvjvfqFhdOo4+0iVIVju+6XOi5XHkqB3P2AXnSwoeTX0HBoXq5gJFtvotJzFnQ== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-transform-classes@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.7.tgz#5103206cf80d02283bbbd044509ea3b65d0906bb" - integrity sha512-9j9rnl+YCQY0IGoeipXvnk3niWicIB6kCsWRGLwX241qSXpbA4MKxtp/EdvFxsc4zI5vqfLxzOd0twIJ7I99zg== - dependencies: - "@babel/helper-annotate-as-pure" "^7.25.7" - "@babel/helper-compilation-targets" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" - "@babel/helper-replace-supers" "^7.25.7" - "@babel/traverse" "^7.25.7" - globals "^11.1.0" - -"@babel/plugin-transform-computed-properties@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.7.tgz#7f621f0aa1354b5348a935ab12e3903842466f65" - integrity sha512-QIv+imtM+EtNxg/XBKL3hiWjgdLjMOmZ+XzQwSgmBfKbfxUjBzGgVPklUuE55eq5/uVoh8gg3dqlrwR/jw3ZeA== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - "@babel/template" "^7.25.7" - -"@babel/plugin-transform-destructuring@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.7.tgz#f6f26a9feefb5aa41fd45b6f5838901b5333d560" - integrity sha512-xKcfLTlJYUczdaM1+epcdh1UGewJqr9zATgrNHcLBcV2QmfvPPEixo/sK/syql9cEmbr7ulu5HMFG5vbbt/sEA== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-transform-dotall-regex@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.7.tgz#9d775c4a3ff1aea64045300fcd4309b4a610ef02" - integrity sha512-kXzXMMRzAtJdDEgQBLF4oaiT6ZCU3oWHgpARnTKDAqPkDJ+bs3NrZb310YYevR5QlRo3Kn7dzzIdHbZm1VzJdQ== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-transform-duplicate-keys@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.7.tgz#fbba7d1155eab76bd4f2a038cbd5d65883bd7a93" - integrity sha512-by+v2CjoL3aMnWDOyCIg+yxU9KXSRa9tN6MbqggH5xvymmr9p4AMjYkNlQy4brMceBnUyHZ9G8RnpvT8wP7Cfg== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-transform-duplicate-named-capturing-groups-regex@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.7.tgz#102b31608dcc22c08fbca1894e104686029dc141" - integrity sha512-HvS6JF66xSS5rNKXLqkk7L9c/jZ/cdIVIcoPVrnl8IsVpLggTjXs8OWekbLHs/VtYDDh5WXnQyeE3PPUGm22MA== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-transform-dynamic-import@^7.25.8": - version "7.25.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.8.tgz#f1edbe75b248cf44c70c8ca8ed3818a668753aaa" - integrity sha512-gznWY+mr4ZQL/EWPcbBQUP3BXS5FwZp8RUOw06BaRn8tQLzN4XLIxXejpHN9Qo8x8jjBmAAKp6FoS51AgkSA/A== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-transform-exponentiation-operator@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.25.7.tgz#5961a3a23a398faccd6cddb34a2182807d75fb5f" - integrity sha512-yjqtpstPfZ0h/y40fAXRv2snciYr0OAoMXY/0ClC7tm4C/nG5NJKmIItlaYlLbIVAWNfrYuy9dq1bE0SbX0PEg== - dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-transform-export-namespace-from@^7.24.1", "@babel/plugin-transform-export-namespace-from@^7.25.8": - version "7.25.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.8.tgz#d1988c3019a380b417e0516418b02804d3858145" - integrity sha512-sPtYrduWINTQTW7FtOy99VCTWp4H23UX7vYcut7S4CIMEXU+54zKX9uCoGkLsWXteyaMXzVHgzWbLfQ1w4GZgw== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-transform-for-of@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.7.tgz#0acfea0f27aa290818b5b48a5a44b3f03fc13669" - integrity sha512-n/TaiBGJxYFWvpJDfsxSj9lEEE44BFM1EPGz4KEiTipTgkoFVVcCmzAL3qA7fdQU96dpo4gGf5HBx/KnDvqiHw== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - "@babel/helper-skip-transparent-expression-wrappers" "^7.25.7" - -"@babel/plugin-transform-function-name@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.7.tgz#7e394ccea3693902a8b50ded8b6ae1fa7b8519fd" - integrity sha512-5MCTNcjCMxQ63Tdu9rxyN6cAWurqfrDZ76qvVPrGYdBxIj+EawuuxTu/+dgJlhK5eRz3v1gLwp6XwS8XaX2NiQ== - dependencies: - "@babel/helper-compilation-targets" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" - "@babel/traverse" "^7.25.7" - -"@babel/plugin-transform-json-strings@^7.25.8": - version "7.25.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.8.tgz#6fb3ec383a2ea92652289fdba653e3f9de722694" - integrity sha512-4OMNv7eHTmJ2YXs3tvxAfa/I43di+VcF+M4Wt66c88EAED1RoGaf1D64cL5FkRpNL+Vx9Hds84lksWvd/wMIdA== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-transform-literals@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.7.tgz#70cbdc742f2cfdb1a63ea2cbd018d12a60b213c3" - integrity sha512-fwzkLrSu2fESR/cm4t6vqd7ebNIopz2QHGtjoU+dswQo/P6lwAG04Q98lliE3jkz/XqnbGFLnUcE0q0CVUf92w== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-transform-logical-assignment-operators@^7.25.8": - version "7.25.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.8.tgz#01868ff92daa9e525b4c7902aa51979082a05710" - integrity sha512-f5W0AhSbbI+yY6VakT04jmxdxz+WsID0neG7+kQZbCOjuyJNdL5Nn4WIBm4hRpKnUcO9lP0eipUhFN12JpoH8g== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-transform-member-expression-literals@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.7.tgz#0a36c3fbd450cc9e6485c507f005fa3d1bc8fca5" - integrity sha512-Std3kXwpXfRV0QtQy5JJcRpkqP8/wG4XL7hSKZmGlxPlDqmpXtEPRmhF7ztnlTCtUN3eXRUJp+sBEZjaIBVYaw== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-transform-modules-amd@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.7.tgz#bb4e543b5611f6c8c685a2fd485408713a3adf3d" - integrity sha512-CgselSGCGzjQvKzghCvDTxKHP3iooenLpJDO842ehn5D2G5fJB222ptnDwQho0WjEvg7zyoxb9P+wiYxiJX5yA== - dependencies: - "@babel/helper-module-transforms" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-transform-modules-commonjs@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.25.7.tgz#173f0c791bb7407c092ce6d77ee90eb3f2d1d2fd" - integrity sha512-L9Gcahi0kKFYXvweO6n0wc3ZG1ChpSFdgG+eV1WYZ3/dGbJK7vvk91FgGgak8YwRgrCuihF8tE/Xg07EkL5COg== - dependencies: - "@babel/helper-module-transforms" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" - "@babel/helper-simple-access" "^7.25.7" - -"@babel/plugin-transform-modules-systemjs@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.7.tgz#8b14d319a177cc9c85ef8b0512afd429d9e2e60b" - integrity sha512-t9jZIvBmOXJsiuyOwhrIGs8dVcD6jDyg2icw1VL4A/g+FnWyJKwUfSSU2nwJuMV2Zqui856El9u+ElB+j9fV1g== - dependencies: - "@babel/helper-module-transforms" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" - "@babel/helper-validator-identifier" "^7.25.7" - "@babel/traverse" "^7.25.7" - -"@babel/plugin-transform-modules-umd@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.7.tgz#00ee7a7e124289549381bfb0e24d87fd7f848367" - integrity sha512-p88Jg6QqsaPh+EB7I9GJrIqi1Zt4ZBHUQtjw3z1bzEXcLh6GfPqzZJ6G+G1HBGKUNukT58MnKG7EN7zXQBCODw== - dependencies: - "@babel/helper-module-transforms" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-transform-named-capturing-groups-regex@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.7.tgz#a2f3f6d7f38693b462542951748f0a72a34d196d" - integrity sha512-BtAT9LzCISKG3Dsdw5uso4oV1+v2NlVXIIomKJgQybotJY3OwCwJmkongjHgwGKoZXd0qG5UZ12JUlDQ07W6Ow== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-transform-new-target@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.7.tgz#52b2bde523b76c548749f38dc3054f1f45e82bc9" - integrity sha512-CfCS2jDsbcZaVYxRFo2qtavW8SpdzmBXC2LOI4oO0rP+JSRDxxF3inF4GcPsLgfb5FjkhXG5/yR/lxuRs2pySA== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-transform-nullish-coalescing-operator@^7.25.8": - version "7.25.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.8.tgz#befb4900c130bd52fccf2b926314557987f1b552" - integrity sha512-Z7WJJWdQc8yCWgAmjI3hyC+5PXIubH9yRKzkl9ZEG647O9szl9zvmKLzpbItlijBnVhTUf1cpyWBsZ3+2wjWPQ== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-transform-numeric-separator@^7.24.1", "@babel/plugin-transform-numeric-separator@^7.25.8": - version "7.25.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.8.tgz#91e370486371637bd42161052f2602c701386891" - integrity sha512-rm9a5iEFPS4iMIy+/A/PiS0QN0UyjPIeVvbU5EMZFKJZHt8vQnasbpo3T3EFcxzCeYO0BHfc4RqooCZc51J86Q== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-transform-object-rest-spread@^7.24.1", "@babel/plugin-transform-object-rest-spread@^7.25.8": - version "7.25.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.8.tgz#0904ac16bcce41df4db12d915d6780f85c7fb04b" - integrity sha512-LkUu0O2hnUKHKE7/zYOIjByMa4VRaV2CD/cdGz0AxU9we+VA3kDDggKEzI0Oz1IroG+6gUP6UmWEHBMWZU316g== - dependencies: - "@babel/helper-compilation-targets" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" - "@babel/plugin-transform-parameters" "^7.25.7" - -"@babel/plugin-transform-object-super@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.7.tgz#582a9cea8cf0a1e02732be5b5a703a38dedf5661" - integrity sha512-pWT6UXCEW3u1t2tcAGtE15ornCBvopHj9Bps9D2DsH15APgNVOTwwczGckX+WkAvBmuoYKRCFa4DK+jM8vh5AA== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - "@babel/helper-replace-supers" "^7.25.7" - -"@babel/plugin-transform-optional-catch-binding@^7.25.8": - version "7.25.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.8.tgz#2649b86a3bb202c6894ec81a6ddf41b94d8f3103" - integrity sha512-EbQYweoMAHOn7iJ9GgZo14ghhb9tTjgOc88xFgYngifx7Z9u580cENCV159M4xDh3q/irbhSjZVpuhpC2gKBbg== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-transform-optional-chaining@^7.25.7", "@babel/plugin-transform-optional-chaining@^7.25.8": - version "7.25.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.8.tgz#f46283b78adcc5b6ab988a952f989e7dce70653f" - integrity sha512-q05Bk7gXOxpTHoQ8RSzGSh/LHVB9JEIkKnk3myAWwZHnYiTGYtbdrYkIsS8Xyh4ltKf7GNUSgzs/6P2bJtBAQg== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - "@babel/helper-skip-transparent-expression-wrappers" "^7.25.7" - -"@babel/plugin-transform-parameters@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.7.tgz#80c38b03ef580f6d6bffe1c5254bb35986859ac7" - integrity sha512-FYiTvku63me9+1Nz7TOx4YMtW3tWXzfANZtrzHhUZrz4d47EEtMQhzFoZWESfXuAMMT5mwzD4+y1N8ONAX6lMQ== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-transform-private-methods@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.7.tgz#c790a04f837b4bd61d6b0317b43aa11ff67dce80" - integrity sha512-KY0hh2FluNxMLwOCHbxVOKfdB5sjWG4M183885FmaqWWiGMhRZq4DQRKH6mHdEucbJnyDyYiZNwNG424RymJjA== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-transform-private-property-in-object@^7.25.8": - version "7.25.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.8.tgz#1234f856ce85e061f9688764194e51ea7577c434" - integrity sha512-8Uh966svuB4V8RHHg0QJOB32QK287NBksJOByoKmHMp1TAobNniNalIkI2i5IPj5+S9NYCG4VIjbEuiSN8r+ow== - dependencies: - "@babel/helper-annotate-as-pure" "^7.25.7" - "@babel/helper-create-class-features-plugin" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-transform-property-literals@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.7.tgz#a8612b4ea4e10430f00012ecf0155662c7d6550d" - integrity sha512-lQEeetGKfFi0wHbt8ClQrUSUMfEeI3MMm74Z73T9/kuz990yYVtfofjf3NuA42Jy3auFOpbjDyCSiIkTs1VIYw== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-transform-react-display-name@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.25.7.tgz#2753e875a1b702fb1d806c4f5d4c194d64cadd88" - integrity sha512-r0QY7NVU8OnrwE+w2IWiRom0wwsTbjx4+xH2RTd7AVdof3uurXOF+/mXHQDRk+2jIvWgSaCHKMgggfvM4dyUGA== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-transform-react-jsx-development@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.25.7.tgz#2fbd77887b8fa2942d7cb61edf1029ea1b048554" - integrity sha512-5yd3lH1PWxzW6IZj+p+Y4OLQzz0/LzlOG8vGqonHfVR3euf1vyzyMUJk9Ac+m97BH46mFc/98t9PmYLyvgL3qg== - dependencies: - "@babel/plugin-transform-react-jsx" "^7.25.7" - -"@babel/plugin-transform-react-jsx@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.25.7.tgz#f5e2af6020a562fe048dd343e571c4428e6c5632" - integrity sha512-vILAg5nwGlR9EXE8JIOX4NHXd49lrYbN8hnjffDtoULwpL9hUx/N55nqh2qd0q6FyNDfjl9V79ecKGvFbcSA0Q== - dependencies: - "@babel/helper-annotate-as-pure" "^7.25.7" - "@babel/helper-module-imports" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" - "@babel/plugin-syntax-jsx" "^7.25.7" - "@babel/types" "^7.25.7" - -"@babel/plugin-transform-react-pure-annotations@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.25.7.tgz#6d0b8dadb2d3c5cbb8ade68c5efd49470b0d65f7" - integrity sha512-6YTHJ7yjjgYqGc8S+CbEXhLICODk0Tn92j+vNJo07HFk9t3bjFgAKxPLFhHwF2NjmQVSI1zBRfBWUeVBa2osfA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-transform-regenerator@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.7.tgz#6eb006e6d26f627bc2f7844a9f19770721ad6f3e" - integrity sha512-mgDoQCRjrY3XK95UuV60tZlFCQGXEtMg8H+IsW72ldw1ih1jZhzYXbJvghmAEpg5UVhhnCeia1CkGttUvCkiMQ== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - regenerator-transform "^0.15.2" - -"@babel/plugin-transform-reserved-words@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.7.tgz#dc56b25e02afaabef3ce0c5b06b0916e8523e995" - integrity sha512-3OfyfRRqiGeOvIWSagcwUTVk2hXBsr/ww7bLn6TRTuXnexA+Udov2icFOxFX9abaj4l96ooYkcNN1qi2Zvqwng== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-transform-runtime@^7.24.3": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.25.7.tgz#435a4fab67273f00047dc806e05069c9c6344e12" - integrity sha512-Y9p487tyTzB0yDYQOtWnC+9HGOuogtP3/wNpun1xJXEEvI6vip59BSBTsHnekZLqxmPcgsrAKt46HAAb//xGhg== - dependencies: - "@babel/helper-module-imports" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" - babel-plugin-polyfill-corejs2 "^0.4.10" - babel-plugin-polyfill-corejs3 "^0.10.6" - babel-plugin-polyfill-regenerator "^0.6.1" - semver "^6.3.1" - -"@babel/plugin-transform-shorthand-properties@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.7.tgz#92690a9c671915602d91533c278cc8f6bf12275f" - integrity sha512-uBbxNwimHi5Bv3hUccmOFlUy3ATO6WagTApenHz9KzoIdn0XeACdB12ZJ4cjhuB2WSi80Ez2FWzJnarccriJeA== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-transform-spread@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.7.tgz#df83e899a9fc66284ee601a7b738568435b92998" - integrity sha512-Mm6aeymI0PBh44xNIv/qvo8nmbkpZze1KvR8MkEqbIREDxoiWTi18Zr2jryfRMwDfVZF9foKh060fWgni44luw== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - "@babel/helper-skip-transparent-expression-wrappers" "^7.25.7" - -"@babel/plugin-transform-sticky-regex@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.7.tgz#341c7002bef7f29037be7fb9684e374442dd0d17" - integrity sha512-ZFAeNkpGuLnAQ/NCsXJ6xik7Id+tHuS+NT+ue/2+rn/31zcdnupCdmunOizEaP0JsUmTFSTOPoQY7PkK2pttXw== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-transform-template-literals@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.7.tgz#e566c581bb16d8541dd8701093bb3457adfce16b" - integrity sha512-SI274k0nUsFFmyQupiO7+wKATAmMFf8iFgq2O+vVFXZ0SV9lNfT1NGzBEhjquFmD8I9sqHLguH+gZVN3vww2AA== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-transform-typeof-symbol@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.7.tgz#debb1287182efd20488f126be343328c679b66eb" - integrity sha512-OmWmQtTHnO8RSUbL0NTdtpbZHeNTnm68Gj5pA4Y2blFNh+V4iZR68V1qL9cI37J21ZN7AaCnkfdHtLExQPf2uA== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-transform-typescript@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.25.7.tgz#8fc7c3d28ddd36bce45b9b48594129d0e560cfbe" - integrity sha512-VKlgy2vBzj8AmEzunocMun2fF06bsSWV+FvVXohtL6FGve/+L217qhHxRTVGHEDO/YR8IANcjzgJsd04J8ge5Q== - dependencies: - "@babel/helper-annotate-as-pure" "^7.25.7" - "@babel/helper-create-class-features-plugin" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" - "@babel/helper-skip-transparent-expression-wrappers" "^7.25.7" - "@babel/plugin-syntax-typescript" "^7.25.7" - -"@babel/plugin-transform-unicode-escapes@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.7.tgz#973592b6d13a914794e1de8cf1383e50e0f87f81" - integrity sha512-BN87D7KpbdiABA+t3HbVqHzKWUDN3dymLaTnPFAMyc8lV+KN3+YzNhVRNdinaCPA4AUqx7ubXbQ9shRjYBl3SQ== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-transform-unicode-property-regex@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.7.tgz#25349197cce964b1343f74fa7cfdf791a1b1919e" - integrity sha512-IWfR89zcEPQGB/iB408uGtSPlQd3Jpq11Im86vUgcmSTcoWAiQMCTOa2K2yNNqFJEBVICKhayctee65Ka8OB0w== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-transform-unicode-regex@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.7.tgz#f93a93441baf61f713b6d5552aaa856bfab34809" - integrity sha512-8JKfg/hiuA3qXnlLx8qtv5HWRbgyFx2hMMtpDDuU2rTckpKkGu4ycK5yYHwuEa16/quXfoxHBIApEsNyMWnt0g== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-transform-unicode-sets-regex@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.7.tgz#d1b3295d29e0f8f4df76abc909ad1ebee919560c" - integrity sha512-YRW8o9vzImwmh4Q3Rffd09bH5/hvY0pxg+1H1i0f7APoUeg12G7+HhLj9ZFNIrYkgBXhIijPJ+IXypN0hLTIbw== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/preset-env@^7.24.4": - version "7.25.8" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.25.8.tgz#dc6b719627fb29cd9cccbbbe041802fd575b524c" - integrity sha512-58T2yulDHMN8YMUxiLq5YmWUnlDCyY1FsHM+v12VMx+1/FlrUj5tY50iDCpofFQEM8fMYOaY9YRvym2jcjn1Dg== - dependencies: - "@babel/compat-data" "^7.25.8" - "@babel/helper-compilation-targets" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" - "@babel/helper-validator-option" "^7.25.7" - "@babel/plugin-bugfix-firefox-class-in-computed-class-key" "^7.25.7" - "@babel/plugin-bugfix-safari-class-field-initializer-scope" "^7.25.7" - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.25.7" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.25.7" - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly" "^7.25.7" - "@babel/plugin-proposal-private-property-in-object" "7.21.0-placeholder-for-preset-env.2" - "@babel/plugin-syntax-import-assertions" "^7.25.7" - "@babel/plugin-syntax-import-attributes" "^7.25.7" - "@babel/plugin-syntax-unicode-sets-regex" "^7.18.6" - "@babel/plugin-transform-arrow-functions" "^7.25.7" - "@babel/plugin-transform-async-generator-functions" "^7.25.8" - "@babel/plugin-transform-async-to-generator" "^7.25.7" - "@babel/plugin-transform-block-scoped-functions" "^7.25.7" - "@babel/plugin-transform-block-scoping" "^7.25.7" - "@babel/plugin-transform-class-properties" "^7.25.7" - "@babel/plugin-transform-class-static-block" "^7.25.8" - "@babel/plugin-transform-classes" "^7.25.7" - "@babel/plugin-transform-computed-properties" "^7.25.7" - "@babel/plugin-transform-destructuring" "^7.25.7" - "@babel/plugin-transform-dotall-regex" "^7.25.7" - "@babel/plugin-transform-duplicate-keys" "^7.25.7" - "@babel/plugin-transform-duplicate-named-capturing-groups-regex" "^7.25.7" - "@babel/plugin-transform-dynamic-import" "^7.25.8" - "@babel/plugin-transform-exponentiation-operator" "^7.25.7" - "@babel/plugin-transform-export-namespace-from" "^7.25.8" - "@babel/plugin-transform-for-of" "^7.25.7" - "@babel/plugin-transform-function-name" "^7.25.7" - "@babel/plugin-transform-json-strings" "^7.25.8" - "@babel/plugin-transform-literals" "^7.25.7" - "@babel/plugin-transform-logical-assignment-operators" "^7.25.8" - "@babel/plugin-transform-member-expression-literals" "^7.25.7" - "@babel/plugin-transform-modules-amd" "^7.25.7" - "@babel/plugin-transform-modules-commonjs" "^7.25.7" - "@babel/plugin-transform-modules-systemjs" "^7.25.7" - "@babel/plugin-transform-modules-umd" "^7.25.7" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.25.7" - "@babel/plugin-transform-new-target" "^7.25.7" - "@babel/plugin-transform-nullish-coalescing-operator" "^7.25.8" - "@babel/plugin-transform-numeric-separator" "^7.25.8" - "@babel/plugin-transform-object-rest-spread" "^7.25.8" - "@babel/plugin-transform-object-super" "^7.25.7" - "@babel/plugin-transform-optional-catch-binding" "^7.25.8" - "@babel/plugin-transform-optional-chaining" "^7.25.8" - "@babel/plugin-transform-parameters" "^7.25.7" - "@babel/plugin-transform-private-methods" "^7.25.7" - "@babel/plugin-transform-private-property-in-object" "^7.25.8" - "@babel/plugin-transform-property-literals" "^7.25.7" - "@babel/plugin-transform-regenerator" "^7.25.7" - "@babel/plugin-transform-reserved-words" "^7.25.7" - "@babel/plugin-transform-shorthand-properties" "^7.25.7" - "@babel/plugin-transform-spread" "^7.25.7" - "@babel/plugin-transform-sticky-regex" "^7.25.7" - "@babel/plugin-transform-template-literals" "^7.25.7" - "@babel/plugin-transform-typeof-symbol" "^7.25.7" - "@babel/plugin-transform-unicode-escapes" "^7.25.7" - "@babel/plugin-transform-unicode-property-regex" "^7.25.7" - "@babel/plugin-transform-unicode-regex" "^7.25.7" - "@babel/plugin-transform-unicode-sets-regex" "^7.25.7" - "@babel/preset-modules" "0.1.6-no-external-plugins" - babel-plugin-polyfill-corejs2 "^0.4.10" - babel-plugin-polyfill-corejs3 "^0.10.6" - babel-plugin-polyfill-regenerator "^0.6.1" - core-js-compat "^3.38.1" - semver "^6.3.1" - -"@babel/preset-modules@0.1.6-no-external-plugins": - version "0.1.6-no-external-plugins" - resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz#ccb88a2c49c817236861fee7826080573b8a923a" - integrity sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/types" "^7.4.4" - esutils "^2.0.2" - -"@babel/preset-react@^7.24.1": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.25.7.tgz#081cbe1dea363b732764d06a0fdda67ffa17735d" - integrity sha512-GjV0/mUEEXpi1U5ZgDprMRRgajGMRW3G5FjMr5KLKD8nT2fTG8+h/klV3+6Dm5739QE+K5+2e91qFKAYI3pmRg== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - "@babel/helper-validator-option" "^7.25.7" - "@babel/plugin-transform-react-display-name" "^7.25.7" - "@babel/plugin-transform-react-jsx" "^7.25.7" - "@babel/plugin-transform-react-jsx-development" "^7.25.7" - "@babel/plugin-transform-react-pure-annotations" "^7.25.7" - -"@babel/preset-typescript@^7.24.1": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.25.7.tgz#43c5b68eccb856ae5b52274b77b1c3c413cde1b7" - integrity sha512-rkkpaXJZOFN45Fb+Gki0c+KMIglk4+zZXOoMJuyEK8y8Kkc8Jd3BDmP7qPsz0zQMJj+UD7EprF+AqAXcILnexw== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - "@babel/helper-validator-option" "^7.25.7" - "@babel/plugin-syntax-jsx" "^7.25.7" - "@babel/plugin-transform-modules-commonjs" "^7.25.7" - "@babel/plugin-transform-typescript" "^7.25.7" - -"@babel/runtime@^7.0.0", "@babel/runtime@^7.10.1", "@babel/runtime@^7.11.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.18.3", "@babel/runtime@^7.20.6", "@babel/runtime@^7.20.7", "@babel/runtime@^7.21.0", "@babel/runtime@^7.21.5", "@babel/runtime@^7.22.3", "@babel/runtime@^7.3.1": - version "7.22.3" - resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.3.tgz" - integrity sha512-XsDuspWKLUsxwCp6r7EhsExHtYfbe5oAGQ19kqngTdCPUoPQzOPdUbD/pB9PJiwb2ptYKQDjSJT3R6dC+EPqfQ== - dependencies: - regenerator-runtime "^0.13.11" - -"@babel/runtime@^7.17.8", "@babel/runtime@^7.24.4", "@babel/runtime@^7.8.4": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.7.tgz#7ffb53c37a8f247c8c4d335e89cdf16a2e0d0fb6" - integrity sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w== - dependencies: - regenerator-runtime "^0.14.0" - -"@babel/runtime@^7.9.2": - version "7.24.8" - resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.8.tgz#5d958c3827b13cc6d05e038c07fb2e5e3420d82e" - integrity sha512-5F7SDGs1T72ZczbRwbGO9lQi0NLjQxzl6i4lJxLxfW9U5UluCSyEJeniWvnhl3/euNiqQVbo8zruhsDfid0esA== - dependencies: - regenerator-runtime "^0.14.0" - -"@babel/template@^7.24.7", "@babel/template@^7.3.3": - version "7.24.7" - resolved "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz#02efcee317d0609d2c07117cb70ef8fb17ab7315" - integrity sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig== - dependencies: - "@babel/code-frame" "^7.24.7" - "@babel/parser" "^7.24.7" - "@babel/types" "^7.24.7" - -"@babel/template@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.25.7.tgz#27f69ce382855d915b14ab0fe5fb4cbf88fa0769" - integrity sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA== - dependencies: - "@babel/code-frame" "^7.25.7" - "@babel/parser" "^7.25.7" - "@babel/types" "^7.25.7" - -"@babel/traverse@^7.18.9", "@babel/traverse@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.7.tgz#83e367619be1cab8e4f2892ef30ba04c26a40fa8" - integrity sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg== - dependencies: - "@babel/code-frame" "^7.25.7" - "@babel/generator" "^7.25.7" - "@babel/parser" "^7.25.7" - "@babel/template" "^7.25.7" - "@babel/types" "^7.25.7" - debug "^4.3.1" - globals "^11.1.0" - -"@babel/traverse@^7.24.7", "@babel/traverse@^7.24.8": - version "7.24.8" - resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.8.tgz#6c14ed5232b7549df3371d820fbd9abfcd7dfab7" - integrity sha512-t0P1xxAPzEDcEPmjprAQq19NWum4K0EQPjMwZQZbHt+GiZqvjCHjj755Weq1YRPVzBI+3zSfvScfpnuIecVFJQ== - dependencies: - "@babel/code-frame" "^7.24.7" - "@babel/generator" "^7.24.8" - "@babel/helper-environment-visitor" "^7.24.7" - "@babel/helper-function-name" "^7.24.7" - "@babel/helper-hoist-variables" "^7.24.7" - "@babel/helper-split-export-declaration" "^7.24.7" - "@babel/parser" "^7.24.8" - "@babel/types" "^7.24.8" - debug "^4.3.1" - globals "^11.1.0" - -"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.24.7", "@babel/types@^7.24.8", "@babel/types@^7.24.9", "@babel/types@^7.3.3": - version "7.24.9" - resolved "https://registry.npmjs.org/@babel/types/-/types-7.24.9.tgz#228ce953d7b0d16646e755acf204f4cf3d08cc73" - integrity sha512-xm8XrMKz0IlUdocVbYJe0Z9xEgidU7msskG8BbhnTPK/HZ2z/7FP7ykqPgrUH+C+r414mNfNWam1f2vqOjqjYQ== - dependencies: - "@babel/helper-string-parser" "^7.24.8" - "@babel/helper-validator-identifier" "^7.24.7" - to-fast-properties "^2.0.0" - -"@babel/types@^7.18.9", "@babel/types@^7.25.7", "@babel/types@^7.25.8", "@babel/types@^7.4.4": - version "7.25.8" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.25.8.tgz#5cf6037258e8a9bcad533f4979025140cb9993e1" - integrity sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg== - dependencies: - "@babel/helper-string-parser" "^7.25.7" - "@babel/helper-validator-identifier" "^7.25.7" - to-fast-properties "^2.0.0" - -"@babel/types@^7.25.4", "@babel/types@^7.25.6": - version "7.25.6" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.25.6.tgz#893942ddb858f32ae7a004ec9d3a76b3463ef8e6" - integrity sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw== - dependencies: - "@babel/helper-string-parser" "^7.24.8" - "@babel/helper-validator-identifier" "^7.24.7" - to-fast-properties "^2.0.0" - -"@base2/pretty-print-object@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@base2/pretty-print-object/-/pretty-print-object-1.0.1.tgz#371ba8be66d556812dc7fb169ebc3c08378f69d4" - integrity sha512-4iri8i1AqYHJE2DstZYkyEprg6Pq6sKx3xn5FpySk9sNhH7qN2LLlHJCfDTZRILNwQNPD7mATWM0TBui7uC1pA== - -"@bcoe/v8-coverage@^0.2.3": - version "0.2.3" - resolved "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" - integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== - -"@braintree/sanitize-url@^6.0.1": - version "6.0.4" - resolved "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-6.0.4.tgz" - integrity sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A== - -"@chromatic-com/storybook@^1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@chromatic-com/storybook/-/storybook-1.9.0.tgz#d95eb3474783bcc17a830a7627c3f099c1f75ba5" - integrity sha512-vYQ+TcfktEE3GHnLZXHCzXF/sN9dw+KivH8a5cmPyd9YtQs7fZtHrEgsIjWpYycXiweKMo1Lm1RZsjxk8DH3rA== - dependencies: - chromatic "^11.4.0" - filesize "^10.0.12" - jsonfile "^6.1.0" - react-confetti "^6.1.0" - strip-ansi "^7.1.0" - -"@cspotcode/source-map-support@^0.8.0": - version "0.8.1" - resolved "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" - integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== - dependencies: - "@jridgewell/trace-mapping" "0.3.9" - -"@dagrejs/dagre@^1.1.2": - version "1.1.2" - resolved "https://registry.npmjs.org/@dagrejs/dagre/-/dagre-1.1.2.tgz" - integrity sha512-F09dphqvHsbe/6C2t2unbmpr5q41BNPEfJCdn8Z7aEBpVSy/zFQ/b4SWsweQjWNsYMDvE2ffNUN8X0CeFsEGNw== - dependencies: - "@dagrejs/graphlib" "2.2.2" - -"@dagrejs/graphlib@2.2.2": - version "2.2.2" - resolved "https://registry.npmjs.org/@dagrejs/graphlib/-/graphlib-2.2.2.tgz" - integrity sha512-CbyGpCDKsiTg/wuk79S7Muoj8mghDGAESWGxcSyhHX5jD35vYMBZochYVFzlHxynpE9unpu6O+4ZuhrLxASsOg== - -"@emnapi/runtime@^0.45.0": - version "0.45.0" - resolved "https://registry.yarnpkg.com/@emnapi/runtime/-/runtime-0.45.0.tgz#e754de04c683263f34fd0c7f32adfe718bbe4ddd" - integrity sha512-Txumi3td7J4A/xTTwlssKieHKTGl3j4A1tglBx72auZ49YK7ePY6XZricgIg9mnZT4xPfA+UPCUdnhRuEFDL+w== - dependencies: - tslib "^2.4.0" - -"@emnapi/runtime@^1.2.0": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@emnapi/runtime/-/runtime-1.3.1.tgz#0fcaa575afc31f455fd33534c19381cfce6c6f60" - integrity sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw== - dependencies: - tslib "^2.4.0" - -"@emoji-mart/data@^1.1.2": - version "1.1.2" - resolved "https://registry.npmjs.org/@emoji-mart/data/-/data-1.1.2.tgz" - integrity sha512-1HP8BxD2azjqWJvxIaWAMyTySeZY0Osr83ukYjltPVkNXeJvTz7yDrPLBtnrD5uqJ3tg4CcLuuBW09wahqL/fg== - -"@esbuild/aix-ppc64@0.23.1": - version "0.23.1" - resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz#51299374de171dbd80bb7d838e1cfce9af36f353" - integrity sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ== - -"@esbuild/android-arm64@0.23.1": - version "0.23.1" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz#58565291a1fe548638adb9c584237449e5e14018" - integrity sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw== - -"@esbuild/android-arm@0.23.1": - version "0.23.1" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.23.1.tgz#5eb8c652d4c82a2421e3395b808e6d9c42c862ee" - integrity sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ== - -"@esbuild/android-x64@0.23.1": - version "0.23.1" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.23.1.tgz#ae19d665d2f06f0f48a6ac9a224b3f672e65d517" - integrity sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg== - -"@esbuild/darwin-arm64@0.23.1": - version "0.23.1" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz#05b17f91a87e557b468a9c75e9d85ab10c121b16" - integrity sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q== - -"@esbuild/darwin-x64@0.23.1": - version "0.23.1" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz#c58353b982f4e04f0d022284b8ba2733f5ff0931" - integrity sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw== - -"@esbuild/freebsd-arm64@0.23.1": - version "0.23.1" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz#f9220dc65f80f03635e1ef96cfad5da1f446f3bc" - integrity sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA== - -"@esbuild/freebsd-x64@0.23.1": - version "0.23.1" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz#69bd8511fa013b59f0226d1609ac43f7ce489730" - integrity sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g== - -"@esbuild/linux-arm64@0.23.1": - version "0.23.1" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.23.1.tgz#8050af6d51ddb388c75653ef9871f5ccd8f12383" - integrity sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g== - -"@esbuild/linux-arm@0.23.1": - version "0.23.1" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz#ecaabd1c23b701070484990db9a82f382f99e771" - integrity sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ== - -"@esbuild/linux-ia32@0.23.1": - version "0.23.1" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.23.1.tgz#3ed2273214178109741c09bd0687098a0243b333" - integrity sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ== - -"@esbuild/linux-loong64@0.23.1": - version "0.23.1" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.23.1.tgz#a0fdf440b5485c81b0fbb316b08933d217f5d3ac" - integrity sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw== - -"@esbuild/linux-mips64el@0.23.1": - version "0.23.1" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.23.1.tgz#e11a2806346db8375b18f5e104c5a9d4e81807f6" - integrity sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q== - -"@esbuild/linux-ppc64@0.23.1": - version "0.23.1" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz#06a2744c5eaf562b1a90937855b4d6cf7c75ec96" - integrity sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw== - -"@esbuild/linux-riscv64@0.23.1": - version "0.23.1" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz#65b46a2892fc0d1af4ba342af3fe0fa4a8fe08e7" - integrity sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA== - -"@esbuild/linux-s390x@0.23.1": - version "0.23.1" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.23.1.tgz#e71ea18c70c3f604e241d16e4e5ab193a9785d6f" - integrity sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw== - -"@esbuild/linux-x64@0.23.1": - version "0.23.1" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz#d47f97391e80690d4dfe811a2e7d6927ad9eed24" - integrity sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ== - -"@esbuild/netbsd-x64@0.23.1": - version "0.23.1" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz#44e743c9778d57a8ace4b72f3c6b839a3b74a653" - integrity sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA== - -"@esbuild/openbsd-arm64@0.23.1": - version "0.23.1" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.1.tgz#05c5a1faf67b9881834758c69f3e51b7dee015d7" - integrity sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q== - -"@esbuild/openbsd-x64@0.23.1": - version "0.23.1" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.23.1.tgz#2e58ae511bacf67d19f9f2dcd9e8c5a93f00c273" - integrity sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA== - -"@esbuild/sunos-x64@0.23.1": - version "0.23.1" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz#adb022b959d18d3389ac70769cef5a03d3abd403" - integrity sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA== - -"@esbuild/win32-arm64@0.23.1": - version "0.23.1" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.23.1.tgz#84906f50c212b72ec360f48461d43202f4c8b9a2" - integrity sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A== - -"@esbuild/win32-ia32@0.23.1": - version "0.23.1" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.23.1.tgz#5e3eacc515820ff729e90d0cb463183128e82fac" - integrity sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ== - -"@esbuild/win32-x64@0.23.1": - version "0.23.1" - resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz#81fd50d11e2c32b2d6241470e3185b70c7b30699" - integrity sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg== - -"@eslint-community/eslint-utils@^4.1.2", "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.3.0": - version "4.4.0" - resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz" - integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== - dependencies: - eslint-visitor-keys "^3.3.0" - -"@eslint-community/regexpp@^4.4.0": - version "4.5.1" - resolved "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz" - integrity sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ== - -"@eslint/eslintrc@^2.0.1": - version "2.0.3" - resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz" - integrity sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ== - dependencies: - ajv "^6.12.4" - debug "^4.3.2" - espree "^9.5.2" - globals "^13.19.0" - ignore "^5.2.0" - import-fresh "^3.2.1" - js-yaml "^4.1.0" - minimatch "^3.1.2" - strip-json-comments "^3.1.1" - -"@eslint/js@8.36.0": - version "8.36.0" - resolved "https://registry.npmjs.org/@eslint/js/-/js-8.36.0.tgz" - integrity sha512-lxJ9R5ygVm8ZWgYdUweoq5ownDlJ4upvoWmO4eLxBYHdMo+vZ/Rx0EN6MbKWDJOSUGrqJy2Gt+Dyv/VKml0fjg== - -"@faker-js/faker@^7.6.0": - version "7.6.0" - resolved "https://registry.npmjs.org/@faker-js/faker/-/faker-7.6.0.tgz" - integrity sha512-XK6BTq1NDMo9Xqw/YkYyGjSsg44fbNwYRx7QK2CuoQgyy+f1rrTDHoExVM5PsyXCtfl2vs2vVJ0MN0yN6LppRw== - -"@floating-ui/core@^1.1.0", "@floating-ui/core@^1.4.1": - version "1.4.1" - resolved "https://registry.npmjs.org/@floating-ui/core/-/core-1.4.1.tgz" - integrity sha512-jk3WqquEJRlcyu7997NtR5PibI+y5bi+LS3hPmguVClypenMsCY3CBa3LAQnozRCtCrYWSEtAdiskpamuJRFOQ== - dependencies: - "@floating-ui/utils" "^0.1.1" - -"@floating-ui/dom@1.1.1": - version "1.1.1" - resolved "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.1.1.tgz" - integrity sha512-TpIO93+DIujg3g7SykEAGZMDtbJRrmnYRCNYSjJlvIbGhBjRSNTLVbNeDQBrzy9qDgUbiWdc7KA0uZHZ2tJmiw== - dependencies: - "@floating-ui/core" "^1.1.0" - -"@floating-ui/dom@^1.5.1": - version "1.5.1" - resolved "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.5.1.tgz" - integrity sha512-KwvVcPSXg6mQygvA1TjbN/gh///36kKtllIF8SUm0qpFj8+rvYrpvlYdL1JoA71SHpDqgSSdGOSoQ0Mp3uY5aw== - dependencies: - "@floating-ui/core" "^1.4.1" - "@floating-ui/utils" "^0.1.1" - -"@floating-ui/react-dom@^2.0.1": - version "2.0.2" - resolved "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.2.tgz" - integrity sha512-5qhlDvjaLmAst/rKb3VdlCinwTF4EYMiVxuuc/HVUjs46W0zgtbMmAZ1UTsDrRTxRmUEzl92mOtWbeeXL26lSQ== - dependencies: - "@floating-ui/dom" "^1.5.1" - -"@floating-ui/react@^0.25.2": - version "0.25.2" - resolved "https://registry.npmjs.org/@floating-ui/react/-/react-0.25.2.tgz" - integrity sha512-3e10G9LFOgl32/SMWLBOwT7oVCtB+d5zBsU2GxTSVOvRgZexwno5MlYbc0BaXr+TR5EEGpqe9tg9OUbjlrVRnQ== - dependencies: - "@floating-ui/react-dom" "^2.0.1" - "@floating-ui/utils" "^0.1.1" - tabbable "^6.0.1" - -"@floating-ui/utils@^0.1.1": - version "0.1.1" - resolved "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.1.tgz" - integrity sha512-m0G6wlnhm/AX0H12IOWtK8gASEMffnX08RtKkCgTdHb9JpHKGloI7icFfLg9ZmQeavcvR0PKmzxClyuFPSjKWw== - -"@formatjs/intl-localematcher@^0.5.4": - version "0.5.4" - resolved "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.4.tgz" - integrity sha512-zTwEpWOzZ2CiKcB93BLngUX59hQkuZjT2+SAQEscSm52peDW/getsawMcWF1rGRpMCX6D7nSJA3CzJ8gn13N/g== - dependencies: - tslib "^2.4.0" - -"@headlessui/react@^1.7.13": - version "1.7.15" - resolved "https://registry.npmjs.org/@headlessui/react/-/react-1.7.15.tgz" - integrity sha512-OTO0XtoRQ6JPB1cKNFYBZv2Q0JMqMGNhYP1CjPvcJvjz8YGokz8oAj89HIYZGN0gZzn/4kk9iUpmMF4Q21Gsqw== - dependencies: - client-only "^0.0.1" - -"@heroicons/react@^2.0.16": - version "2.0.18" - resolved "https://registry.npmjs.org/@heroicons/react/-/react-2.0.18.tgz" - integrity sha512-7TyMjRrZZMBPa+/5Y8lN0iyvUU/01PeMGX2+RE7cQWpEUIcb4QotzUObFkJDejj/HUH4qjP/eQ0gzzKs2f+6Yw== - -"@hookform/resolvers@^3.3.4": - version "3.3.4" - resolved "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-3.3.4.tgz" - integrity sha512-o5cgpGOuJYrd+iMKvkttOclgwRW86EsWJZZRC23prf0uU2i48Htq4PuT73AVb9ionFyZrwYEITuOFGF+BydEtQ== - -"@humanwhocodes/config-array@^0.11.8": - version "0.11.10" - resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz" - integrity sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ== - dependencies: - "@humanwhocodes/object-schema" "^1.2.1" - debug "^4.1.1" - minimatch "^3.0.5" - -"@humanwhocodes/module-importer@^1.0.1": - version "1.0.1" - resolved "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz" - integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== - -"@humanwhocodes/object-schema@^1.2.1": - version "1.2.1" - resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz" - integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== - -"@img/sharp-darwin-arm64@0.33.2": - version "0.33.2" - resolved "https://registry.yarnpkg.com/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.2.tgz#0a52a82c2169112794dac2c71bfba9e90f7c5bd1" - integrity sha512-itHBs1rPmsmGF9p4qRe++CzCgd+kFYktnsoR1sbIAfsRMrJZau0Tt1AH9KVnufc2/tU02Gf6Ibujx+15qRE03w== - optionalDependencies: - "@img/sharp-libvips-darwin-arm64" "1.0.1" - -"@img/sharp-darwin-arm64@0.33.5": - version "0.33.5" - resolved "https://registry.yarnpkg.com/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz#ef5b5a07862805f1e8145a377c8ba6e98813ca08" - integrity sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ== - optionalDependencies: - "@img/sharp-libvips-darwin-arm64" "1.0.4" - -"@img/sharp-darwin-x64@0.33.2": - version "0.33.2" - resolved "https://registry.yarnpkg.com/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.2.tgz#982e26bb9d38a81f75915c4032539aed621d1c21" - integrity sha512-/rK/69Rrp9x5kaWBjVN07KixZanRr+W1OiyKdXcbjQD6KbW+obaTeBBtLUAtbBsnlTTmWthw99xqoOS7SsySDg== - optionalDependencies: - "@img/sharp-libvips-darwin-x64" "1.0.1" - -"@img/sharp-darwin-x64@0.33.5": - version "0.33.5" - resolved "https://registry.yarnpkg.com/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz#e03d3451cd9e664faa72948cc70a403ea4063d61" - integrity sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q== - optionalDependencies: - "@img/sharp-libvips-darwin-x64" "1.0.4" - -"@img/sharp-libvips-darwin-arm64@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.1.tgz#81e83ffc2c497b3100e2f253766490f8fad479cd" - integrity sha512-kQyrSNd6lmBV7O0BUiyu/OEw9yeNGFbQhbxswS1i6rMDwBBSX+e+rPzu3S+MwAiGU3HdLze3PanQ4Xkfemgzcw== - -"@img/sharp-libvips-darwin-arm64@1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz#447c5026700c01a993c7804eb8af5f6e9868c07f" - integrity sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg== - -"@img/sharp-libvips-darwin-x64@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.1.tgz#fc1fcd9d78a178819eefe2c1a1662067a83ab1d6" - integrity sha512-eVU/JYLPVjhhrd8Tk6gosl5pVlvsqiFlt50wotCvdkFGf+mDNBJxMh+bvav+Wt3EBnNZWq8Sp2I7XfSjm8siog== - -"@img/sharp-libvips-darwin-x64@1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz#e0456f8f7c623f9dbfbdc77383caa72281d86062" - integrity sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ== - -"@img/sharp-libvips-linux-arm64@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.1.tgz#26eb8c556a9b0db95f343fc444abc3effb67ebcf" - integrity sha512-bnGG+MJjdX70mAQcSLxgeJco11G+MxTz+ebxlz8Y3dxyeb3Nkl7LgLI0mXupoO+u1wRNx/iRj5yHtzA4sde1yA== - -"@img/sharp-libvips-linux-arm64@1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz#979b1c66c9a91f7ff2893556ef267f90ebe51704" - integrity sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA== - -"@img/sharp-libvips-linux-arm@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.1.tgz#2a377b959ff7dd6528deee486c25461296a4fa8b" - integrity sha512-FtdMvR4R99FTsD53IA3LxYGghQ82t3yt0ZQ93WMZ2xV3dqrb0E8zq4VHaTOuLEAuA83oDawHV3fd+BsAPadHIQ== - -"@img/sharp-libvips-linux-arm@1.0.5": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz#99f922d4e15216ec205dcb6891b721bfd2884197" - integrity sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g== - -"@img/sharp-libvips-linux-s390x@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.1.tgz#af28ac9ba929204467ecdf843330d791e9421e10" - integrity sha512-3+rzfAR1YpMOeA2zZNp+aYEzGNWK4zF3+sdMxuCS3ey9HhDbJ66w6hDSHDMoap32DueFwhhs3vwooAB2MaK4XQ== - -"@img/sharp-libvips-linux-s390x@1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz#f8a5eb1f374a082f72b3f45e2fb25b8118a8a5ce" - integrity sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA== - -"@img/sharp-libvips-linux-x64@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.1.tgz#4273d182aa51912e655e1214ea47983d7c1f7f8d" - integrity sha512-3NR1mxFsaSgMMzz1bAnnKbSAI+lHXVTqAHgc1bgzjHuXjo4hlscpUxc0vFSAPKI3yuzdzcZOkq7nDPrP2F8Jgw== - -"@img/sharp-libvips-linux-x64@1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz#d4c4619cdd157774906e15770ee119931c7ef5e0" - integrity sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw== - -"@img/sharp-libvips-linuxmusl-arm64@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.1.tgz#d150c92151cea2e8d120ad168b9c358d09c77ce8" - integrity sha512-5aBRcjHDG/T6jwC3Edl3lP8nl9U2Yo8+oTl5drd1dh9Z1EBfzUKAJFUDTDisDjUwc7N4AjnPGfCA3jl3hY8uDg== - -"@img/sharp-libvips-linuxmusl-arm64@1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz#166778da0f48dd2bded1fa3033cee6b588f0d5d5" - integrity sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA== - -"@img/sharp-libvips-linuxmusl-x64@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.1.tgz#e297c1a4252c670d93b0f9e51fca40a7a5b6acfd" - integrity sha512-dcT7inI9DBFK6ovfeWRe3hG30h51cBAP5JXlZfx6pzc/Mnf9HFCQDLtYf4MCBjxaaTfjCCjkBxcy3XzOAo5txw== - -"@img/sharp-libvips-linuxmusl-x64@1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz#93794e4d7720b077fcad3e02982f2f1c246751ff" - integrity sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw== - -"@img/sharp-linux-arm64@0.33.2": - version "0.33.2" - resolved "https://registry.yarnpkg.com/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.2.tgz#af3409f801a9bee1d11d0c7e971dcd6180f80022" - integrity sha512-pz0NNo882vVfqJ0yNInuG9YH71smP4gRSdeL09ukC2YLE6ZyZePAlWKEHgAzJGTiOh8Qkaov6mMIMlEhmLdKew== - optionalDependencies: - "@img/sharp-libvips-linux-arm64" "1.0.1" - -"@img/sharp-linux-arm64@0.33.5": - version "0.33.5" - resolved "https://registry.yarnpkg.com/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz#edb0697e7a8279c9fc829a60fc35644c4839bb22" - integrity sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA== - optionalDependencies: - "@img/sharp-libvips-linux-arm64" "1.0.4" - -"@img/sharp-linux-arm@0.33.2": - version "0.33.2" - resolved "https://registry.yarnpkg.com/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.2.tgz#181f7466e6ac074042a38bfb679eb82505e17083" - integrity sha512-Fndk/4Zq3vAc4G/qyfXASbS3HBZbKrlnKZLEJzPLrXoJuipFNNwTes71+Ki1hwYW5lch26niRYoZFAtZVf3EGA== - optionalDependencies: - "@img/sharp-libvips-linux-arm" "1.0.1" - -"@img/sharp-linux-arm@0.33.5": - version "0.33.5" - resolved "https://registry.yarnpkg.com/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz#422c1a352e7b5832842577dc51602bcd5b6f5eff" - integrity sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ== - optionalDependencies: - "@img/sharp-libvips-linux-arm" "1.0.5" - -"@img/sharp-linux-s390x@0.33.2": - version "0.33.2" - resolved "https://registry.yarnpkg.com/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.2.tgz#9c171f49211f96fba84410b3e237b301286fa00f" - integrity sha512-MBoInDXDppMfhSzbMmOQtGfloVAflS2rP1qPcUIiITMi36Mm5YR7r0ASND99razjQUpHTzjrU1flO76hKvP5RA== - optionalDependencies: - "@img/sharp-libvips-linux-s390x" "1.0.1" - -"@img/sharp-linux-s390x@0.33.5": - version "0.33.5" - resolved "https://registry.yarnpkg.com/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz#f5c077926b48e97e4a04d004dfaf175972059667" - integrity sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q== - optionalDependencies: - "@img/sharp-libvips-linux-s390x" "1.0.4" - -"@img/sharp-linux-x64@0.33.2": - version "0.33.2" - resolved "https://registry.yarnpkg.com/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.2.tgz#b956dfc092adc58c2bf0fae2077e6f01a8b2d5d7" - integrity sha512-xUT82H5IbXewKkeF5aiooajoO1tQV4PnKfS/OZtb5DDdxS/FCI/uXTVZ35GQ97RZXsycojz/AJ0asoz6p2/H/A== - optionalDependencies: - "@img/sharp-libvips-linux-x64" "1.0.1" - -"@img/sharp-linux-x64@0.33.5": - version "0.33.5" - resolved "https://registry.yarnpkg.com/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz#d806e0afd71ae6775cc87f0da8f2d03a7c2209cb" - integrity sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA== - optionalDependencies: - "@img/sharp-libvips-linux-x64" "1.0.4" - -"@img/sharp-linuxmusl-arm64@0.33.2": - version "0.33.2" - resolved "https://registry.yarnpkg.com/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.2.tgz#10e0ec5a79d1234c6a71df44c9f3b0bef0bc0f15" - integrity sha512-F+0z8JCu/UnMzg8IYW1TMeiViIWBVg7IWP6nE0p5S5EPQxlLd76c8jYemG21X99UzFwgkRo5yz2DS+zbrnxZeA== - optionalDependencies: - "@img/sharp-libvips-linuxmusl-arm64" "1.0.1" - -"@img/sharp-linuxmusl-arm64@0.33.5": - version "0.33.5" - resolved "https://registry.yarnpkg.com/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz#252975b915894fb315af5deea174651e208d3d6b" - integrity sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g== - optionalDependencies: - "@img/sharp-libvips-linuxmusl-arm64" "1.0.4" - -"@img/sharp-linuxmusl-x64@0.33.2": - version "0.33.2" - resolved "https://registry.yarnpkg.com/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.2.tgz#29e0030c24aa27c38201b1fc84e3d172899fcbe0" - integrity sha512-+ZLE3SQmSL+Fn1gmSaM8uFusW5Y3J9VOf+wMGNnTtJUMUxFhv+P4UPaYEYT8tqnyYVaOVGgMN/zsOxn9pSsO2A== - optionalDependencies: - "@img/sharp-libvips-linuxmusl-x64" "1.0.1" - -"@img/sharp-linuxmusl-x64@0.33.5": - version "0.33.5" - resolved "https://registry.yarnpkg.com/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz#3f4609ac5d8ef8ec7dadee80b560961a60fd4f48" - integrity sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw== - optionalDependencies: - "@img/sharp-libvips-linuxmusl-x64" "1.0.4" - -"@img/sharp-wasm32@0.33.2": - version "0.33.2" - resolved "https://registry.yarnpkg.com/@img/sharp-wasm32/-/sharp-wasm32-0.33.2.tgz#38d7c740a22de83a60ad1e6bcfce17462b0d4230" - integrity sha512-fLbTaESVKuQcpm8ffgBD7jLb/CQLcATju/jxtTXR1XCLwbOQt+OL5zPHSDMmp2JZIeq82e18yE0Vv7zh6+6BfQ== - dependencies: - "@emnapi/runtime" "^0.45.0" - -"@img/sharp-wasm32@0.33.5": - version "0.33.5" - resolved "https://registry.yarnpkg.com/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz#6f44f3283069d935bb5ca5813153572f3e6f61a1" - integrity sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg== - dependencies: - "@emnapi/runtime" "^1.2.0" - -"@img/sharp-win32-ia32@0.33.2": - version "0.33.2" - resolved "https://registry.yarnpkg.com/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.2.tgz#09456314e223f68e5417c283b45c399635c16202" - integrity sha512-okBpql96hIGuZ4lN3+nsAjGeggxKm7hIRu9zyec0lnfB8E7Z6p95BuRZzDDXZOl2e8UmR4RhYt631i7mfmKU8g== - -"@img/sharp-win32-ia32@0.33.5": - version "0.33.5" - resolved "https://registry.yarnpkg.com/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz#1a0c839a40c5351e9885628c85f2e5dfd02b52a9" - integrity sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ== - -"@img/sharp-win32-x64@0.33.2": - version "0.33.2" - resolved "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.2.tgz" - integrity sha512-E4magOks77DK47FwHUIGH0RYWSgRBfGdK56kIHSVeB9uIS4pPFr4N2kIVsXdQQo4LzOsENKV5KAhRlRL7eMAdg== - -"@img/sharp-win32-x64@0.33.5": - version "0.33.5" - resolved "https://registry.yarnpkg.com/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz#56f00962ff0c4e0eb93d34a047d29fa995e3e342" - integrity sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg== - -"@isaacs/cliui@^8.0.2": - version "8.0.2" - resolved "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz" - integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== - dependencies: - string-width "^5.1.2" - string-width-cjs "npm:string-width@^4.2.0" - strip-ansi "^7.0.1" - strip-ansi-cjs "npm:strip-ansi@^6.0.1" - wrap-ansi "^8.1.0" - wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" - -"@istanbuljs/load-nyc-config@^1.0.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" - integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== - dependencies: - camelcase "^5.3.1" - find-up "^4.1.0" - get-package-type "^0.1.0" - js-yaml "^3.13.1" - resolve-from "^5.0.0" - -"@istanbuljs/schema@^0.1.2", "@istanbuljs/schema@^0.1.3": - version "0.1.3" - resolved "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" - integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== - -"@jest/console@^29.7.0": - version "29.7.0" - resolved "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz#cd4822dbdb84529265c5a2bdb529a3c9cc950ffc" - integrity sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg== - dependencies: - "@jest/types" "^29.6.3" - "@types/node" "*" - chalk "^4.0.0" - jest-message-util "^29.7.0" - jest-util "^29.7.0" - slash "^3.0.0" - -"@jest/core@^29.7.0": - version "29.7.0" - resolved "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz#b6cccc239f30ff36609658c5a5e2291757ce448f" - integrity sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg== - dependencies: - "@jest/console" "^29.7.0" - "@jest/reporters" "^29.7.0" - "@jest/test-result" "^29.7.0" - "@jest/transform" "^29.7.0" - "@jest/types" "^29.6.3" - "@types/node" "*" - ansi-escapes "^4.2.1" - chalk "^4.0.0" - ci-info "^3.2.0" - exit "^0.1.2" - graceful-fs "^4.2.9" - jest-changed-files "^29.7.0" - jest-config "^29.7.0" - jest-haste-map "^29.7.0" - jest-message-util "^29.7.0" - jest-regex-util "^29.6.3" - jest-resolve "^29.7.0" - jest-resolve-dependencies "^29.7.0" - jest-runner "^29.7.0" - jest-runtime "^29.7.0" - jest-snapshot "^29.7.0" - jest-util "^29.7.0" - jest-validate "^29.7.0" - jest-watcher "^29.7.0" - micromatch "^4.0.4" - pretty-format "^29.7.0" - slash "^3.0.0" - strip-ansi "^6.0.0" - -"@jest/environment@^29.7.0": - version "29.7.0" - resolved "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz#24d61f54ff1f786f3cd4073b4b94416383baf2a7" - integrity sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw== - dependencies: - "@jest/fake-timers" "^29.7.0" - "@jest/types" "^29.6.3" - "@types/node" "*" - jest-mock "^29.7.0" - -"@jest/expect-utils@^29.7.0": - version "29.7.0" - resolved "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz#023efe5d26a8a70f21677d0a1afc0f0a44e3a1c6" - integrity sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA== - dependencies: - jest-get-type "^29.6.3" - -"@jest/expect@^29.7.0": - version "29.7.0" - resolved "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz#76a3edb0cb753b70dfbfe23283510d3d45432bf2" - integrity sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ== - dependencies: - expect "^29.7.0" - jest-snapshot "^29.7.0" - -"@jest/fake-timers@^29.7.0": - version "29.7.0" - resolved "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz#fd91bf1fffb16d7d0d24a426ab1a47a49881a565" - integrity sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ== - dependencies: - "@jest/types" "^29.6.3" - "@sinonjs/fake-timers" "^10.0.2" - "@types/node" "*" - jest-message-util "^29.7.0" - jest-mock "^29.7.0" - jest-util "^29.7.0" - -"@jest/globals@^29.7.0": - version "29.7.0" - resolved "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz#8d9290f9ec47ff772607fa864ca1d5a2efae1d4d" - integrity sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ== - dependencies: - "@jest/environment" "^29.7.0" - "@jest/expect" "^29.7.0" - "@jest/types" "^29.6.3" - jest-mock "^29.7.0" - -"@jest/reporters@^29.7.0": - version "29.7.0" - resolved "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz#04b262ecb3b8faa83b0b3d321623972393e8f4c7" - integrity sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg== - dependencies: - "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^29.7.0" - "@jest/test-result" "^29.7.0" - "@jest/transform" "^29.7.0" - "@jest/types" "^29.6.3" - "@jridgewell/trace-mapping" "^0.3.18" - "@types/node" "*" - chalk "^4.0.0" - collect-v8-coverage "^1.0.0" - exit "^0.1.2" - glob "^7.1.3" - graceful-fs "^4.2.9" - istanbul-lib-coverage "^3.0.0" - istanbul-lib-instrument "^6.0.0" - istanbul-lib-report "^3.0.0" - istanbul-lib-source-maps "^4.0.0" - istanbul-reports "^3.1.3" - jest-message-util "^29.7.0" - jest-util "^29.7.0" - jest-worker "^29.7.0" - slash "^3.0.0" - string-length "^4.0.1" - strip-ansi "^6.0.0" - v8-to-istanbul "^9.0.1" - -"@jest/schemas@^29.6.3": - version "29.6.3" - resolved "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz#430b5ce8a4e0044a7e3819663305a7b3091c8e03" - integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA== - dependencies: - "@sinclair/typebox" "^0.27.8" - -"@jest/source-map@^29.6.3": - version "29.6.3" - resolved "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz#d90ba772095cf37a34a5eb9413f1b562a08554c4" - integrity sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw== - dependencies: - "@jridgewell/trace-mapping" "^0.3.18" - callsites "^3.0.0" - graceful-fs "^4.2.9" - -"@jest/test-result@^29.7.0": - version "29.7.0" - resolved "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz#8db9a80aa1a097bb2262572686734baed9b1657c" - integrity sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA== - dependencies: - "@jest/console" "^29.7.0" - "@jest/types" "^29.6.3" - "@types/istanbul-lib-coverage" "^2.0.0" - collect-v8-coverage "^1.0.0" - -"@jest/test-sequencer@^29.7.0": - version "29.7.0" - resolved "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz#6cef977ce1d39834a3aea887a1726628a6f072ce" - integrity sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw== - dependencies: - "@jest/test-result" "^29.7.0" - graceful-fs "^4.2.9" - jest-haste-map "^29.7.0" - slash "^3.0.0" - -"@jest/transform@^29.7.0": - version "29.7.0" - resolved "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz#df2dd9c346c7d7768b8a06639994640c642e284c" - integrity sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw== - dependencies: - "@babel/core" "^7.11.6" - "@jest/types" "^29.6.3" - "@jridgewell/trace-mapping" "^0.3.18" - babel-plugin-istanbul "^6.1.1" - chalk "^4.0.0" - convert-source-map "^2.0.0" - fast-json-stable-stringify "^2.1.0" - graceful-fs "^4.2.9" - jest-haste-map "^29.7.0" - jest-regex-util "^29.6.3" - jest-util "^29.7.0" - micromatch "^4.0.4" - pirates "^4.0.4" - slash "^3.0.0" - write-file-atomic "^4.0.2" - -"@jest/types@^29.6.3": - version "29.6.3" - resolved "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz#1131f8cf634e7e84c5e77bab12f052af585fba59" - integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw== - dependencies: - "@jest/schemas" "^29.6.3" - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^3.0.0" - "@types/node" "*" - "@types/yargs" "^17.0.8" - chalk "^4.0.0" - -"@jridgewell/gen-mapping@^0.3.2", "@jridgewell/gen-mapping@^0.3.5": - version "0.3.5" - resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz" - integrity sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg== - dependencies: - "@jridgewell/set-array" "^1.2.1" - "@jridgewell/sourcemap-codec" "^1.4.10" - "@jridgewell/trace-mapping" "^0.3.24" - -"@jridgewell/resolve-uri@^3.0.3": - version "3.1.2" - resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" - integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== - -"@jridgewell/resolve-uri@^3.1.0": - version "3.1.0" - resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz" - integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== - -"@jridgewell/set-array@^1.2.1": - version "1.2.1" - resolved "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz" - integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== - -"@jridgewell/source-map@^0.3.3": - version "0.3.6" - resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.6.tgz#9d71ca886e32502eb9362c9a74a46787c36df81a" - integrity sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ== - dependencies: - "@jridgewell/gen-mapping" "^0.3.5" - "@jridgewell/trace-mapping" "^0.3.25" - -"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": - version "1.4.15" - resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz" - integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== - -"@jridgewell/sourcemap-codec@^1.5.0": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" - integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== - -"@jridgewell/trace-mapping@0.3.9": - version "0.3.9" - resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" - integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== - dependencies: - "@jridgewell/resolve-uri" "^3.0.3" - "@jridgewell/sourcemap-codec" "^1.4.10" - -"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.20", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": - version "0.3.25" - resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz" - integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== - dependencies: - "@jridgewell/resolve-uri" "^3.1.0" - "@jridgewell/sourcemap-codec" "^1.4.14" - -"@lexical/clipboard@0.16.0": - version "0.16.0" - resolved "https://registry.npmjs.org/@lexical/clipboard/-/clipboard-0.16.0.tgz" - integrity sha512-eYMJ6jCXpWBVC05Mu9HLMysrBbfi++xFfsm+Yo7A6kYGrqYUhpXqjJkYnw1xdZYL3bV73Oe4ByVJuq42GU+Mqw== - dependencies: - "@lexical/html" "0.16.0" - "@lexical/list" "0.16.0" - "@lexical/selection" "0.16.0" - "@lexical/utils" "0.16.0" - lexical "0.16.0" - -"@lexical/code@0.16.0": - version "0.16.0" - resolved "https://registry.npmjs.org/@lexical/code/-/code-0.16.0.tgz" - integrity sha512-1EKCBSFV745UI2zn5v75sKcvVdmd+y2JtZhw8CItiQkRnBLv4l4d/RZYy+cKOuXJGsoBrKtxXn5sl7HebwQbPw== - dependencies: - "@lexical/utils" "0.16.0" - lexical "0.16.0" - prismjs "^1.27.0" - -"@lexical/devtools-core@0.16.0": - version "0.16.0" - resolved "https://registry.npmjs.org/@lexical/devtools-core/-/devtools-core-0.16.0.tgz" - integrity sha512-Jt8p0J0UoMHf3UMh3VdyrXbLLwpEZuMqihTmbPRpwo+YQ6NGQU35QgwY2K0DpPAThpxL/Cm7uaFqGOy8Kjrhqw== - dependencies: - "@lexical/html" "0.16.0" - "@lexical/link" "0.16.0" - "@lexical/mark" "0.16.0" - "@lexical/table" "0.16.0" - "@lexical/utils" "0.16.0" - lexical "0.16.0" - -"@lexical/dragon@0.16.0": - version "0.16.0" - resolved "https://registry.npmjs.org/@lexical/dragon/-/dragon-0.16.0.tgz" - integrity sha512-Yr29SFZzOPs+S6UrEZaXnnso1fJGVfZOXVJQZbyzlspqJpSHXVH7InOXYHWN6JSWQ8Hs/vU3ksJXwqz+0TCp2g== - dependencies: - lexical "0.16.0" - -"@lexical/hashtag@0.16.0": - version "0.16.0" - resolved "https://registry.npmjs.org/@lexical/hashtag/-/hashtag-0.16.0.tgz" - integrity sha512-2EdAvxYVYqb0nv6vgxCRgE8ip7yez5p0y0oeUyxmdbcfZdA+Jl90gYH3VdevmZ5Bk3wE0/fIqiLD+Bb5smqjCQ== - dependencies: - "@lexical/utils" "0.16.0" - lexical "0.16.0" - -"@lexical/history@0.16.0": - version "0.16.0" - resolved "https://registry.npmjs.org/@lexical/history/-/history-0.16.0.tgz" - integrity sha512-xwFxgDZGviyGEqHmgt6A6gPhsyU/yzlKRk9TBUVByba3khuTknlJ1a80H5jb+OYcrpiElml7iVuGYt+oC7atCA== - dependencies: - "@lexical/utils" "0.16.0" - lexical "0.16.0" - -"@lexical/html@0.16.0": - version "0.16.0" - resolved "https://registry.npmjs.org/@lexical/html/-/html-0.16.0.tgz" - integrity sha512-okxn3q/1qkUpCZNEFRI39XeJj4YRjb6prm3WqZgP4d39DI1W24feeTZJjYRCW+dc3NInwFaolU3pNA2MGkjRtg== - dependencies: - "@lexical/selection" "0.16.0" - "@lexical/utils" "0.16.0" - lexical "0.16.0" - -"@lexical/link@0.16.0": - version "0.16.0" - resolved "https://registry.npmjs.org/@lexical/link/-/link-0.16.0.tgz" - integrity sha512-ppvJSh/XGqlzbeymOiwcXJcUcrqgQqTK2QXTBAZq7JThtb0WsJxYd2CSLSN+Ycu23prnwqOqILcU0+34+gAVFw== - dependencies: - "@lexical/utils" "0.16.0" - lexical "0.16.0" - -"@lexical/list@0.16.0": - version "0.16.0" - resolved "https://registry.npmjs.org/@lexical/list/-/list-0.16.0.tgz" - integrity sha512-nBx/DMM7nCgnOzo1JyNnVaIrk/Xi5wIPNi8jixrEV6w9Om2K6dHutn/79Xzp2dQlNGSLHEDjky6N2RyFgmXh0g== - dependencies: - "@lexical/utils" "0.16.0" - lexical "0.16.0" - -"@lexical/mark@0.16.0": - version "0.16.0" - resolved "https://registry.npmjs.org/@lexical/mark/-/mark-0.16.0.tgz" - integrity sha512-WMR4nqygSgIQ6Vdr5WAzohxBGjH+m44dBNTbWTGZGVlRvPzvBT6tieCoxFqpceIq/ko67HGTCNoFj2cMKVwgIA== - dependencies: - "@lexical/utils" "0.16.0" - lexical "0.16.0" - -"@lexical/markdown@0.16.0": - version "0.16.0" - resolved "https://registry.npmjs.org/@lexical/markdown/-/markdown-0.16.0.tgz" - integrity sha512-7HQLFrBbpY68mcq4A6C1qIGmjgA+fAByditi2WRe7tD2eoIKb/B5baQAnDKis0J+m5kTaCBmdlT6csSzyOPzeQ== - dependencies: - "@lexical/code" "0.16.0" - "@lexical/link" "0.16.0" - "@lexical/list" "0.16.0" - "@lexical/rich-text" "0.16.0" - "@lexical/text" "0.16.0" - "@lexical/utils" "0.16.0" - lexical "0.16.0" - -"@lexical/offset@0.16.0": - version "0.16.0" - resolved "https://registry.npmjs.org/@lexical/offset/-/offset-0.16.0.tgz" - integrity sha512-4TqPEC2qA7sgO8Tm65nOWnhJ8dkl22oeuGv9sUB+nhaiRZnw3R45mDelg23r56CWE8itZnvueE7TKvV+F3OXtQ== - dependencies: - lexical "0.16.0" - -"@lexical/overflow@0.16.0": - version "0.16.0" - resolved "https://registry.npmjs.org/@lexical/overflow/-/overflow-0.16.0.tgz" - integrity sha512-a7gtIRxleEuMN9dj2yO4CdezBBfIr9Mq+m7G5z62+xy7VL7cfMfF+xWjy3EmDYDXS4vOQgAXAUgO4oKz2AKGhQ== - dependencies: - lexical "0.16.0" - -"@lexical/plain-text@0.16.0": - version "0.16.0" - resolved "https://registry.npmjs.org/@lexical/plain-text/-/plain-text-0.16.0.tgz" - integrity sha512-BK7/GSOZUHRJTbNPkpb9a/xN9z+FBCdunTsZhnOY8pQ7IKws3kuMO2Tk1zXfTd882ZNAxFdDKNdLYDSeufrKpw== - dependencies: - "@lexical/clipboard" "0.16.0" - "@lexical/selection" "0.16.0" - "@lexical/utils" "0.16.0" - lexical "0.16.0" - -"@lexical/react@^0.16.0": - version "0.16.0" - resolved "https://registry.npmjs.org/@lexical/react/-/react-0.16.0.tgz" - integrity sha512-WKFQbI0/m1YkLjL5t90YLJwjGcl5QRe6mkfm3ljQuL7Ioj3F92ZN/J2gHFVJ9iC8/lJs6Zzw6oFjiP8hQxJf9Q== - dependencies: - "@lexical/clipboard" "0.16.0" - "@lexical/code" "0.16.0" - "@lexical/devtools-core" "0.16.0" - "@lexical/dragon" "0.16.0" - "@lexical/hashtag" "0.16.0" - "@lexical/history" "0.16.0" - "@lexical/link" "0.16.0" - "@lexical/list" "0.16.0" - "@lexical/mark" "0.16.0" - "@lexical/markdown" "0.16.0" - "@lexical/overflow" "0.16.0" - "@lexical/plain-text" "0.16.0" - "@lexical/rich-text" "0.16.0" - "@lexical/selection" "0.16.0" - "@lexical/table" "0.16.0" - "@lexical/text" "0.16.0" - "@lexical/utils" "0.16.0" - "@lexical/yjs" "0.16.0" - lexical "0.16.0" - react-error-boundary "^3.1.4" - -"@lexical/rich-text@0.16.0": - version "0.16.0" - resolved "https://registry.npmjs.org/@lexical/rich-text/-/rich-text-0.16.0.tgz" - integrity sha512-AGTD6yJZ+kj2TNah1r7/6vyufs6fZANeSvv9x5eG+WjV4uyUJYkd1qR8C5gFZHdkyr+bhAcsAXvS039VzAxRrQ== - dependencies: - "@lexical/clipboard" "0.16.0" - "@lexical/selection" "0.16.0" - "@lexical/utils" "0.16.0" - lexical "0.16.0" - -"@lexical/selection@0.16.0": - version "0.16.0" - resolved "https://registry.npmjs.org/@lexical/selection/-/selection-0.16.0.tgz" - integrity sha512-trT9gQVJ2j6AwAe7tHJ30SRuxCpV6yR9LFtggxphHsXSvJYnoHC0CXh1TF2jHl8Gd5OsdWseexGLBE4Y0V3gwQ== - dependencies: - lexical "0.16.0" - -"@lexical/table@0.16.0": - version "0.16.0" - resolved "https://registry.npmjs.org/@lexical/table/-/table-0.16.0.tgz" - integrity sha512-A66K779kxdr0yH2RwT2itsMnkzyFLFNPXyiWGLobCH8ON4QPuBouZvjbRHBe8Pe64yJ0c1bRDxSbTqUi9Wt3Gg== - dependencies: - "@lexical/utils" "0.16.0" - lexical "0.16.0" - -"@lexical/text@0.16.0": - version "0.16.0" - resolved "https://registry.npmjs.org/@lexical/text/-/text-0.16.0.tgz" - integrity sha512-9ilaOhuNIIGHKC8g8j3K/mEvJ09af9B6RKbm3GNoRcf/WNHD4dEFWNTEvgo/3zCzAS8EUBI6UINmfQQWlMjdIQ== - dependencies: - lexical "0.16.0" - -"@lexical/utils@0.16.0": - version "0.16.0" - resolved "https://registry.npmjs.org/@lexical/utils/-/utils-0.16.0.tgz" - integrity sha512-GWmFEmd7o3GHqJBaEwzuZQbfTNI3Gg8ReGuHMHABgrkhZ8j2NggoRBlxsQLG0f7BewfTMVwbye22yBPq78775w== - dependencies: - "@lexical/list" "0.16.0" - "@lexical/selection" "0.16.0" - "@lexical/table" "0.16.0" - lexical "0.16.0" - -"@lexical/yjs@0.16.0": - version "0.16.0" - resolved "https://registry.npmjs.org/@lexical/yjs/-/yjs-0.16.0.tgz" - integrity sha512-YIJr87DfAXTwoVHDjR7cci//hr4r/a61Nn95eo2JNwbTqQo65Gp8rwJivqVxNfvKZmRdwHTKgvdEDoBmI/tGog== - dependencies: - "@lexical/offset" "0.16.0" - lexical "0.16.0" - -"@mdx-js/loader@^2.3.0": - version "2.3.0" - resolved "https://registry.npmjs.org/@mdx-js/loader/-/loader-2.3.0.tgz" - integrity sha512-IqsscXh7Q3Rzb+f5DXYk0HU71PK+WuFsEhf+mSV3fOhpLcEpgsHvTQ2h0T6TlZ5gHOaBeFjkXwB52by7ypMyNg== - dependencies: - "@mdx-js/mdx" "^2.0.0" - source-map "^0.7.0" - -"@mdx-js/mdx@^2.0.0": - version "2.3.0" - resolved "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-2.3.0.tgz" - integrity sha512-jLuwRlz8DQfQNiUCJR50Y09CGPq3fLtmtUQfVrj79E0JWu3dvsVcxVIcfhR5h0iXu+/z++zDrYeiJqifRynJkA== - dependencies: - "@types/estree-jsx" "^1.0.0" - "@types/mdx" "^2.0.0" - estree-util-build-jsx "^2.0.0" - estree-util-is-identifier-name "^2.0.0" - estree-util-to-js "^1.1.0" - estree-walker "^3.0.0" - hast-util-to-estree "^2.0.0" - markdown-extensions "^1.0.0" - periscopic "^3.0.0" - remark-mdx "^2.0.0" - remark-parse "^10.0.0" - remark-rehype "^10.0.0" - unified "^10.0.0" - unist-util-position-from-estree "^1.0.0" - unist-util-stringify-position "^3.0.0" - unist-util-visit "^4.0.0" - vfile "^5.0.0" - -"@mdx-js/react@^2.3.0": - version "2.3.0" - resolved "https://registry.npmjs.org/@mdx-js/react/-/react-2.3.0.tgz" - integrity sha512-zQH//gdOmuu7nt2oJR29vFhDv88oGPmVw6BggmrHeMI+xgEkp1B2dX9/bMBSYtK0dyLX/aOmesKS09g222K1/g== - dependencies: - "@types/mdx" "^2.0.0" - "@types/react" ">=16" - -"@mdx-js/react@^3.0.0": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@mdx-js/react/-/react-3.0.1.tgz#997a19b3a5b783d936c75ae7c47cfe62f967f746" - integrity sha512-9ZrPIU4MGf6et1m1ov3zKf+q9+deetI51zprKB1D/z3NOb+rUxxtEl3mCjW5wTGh6VhRdwPueh1oRzi6ezkA8A== - dependencies: - "@types/mdx" "^2.0.0" - -"@monaco-editor/loader@^1.4.0": - version "1.4.0" - resolved "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.4.0.tgz" - integrity sha512-00ioBig0x642hytVspPl7DbQyaSWRaolYie/UFNjoTdvoKPzo6xrXLhTk9ixgIKcLH5b5vDOjVNiGyY+uDCUlg== - dependencies: - state-local "^1.0.6" - -"@monaco-editor/react@^4.6.0": - version "4.6.0" - resolved "https://registry.npmjs.org/@monaco-editor/react/-/react-4.6.0.tgz" - integrity sha512-RFkU9/i7cN2bsq/iTkurMWOEErmYcY6JiQI3Jn+WeR/FGISH8JbHERjpS9oRuSOPvDMJI0Z8nJeKkbOs9sBYQw== - dependencies: - "@monaco-editor/loader" "^1.4.0" - -"@next/env@14.2.4": - version "14.2.4" - resolved "https://registry.npmjs.org/@next/env/-/env-14.2.4.tgz" - integrity sha512-3EtkY5VDkuV2+lNmKlbkibIJxcO4oIHEhBWne6PaAp+76J9KoSsGvNikp6ivzAT8dhhBMYrm6op2pS1ApG0Hzg== - -"@next/eslint-plugin-next@14.1.0": - version "14.1.0" - resolved "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.1.0.tgz" - integrity sha512-x4FavbNEeXx/baD/zC/SdrvkjSby8nBn8KcCREqk6UuwvwoAPZmaV8TFCAuo/cpovBRTIY67mHhe86MQQm/68Q== - dependencies: - glob "10.3.10" - -"@next/mdx@^14.0.4": - version "14.1.0" - resolved "https://registry.npmjs.org/@next/mdx/-/mdx-14.1.0.tgz" - integrity sha512-YLYsViq91+H8+3oCtK1iuMWdeN14K70Hy6/tYScY+nfo5bQ84A/A+vA6UdNC9MkbWQ/373hQubx2p4JvUjlb2Q== - dependencies: - source-map "^0.7.0" - -"@next/swc-darwin-arm64@14.2.4": - version "14.2.4" - resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.4.tgz#da9f04c34a3d5f0b8401ed745768420e4a604036" - integrity sha512-AH3mO4JlFUqsYcwFUHb1wAKlebHU/Hv2u2kb1pAuRanDZ7pD/A/KPD98RHZmwsJpdHQwfEc/06mgpSzwrJYnNg== - -"@next/swc-darwin-x64@14.2.4": - version "14.2.4" - resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.4.tgz#46dedb29ec5503bf171a72a3ecb8aac6e738e9d6" - integrity sha512-QVadW73sWIO6E2VroyUjuAxhWLZWEpiFqHdZdoQ/AMpN9YWGuHV8t2rChr0ahy+irKX5mlDU7OY68k3n4tAZTg== - -"@next/swc-linux-arm64-gnu@14.2.4": - version "14.2.4" - resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.4.tgz#c9697ab9eb422bd1d7ffd0eb0779cc2aefa9d4a1" - integrity sha512-KT6GUrb3oyCfcfJ+WliXuJnD6pCpZiosx2X3k66HLR+DMoilRb76LpWPGb4tZprawTtcnyrv75ElD6VncVamUQ== - -"@next/swc-linux-arm64-musl@14.2.4": - version "14.2.4" - resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.4.tgz#cbbceb2008571c743b5a310a488d2e166d200a75" - integrity sha512-Alv8/XGSs/ytwQcbCHwze1HmiIkIVhDHYLjczSVrf0Wi2MvKn/blt7+S6FJitj3yTlMwMxII1gIJ9WepI4aZ/A== - -"@next/swc-linux-x64-gnu@14.2.4": - version "14.2.4" - resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.4.tgz#d79184223f857bacffb92f643cb2943a43632568" - integrity sha512-ze0ShQDBPCqxLImzw4sCdfnB3lRmN3qGMB2GWDRlq5Wqy4G36pxtNOo2usu/Nm9+V2Rh/QQnrRc2l94kYFXO6Q== - -"@next/swc-linux-x64-musl@14.2.4": - version "14.2.4" - resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.4.tgz#6b6c3e5ac02ca5e63394d280ec8ee607491902df" - integrity sha512-8dwC0UJoc6fC7PX70csdaznVMNr16hQrTDAMPvLPloazlcaWfdPogq+UpZX6Drqb1OBlwowz8iG7WR0Tzk/diQ== - -"@next/swc-win32-arm64-msvc@14.2.4": - version "14.2.4" - resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.4.tgz#dbad3906e870dba84c5883d9d4c4838472e0697f" - integrity sha512-jxyg67NbEWkDyvM+O8UDbPAyYRZqGLQDTPwvrBBeOSyVWW/jFQkQKQ70JDqDSYg1ZDdl+E3nkbFbq8xM8E9x8A== - -"@next/swc-win32-ia32-msvc@14.2.4": - version "14.2.4" - resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.4.tgz#6074529b91ba49132922ce89a2e16d25d2ec235d" - integrity sha512-twrmN753hjXRdcrZmZttb/m5xaCBFa48Dt3FbeEItpJArxriYDunWxJn+QFXdJ3hPkm4u7CKxncVvnmgQMY1ag== - -"@next/swc-win32-x64-msvc@14.2.4": - version "14.2.4" - resolved "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.4.tgz" - integrity sha512-tkLrjBzqFTP8DVrAAQmZelEahfR9OxWpFR++vAI9FBhCiIxtwHwBHC23SBHCTURBtwB4kc/x44imVOnkKGNVGg== - -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": - version "2.0.5" - resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - -"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": - version "1.2.8" - resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - -"@pkgjs/parseargs@^0.11.0": - version "0.11.0" - resolved "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz" - integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== - -"@pkgr/utils@^2.3.1": - version "2.4.1" - resolved "https://registry.npmjs.org/@pkgr/utils/-/utils-2.4.1.tgz" - integrity sha512-JOqwkgFEyi+OROIyq7l4Jy28h/WwhDnG/cPkXG2Z1iFbubB6jsHW1NDvmyOzTBxHr3yg68YGirmh1JUgMqa+9w== - dependencies: - cross-spawn "^7.0.3" - fast-glob "^3.2.12" - is-glob "^4.0.3" - open "^9.1.0" - picocolors "^1.0.0" - tslib "^2.5.0" - -"@pmmmwh/react-refresh-webpack-plugin@^0.5.11": - version "0.5.15" - resolved "https://registry.yarnpkg.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.15.tgz#f126be97c30b83ed777e2aeabd518bc592e6e7c4" - integrity sha512-LFWllMA55pzB9D34w/wXUCf8+c+IYKuJDgxiZ3qMhl64KRMBHYM1I3VdGaD2BV5FNPV2/S2596bppxHbv2ZydQ== - dependencies: - ansi-html "^0.0.9" - core-js-pure "^3.23.3" - error-stack-parser "^2.0.6" - html-entities "^2.1.0" - loader-utils "^2.0.4" - schema-utils "^4.2.0" - source-map "^0.7.3" - -"@reactflow/background@11.3.13": - version "11.3.13" - resolved "https://registry.npmjs.org/@reactflow/background/-/background-11.3.13.tgz" - integrity sha512-hkvpVEhgvfTDyCvdlitw4ioKCYLaaiRXnuEG+1QM3Np+7N1DiWF1XOv5I8AFyNoJL07yXEkbECUTsHvkBvcG5A== - dependencies: - "@reactflow/core" "11.11.3" - classcat "^5.0.3" - zustand "^4.4.1" - -"@reactflow/controls@11.2.13": - version "11.2.13" - resolved "https://registry.npmjs.org/@reactflow/controls/-/controls-11.2.13.tgz" - integrity sha512-3xgEg6ALIVkAQCS4NiBjb7ad8Cb3D8CtA7Vvl4Hf5Ar2PIVs6FOaeft9s2iDZGtsWP35ECDYId1rIFVhQL8r+A== - dependencies: - "@reactflow/core" "11.11.3" - classcat "^5.0.3" - zustand "^4.4.1" - -"@reactflow/core@11.11.3": - version "11.11.3" - resolved "https://registry.npmjs.org/@reactflow/core/-/core-11.11.3.tgz" - integrity sha512-+adHdUa7fJSEM93fWfjQwyWXeI92a1eLKwWbIstoCakHpL8UjzwhEh6sn+mN2h/59MlVI7Ehr1iGTt3MsfcIFA== - dependencies: - "@types/d3" "^7.4.0" - "@types/d3-drag" "^3.0.1" - "@types/d3-selection" "^3.0.3" - "@types/d3-zoom" "^3.0.1" - classcat "^5.0.3" - d3-drag "^3.0.0" - d3-selection "^3.0.0" - d3-zoom "^3.0.0" - zustand "^4.4.1" - -"@reactflow/minimap@11.7.13": - version "11.7.13" - resolved "https://registry.npmjs.org/@reactflow/minimap/-/minimap-11.7.13.tgz" - integrity sha512-m2MvdiGSyOu44LEcERDEl1Aj6x//UQRWo3HEAejNU4HQTlJnYrSN8tgrYF8TxC1+c/9UdyzQY5VYgrTwW4QWdg== - dependencies: - "@reactflow/core" "11.11.3" - "@types/d3-selection" "^3.0.3" - "@types/d3-zoom" "^3.0.1" - classcat "^5.0.3" - d3-selection "^3.0.0" - d3-zoom "^3.0.0" - zustand "^4.4.1" - -"@reactflow/node-resizer@2.2.13": - version "2.2.13" - resolved "https://registry.npmjs.org/@reactflow/node-resizer/-/node-resizer-2.2.13.tgz" - integrity sha512-X7ceQ2s3jFLgbkg03n2RYr4hm3jTVrzkW2W/8ANv/SZfuVmF8XJxlERuD8Eka5voKqLda0ywIZGAbw9GoHLfUQ== - dependencies: - "@reactflow/core" "11.11.3" - classcat "^5.0.4" - d3-drag "^3.0.0" - d3-selection "^3.0.0" - zustand "^4.4.1" - -"@reactflow/node-toolbar@1.3.13": - version "1.3.13" - resolved "https://registry.npmjs.org/@reactflow/node-toolbar/-/node-toolbar-1.3.13.tgz" - integrity sha512-aknvNICO10uWdthFSpgD6ctY/CTBeJUMV9co8T9Ilugr08Nb89IQ4uD0dPmr031ewMQxixtYIkw+sSDDzd2aaQ== - dependencies: - "@reactflow/core" "11.11.3" - classcat "^5.0.3" - zustand "^4.4.1" - -"@remixicon/react@^4.2.0": - version "4.2.0" - resolved "https://registry.npmjs.org/@remixicon/react/-/react-4.2.0.tgz" - integrity sha512-eGhKpZ88OU0qkcY9pJu6khBmItDV82nU130E6C68yc+FbljueHlUYy/4CrJsmf860RIDMay2Rpzl27OSJ81miw== - -"@rgrove/parse-xml@^4.1.0": - version "4.1.0" - resolved "https://registry.npmjs.org/@rgrove/parse-xml/-/parse-xml-4.1.0.tgz" - integrity sha512-pBiltENdy8SfI0AeR1e5TRpS9/9Gl0eiOEt6ful2jQfzsgvZYWqsKiBWaOCLdocQuk0wS7KOHI37n0C1pnKqTw== - -"@rushstack/eslint-patch@^1.3.3": - version "1.7.2" - resolved "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.7.2.tgz" - integrity sha512-RbhOOTCNoCrbfkRyoXODZp75MlpiHMgbE5MEBZAnnnLyQNgrigEj4p0lzsMDyc1zVsJDLrivB58tgg3emX0eEA== - -"@sentry-internal/tracing@7.54.0": - version "7.54.0" - resolved "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.54.0.tgz" - integrity sha512-JsyhZ0wWZ+VqbHJg+azqRGdYJDkcI5R9+pnkO6SzbzxrRewqMAIwzkpPee3oI7vG99uhMEkOkMjHu0nQGwkOQw== - dependencies: - "@sentry/core" "7.54.0" - "@sentry/types" "7.54.0" - "@sentry/utils" "7.54.0" - tslib "^1.9.3" - -"@sentry/browser@7.54.0": - version "7.54.0" - resolved "https://registry.npmjs.org/@sentry/browser/-/browser-7.54.0.tgz" - integrity sha512-EvLAw03N9WE2m1CMl2/1YMeIs1icw9IEOVJhWmf3uJEysNJOFWXu6ZzdtHEz1E6DiJYhc1HzDya0ExZeJxNARA== - dependencies: - "@sentry-internal/tracing" "7.54.0" - "@sentry/core" "7.54.0" - "@sentry/replay" "7.54.0" - "@sentry/types" "7.54.0" - "@sentry/utils" "7.54.0" - tslib "^1.9.3" - -"@sentry/core@7.54.0": - version "7.54.0" - resolved "https://registry.npmjs.org/@sentry/core/-/core-7.54.0.tgz" - integrity sha512-MAn0E2EwgNn1pFQn4qxhU+1kz6edullWg6VE5wCmtpXWOVw6sILBUsQpeIG5djBKMcneJCdOlz5jeqcKPrLvZQ== - dependencies: - "@sentry/types" "7.54.0" - "@sentry/utils" "7.54.0" - tslib "^1.9.3" - -"@sentry/react@^7.54.0": - version "7.54.0" - resolved "https://registry.npmjs.org/@sentry/react/-/react-7.54.0.tgz" - integrity sha512-qUbwmRRpTh05m2rbC8A2zAFQYsoHhwIpxT5UXxh0P64ZlA3cSg1/DmTTgwnd1l+7gzKrc31UikXQ4y0YDbMNKg== - dependencies: - "@sentry/browser" "7.54.0" - "@sentry/types" "7.54.0" - "@sentry/utils" "7.54.0" - hoist-non-react-statics "^3.3.2" - tslib "^1.9.3" - -"@sentry/replay@7.54.0": - version "7.54.0" - resolved "https://registry.npmjs.org/@sentry/replay/-/replay-7.54.0.tgz" - integrity sha512-C0F0568ybphzGmKGe23duB6n5wJcgM7WLYhoeqW3o2bHeqpj1dGPSka/K3s9KzGaAgzn1zeOUYXJsOs+T/XdsA== - dependencies: - "@sentry/core" "7.54.0" - "@sentry/types" "7.54.0" - "@sentry/utils" "7.54.0" - -"@sentry/types@7.54.0": - version "7.54.0" - resolved "https://registry.npmjs.org/@sentry/types/-/types-7.54.0.tgz" - integrity sha512-D+i9xogBeawvQi2r0NOrM7zYcUaPuijeME4O9eOTrDF20tj71hWtJLilK+KTGLYFtpGg1h+9bPaz7OHEIyVopg== - -"@sentry/utils@7.54.0", "@sentry/utils@^7.54.0": - version "7.54.0" - resolved "https://registry.npmjs.org/@sentry/utils/-/utils-7.54.0.tgz" - integrity sha512-3Yf5KlKjIcYLddOexSt2ovu2TWlR4Fi7M+aCK8yUTzwNzf/xwFSWOstHlD/WiDy9HvfhWAOB/ukNTuAeJmtasw== - dependencies: - "@sentry/types" "7.54.0" - tslib "^1.9.3" - -"@sinclair/typebox@^0.27.8": - version "0.27.8" - resolved "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" - integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== - -"@sindresorhus/is@^4.0.0": - version "4.6.0" - resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f" - integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw== - -"@sinonjs/commons@^3.0.0": - version "3.0.1" - resolved "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz#1029357e44ca901a615585f6d27738dbc89084cd" - integrity sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ== - dependencies: - type-detect "4.0.8" - -"@sinonjs/fake-timers@^10.0.2": - version "10.3.0" - resolved "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz#55fdff1ecab9f354019129daf4df0dd4d923ea66" - integrity sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA== - dependencies: - "@sinonjs/commons" "^3.0.0" - -"@storybook/addon-actions@8.3.5": - version "8.3.5" - resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-8.3.5.tgz#03fdb891114439ed47cb7df6ef21826530449db7" - integrity sha512-t8D5oo+4XfD+F8091wLa2y/CDd/W2lExCeol5Vm1tp5saO+u6f2/d7iykLhTowWV84Uohi3D073uFeyTAlGebg== - dependencies: - "@storybook/global" "^5.0.0" - "@types/uuid" "^9.0.1" - dequal "^2.0.2" - polished "^4.2.2" - uuid "^9.0.0" - -"@storybook/addon-backgrounds@8.3.5": - version "8.3.5" - resolved "https://registry.yarnpkg.com/@storybook/addon-backgrounds/-/addon-backgrounds-8.3.5.tgz#479ecb6181441e7f8429569bd7cefdb74058c12f" - integrity sha512-IQGjDujuw8+iSqKREdkL8I5E/5CAHZbfOWd4A75PQK2D6qZ0fu/xRwTOQOH4jP6xn/abvfACOdL6A0d5bU90ag== - dependencies: - "@storybook/global" "^5.0.0" - memoizerific "^1.11.3" - ts-dedent "^2.0.0" - -"@storybook/addon-controls@8.3.5": - version "8.3.5" - resolved "https://registry.yarnpkg.com/@storybook/addon-controls/-/addon-controls-8.3.5.tgz#d9b7aec16e2673a473ab018b3b453cd114628181" - integrity sha512-2eCVobUUvY1Rq7sp1U8Mx8t44VXwvi0E+hqyrsqOx5TTSC/FUQ+hNAX6GSYUcFIyQQ1ORpKNlUjAAdjxBv1ZHQ== - dependencies: - "@storybook/global" "^5.0.0" - dequal "^2.0.2" - lodash "^4.17.21" - ts-dedent "^2.0.0" - -"@storybook/addon-docs@8.3.5": - version "8.3.5" - resolved "https://registry.yarnpkg.com/@storybook/addon-docs/-/addon-docs-8.3.5.tgz#df9e3310b7a63355184f5a2a7f2e2aa396588765" - integrity sha512-MOVfo1bY8kXTzbvmWnx3UuSO4WNykFz7Edvb3mxltNyuW7UDRZGuIuSe32ddT/EtLJfurrC9Ja3yBy4KBUGnMA== - dependencies: - "@mdx-js/react" "^3.0.0" - "@storybook/blocks" "8.3.5" - "@storybook/csf-plugin" "8.3.5" - "@storybook/global" "^5.0.0" - "@storybook/react-dom-shim" "8.3.5" - "@types/react" "^16.8.0 || ^17.0.0 || ^18.0.0" - fs-extra "^11.1.0" - react "^16.8.0 || ^17.0.0 || ^18.0.0" - react-dom "^16.8.0 || ^17.0.0 || ^18.0.0" - rehype-external-links "^3.0.0" - rehype-slug "^6.0.0" - ts-dedent "^2.0.0" - -"@storybook/addon-essentials@^8.3.5": - version "8.3.5" - resolved "https://registry.yarnpkg.com/@storybook/addon-essentials/-/addon-essentials-8.3.5.tgz#59599a75e3f72d1048d715f3ec35a4c07149b2f8" - integrity sha512-hXTtPuN4/IsXjUrkMPAuz1qKAl8DovdXpjQgjQs7jSAVx3kc4BZaGqJ3gaVenKtO8uDchmA92BoQygpkc8eWhw== - dependencies: - "@storybook/addon-actions" "8.3.5" - "@storybook/addon-backgrounds" "8.3.5" - "@storybook/addon-controls" "8.3.5" - "@storybook/addon-docs" "8.3.5" - "@storybook/addon-highlight" "8.3.5" - "@storybook/addon-measure" "8.3.5" - "@storybook/addon-outline" "8.3.5" - "@storybook/addon-toolbars" "8.3.5" - "@storybook/addon-viewport" "8.3.5" - ts-dedent "^2.0.0" - -"@storybook/addon-highlight@8.3.5": - version "8.3.5" - resolved "https://registry.yarnpkg.com/@storybook/addon-highlight/-/addon-highlight-8.3.5.tgz#62293e7b39844ded33bb4ba7ee79c3c96d997fe2" - integrity sha512-ku0epul9aReCR3Gv/emwYnsqg3vgux5OmYMjoDcJC7s+LyfweSzLV/f5t9gSHazikJElh5TehtVkWbC4QfbGSw== - dependencies: - "@storybook/global" "^5.0.0" - -"@storybook/addon-interactions@^8.3.5": - version "8.3.5" - resolved "https://registry.yarnpkg.com/@storybook/addon-interactions/-/addon-interactions-8.3.5.tgz#c971925937aeb6d66bf108dc27a90a4a9cbbf8f4" - integrity sha512-GtTy/A+mG7vDOahQr2avT4dpWtCRiFDSYcWyuQOZm10y8VDDw157HQM+FuhxjV9Owrrohy9F24oBUwRG8H3b5A== - dependencies: - "@storybook/global" "^5.0.0" - "@storybook/instrumenter" "8.3.5" - "@storybook/test" "8.3.5" - polished "^4.2.2" - ts-dedent "^2.2.0" - -"@storybook/addon-links@^8.3.5": - version "8.3.5" - resolved "https://registry.yarnpkg.com/@storybook/addon-links/-/addon-links-8.3.5.tgz#1621afd8be06af6de5e942644053d5136cc5bb83" - integrity sha512-giRCpn6cfJMYPnVJkojoQDO5ae6098fgY9YgAhwaJej/9dufNcioFdbiyfK1vyzbG6TGeTmJ9ncWCXgWRtzxPQ== - dependencies: - "@storybook/csf" "^0.1.11" - "@storybook/global" "^5.0.0" - ts-dedent "^2.0.0" - -"@storybook/addon-measure@8.3.5": - version "8.3.5" - resolved "https://registry.yarnpkg.com/@storybook/addon-measure/-/addon-measure-8.3.5.tgz#4eef622137f9ee615eb179e5e2af050ea0f7ab8b" - integrity sha512-6GVehgbHhFIFS69xSfRV+12VK0cnuIAtZdp1J3eUCc2ATrcigqVjTM6wzZz6kBuX6O3dcusr7Wg46KtNliqLqg== - dependencies: - "@storybook/global" "^5.0.0" - tiny-invariant "^1.3.1" - -"@storybook/addon-onboarding@^8.3.5": - version "8.3.5" - resolved "https://registry.yarnpkg.com/@storybook/addon-onboarding/-/addon-onboarding-8.3.5.tgz#dc1c4098b2df602d8b0cd7b66c3daf4b0d92edb4" - integrity sha512-QE/+6KEYO5tGziMdo+81oor0KNVnbPsfDpnhtClu+t1XC2F2nKQpDISujwLSYm9voEk1D/NxYWMbQ6eTDR/ViA== - dependencies: - react-confetti "^6.1.0" - -"@storybook/addon-outline@8.3.5": - version "8.3.5" - resolved "https://registry.yarnpkg.com/@storybook/addon-outline/-/addon-outline-8.3.5.tgz#274a497b9a6b391bf3c47aa61e19ddc28cbae395" - integrity sha512-dwmK6GzjEnQP9Yo0VnBUQtJkXZlXdfjWyskZ/IlUVc+IFdeeCtIiMyA92oMfHo8eXt0k1g21ZqMaIn7ZltOuHw== - dependencies: - "@storybook/global" "^5.0.0" - ts-dedent "^2.0.0" - -"@storybook/addon-themes@^8.3.5": - version "8.3.5" - resolved "https://registry.yarnpkg.com/@storybook/addon-themes/-/addon-themes-8.3.5.tgz#fef6a783612a091675e96fc37c93b24ba406f4f3" - integrity sha512-kXHKAZvAtMoOR1XFGTo5/T8anE9x7W8Ddpof2wyi+du5HscFiEW7TesWdvNgBUR7wAaiR21aW2S4jC72a6gTCw== - dependencies: - ts-dedent "^2.0.0" - -"@storybook/addon-toolbars@8.3.5": - version "8.3.5" - resolved "https://registry.yarnpkg.com/@storybook/addon-toolbars/-/addon-toolbars-8.3.5.tgz#7328fed0f4a24c6828ba23e06b9cddd0d3e00e2b" - integrity sha512-Ml2gc9q8WbteDvmuAZGgBxt5SqWMXzuTkMjlsA8EB53hlkN1w9esX4s8YtBeNqC3HKoUzcdq8uexSBqU8fDbSA== - -"@storybook/addon-viewport@8.3.5": - version "8.3.5" - resolved "https://registry.yarnpkg.com/@storybook/addon-viewport/-/addon-viewport-8.3.5.tgz#10f10871eba32cf6c484db199241122184a4324b" - integrity sha512-FSWydoPiVWFXEittG7O1YgvuaqoU9Vb+qoq9XfP/hvQHHMDcMZvC40JaV8AnJeTXaM7ngIjcn9XDEfGbFfOzXw== - dependencies: - memoizerific "^1.11.3" - -"@storybook/blocks@8.3.5", "@storybook/blocks@^8.3.5": - version "8.3.5" - resolved "https://registry.yarnpkg.com/@storybook/blocks/-/blocks-8.3.5.tgz#35e20efb0c13a235832dd945520ff8ac61f40717" - integrity sha512-8cHTdTywolTHlgwN8I7YH7saWAIjGzV617AwjhJ95AKlC0VtpO1gAFcAgCqr4DU9eMc+LZuvbnaU/RSvA5eCCQ== - dependencies: - "@storybook/csf" "^0.1.11" - "@storybook/global" "^5.0.0" - "@storybook/icons" "^1.2.10" - "@types/lodash" "^4.14.167" - color-convert "^2.0.1" - dequal "^2.0.2" - lodash "^4.17.21" - markdown-to-jsx "^7.4.5" - memoizerific "^1.11.3" - polished "^4.2.2" - react-colorful "^5.1.2" - telejson "^7.2.0" - ts-dedent "^2.0.0" - util-deprecate "^1.0.2" - -"@storybook/builder-webpack5@8.3.5": - version "8.3.5" - resolved "https://registry.yarnpkg.com/@storybook/builder-webpack5/-/builder-webpack5-8.3.5.tgz#86eba6b8f3546aa1a4b264bb0253e8444b69c6f8" - integrity sha512-rhmfdiSlDn3Arki7IMYk11PO29rYuYM4LZ8GlNqREU7VUl/8Vngo/jFIa4pKaIns3ql1RrwzO1wm9JvuL/4ydA== - dependencies: - "@storybook/core-webpack" "8.3.5" - "@types/node" "^22.0.0" - "@types/semver" "^7.3.4" - browser-assert "^1.2.1" - case-sensitive-paths-webpack-plugin "^2.4.0" - cjs-module-lexer "^1.2.3" - constants-browserify "^1.0.0" - css-loader "^6.7.1" - es-module-lexer "^1.5.0" - express "^4.19.2" - fork-ts-checker-webpack-plugin "^8.0.0" - fs-extra "^11.1.0" - html-webpack-plugin "^5.5.0" - magic-string "^0.30.5" - path-browserify "^1.0.1" - process "^0.11.10" - semver "^7.3.7" - style-loader "^3.3.1" - terser-webpack-plugin "^5.3.1" - ts-dedent "^2.0.0" - url "^0.11.0" - util "^0.12.4" - util-deprecate "^1.0.2" - webpack "5" - webpack-dev-middleware "^6.1.2" - webpack-hot-middleware "^2.25.1" - webpack-virtual-modules "^0.6.0" - -"@storybook/components@^8.3.5": - version "8.3.5" - resolved "https://registry.yarnpkg.com/@storybook/components/-/components-8.3.5.tgz#6a8e7f95f1b1f45df7ffcbdeeb3eef3c6cce0d3f" - integrity sha512-Rq28YogakD3FO4F8KwAtGpo1g3t4V/gfCLqTQ8B6oQUFoxLqegkWk/DlwCzvoJndXuQJfdSyM6+r1JcA4Nql5A== - -"@storybook/core-webpack@8.3.5": - version "8.3.5" - resolved "https://registry.yarnpkg.com/@storybook/core-webpack/-/core-webpack-8.3.5.tgz#3e058fdb4bd73ca5deee5b3ce5621f599dfa248d" - integrity sha512-mN8BHNc6lSGUf/nKgDr6XoTt1cX+Tap9RnKMUiROCDzfVlJPeJBrG4qrTOok7AwObzeDl9DNFyun6+pVgXJe7A== - dependencies: - "@types/node" "^22.0.0" - ts-dedent "^2.0.0" - -"@storybook/core@8.3.5": - version "8.3.5" - resolved "https://registry.yarnpkg.com/@storybook/core/-/core-8.3.5.tgz#d77c93bb67c2df12e3bf84ae7def4693891b225d" - integrity sha512-GOGfTvdioNa/n+Huwg4u/dsyYyBcM+gEcdxi3B7i5x4yJ3I912KoVshumQAOF2myKSRdI8h8aGWdx7nnjd0+5Q== - dependencies: - "@storybook/csf" "^0.1.11" - "@types/express" "^4.17.21" - better-opn "^3.0.2" - browser-assert "^1.2.1" - esbuild "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0" - esbuild-register "^3.5.0" - express "^4.19.2" - jsdoc-type-pratt-parser "^4.0.0" - process "^0.11.10" - recast "^0.23.5" - semver "^7.6.2" - util "^0.12.5" - ws "^8.2.3" - -"@storybook/csf-plugin@8.3.5": - version "8.3.5" - resolved "https://registry.yarnpkg.com/@storybook/csf-plugin/-/csf-plugin-8.3.5.tgz#198946c438be8915b63abde04a19f26610a6d88a" - integrity sha512-ODVqNXwJt90hG7QW8I9w/XUyOGlr0l7XltmIJgXwB/2cYDvaGu3JV5Ybg7O0fxPV8uXk7JlRuUD8ZYv5Low6pA== - dependencies: - unplugin "^1.3.1" - -"@storybook/csf@^0.0.1": - version "0.0.1" - resolved "https://registry.yarnpkg.com/@storybook/csf/-/csf-0.0.1.tgz#95901507dc02f0bc6f9ac8ee1983e2fc5bb98ce6" - integrity sha512-USTLkZze5gkel8MYCujSRBVIrUQ3YPBrLOx7GNk/0wttvVtlzWXAq9eLbQ4p/NicGxP+3T7KPEMVV//g+yubpw== - dependencies: - lodash "^4.17.15" - -"@storybook/csf@^0.1.11": - version "0.1.11" - resolved "https://registry.yarnpkg.com/@storybook/csf/-/csf-0.1.11.tgz#ad685a4fe564a47a6b73571c2e7c07b526f4f71b" - integrity sha512-dHYFQH3mA+EtnCkHXzicbLgsvzYjcDJ1JWsogbItZogkPHgSJM/Wr71uMkcvw8v9mmCyP4NpXJuu6bPoVsOnzg== - dependencies: - type-fest "^2.19.0" - -"@storybook/global@^5.0.0": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@storybook/global/-/global-5.0.0.tgz#b793d34b94f572c1d7d9e0f44fac4e0dbc9572ed" - integrity sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ== - -"@storybook/icons@^1.2.10": - version "1.2.12" - resolved "https://registry.yarnpkg.com/@storybook/icons/-/icons-1.2.12.tgz#3e4c939113b67df7ab17b78f805dbb57f4acf0db" - integrity sha512-UxgyK5W3/UV4VrI3dl6ajGfHM4aOqMAkFLWe2KibeQudLf6NJpDrDMSHwZj+3iKC4jFU7dkKbbtH2h/al4sW3Q== - -"@storybook/instrumenter@8.3.5": - version "8.3.5" - resolved "https://registry.yarnpkg.com/@storybook/instrumenter/-/instrumenter-8.3.5.tgz#ba3c6adcd928ef98859ac4ed1e5addb1164659ea" - integrity sha512-NLDXai5y2t1ITgHVK9chyL0rMFZbICCOGcnTbyWhkLbiEWZKPJ8FuB8+g+Ba6zwtCve1A1Cnb4O2LOWy7TgWQw== - dependencies: - "@storybook/global" "^5.0.0" - "@vitest/utils" "^2.0.5" - util "^0.12.4" - -"@storybook/manager-api@^8.3.5": - version "8.3.5" - resolved "https://registry.yarnpkg.com/@storybook/manager-api/-/manager-api-8.3.5.tgz#73560ffc3774901e503e31aefac91cd4a1579bbb" - integrity sha512-fEQoKKi7h7pzh2z9RfuzatJxubrsfL/CB99fNXQ0wshMSY/7O4ckd18pK4fzG9ErnCtLAO9qsim4N/4eQC+/8Q== - -"@storybook/nextjs@^8.3.5": - version "8.3.5" - resolved "https://registry.yarnpkg.com/@storybook/nextjs/-/nextjs-8.3.5.tgz#0861d87e5abcb41eddef8b8e7b4e7634bab059ce" - integrity sha512-YMjDSVd7BHIvj6oLMEFMKRvfZ83INxZinxtrx4ZZXGe+5iP8j7rcV7D67lxKQKWNy36d9Foj4pjT85yYj5s+ZQ== - dependencies: - "@babel/core" "^7.24.4" - "@babel/plugin-syntax-bigint" "^7.8.3" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" - "@babel/plugin-syntax-import-assertions" "^7.24.1" - "@babel/plugin-transform-class-properties" "^7.24.1" - "@babel/plugin-transform-export-namespace-from" "^7.24.1" - "@babel/plugin-transform-numeric-separator" "^7.24.1" - "@babel/plugin-transform-object-rest-spread" "^7.24.1" - "@babel/plugin-transform-runtime" "^7.24.3" - "@babel/preset-env" "^7.24.4" - "@babel/preset-react" "^7.24.1" - "@babel/preset-typescript" "^7.24.1" - "@babel/runtime" "^7.24.4" - "@pmmmwh/react-refresh-webpack-plugin" "^0.5.11" - "@storybook/builder-webpack5" "8.3.5" - "@storybook/preset-react-webpack" "8.3.5" - "@storybook/react" "8.3.5" - "@storybook/test" "8.3.5" - "@types/node" "^22.0.0" - "@types/semver" "^7.3.4" - babel-loader "^9.1.3" - css-loader "^6.7.3" - find-up "^5.0.0" - fs-extra "^11.1.0" - image-size "^1.0.0" - loader-utils "^3.2.1" - node-polyfill-webpack-plugin "^2.0.1" - pnp-webpack-plugin "^1.7.0" - postcss "^8.4.38" - postcss-loader "^8.1.1" - react-refresh "^0.14.0" - resolve-url-loader "^5.0.0" - sass-loader "^13.2.0" - semver "^7.3.5" - style-loader "^3.3.1" - styled-jsx "^5.1.6" - ts-dedent "^2.0.0" - tsconfig-paths "^4.0.0" - tsconfig-paths-webpack-plugin "^4.0.1" - optionalDependencies: - sharp "^0.33.3" - -"@storybook/preset-react-webpack@8.3.5": - version "8.3.5" - resolved "https://registry.yarnpkg.com/@storybook/preset-react-webpack/-/preset-react-webpack-8.3.5.tgz#5886d265027e7854cb4d15d8ca728990894ac4f8" - integrity sha512-laS9CiZrZ4CSnBTBfkBba3hmlDhzcjIfCvx8/rk3SZ+zh93NpqXixzRt6m0UH2po63dpdu21nXrsW5Cfs88Ypw== - dependencies: - "@storybook/core-webpack" "8.3.5" - "@storybook/react" "8.3.5" - "@storybook/react-docgen-typescript-plugin" "1.0.6--canary.9.0c3f3b7.0" - "@types/node" "^22.0.0" - "@types/semver" "^7.3.4" - find-up "^5.0.0" - fs-extra "^11.1.0" - magic-string "^0.30.5" - react-docgen "^7.0.0" - resolve "^1.22.8" - semver "^7.3.7" - tsconfig-paths "^4.2.0" - webpack "5" - -"@storybook/preview-api@^8.3.5": - version "8.3.5" - resolved "https://registry.yarnpkg.com/@storybook/preview-api/-/preview-api-8.3.5.tgz#d30debc89793a912cdd26aea1e18b92527f2cf76" - integrity sha512-VPqpudE8pmjTLvdNJoW/2//nqElDgUOmIn3QxbbCmdZTHDg5tFtxuqwdlNfArF0TxvTSBDIulXt/Q6K56TAfTg== - -"@storybook/react-docgen-typescript-plugin@1.0.6--canary.9.0c3f3b7.0": - version "1.0.6--canary.9.0c3f3b7.0" - resolved "https://registry.yarnpkg.com/@storybook/react-docgen-typescript-plugin/-/react-docgen-typescript-plugin-1.0.6--canary.9.0c3f3b7.0.tgz#7f10f3c641f32e4513a8b6ffb5036933e7059534" - integrity sha512-KUqXC3oa9JuQ0kZJLBhVdS4lOneKTOopnNBK4tUAgoxWQ3u/IjzdueZjFr7gyBrXMoU6duutk3RQR9u8ZpYJ4Q== - dependencies: - debug "^4.1.1" - endent "^2.0.1" - find-cache-dir "^3.3.1" - flat-cache "^3.0.4" - micromatch "^4.0.2" - react-docgen-typescript "^2.2.2" - tslib "^2.0.0" - -"@storybook/react-dom-shim@8.3.5": - version "8.3.5" - resolved "https://registry.yarnpkg.com/@storybook/react-dom-shim/-/react-dom-shim-8.3.5.tgz#dda5356d3bf55623b9b1429fac7bf185e59c58fd" - integrity sha512-Hf0UitJ/K0C7ajooooUK/PxOR4ihUWqsC7iCV1Gqth8U37dTeLMbaEO4PBwu0VQ+Ufg0N8BJLWfg7o6G4hrODw== - -"@storybook/react@8.3.5", "@storybook/react@^8.3.5": - version "8.3.5" - resolved "https://registry.yarnpkg.com/@storybook/react/-/react-8.3.5.tgz#d4e333b09f275f06b38fb1367234ad1619fbe4fa" - integrity sha512-kuBPe/wBin10SWr4EWPKxiTRGQ4RD2etGEVWVQLqVpOuJp/J2hVvXQHtCfZXU4TZT5x4PBbPRswbr58+XlF+kQ== - dependencies: - "@storybook/components" "^8.3.5" - "@storybook/global" "^5.0.0" - "@storybook/manager-api" "^8.3.5" - "@storybook/preview-api" "^8.3.5" - "@storybook/react-dom-shim" "8.3.5" - "@storybook/theming" "^8.3.5" - "@types/escodegen" "^0.0.6" - "@types/estree" "^0.0.51" - "@types/node" "^22.0.0" - acorn "^7.4.1" - acorn-jsx "^5.3.1" - acorn-walk "^7.2.0" - escodegen "^2.1.0" - html-tags "^3.1.0" - prop-types "^15.7.2" - react-element-to-jsx-string "^15.0.0" - semver "^7.3.7" - ts-dedent "^2.0.0" - type-fest "~2.19" - util-deprecate "^1.0.2" - -"@storybook/test@8.3.5", "@storybook/test@^8.3.5": - version "8.3.5" - resolved "https://registry.yarnpkg.com/@storybook/test/-/test-8.3.5.tgz#0dffc9d4a1eaa9552e69457b16b5085e36883c8a" - integrity sha512-1BXWsUGWk9FiKKelZZ55FDJdeoL8uRBHbjTYBRM2xJLhdNSvGzI4Tb3bkmxPpGn72Ua6AyldhlTxr2BpUFKOHA== - dependencies: - "@storybook/csf" "^0.1.11" - "@storybook/global" "^5.0.0" - "@storybook/instrumenter" "8.3.5" - "@testing-library/dom" "10.4.0" - "@testing-library/jest-dom" "6.5.0" - "@testing-library/user-event" "14.5.2" - "@vitest/expect" "2.0.5" - "@vitest/spy" "2.0.5" - util "^0.12.4" - -"@storybook/theming@^8.3.5": - version "8.3.5" - resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-8.3.5.tgz#c6b807193099a8f9d1afb5d71a59037c0ef54e85" - integrity sha512-9HmDDyC691oqfg4RziIM9ElsS2HITaxmH7n/yeUPtuirkPdAQzqOzhvH/Sa0qOhifzs8VjR+Gd/a/ZQ+S38r7w== - -"@svgdotjs/svg.js@^3.2.4": - version "3.2.4" - resolved "https://registry.yarnpkg.com/@svgdotjs/svg.js/-/svg.js-3.2.4.tgz#4716be92a64c66b29921b63f7235fcfb953fb13a" - integrity sha512-BjJ/7vWNowlX3Z8O4ywT58DqbNRyYlkk6Yz/D13aB7hGmfQTvGX4Tkgtm/ApYlu9M7lCQi15xUEidqMUmdMYwg== - -"@swc/counter@^0.1.3": - version "0.1.3" - resolved "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz" - integrity sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ== - -"@swc/helpers@0.5.5": - version "0.5.5" - resolved "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz" - integrity sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A== - dependencies: - "@swc/counter" "^0.1.3" - tslib "^2.4.0" - -"@szmarczak/http-timer@^4.0.5": - version "4.0.6" - resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.6.tgz#b4a914bb62e7c272d4e5989fe4440f812ab1d807" - integrity sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w== - dependencies: - defer-to-connect "^2.0.0" - -"@tailwindcss/line-clamp@^0.4.4": - version "0.4.4" - resolved "https://registry.npmjs.org/@tailwindcss/line-clamp/-/line-clamp-0.4.4.tgz" - integrity sha512-5U6SY5z8N42VtrCrKlsTAA35gy2VSyYtHWCsg1H87NU1SXnEfekTVlrga9fzUDrrHcGi2Lb5KenUWb4lRQT5/g== - -"@tailwindcss/typography@^0.5.9": - version "0.5.9" - resolved "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.9.tgz" - integrity sha512-t8Sg3DyynFysV9f4JDOVISGsjazNb48AeIYQwcL+Bsq5uf4RYL75C1giZ43KISjeDGBaTN3Kxh7Xj/vRSMJUUg== - dependencies: - lodash.castarray "^4.4.0" - lodash.isplainobject "^4.0.6" - lodash.merge "^4.6.2" - postcss-selector-parser "6.0.10" - -"@testing-library/dom@10.4.0": - version "10.4.0" - resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-10.4.0.tgz#82a9d9462f11d240ecadbf406607c6ceeeff43a8" - integrity sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/runtime" "^7.12.5" - "@types/aria-query" "^5.0.1" - aria-query "5.3.0" - chalk "^4.1.0" - dom-accessibility-api "^0.5.9" - lz-string "^1.5.0" - pretty-format "^27.0.2" - -"@testing-library/dom@^10.3.2": - version "10.3.2" - resolved "https://registry.npmjs.org/@testing-library/dom/-/dom-10.3.2.tgz#0285f643510d5ff4a0b12e4efa7f734a78d80aa3" - integrity sha512-0bxIdP9mmPiOJ6wHLj8bdJRq+51oddObeCGdEf6PNEhYd93ZYAN+lPRnEOVFtheVwDM7+p+tza3LAQgp0PTudg== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/runtime" "^7.12.5" - "@types/aria-query" "^5.0.1" - aria-query "5.3.0" - chalk "^4.1.0" - dom-accessibility-api "^0.5.9" - lz-string "^1.5.0" - pretty-format "^27.0.2" - -"@testing-library/jest-dom@6.5.0": - version "6.5.0" - resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-6.5.0.tgz#50484da3f80fb222a853479f618a9ce5c47bfe54" - integrity sha512-xGGHpBXYSHUUr6XsKBfs85TWlYKpTc37cSBBVrXcib2MkHLboWlkClhWF37JKlDb9KEq3dHs+f2xR7XJEWGBxA== - dependencies: - "@adobe/css-tools" "^4.4.0" - aria-query "^5.0.0" - chalk "^3.0.0" - css.escape "^1.5.1" - dom-accessibility-api "^0.6.3" - lodash "^4.17.21" - redent "^3.0.0" - -"@testing-library/jest-dom@^6.4.6": - version "6.4.6" - resolved "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.4.6.tgz#ec1df8108651bed5475534955565bed88c6732ce" - integrity sha512-8qpnGVincVDLEcQXWaHOf6zmlbwTKc6Us6PPu4CRnPXCzo2OGBS5cwgMMOWdxDpEz1mkbvXHpEy99M5Yvt682w== - dependencies: - "@adobe/css-tools" "^4.4.0" - "@babel/runtime" "^7.9.2" - aria-query "^5.0.0" - chalk "^3.0.0" - css.escape "^1.5.1" - dom-accessibility-api "^0.6.3" - lodash "^4.17.21" - redent "^3.0.0" - -"@testing-library/react@^16.0.0": - version "16.0.0" - resolved "https://registry.npmjs.org/@testing-library/react/-/react-16.0.0.tgz#0a1e0c7a3de25841c3591b8cb7fb0cf0c0a27321" - integrity sha512-guuxUKRWQ+FgNX0h0NS0FIq3Q3uLtWVpBzcLOggmfMoUpgBnzBzvLLd4fbm6yS8ydJd94cIfY4yP9qUQjM2KwQ== - dependencies: - "@babel/runtime" "^7.12.5" - -"@testing-library/user-event@14.5.2": - version "14.5.2" - resolved "https://registry.yarnpkg.com/@testing-library/user-event/-/user-event-14.5.2.tgz#db7257d727c891905947bd1c1a99da20e03c2ebd" - integrity sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ== - -"@tootallnate/once@2": - version "2.0.0" - resolved "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" - integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== - -"@tsconfig/node10@^1.0.7": - version "1.0.11" - resolved "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz#6ee46400685f130e278128c7b38b7e031ff5b2f2" - integrity sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw== - -"@tsconfig/node12@^1.0.7": - version "1.0.11" - resolved "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" - integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== - -"@tsconfig/node14@^1.0.0": - version "1.0.3" - resolved "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" - integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== - -"@tsconfig/node16@^1.0.2": - version "1.0.4" - resolved "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" - integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== - -"@types/acorn@^4.0.0": - version "4.0.6" - resolved "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz" - integrity sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ== - dependencies: - "@types/estree" "*" - -"@types/aria-query@^5.0.1": - version "5.0.4" - resolved "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz#1a31c3d378850d2778dabb6374d036dcba4ba708" - integrity sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw== - -"@types/babel__core@^7.1.14", "@types/babel__core@^7.18.0": - version "7.20.5" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017" - integrity sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA== - dependencies: - "@babel/parser" "^7.20.7" - "@babel/types" "^7.20.7" - "@types/babel__generator" "*" - "@types/babel__template" "*" - "@types/babel__traverse" "*" - -"@types/babel__generator@*": - version "7.6.8" - resolved "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz#f836c61f48b1346e7d2b0d93c6dacc5b9535d3ab" - integrity sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw== - dependencies: - "@babel/types" "^7.0.0" - -"@types/babel__template@*": - version "7.4.4" - resolved "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz#5672513701c1b2199bc6dad636a9d7491586766f" - integrity sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A== - dependencies: - "@babel/parser" "^7.1.0" - "@babel/types" "^7.0.0" - -"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6", "@types/babel__traverse@^7.18.0": - version "7.20.6" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.6.tgz#8dc9f0ae0f202c08d8d4dab648912c8d6038e3f7" - integrity sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg== - dependencies: - "@babel/types" "^7.20.7" - -"@types/body-parser@*": - version "1.19.5" - resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.5.tgz#04ce9a3b677dc8bd681a17da1ab9835dc9d3ede4" - integrity sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg== - dependencies: - "@types/connect" "*" - "@types/node" "*" - -"@types/cacheable-request@^6.0.1": - version "6.0.3" - resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.3.tgz#a430b3260466ca7b5ca5bfd735693b36e7a9d183" - integrity sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw== - dependencies: - "@types/http-cache-semantics" "*" - "@types/keyv" "^3.1.4" - "@types/node" "*" - "@types/responselike" "^1.0.0" - -"@types/connect@*": - version "3.4.38" - resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.38.tgz#5ba7f3bc4fbbdeaff8dded952e5ff2cc53f8d858" - integrity sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug== - dependencies: - "@types/node" "*" - -"@types/crypto-js@^4.1.1": - version "4.1.1" - resolved "https://registry.npmjs.org/@types/crypto-js/-/crypto-js-4.1.1.tgz" - integrity sha512-BG7fQKZ689HIoc5h+6D2Dgq1fABRa0RbBWKBd9SP/MVRVXROflpm5fhwyATX5duFmbStzyzyycPB8qUYKDH3NA== - -"@types/d3-array@*": - version "3.2.1" - resolved "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz" - integrity sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg== - -"@types/d3-axis@*": - version "3.0.6" - resolved "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.6.tgz" - integrity sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw== - dependencies: - "@types/d3-selection" "*" - -"@types/d3-brush@*": - version "3.0.6" - resolved "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.6.tgz" - integrity sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A== - dependencies: - "@types/d3-selection" "*" - -"@types/d3-chord@*": - version "3.0.6" - resolved "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.6.tgz" - integrity sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg== - -"@types/d3-color@*": - version "3.1.3" - resolved "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz" - integrity sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A== - -"@types/d3-contour@*": - version "3.0.6" - resolved "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.6.tgz" - integrity sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg== - dependencies: - "@types/d3-array" "*" - "@types/geojson" "*" - -"@types/d3-delaunay@*": - version "6.0.4" - resolved "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz" - integrity sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw== - -"@types/d3-dispatch@*": - version "3.0.6" - resolved "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.6.tgz" - integrity sha512-4fvZhzMeeuBJYZXRXrRIQnvUYfyXwYmLsdiN7XXmVNQKKw1cM8a5WdID0g1hVFZDqT9ZqZEY5pD44p24VS7iZQ== - -"@types/d3-drag@*", "@types/d3-drag@^3.0.1": - version "3.0.7" - resolved "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz" - integrity sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ== - dependencies: - "@types/d3-selection" "*" - -"@types/d3-dsv@*": - version "3.0.7" - resolved "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.7.tgz" - integrity sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g== - -"@types/d3-ease@*": - version "3.0.2" - resolved "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz" - integrity sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA== - -"@types/d3-fetch@*": - version "3.0.7" - resolved "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.7.tgz" - integrity sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA== - dependencies: - "@types/d3-dsv" "*" - -"@types/d3-force@*": - version "3.0.9" - resolved "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.9.tgz" - integrity sha512-IKtvyFdb4Q0LWna6ymywQsEYjK/94SGhPrMfEr1TIc5OBeziTi+1jcCvttts8e0UWZIxpasjnQk9MNk/3iS+kA== - -"@types/d3-format@*": - version "3.0.4" - resolved "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz" - integrity sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g== - -"@types/d3-geo@*": - version "3.1.0" - resolved "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.1.0.tgz" - integrity sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ== - dependencies: - "@types/geojson" "*" - -"@types/d3-hierarchy@*": - version "3.1.7" - resolved "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz" - integrity sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg== - -"@types/d3-interpolate@*": - version "3.0.4" - resolved "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz" - integrity sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA== - dependencies: - "@types/d3-color" "*" - -"@types/d3-path@*": - version "3.1.0" - resolved "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.0.tgz" - integrity sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ== - -"@types/d3-polygon@*": - version "3.0.2" - resolved "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.2.tgz" - integrity sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA== - -"@types/d3-quadtree@*": - version "3.0.6" - resolved "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz" - integrity sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg== - -"@types/d3-random@*": - version "3.0.3" - resolved "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.3.tgz" - integrity sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ== - -"@types/d3-scale-chromatic@*", "@types/d3-scale-chromatic@^3.0.0": - version "3.0.0" - resolved "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz" - integrity sha512-dsoJGEIShosKVRBZB0Vo3C8nqSDqVGujJU6tPznsBJxNJNwMF8utmS83nvCBKQYPpjCzaaHcrf66iTRpZosLPw== - -"@types/d3-scale@*", "@types/d3-scale@^4.0.3": - version "4.0.4" - resolved "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.4.tgz" - integrity sha512-eq1ZeTj0yr72L8MQk6N6heP603ubnywSDRfNpi5enouR112HzGLS6RIvExCzZTraFF4HdzNpJMwA/zGiMoHUUw== - dependencies: - "@types/d3-time" "*" - -"@types/d3-selection@*", "@types/d3-selection@^3.0.3": - version "3.0.10" - resolved "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.10.tgz" - integrity sha512-cuHoUgS/V3hLdjJOLTT691+G2QoqAjCVLmr4kJXR4ha56w1Zdu8UUQ5TxLRqudgNjwXeQxKMq4j+lyf9sWuslg== - -"@types/d3-shape@*": - version "3.1.6" - resolved "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.6.tgz" - integrity sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA== - dependencies: - "@types/d3-path" "*" - -"@types/d3-time-format@*": - version "4.0.3" - resolved "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.3.tgz" - integrity sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg== - -"@types/d3-time@*": - version "3.0.0" - resolved "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.0.tgz" - integrity sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg== - -"@types/d3-timer@*": - version "3.0.2" - resolved "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz" - integrity sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw== - -"@types/d3-transition@*": - version "3.0.8" - resolved "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.8.tgz" - integrity sha512-ew63aJfQ/ms7QQ4X7pk5NxQ9fZH/z+i24ZfJ6tJSfqxJMrYLiK01EAs2/Rtw/JreGUsS3pLPNV644qXFGnoZNQ== - dependencies: - "@types/d3-selection" "*" - -"@types/d3-zoom@*", "@types/d3-zoom@^3.0.1": - version "3.0.8" - resolved "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz" - integrity sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw== - dependencies: - "@types/d3-interpolate" "*" - "@types/d3-selection" "*" - -"@types/d3@^7.4.0": - version "7.4.3" - resolved "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz" - integrity sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww== - dependencies: - "@types/d3-array" "*" - "@types/d3-axis" "*" - "@types/d3-brush" "*" - "@types/d3-chord" "*" - "@types/d3-color" "*" - "@types/d3-contour" "*" - "@types/d3-delaunay" "*" - "@types/d3-dispatch" "*" - "@types/d3-drag" "*" - "@types/d3-dsv" "*" - "@types/d3-ease" "*" - "@types/d3-fetch" "*" - "@types/d3-force" "*" - "@types/d3-format" "*" - "@types/d3-geo" "*" - "@types/d3-hierarchy" "*" - "@types/d3-interpolate" "*" - "@types/d3-path" "*" - "@types/d3-polygon" "*" - "@types/d3-quadtree" "*" - "@types/d3-random" "*" - "@types/d3-scale" "*" - "@types/d3-scale-chromatic" "*" - "@types/d3-selection" "*" - "@types/d3-shape" "*" - "@types/d3-time" "*" - "@types/d3-time-format" "*" - "@types/d3-timer" "*" - "@types/d3-transition" "*" - "@types/d3-zoom" "*" - -"@types/dagre@^0.7.52": - version "0.7.52" - resolved "https://registry.npmjs.org/@types/dagre/-/dagre-0.7.52.tgz" - integrity sha512-XKJdy+OClLk3hketHi9Qg6gTfe1F3y+UFnHxKA2rn9Dw+oXa4Gb378Ztz9HlMgZKSxpPmn4BNVh9wgkpvrK1uw== - -"@types/debug@^4.0.0": - version "4.1.8" - resolved "https://registry.npmjs.org/@types/debug/-/debug-4.1.8.tgz" - integrity sha512-/vPO1EPOs306Cvhwv7KfVfYvOJqA/S/AXjaHQiJboCZzcNDb+TIJFN9/2C9DZ//ijSKWioNyUxD792QmDJ+HKQ== - dependencies: - "@types/ms" "*" - -"@types/doctrine@^0.0.9": - version "0.0.9" - resolved "https://registry.yarnpkg.com/@types/doctrine/-/doctrine-0.0.9.tgz#d86a5f452a15e3e3113b99e39616a9baa0f9863f" - integrity sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA== - -"@types/escodegen@^0.0.6": - version "0.0.6" - resolved "https://registry.yarnpkg.com/@types/escodegen/-/escodegen-0.0.6.tgz#5230a9ce796e042cda6f086dbf19f22ea330659c" - integrity sha512-AjwI4MvWx3HAOaZqYsjKWyEObT9lcVV0Y0V8nXo6cXzN8ZiMxVhf6F3d/UNvXVGKrEzL/Dluc5p+y9GkzlTWig== - -"@types/estree-jsx@^1.0.0": - version "1.0.0" - resolved "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.0.tgz" - integrity sha512-3qvGd0z8F2ENTGr/GG1yViqfiKmRfrXVx5sJyHGFu3z7m5g5utCQtGp/g29JnjflhtQJBv1WDQukHiT58xPcYQ== - dependencies: - "@types/estree" "*" - -"@types/estree@*", "@types/estree@^1.0.0": - version "1.0.5" - resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz" - integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== - -"@types/estree@^0.0.51": - version "0.0.51" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" - integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== - -"@types/estree@^1.0.5": - version "1.0.6" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50" - integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw== - -"@types/express-serve-static-core@^4.17.33": - version "4.19.6" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz#e01324c2a024ff367d92c66f48553ced0ab50267" - integrity sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A== - dependencies: - "@types/node" "*" - "@types/qs" "*" - "@types/range-parser" "*" - "@types/send" "*" - -"@types/express@^4.17.21": - version "4.17.21" - resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.21.tgz#c26d4a151e60efe0084b23dc3369ebc631ed192d" - integrity sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ== - dependencies: - "@types/body-parser" "*" - "@types/express-serve-static-core" "^4.17.33" - "@types/qs" "*" - "@types/serve-static" "*" - -"@types/geojson@*": - version "7946.0.14" - resolved "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.14.tgz" - integrity sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg== - -"@types/graceful-fs@^4.1.3": - version "4.1.9" - resolved "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz#2a06bc0f68a20ab37b3e36aa238be6abdf49e8b4" - integrity sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ== - dependencies: - "@types/node" "*" - -"@types/hast@^2.0.0": - version "2.3.4" - resolved "https://registry.npmjs.org/@types/hast/-/hast-2.3.4.tgz" - integrity sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g== - dependencies: - "@types/unist" "*" - -"@types/hast@^3.0.0": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@types/hast/-/hast-3.0.4.tgz#1d6b39993b82cea6ad783945b0508c25903e15aa" - integrity sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ== - dependencies: - "@types/unist" "*" - -"@types/html-minifier-terser@^6.0.0": - version "6.1.0" - resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#4fc33a00c1d0c16987b1a20cf92d20614c55ac35" - integrity sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg== - -"@types/http-cache-semantics@*": - version "4.0.4" - resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz#b979ebad3919799c979b17c72621c0bc0a31c6c4" - integrity sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA== - -"@types/http-errors@*": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.4.tgz#7eb47726c391b7345a6ec35ad7f4de469cf5ba4f" - integrity sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA== - -"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": - version "2.0.6" - resolved "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz#7739c232a1fee9b4d3ce8985f314c0c6d33549d7" - integrity sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w== - -"@types/istanbul-lib-report@*": - version "3.0.3" - resolved "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz#53047614ae72e19fc0401d872de3ae2b4ce350bf" - integrity sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA== - dependencies: - "@types/istanbul-lib-coverage" "*" - -"@types/istanbul-reports@^3.0.0": - version "3.0.4" - resolved "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz#0f03e3d2f670fbdac586e34b433783070cc16f54" - integrity sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ== - dependencies: - "@types/istanbul-lib-report" "*" - -"@types/jest@^29.5.12": - version "29.5.12" - resolved "https://registry.npmjs.org/@types/jest/-/jest-29.5.12.tgz#7f7dc6eb4cf246d2474ed78744b05d06ce025544" - integrity sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw== - dependencies: - expect "^29.0.0" - pretty-format "^29.0.0" - -"@types/js-cookie@^2.x.x": - version "2.2.7" - resolved "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-2.2.7.tgz" - integrity sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA== - -"@types/js-cookie@^3.0.3": - version "3.0.3" - resolved "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-3.0.3.tgz" - integrity sha512-Xe7IImK09HP1sv2M/aI+48a20VX+TdRJucfq4vfRVy6nWN8PYPOEnlMRSgxJAgYQIXJVL8dZ4/ilAM7dWNaOww== - -"@types/jsdom@^20.0.0": - version "20.0.1" - resolved "https://registry.npmjs.org/@types/jsdom/-/jsdom-20.0.1.tgz#07c14bc19bd2f918c1929541cdaacae894744808" - integrity sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ== - dependencies: - "@types/node" "*" - "@types/tough-cookie" "*" - parse5 "^7.0.0" - -"@types/json-schema@^7.0.8": - version "7.0.15" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" - integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== - -"@types/json-schema@^7.0.9": - version "7.0.12" - resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz" - integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA== - -"@types/json5@^0.0.29": - version "0.0.29" - resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz" - integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== - -"@types/katex@^0.14.0": - version "0.14.0" - resolved "https://registry.npmjs.org/@types/katex/-/katex-0.14.0.tgz" - integrity sha512-+2FW2CcT0K3P+JMR8YG846bmDwplKUTsWgT2ENwdQ1UdVfRk3GQrh6Mi4sTopy30gI8Uau5CEqHTDZ6YvWIUPA== - -"@types/katex@^0.16.0": - version "0.16.0" - resolved "https://registry.npmjs.org/@types/katex/-/katex-0.16.0.tgz" - integrity sha512-hz+S3nV6Mym5xPbT9fnO8dDhBFQguMYpY0Ipxv06JMi1ORgnEM4M1ymWDUhUNer3ElLmT583opRo4RzxKmh9jw== - -"@types/keyv@^3.1.4": - version "3.1.4" - resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.4.tgz#3ccdb1c6751b0c7e52300bcdacd5bcbf8faa75b6" - integrity sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg== - dependencies: - "@types/node" "*" - -"@types/lodash-es@^4.17.7": - version "4.17.7" - resolved "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.7.tgz" - integrity sha512-z0ptr6UI10VlU6l5MYhGwS4mC8DZyYer2mCoyysZtSF7p26zOX8UpbrV0YpNYLGS8K4PUFIyEr62IMFFjveSiQ== - dependencies: - "@types/lodash" "*" - -"@types/lodash@*": - version "4.14.195" - resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.195.tgz" - integrity sha512-Hwx9EUgdwf2GLarOjQp5ZH8ZmblzcbTBC2wtQWNKARBSxM9ezRIAUpeDTgoQRAFB0+8CNWXVA9+MaSOzOF3nPg== - -"@types/lodash@^4.14.167": - version "4.17.10" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.10.tgz#64f3edf656af2fe59e7278b73d3e62404144a6e6" - integrity sha512-YpS0zzoduEhuOWjAotS6A5AVCva7X4lVlYLF0FYHAY9sdraBfnatttHItlWeZdGhuEkf+OzMNg2ZYAx8t+52uQ== - -"@types/mdast@^3.0.0": - version "3.0.11" - resolved "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.11.tgz" - integrity sha512-Y/uImid8aAwrEA24/1tcRZwpxX3pIFTSilcNDKSPn+Y2iDywSEachzRuvgAYYLR3wpGXAsMbv5lvKLDZLeYPAw== - dependencies: - "@types/unist" "*" - -"@types/mdast@^4.0.0": - version "4.0.4" - resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-4.0.4.tgz#7ccf72edd2f1aa7dd3437e180c64373585804dd6" - integrity sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA== - dependencies: - "@types/unist" "*" - -"@types/mdx@^2.0.0": - version "2.0.5" - resolved "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.5.tgz" - integrity sha512-76CqzuD6Q7LC+AtbPqrvD9AqsN0k8bsYo2bM2J8pmNldP1aIPAbzUQ7QbobyXL4eLr1wK5x8FZFe8eF/ubRuBg== - -"@types/mime@^1": - version "1.3.5" - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690" - integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w== - -"@types/ms@*": - version "0.7.31" - resolved "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz" - integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== - -"@types/negotiator@^0.6.1": - version "0.6.1" - resolved "https://registry.npmjs.org/@types/negotiator/-/negotiator-0.6.1.tgz" - integrity sha512-c4mvXFByghezQ/eVGN5HvH/jI63vm3B7FiE81BUzDAWmuiohRecCO6ddU60dfq29oKUMiQujsoB2h0JQC7JHKA== - -"@types/node@*", "@types/node@18.15.0": - version "18.15.0" - resolved "https://registry.npmjs.org/@types/node/-/node-18.15.0.tgz" - integrity sha512-z6nr0TTEOBGkzLGmbypWOGnpSpSIBorEhC4L+4HeQ2iezKCi4f77kyslRwvHeNitymGQ+oFyIWGP96l/DPSV9w== - -"@types/node@^22.0.0": - version "22.7.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-22.7.6.tgz#3ec3e2b071e136cd11093c19128405e1d1f92f33" - integrity sha512-/d7Rnj0/ExXDMcioS78/kf1lMzYk4BZV8MZGTBKzTGZ6/406ukkbYlIsZmMPhcR5KlkunDHQLrtAVmSq7r+mSw== - dependencies: - undici-types "~6.19.2" - -"@types/normalize-package-data@^2.4.0": - version "2.4.1" - resolved "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz" - integrity sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw== - -"@types/papaparse@^5.3.1": - version "5.3.7" - resolved "https://registry.npmjs.org/@types/papaparse/-/papaparse-5.3.7.tgz" - integrity sha512-f2HKmlnPdCvS0WI33WtCs5GD7X1cxzzS/aduaxSu3I7TbhWlENjSPs6z5TaB9K0J+BH1jbmqTaM+ja5puis4wg== - dependencies: - "@types/node" "*" - -"@types/parse-json@^4.0.0": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.2.tgz#5950e50960793055845e956c427fc2b0d70c5239" - integrity sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw== - -"@types/prop-types@*", "@types/prop-types@^15.0.0": - version "15.7.5" - resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz" - integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== - -"@types/qs@*": - version "6.9.16" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.16.tgz#52bba125a07c0482d26747d5d4947a64daf8f794" - integrity sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A== - -"@types/qs@^6.9.7": - version "6.9.7" - resolved "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz" - integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== - -"@types/range-parser@*": - version "1.2.7" - resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.7.tgz#50ae4353eaaddc04044279812f52c8c65857dbcb" - integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ== - -"@types/react-dom@~18.2.0": - version "18.2.25" - resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.25.tgz" - integrity sha512-o/V48vf4MQh7juIKZU2QGDfli6p1+OOi5oXx36Hffpc9adsHeXjVp8rHuPkjd8VT8sOJ2Zp05HR7CdpGTIUFUA== - dependencies: - "@types/react" "*" - -"@types/react-slider@^1.3.1": - version "1.3.1" - resolved "https://registry.npmjs.org/@types/react-slider/-/react-slider-1.3.1.tgz" - integrity sha512-4X2yK7RyCIy643YCFL+bc6XNmcnBtt8n88uuyihvcn5G7Lut23eNQU3q3KmwF7MWIfKfsW5NxCjw0SeDZRtgaA== - dependencies: - "@types/react" "*" - -"@types/react-syntax-highlighter@^15.5.6": - version "15.5.7" - resolved "https://registry.npmjs.org/@types/react-syntax-highlighter/-/react-syntax-highlighter-15.5.7.tgz" - integrity sha512-bo5fEO5toQeyCp0zVHBeggclqf5SQ/Z5blfFmjwO5dkMVGPgmiwZsJh9nu/Bo5L7IHTuGWrja6LxJVE2uB5ZrQ== - dependencies: - "@types/react" "*" - -"@types/react-window-infinite-loader@^1.0.6": - version "1.0.6" - resolved "https://registry.npmjs.org/@types/react-window-infinite-loader/-/react-window-infinite-loader-1.0.6.tgz" - integrity sha512-V8g8sBDLVeJJAfEENJS7VXZK+DRJ+jzPNtk8jpj2G+obhf+iqGNUDGwNWCbBhLiD+KpHhf3kWQlKBRi0tAeU4Q== - dependencies: - "@types/react" "*" - "@types/react-window" "*" - -"@types/react-window@*", "@types/react-window@^1.8.5": - version "1.8.5" - resolved "https://registry.npmjs.org/@types/react-window/-/react-window-1.8.5.tgz" - integrity sha512-V9q3CvhC9Jk9bWBOysPGaWy/Z0lxYcTXLtLipkt2cnRj1JOSFNF7wqGpkScSXMgBwC+fnVRg/7shwgddBG5ICw== - dependencies: - "@types/react" "*" - -"@types/react@*", "@types/react@>=16", "@types/react@^16.8.0 || ^17.0.0 || ^18.0.0", "@types/react@~18.2.0": - version "18.2.79" - resolved "https://registry.npmjs.org/@types/react/-/react-18.2.79.tgz" - integrity sha512-RwGAGXPl9kSXwdNTafkOEuFrTBD5SA2B3iEB96xi8+xu5ddUa/cpvyVCSNn+asgLCTHkb5ZxN8gbuibYJi4s1w== - dependencies: - "@types/prop-types" "*" - csstype "^3.0.2" - -"@types/recordrtc@^5.6.11": - version "5.6.11" - resolved "https://registry.npmjs.org/@types/recordrtc/-/recordrtc-5.6.11.tgz" - integrity sha512-X4XD5nltz0cjmyzsPNegQReOPF+C5ARTfSPAPhqnKV7SsfRta/M4FBJ5AtSInCaEveL71FLLSVQE9mg8Uuo++w== - -"@types/resolve@^1.20.2": - version "1.20.6" - resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.20.6.tgz#e6e60dad29c2c8c206c026e6dd8d6d1bdda850b8" - integrity sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ== - -"@types/responselike@^1.0.0": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.3.tgz#cc29706f0a397cfe6df89debfe4bf5cea159db50" - integrity sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw== - dependencies: - "@types/node" "*" - -"@types/semver@^7.3.12": - version "7.5.0" - resolved "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz" - integrity sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw== - -"@types/semver@^7.3.4": - version "7.5.8" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.8.tgz#8268a8c57a3e4abd25c165ecd36237db7948a55e" - integrity sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ== - -"@types/send@*": - version "0.17.4" - resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.4.tgz#6619cd24e7270793702e4e6a4b958a9010cfc57a" - integrity sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA== - dependencies: - "@types/mime" "^1" - "@types/node" "*" - -"@types/serve-static@*": - version "1.15.7" - resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.7.tgz#22174bbd74fb97fe303109738e9b5c2f3064f714" - integrity sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw== - dependencies: - "@types/http-errors" "*" - "@types/node" "*" - "@types/send" "*" - -"@types/sortablejs@^1.15.1": - version "1.15.1" - resolved "https://registry.npmjs.org/@types/sortablejs/-/sortablejs-1.15.1.tgz" - integrity sha512-g/JwBNToh6oCTAwNS8UGVmjO7NLDKsejVhvE4x1eWiPTC3uCuNsa/TD4ssvX3du+MLiM+SHPNDuijp8y76JzLQ== - -"@types/stack-utils@^2.0.0": - version "2.0.3" - resolved "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8" - integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw== - -"@types/tough-cookie@*": - version "4.0.5" - resolved "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz#cb6e2a691b70cb177c6e3ae9c1d2e8b2ea8cd304" - integrity sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA== - -"@types/unist@*", "@types/unist@^2.0.0", "@types/unist@^2.0.2": - version "2.0.6" - resolved "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz" - integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ== - -"@types/unist@^3.0.0": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@types/unist/-/unist-3.0.2.tgz#6dd61e43ef60b34086287f83683a5c1b2dc53d20" - integrity sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ== - -"@types/uuid@^9.0.1", "@types/uuid@^9.0.8": - version "9.0.8" - resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.8.tgz#7545ba4fc3c003d6c756f651f3bf163d8f0f29ba" - integrity sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA== - -"@types/yargs-parser@*": - version "21.0.3" - resolved "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15" - integrity sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ== - -"@types/yargs@^17.0.8": - version "17.0.32" - resolved "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz#030774723a2f7faafebf645f4e5a48371dca6229" - integrity sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog== - dependencies: - "@types/yargs-parser" "*" - -"@typescript-eslint/eslint-plugin@^5.53.0": - version "5.59.9" - resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.9.tgz" - integrity sha512-4uQIBq1ffXd2YvF7MAvehWKW3zVv/w+mSfRAu+8cKbfj3nwzyqJLNcZJpQ/WZ1HLbJDiowwmQ6NO+63nCA+fqA== - dependencies: - "@eslint-community/regexpp" "^4.4.0" - "@typescript-eslint/scope-manager" "5.59.9" - "@typescript-eslint/type-utils" "5.59.9" - "@typescript-eslint/utils" "5.59.9" - debug "^4.3.4" - grapheme-splitter "^1.0.4" - ignore "^5.2.0" - natural-compare-lite "^1.4.0" - semver "^7.3.7" - tsutils "^3.21.0" - -"@typescript-eslint/parser@^5.4.2 || ^6.0.0", "@typescript-eslint/parser@^5.53.0": - version "5.59.9" - resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.9.tgz" - integrity sha512-FsPkRvBtcLQ/eVK1ivDiNYBjn3TGJdXy2fhXX+rc7czWl4ARwnpArwbihSOHI2Peg9WbtGHrbThfBUkZZGTtvQ== - dependencies: - "@typescript-eslint/scope-manager" "5.59.9" - "@typescript-eslint/types" "5.59.9" - "@typescript-eslint/typescript-estree" "5.59.9" - debug "^4.3.4" - -"@typescript-eslint/scope-manager@5.59.9": - version "5.59.9" - resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.9.tgz" - integrity sha512-8RA+E+w78z1+2dzvK/tGZ2cpGigBZ58VMEHDZtpE1v+LLjzrYGc8mMaTONSxKyEkz3IuXFM0IqYiGHlCsmlZxQ== - dependencies: - "@typescript-eslint/types" "5.59.9" - "@typescript-eslint/visitor-keys" "5.59.9" - -"@typescript-eslint/scope-manager@5.62.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz#d9457ccc6a0b8d6b37d0eb252a23022478c5460c" - integrity sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w== - dependencies: - "@typescript-eslint/types" "5.62.0" - "@typescript-eslint/visitor-keys" "5.62.0" - -"@typescript-eslint/type-utils@5.59.9": - version "5.59.9" - resolved "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.9.tgz" - integrity sha512-ksEsT0/mEHg9e3qZu98AlSrONAQtrSTljL3ow9CGej8eRo7pe+yaC/mvTjptp23Xo/xIf2mLZKC6KPv4Sji26Q== - dependencies: - "@typescript-eslint/typescript-estree" "5.59.9" - "@typescript-eslint/utils" "5.59.9" - debug "^4.3.4" - tsutils "^3.21.0" - -"@typescript-eslint/types@5.59.9": - version "5.59.9" - resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.9.tgz" - integrity sha512-uW8H5NRgTVneSVTfiCVffBb8AbwWSKg7qcA4Ot3JI3MPCJGsB4Db4BhvAODIIYE5mNj7Q+VJkK7JxmRhk2Lyjw== - -"@typescript-eslint/types@5.62.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f" - integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ== - -"@typescript-eslint/typescript-estree@5.59.9": - version "5.59.9" - resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.9.tgz" - integrity sha512-pmM0/VQ7kUhd1QyIxgS+aRvMgw+ZljB3eDb+jYyp6d2bC0mQWLzUDF+DLwCTkQ3tlNyVsvZRXjFyV0LkU/aXjA== - dependencies: - "@typescript-eslint/types" "5.59.9" - "@typescript-eslint/visitor-keys" "5.59.9" - debug "^4.3.4" - globby "^11.1.0" - is-glob "^4.0.3" - semver "^7.3.7" - tsutils "^3.21.0" - -"@typescript-eslint/typescript-estree@5.62.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz#7d17794b77fabcac615d6a48fb143330d962eb9b" - integrity sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA== - dependencies: - "@typescript-eslint/types" "5.62.0" - "@typescript-eslint/visitor-keys" "5.62.0" - debug "^4.3.4" - globby "^11.1.0" - is-glob "^4.0.3" - semver "^7.3.7" - tsutils "^3.21.0" - -"@typescript-eslint/utils@5.59.9", "@typescript-eslint/utils@^5.10.0", "@typescript-eslint/utils@^5.53.0": - version "5.59.9" - resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.9.tgz" - integrity sha512-1PuMYsju/38I5Ggblaeb98TOoUvjhRvLpLa1DoTOFaLWqaXl/1iQ1eGurTXgBY58NUdtfTXKP5xBq7q9NDaLKg== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@types/json-schema" "^7.0.9" - "@types/semver" "^7.3.12" - "@typescript-eslint/scope-manager" "5.59.9" - "@typescript-eslint/types" "5.59.9" - "@typescript-eslint/typescript-estree" "5.59.9" - eslint-scope "^5.1.1" - semver "^7.3.7" - -"@typescript-eslint/utils@^5.62.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.62.0.tgz#141e809c71636e4a75daa39faed2fb5f4b10df86" - integrity sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@types/json-schema" "^7.0.9" - "@types/semver" "^7.3.12" - "@typescript-eslint/scope-manager" "5.62.0" - "@typescript-eslint/types" "5.62.0" - "@typescript-eslint/typescript-estree" "5.62.0" - eslint-scope "^5.1.1" - semver "^7.3.7" - -"@typescript-eslint/visitor-keys@5.59.9": - version "5.59.9" - resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.9.tgz" - integrity sha512-bT7s0td97KMaLwpEBckbzj/YohnvXtqbe2XgqNvTl6RJVakY5mvENOTPvw5u66nljfZxthESpDozs86U+oLY8Q== - dependencies: - "@typescript-eslint/types" "5.59.9" - eslint-visitor-keys "^3.3.0" - -"@typescript-eslint/visitor-keys@5.62.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz#2174011917ce582875954ffe2f6912d5931e353e" - integrity sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw== - dependencies: - "@typescript-eslint/types" "5.62.0" - eslint-visitor-keys "^3.3.0" - -"@ungap/structured-clone@^1.0.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" - integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== - -"@vitest/expect@2.0.5": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-2.0.5.tgz#f3745a6a2c18acbea4d39f5935e913f40d26fa86" - integrity sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA== - dependencies: - "@vitest/spy" "2.0.5" - "@vitest/utils" "2.0.5" - chai "^5.1.1" - tinyrainbow "^1.2.0" - -"@vitest/pretty-format@2.0.5": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@vitest/pretty-format/-/pretty-format-2.0.5.tgz#91d2e6d3a7235c742e1a6cc50e7786e2f2979b1e" - integrity sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ== - dependencies: - tinyrainbow "^1.2.0" - -"@vitest/pretty-format@2.1.3": - version "2.1.3" - resolved "https://registry.yarnpkg.com/@vitest/pretty-format/-/pretty-format-2.1.3.tgz#48b9b03de75507d1d493df7beb48dc39a1946a3e" - integrity sha512-XH1XdtoLZCpqV59KRbPrIhFCOO0hErxrQCMcvnQete3Vibb9UeIOX02uFPfVn3Z9ZXsq78etlfyhnkmIZSzIwQ== - dependencies: - tinyrainbow "^1.2.0" - -"@vitest/spy@2.0.5": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-2.0.5.tgz#590fc07df84a78b8e9dd976ec2090920084a2b9f" - integrity sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA== - dependencies: - tinyspy "^3.0.0" - -"@vitest/utils@2.0.5": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-2.0.5.tgz#6f8307a4b6bc6ceb9270007f73c67c915944e926" - integrity sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ== - dependencies: - "@vitest/pretty-format" "2.0.5" - estree-walker "^3.0.3" - loupe "^3.1.1" - tinyrainbow "^1.2.0" - -"@vitest/utils@^2.0.5": - version "2.1.3" - resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-2.1.3.tgz#e52aa5745384091b151cbdf79bb5a3ad2bea88d2" - integrity sha512-xpiVfDSg1RrYT0tX6czgerkpcKFmFOF/gCr30+Mve5V2kewCy4Prn1/NDMSRwaSmT7PRaOF83wu+bEtsY1wrvA== - dependencies: - "@vitest/pretty-format" "2.1.3" - loupe "^3.1.1" - tinyrainbow "^1.2.0" - -"@vue/compiler-core@3.4.25": - version "3.4.25" - resolved "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.25.tgz" - integrity sha512-Y2pLLopaElgWnMNolgG8w3C5nNUVev80L7hdQ5iIKPtMJvhVpG0zhnBG/g3UajJmZdvW0fktyZTotEHD1Srhbg== - dependencies: - "@babel/parser" "^7.24.4" - "@vue/shared" "3.4.25" - entities "^4.5.0" - estree-walker "^2.0.2" - source-map-js "^1.2.0" - -"@vue/compiler-dom@^3.2.47": - version "3.4.25" - resolved "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.25.tgz" - integrity sha512-Ugz5DusW57+HjllAugLci19NsDK+VyjGvmbB2TXaTcSlQxwL++2PETHx/+Qv6qFwNLzSt7HKepPe4DcTE3pBWg== - dependencies: - "@vue/compiler-core" "3.4.25" - "@vue/shared" "3.4.25" - -"@vue/shared@3.4.25": - version "3.4.25" - resolved "https://registry.npmjs.org/@vue/shared/-/shared-3.4.25.tgz" - integrity sha512-k0yappJ77g2+KNrIaF0FFnzwLvUBLUYr8VOwz+/6vLsmItFp51AcxLL7Ey3iPd7BIRyWPOcqUjMnm7OkahXllA== - -"@webassemblyjs/ast@1.12.1", "@webassemblyjs/ast@^1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.12.1.tgz#bb16a0e8b1914f979f45864c23819cc3e3f0d4bb" - integrity sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg== - dependencies: - "@webassemblyjs/helper-numbers" "1.11.6" - "@webassemblyjs/helper-wasm-bytecode" "1.11.6" - -"@webassemblyjs/floating-point-hex-parser@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz#dacbcb95aff135c8260f77fa3b4c5fea600a6431" - integrity sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw== - -"@webassemblyjs/helper-api-error@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz#6132f68c4acd59dcd141c44b18cbebbd9f2fa768" - integrity sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q== - -"@webassemblyjs/helper-buffer@1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz#6df20d272ea5439bf20ab3492b7fb70e9bfcb3f6" - integrity sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw== - -"@webassemblyjs/helper-numbers@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz#cbce5e7e0c1bd32cf4905ae444ef64cea919f1b5" - integrity sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g== - dependencies: - "@webassemblyjs/floating-point-hex-parser" "1.11.6" - "@webassemblyjs/helper-api-error" "1.11.6" - "@xtuc/long" "4.2.2" - -"@webassemblyjs/helper-wasm-bytecode@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz#bb2ebdb3b83aa26d9baad4c46d4315283acd51e9" - integrity sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA== - -"@webassemblyjs/helper-wasm-section@1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz#3da623233ae1a60409b509a52ade9bc22a37f7bf" - integrity sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g== - dependencies: - "@webassemblyjs/ast" "1.12.1" - "@webassemblyjs/helper-buffer" "1.12.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.6" - "@webassemblyjs/wasm-gen" "1.12.1" - -"@webassemblyjs/ieee754@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz#bb665c91d0b14fffceb0e38298c329af043c6e3a" - integrity sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg== - dependencies: - "@xtuc/ieee754" "^1.2.0" - -"@webassemblyjs/leb128@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.6.tgz#70e60e5e82f9ac81118bc25381a0b283893240d7" - integrity sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ== - dependencies: - "@xtuc/long" "4.2.2" - -"@webassemblyjs/utf8@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.6.tgz#90f8bc34c561595fe156603be7253cdbcd0fab5a" - integrity sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA== - -"@webassemblyjs/wasm-edit@^1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz#9f9f3ff52a14c980939be0ef9d5df9ebc678ae3b" - integrity sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g== - dependencies: - "@webassemblyjs/ast" "1.12.1" - "@webassemblyjs/helper-buffer" "1.12.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.6" - "@webassemblyjs/helper-wasm-section" "1.12.1" - "@webassemblyjs/wasm-gen" "1.12.1" - "@webassemblyjs/wasm-opt" "1.12.1" - "@webassemblyjs/wasm-parser" "1.12.1" - "@webassemblyjs/wast-printer" "1.12.1" - -"@webassemblyjs/wasm-gen@1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz#a6520601da1b5700448273666a71ad0a45d78547" - integrity sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w== - dependencies: - "@webassemblyjs/ast" "1.12.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.6" - "@webassemblyjs/ieee754" "1.11.6" - "@webassemblyjs/leb128" "1.11.6" - "@webassemblyjs/utf8" "1.11.6" - -"@webassemblyjs/wasm-opt@1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz#9e6e81475dfcfb62dab574ac2dda38226c232bc5" - integrity sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg== - dependencies: - "@webassemblyjs/ast" "1.12.1" - "@webassemblyjs/helper-buffer" "1.12.1" - "@webassemblyjs/wasm-gen" "1.12.1" - "@webassemblyjs/wasm-parser" "1.12.1" - -"@webassemblyjs/wasm-parser@1.12.1", "@webassemblyjs/wasm-parser@^1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz#c47acb90e6f083391e3fa61d113650eea1e95937" - integrity sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ== - dependencies: - "@webassemblyjs/ast" "1.12.1" - "@webassemblyjs/helper-api-error" "1.11.6" - "@webassemblyjs/helper-wasm-bytecode" "1.11.6" - "@webassemblyjs/ieee754" "1.11.6" - "@webassemblyjs/leb128" "1.11.6" - "@webassemblyjs/utf8" "1.11.6" - -"@webassemblyjs/wast-printer@1.12.1": - version "1.12.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz#bcecf661d7d1abdaf989d8341a4833e33e2b31ac" - integrity sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA== - dependencies: - "@webassemblyjs/ast" "1.12.1" - "@xtuc/long" "4.2.2" - -"@xtuc/ieee754@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" - integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== - -"@xtuc/long@4.2.2": - version "4.2.2" - resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" - integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== - -abab@^2.0.6: - version "2.0.6" - resolved "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" - integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== - -abort-controller@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" - integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== - dependencies: - event-target-shim "^5.0.0" - -accepts@~1.3.8: - version "1.3.8" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" - integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== - dependencies: - mime-types "~2.1.34" - negotiator "0.6.3" - -acorn-globals@^7.0.0: - version "7.0.1" - resolved "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz#0dbf05c44fa7c94332914c02066d5beff62c40c3" - integrity sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q== - dependencies: - acorn "^8.1.0" - acorn-walk "^8.0.2" - -acorn-import-attributes@^1.9.5: - version "1.9.5" - resolved "https://registry.yarnpkg.com/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz#7eb1557b1ba05ef18b5ed0ec67591bfab04688ef" - integrity sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ== - -acorn-jsx@^5.0.0, acorn-jsx@^5.3.1, acorn-jsx@^5.3.2: - version "5.3.2" - resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" - integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== - -acorn-walk@^7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" - integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== - -acorn-walk@^8.0.2, acorn-walk@^8.1.1: - version "8.3.3" - resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz#9caeac29eefaa0c41e3d4c65137de4d6f34df43e" - integrity sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw== - dependencies: - acorn "^8.11.0" - -acorn@^7.4.1: - version "7.4.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" - integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== - -acorn@^8.0.0, acorn@^8.5.0, acorn@^8.8.0: - version "8.8.2" - resolved "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz" - integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== - -acorn@^8.1.0, acorn@^8.11.0, acorn@^8.4.1, acorn@^8.8.1: - version "8.12.1" - resolved "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz#71616bdccbe25e27a54439e0046e89ca76df2248" - integrity sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg== - -acorn@^8.12.1, acorn@^8.7.1, acorn@^8.8.2: - version "8.13.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.13.0.tgz#2a30d670818ad16ddd6a35d3842dacec9e5d7ca3" - integrity sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w== - -adjust-sourcemap-loader@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz#fc4a0fd080f7d10471f30a7320f25560ade28c99" - integrity sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A== - dependencies: - loader-utils "^2.0.0" - regex-parser "^2.2.11" - -agent-base@6: - version "6.0.2" - resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== - dependencies: - debug "4" - -aggregate-error@^3.0.0: - version "3.1.0" - resolved "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz" - integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== - dependencies: - clean-stack "^2.0.0" - indent-string "^4.0.0" - -ahooks-v3-count@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/ahooks-v3-count/-/ahooks-v3-count-1.0.0.tgz" - integrity sha512-V7uUvAwnimu6eh/PED4mCDjE7tokeZQLKlxg9lCTMPhN+NjsSbtdacByVlR1oluXQzD3MOw55wylDmQo4+S9ZQ== - -ahooks@^3.7.5: - version "3.7.7" - resolved "https://registry.npmjs.org/ahooks/-/ahooks-3.7.7.tgz" - integrity sha512-5e5WlPq81Y84UnTLOKIQeq2cJw4aa7yj8fR2Nb/oMmXPrWMjIMCbPS1o+fpxSfCaNA3AzOnnMc8AehWRZltkJQ== - dependencies: - "@babel/runtime" "^7.21.0" - "@types/js-cookie" "^2.x.x" - ahooks-v3-count "^1.0.0" - dayjs "^1.9.1" - intersection-observer "^0.12.0" - js-cookie "^2.x.x" - lodash "^4.17.21" - resize-observer-polyfill "^1.5.1" - screenfull "^5.0.0" - tslib "^2.4.1" - -ajv-formats@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" - integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== - dependencies: - ajv "^8.0.0" - -ajv-keywords@^3.5.2: - version "3.5.2" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" - integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== - -ajv-keywords@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" - integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== - dependencies: - fast-deep-equal "^3.1.3" - -ajv@^6.10.0, ajv@^6.12.4, ajv@^6.12.5: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ajv@^8.0.0, ajv@^8.9.0: - version "8.17.1" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.17.1.tgz#37d9a5c776af6bc92d7f4f9510eba4c0a60d11a6" - integrity sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g== - dependencies: - fast-deep-equal "^3.1.3" - fast-uri "^3.0.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - -ansi-escapes@^4.2.1, ansi-escapes@^4.3.0: - version "4.3.2" - resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz" - integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== - dependencies: - type-fest "^0.21.3" - -ansi-html-community@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" - integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== - -ansi-html@^0.0.9: - version "0.0.9" - resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.9.tgz#6512d02342ae2cc68131952644a129cb734cd3f0" - integrity sha512-ozbS3LuenHVxNRh/wdnN16QapUHzauqSomAl1jwwJRRsGwFwtj644lIhxfWu0Fy0acCij2+AEgHvjscq3dlVXg== - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -ansi-regex@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz" - integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== - -ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -ansi-styles@^5.0.0: - version "5.2.0" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" - integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== - -ansi-styles@^6.0.0, ansi-styles@^6.1.0: - version "6.2.1" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz" - integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== - -any-promise@^1.0.0: - version "1.3.0" - resolved "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz" - integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== - -anymatch@^3.0.3, anymatch@~3.1.2: - version "3.1.3" - resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz" - integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -arg@^4.1.0: - version "4.1.3" - resolved "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" - integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== - -arg@^5.0.2: - version "5.0.2" - resolved "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz" - integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg== - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - -aria-query@5.3.0, aria-query@^5.0.0: - version "5.3.0" - resolved "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz#650c569e41ad90b51b3d7df5e5eed1c7549c103e" - integrity sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A== - dependencies: - dequal "^2.0.3" - -aria-query@^5.1.3: - version "5.1.3" - resolved "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz" - integrity sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ== - dependencies: - deep-equal "^2.0.5" - -array-buffer-byte-length@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz" - integrity sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A== - dependencies: - call-bind "^1.0.2" - is-array-buffer "^3.0.1" - -array-flatten@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" - integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== - -array-includes@^3.1.5, array-includes@^3.1.6, array-includes@^3.1.7: - version "3.1.7" - resolved "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz" - integrity sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" - is-string "^1.0.7" - -array-union@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz" - integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== - -array.prototype.findlastindex@^1.2.3: - version "1.2.3" - resolved "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz" - integrity sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-shim-unscopables "^1.0.0" - get-intrinsic "^1.2.1" - -array.prototype.flat@^1.3.2: - version "1.3.2" - resolved "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz" - integrity sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-shim-unscopables "^1.0.0" - -array.prototype.flatmap@^1.3.1, array.prototype.flatmap@^1.3.2: - version "1.3.2" - resolved "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz" - integrity sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-shim-unscopables "^1.0.0" - -array.prototype.tosorted@^1.1.1: - version "1.1.2" - resolved "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.2.tgz" - integrity sha512-HuQCHOlk1Weat5jzStICBCd83NxiIMwqDg/dHEsoefabn/hJRj5pVdWcPUSpRrwhwxZOsQassMpgN/xRYFBMIg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-shim-unscopables "^1.0.0" - get-intrinsic "^1.2.1" - -arraybuffer.prototype.slice@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz" - integrity sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw== - dependencies: - array-buffer-byte-length "^1.0.0" - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" - is-array-buffer "^3.0.2" - is-shared-array-buffer "^1.0.2" - -asn1.js@^4.10.1: - version "4.10.1" - resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" - integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw== - dependencies: - bn.js "^4.0.0" - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - -assert@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/assert/-/assert-2.1.0.tgz#6d92a238d05dc02e7427c881fb8be81c8448b2dd" - integrity sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw== - dependencies: - call-bind "^1.0.2" - is-nan "^1.3.2" - object-is "^1.1.5" - object.assign "^4.1.4" - util "^0.12.5" - -assertion-error@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-2.0.1.tgz#f641a196b335690b1070bf00b6e7593fec190bf7" - integrity sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA== - -ast-types-flow@^0.0.7: - version "0.0.7" - resolved "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz" - integrity sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag== - -ast-types@^0.16.1: - version "0.16.1" - resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.16.1.tgz#7a9da1617c9081bc121faafe91711b4c8bb81da2" - integrity sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg== - dependencies: - tslib "^2.0.1" - -astral-regex@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz" - integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== - -astring@^1.8.0: - version "1.8.6" - resolved "https://registry.npmjs.org/astring/-/astring-1.8.6.tgz" - integrity sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg== - -async@^2.6.4: - version "2.6.4" - resolved "https://registry.npmjs.org/async/-/async-2.6.4.tgz" - integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA== - dependencies: - lodash "^4.17.14" - -asynciterator.prototype@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz" - integrity sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg== - dependencies: - has-symbols "^1.0.3" - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== - -autoprefixer@^10.4.14: - version "10.4.14" - resolved "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz" - integrity sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ== - dependencies: - browserslist "^4.21.5" - caniuse-lite "^1.0.30001464" - fraction.js "^4.2.0" - normalize-range "^0.1.2" - picocolors "^1.0.0" - postcss-value-parser "^4.2.0" - -available-typed-arrays@^1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz" - integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== - -available-typed-arrays@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz#a5cc375d6a03c2efc87a553f3e0b1522def14846" - integrity sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ== - dependencies: - possible-typed-array-names "^1.0.0" - -axe-core@^4.6.2: - version "4.7.2" - resolved "https://registry.npmjs.org/axe-core/-/axe-core-4.7.2.tgz" - integrity sha512-zIURGIS1E1Q4pcrMjp+nnEh+16G56eG/MUllJH8yEvw7asDo7Ac9uhC9KIH5jzpITueEZolfYglnCGIuSBz39g== - -axobject-query@^3.1.1: - version "3.1.1" - resolved "https://registry.npmjs.org/axobject-query/-/axobject-query-3.1.1.tgz" - integrity sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg== - dependencies: - deep-equal "^2.0.5" - -babel-jest@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz#f4369919225b684c56085998ac63dbd05be020d5" - integrity sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg== - dependencies: - "@jest/transform" "^29.7.0" - "@types/babel__core" "^7.1.14" - babel-plugin-istanbul "^6.1.1" - babel-preset-jest "^29.6.3" - chalk "^4.0.0" - graceful-fs "^4.2.9" - slash "^3.0.0" - -babel-loader@^9.1.3: - version "9.2.1" - resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-9.2.1.tgz#04c7835db16c246dd19ba0914418f3937797587b" - integrity sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA== - dependencies: - find-cache-dir "^4.0.0" - schema-utils "^4.0.0" - -babel-plugin-istanbul@^6.1.1: - version "6.1.1" - resolved "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" - integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@istanbuljs/load-nyc-config" "^1.0.0" - "@istanbuljs/schema" "^0.1.2" - istanbul-lib-instrument "^5.0.4" - test-exclude "^6.0.0" - -babel-plugin-jest-hoist@^29.6.3: - version "29.6.3" - resolved "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz#aadbe943464182a8922c3c927c3067ff40d24626" - integrity sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg== - dependencies: - "@babel/template" "^7.3.3" - "@babel/types" "^7.3.3" - "@types/babel__core" "^7.1.14" - "@types/babel__traverse" "^7.0.6" - -babel-plugin-polyfill-corejs2@^0.4.10: - version "0.4.11" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz#30320dfe3ffe1a336c15afdcdafd6fd615b25e33" - integrity sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q== - dependencies: - "@babel/compat-data" "^7.22.6" - "@babel/helper-define-polyfill-provider" "^0.6.2" - semver "^6.3.1" - -babel-plugin-polyfill-corejs3@^0.10.6: - version "0.10.6" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz#2deda57caef50f59c525aeb4964d3b2f867710c7" - integrity sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA== - dependencies: - "@babel/helper-define-polyfill-provider" "^0.6.2" - core-js-compat "^3.38.0" - -babel-plugin-polyfill-regenerator@^0.6.1: - version "0.6.2" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz#addc47e240edd1da1058ebda03021f382bba785e" - integrity sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg== - dependencies: - "@babel/helper-define-polyfill-provider" "^0.6.2" - -babel-preset-current-node-syntax@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" - integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== - dependencies: - "@babel/plugin-syntax-async-generators" "^7.8.4" - "@babel/plugin-syntax-bigint" "^7.8.3" - "@babel/plugin-syntax-class-properties" "^7.8.3" - "@babel/plugin-syntax-import-meta" "^7.8.3" - "@babel/plugin-syntax-json-strings" "^7.8.3" - "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - "@babel/plugin-syntax-numeric-separator" "^7.8.3" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - "@babel/plugin-syntax-top-level-await" "^7.8.3" - -babel-preset-jest@^29.6.3: - version "29.6.3" - resolved "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz#fa05fa510e7d493896d7b0dd2033601c840f171c" - integrity sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA== - dependencies: - babel-plugin-jest-hoist "^29.6.3" - babel-preset-current-node-syntax "^1.0.0" - -bail@^2.0.0: - version "2.0.2" - resolved "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz" - integrity sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw== - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -base64-js@^1.3.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - -better-opn@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/better-opn/-/better-opn-3.0.2.tgz#f96f35deaaf8f34144a4102651babcf00d1d8817" - integrity sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ== - dependencies: - open "^8.0.4" - -big-integer@^1.6.44: - version "1.6.51" - resolved "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz" - integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg== - -big.js@^5.2.2: - version "5.2.2" - resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" - integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== - -binary-extensions@^2.0.0: - version "2.2.0" - resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" - integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== - -bing-translate-api@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/bing-translate-api/-/bing-translate-api-4.0.2.tgz#52807a128e883bf074b4174c5e674ffca60685e7" - integrity sha512-JJ8XUehnxzOhHU91oy86xEtp8OOMjVEjCZJX042fKxoO19NNvxJ5omeCcxQNFoPbDqVpBJwqiGVquL0oPdQm1Q== - dependencies: - got "^11.8.6" - -bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9: - version "4.12.0" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" - integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== - -bn.js@^5.2.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" - integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== - -body-parser@1.20.3: - version "1.20.3" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.3.tgz#1953431221c6fb5cd63c4b36d53fab0928e548c6" - integrity sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g== - dependencies: - bytes "3.1.2" - content-type "~1.0.5" - debug "2.6.9" - depd "2.0.0" - destroy "1.2.0" - http-errors "2.0.0" - iconv-lite "0.4.24" - on-finished "2.4.1" - qs "6.13.0" - raw-body "2.5.2" - type-is "~1.6.18" - unpipe "1.0.0" - -boolbase@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz" - integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== - -bplist-parser@^0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz" - integrity sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw== - dependencies: - big-integer "^1.6.44" - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -brace-expansion@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz" - integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== - dependencies: - balanced-match "^1.0.0" - -braces@^3.0.3, braces@~3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" - integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== - dependencies: - fill-range "^7.1.1" - -brorand@^1.0.1, brorand@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" - integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== - -browser-assert@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/browser-assert/-/browser-assert-1.2.1.tgz#9aaa5a2a8c74685c2ae05bfe46efd606f068c200" - integrity sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ== - -browserify-aes@^1.0.4, browserify-aes@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" - integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== - dependencies: - buffer-xor "^1.0.3" - cipher-base "^1.0.0" - create-hash "^1.1.0" - evp_bytestokey "^1.0.3" - inherits "^2.0.1" - safe-buffer "^5.0.1" - -browserify-cipher@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" - integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== - dependencies: - browserify-aes "^1.0.4" - browserify-des "^1.0.0" - evp_bytestokey "^1.0.0" - -browserify-des@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" - integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== - dependencies: - cipher-base "^1.0.1" - des.js "^1.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - -browserify-rsa@^4.0.0, browserify-rsa@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.1.tgz#06e530907fe2949dc21fc3c2e2302e10b1437238" - integrity sha512-YBjSAiTqM04ZVei6sXighu679a3SqWORA3qZTEqZImnlkDIFtKc6pNutpjyZ8RJTjQtuYfeetkxM11GwoYXMIQ== - dependencies: - bn.js "^5.2.1" - randombytes "^2.1.0" - safe-buffer "^5.2.1" - -browserify-sign@^4.0.0: - version "4.2.3" - resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.3.tgz#7afe4c01ec7ee59a89a558a4b75bd85ae62d4208" - integrity sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw== - dependencies: - bn.js "^5.2.1" - browserify-rsa "^4.1.0" - create-hash "^1.2.0" - create-hmac "^1.1.7" - elliptic "^6.5.5" - hash-base "~3.0" - inherits "^2.0.4" - parse-asn1 "^5.1.7" - readable-stream "^2.3.8" - safe-buffer "^5.2.1" - -browserify-zlib@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" - integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== - dependencies: - pako "~1.0.5" - -browserslist@^4.21.10, browserslist@^4.23.3, browserslist@^4.24.0: - version "4.24.0" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.24.0.tgz#a1325fe4bc80b64fda169629fc01b3d6cecd38d4" - integrity sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A== - dependencies: - caniuse-lite "^1.0.30001663" - electron-to-chromium "^1.5.28" - node-releases "^2.0.18" - update-browserslist-db "^1.1.0" - -browserslist@^4.21.5: - version "4.23.0" - resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz" - integrity sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ== - dependencies: - caniuse-lite "^1.0.30001587" - electron-to-chromium "^1.4.668" - node-releases "^2.0.14" - update-browserslist-db "^1.0.13" - -browserslist@^4.23.1: - version "4.23.2" - resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz#244fe803641f1c19c28c48c4b6ec9736eb3d32ed" - integrity sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA== - dependencies: - caniuse-lite "^1.0.30001640" - electron-to-chromium "^1.4.820" - node-releases "^2.0.14" - update-browserslist-db "^1.1.0" - -bser@2.1.1: - version "2.1.1" - resolved "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" - integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== - dependencies: - node-int64 "^0.4.0" - -buffer-from@^1.0.0: - version "1.1.2" - resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" - integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== - -buffer-xor@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" - integrity sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ== - -buffer@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" - integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.2.1" - -builtin-modules@^3.3.0: - version "3.3.0" - resolved "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz" - integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw== - -builtin-status-codes@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" - integrity sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ== - -builtins@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz" - integrity sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ== - dependencies: - semver "^7.0.0" - -bundle-name@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz" - integrity sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw== - dependencies: - run-applescript "^5.0.0" - -busboy@1.6.0: - version "1.6.0" - resolved "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz" - integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA== - dependencies: - streamsearch "^1.1.0" - -bytes@3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" - integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== - -cacheable-lookup@^5.0.3: - version "5.0.4" - resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005" - integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA== - -cacheable-request@^7.0.2: - version "7.0.4" - resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.4.tgz#7a33ebf08613178b403635be7b899d3e69bbe817" - integrity sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg== - dependencies: - clone-response "^1.0.2" - get-stream "^5.1.0" - http-cache-semantics "^4.0.0" - keyv "^4.0.0" - lowercase-keys "^2.0.0" - normalize-url "^6.0.1" - responselike "^2.0.0" - -call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.4, call-bind@^1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz" - integrity sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ== - dependencies: - function-bind "^1.1.2" - get-intrinsic "^1.2.1" - set-function-length "^1.1.1" - -call-bind@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" - integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== - dependencies: - es-define-property "^1.0.0" - es-errors "^1.3.0" - function-bind "^1.1.2" - get-intrinsic "^1.2.4" - set-function-length "^1.2.1" - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - -camel-case@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.2.tgz#9728072a954f805228225a6deea6b38461e1bd5a" - integrity sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw== - dependencies: - pascal-case "^3.1.2" - tslib "^2.0.3" - -camelcase-css@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz" - integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== - -camelcase@^5.3.1: - version "5.3.1" - resolved "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - -camelcase@^6.2.0: - version "6.3.0" - resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" - integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== - -caniuse-lite@^1.0.30001464, caniuse-lite@^1.0.30001579, caniuse-lite@^1.0.30001587: - version "1.0.30001620" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001620.tgz" - integrity sha512-WJvYsOjd1/BYUY6SNGUosK9DUidBPDTnOARHp3fSmFO1ekdxaY6nKRttEVrfMmYi80ctS0kz1wiWmm14fVc3ew== - -caniuse-lite@^1.0.30001640: - version "1.0.30001642" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001642.tgz#6aa6610eb24067c246d30c57f055a9d0a7f8d05f" - integrity sha512-3XQ0DoRgLijXJErLSl+bLnJ+Et4KqV1PY6JJBGAFlsNsz31zeAIncyeZfLCabHK/jtSh+671RM9YMldxjUPZtA== - -caniuse-lite@^1.0.30001663: - version "1.0.30001669" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001669.tgz#fda8f1d29a8bfdc42de0c170d7f34a9cf19ed7a3" - integrity sha512-DlWzFDJqstqtIVx1zeSpIMLjunf5SmwOw0N2Ck/QSQdS8PLS4+9HrLaYei4w8BIAL7IB/UEDu889d8vhCTPA0w== - -case-sensitive-paths-webpack-plugin@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz#db64066c6422eed2e08cc14b986ca43796dbc6d4" - integrity sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw== - -ccount@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz" - integrity sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg== - -chai@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/chai/-/chai-5.1.1.tgz#f035d9792a22b481ead1c65908d14bb62ec1c82c" - integrity sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA== - dependencies: - assertion-error "^2.0.1" - check-error "^2.1.1" - deep-eql "^5.0.1" - loupe "^3.1.0" - pathval "^2.0.0" - -chalk@4.1.1, chalk@^4.0.0, chalk@^4.1.1: - version "4.1.1" - resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz" - integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chalk@5.2.0: - version "5.2.0" - resolved "https://registry.npmjs.org/chalk/-/chalk-5.2.0.tgz" - integrity sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA== - -chalk@^2.0.0, chalk@^2.4.2: - version "2.4.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" - integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chalk@^4.1.0, chalk@^4.1.2: - version "4.1.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -char-regex@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" - integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== - -character-entities-html4@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz" - integrity sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA== - -character-entities-legacy@^1.0.0: - version "1.1.4" - resolved "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz" - integrity sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA== - -character-entities-legacy@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz" - integrity sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ== - -character-entities@^1.0.0: - version "1.2.4" - resolved "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz" - integrity sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw== - -character-entities@^2.0.0: - version "2.0.2" - resolved "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz" - integrity sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ== - -character-reference-invalid@^1.0.0: - version "1.1.4" - resolved "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz" - integrity sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg== - -character-reference-invalid@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz" - integrity sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw== - -check-error@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/check-error/-/check-error-2.1.1.tgz#87eb876ae71ee388fa0471fe423f494be1d96ccc" - integrity sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw== - -"chokidar@>=3.0.0 <4.0.0", chokidar@^3.5.3: - version "3.5.3" - resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz" - integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== - dependencies: - anymatch "~3.1.2" - braces "~3.0.2" - glob-parent "~5.1.2" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.6.0" - optionalDependencies: - fsevents "~2.3.2" - -chromatic@^11.4.0: - version "11.12.5" - resolved "https://registry.yarnpkg.com/chromatic/-/chromatic-11.12.5.tgz#befbc9cbf62722183a8ac73813b3a7fb07d0b62f" - integrity sha512-5z+BXQy3TMyXIzCdCDO9Psc8aMs9kIrCFHhMgYbwA6dTXxAL0oUjHZbICn5h4Ay/fM9cZQPaCH9T7a3myPA8Sw== - -chrome-trace-event@^1.0.2: - version "1.0.4" - resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz#05bffd7ff928465093314708c93bdfa9bd1f0f5b" - integrity sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ== - -ci-info@^3.2.0: - version "3.9.0" - resolved "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" - integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== - -ci-info@^3.6.1: - version "3.8.0" - resolved "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz" - integrity sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw== - -cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" - integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -cjs-module-lexer@^1.0.0: - version "1.3.1" - resolved "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz#c485341ae8fd999ca4ee5af2d7a1c9ae01e0099c" - integrity sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q== - -cjs-module-lexer@^1.2.3: - version "1.4.1" - resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.4.1.tgz#707413784dbb3a72aa11c2f2b042a0bef4004170" - integrity sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA== - -class-variance-authority@^0.7.0: - version "0.7.0" - resolved "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.0.tgz" - integrity sha512-jFI8IQw4hczaL4ALINxqLEXQbWcNjoSkloa4IaufXCJr6QawJyw7tuRysRsrE8w2p/4gGaxKIt/hX3qz/IbD1A== - dependencies: - clsx "2.0.0" - -classcat@^5.0.3, classcat@^5.0.4: - version "5.0.5" - resolved "https://registry.npmjs.org/classcat/-/classcat-5.0.5.tgz" - integrity sha512-JhZUT7JFcQy/EzW605k/ktHtncoo9vnyW/2GspNYwFlN1C/WmjuV/xtS04e9SOkL2sTdw0VAZ2UGCcQ9lR6p6w== - -classnames@2.3.1: - version "2.3.1" - resolved "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz" - integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA== - -classnames@^2.2.1, classnames@^2.3.2: - version "2.3.2" - resolved "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz" - integrity sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw== - -clean-css@^5.2.2: - version "5.3.3" - resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.3.3.tgz#b330653cd3bd6b75009cc25c714cae7b93351ccd" - integrity sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg== - dependencies: - source-map "~0.6.0" - -clean-regexp@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz" - integrity sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw== - dependencies: - escape-string-regexp "^1.0.5" - -clean-stack@^2.0.0: - version "2.2.0" - resolved "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz" - integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== - -cli-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz" - integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== - dependencies: - restore-cursor "^3.1.0" - -cli-truncate@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz" - integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg== - dependencies: - slice-ansi "^3.0.0" - string-width "^4.2.0" - -cli-truncate@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz" - integrity sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA== - dependencies: - slice-ansi "^5.0.0" - string-width "^5.0.0" - -client-only@0.0.1, client-only@^0.0.1: - version "0.0.1" - resolved "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz" - integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA== - -cliui@^8.0.1: - version "8.0.1" - resolved "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" - integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.1" - wrap-ansi "^7.0.0" - -clone-response@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.3.tgz#af2032aa47816399cf5f0a1d0db902f517abb8c3" - integrity sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA== - dependencies: - mimic-response "^1.0.0" - -clsx@2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz" - integrity sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q== - -co@^4.6.0: - version "4.6.0" - resolved "https://registry.npmjs.org/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== - -code-inspector-core@0.13.0: - version "0.13.0" - resolved "https://registry.npmjs.org/code-inspector-core/-/code-inspector-core-0.13.0.tgz" - integrity sha512-oYPNLdJjn3SY50YtF3IuxZOKLBNwzXSRPOqiXVnZFceMz9Ar6ugP3+zj7HszouxrsLFb2dVtlv//5wr4+cq62A== - dependencies: - "@vue/compiler-dom" "^3.2.47" - chalk "^4.1.1" - portfinder "^1.0.28" - -code-inspector-plugin@^0.13.0: - version "0.13.0" - resolved "https://registry.npmjs.org/code-inspector-plugin/-/code-inspector-plugin-0.13.0.tgz" - integrity sha512-v4mq5hhHkyMmutembTzREVsFeZ/+KsCwfx20+0gTqm1Il/M1T4d2BCv9mZ4ivie3GvvDMt/pVz1iBBVP3SuzJA== - dependencies: - chalk "4.1.1" - code-inspector-core "0.13.0" - vite-code-inspector-plugin "0.13.0" - webpack-code-inspector-plugin "0.13.0" - -collect-v8-coverage@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz#c0b29bcd33bcd0779a1344c2136051e6afd3d9e9" - integrity sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q== - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" - integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== - -color-name@^1.0.0, color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -color-string@^1.9.0: - version "1.9.1" - resolved "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz" - integrity sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg== - dependencies: - color-name "^1.0.0" - simple-swizzle "^0.2.2" - -color@^4.2.3: - version "4.2.3" - resolved "https://registry.npmjs.org/color/-/color-4.2.3.tgz" - integrity sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A== - dependencies: - color-convert "^2.0.1" - color-string "^1.9.0" - -colorette@^2.0.10, colorette@^2.0.19: - version "2.0.20" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" - integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== - -combined-stream@^1.0.8: - version "1.0.8" - resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - -comma-separated-tokens@^1.0.0: - version "1.0.8" - resolved "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz" - integrity sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw== - -comma-separated-tokens@^2.0.0: - version "2.0.3" - resolved "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz" - integrity sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg== - -commander@7: - version "7.2.0" - resolved "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz" - integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== - -commander@^10.0.0: - version "10.0.1" - resolved "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz" - integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== - -commander@^2.20.0: - version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - -commander@^4.0.0: - version "4.1.1" - resolved "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz" - integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== - -commander@^8.3.0: - version "8.3.0" - resolved "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz" - integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== - -common-path-prefix@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/common-path-prefix/-/common-path-prefix-3.0.0.tgz#7d007a7e07c58c4b4d5f433131a19141b29f11e0" - integrity sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w== - -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" - integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== - -console-browserify@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" - integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== - -constants-browserify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" - integrity sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ== - -content-disposition@0.5.4: - version "0.5.4" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" - integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== - dependencies: - safe-buffer "5.2.1" - -content-type@~1.0.4, content-type@~1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" - integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== - -convert-source-map@^1.7.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" - integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== - -convert-source-map@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" - integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== - -cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== - -cookie@0.7.1: - version "0.7.1" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.1.tgz#2f73c42142d5d5cf71310a74fc4ae61670e5dbc9" - integrity sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w== - -copy-to-clipboard@^3.3.3: - version "3.3.3" - resolved "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz" - integrity sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA== - dependencies: - toggle-selection "^1.0.6" - -core-js-compat@^3.38.0, core-js-compat@^3.38.1: - version "3.38.1" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.38.1.tgz#2bc7a298746ca5a7bcb9c164bcb120f2ebc09a09" - integrity sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw== - dependencies: - browserslist "^4.23.3" - -core-js-pure@^3.23.3: - version "3.38.1" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.38.1.tgz#e8534062a54b7221344884ba9b52474be495ada3" - integrity sha512-BY8Etc1FZqdw1glX0XNOq2FDwfrg/VGqoZOZCdaL+UmdaqDwQwYXkMJT4t6In+zfEfOJDcM9T0KdbBeJg8KKCQ== - -core-util-is@~1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" - integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== - -cose-base@^1.0.0: - version "1.0.3" - resolved "https://registry.npmjs.org/cose-base/-/cose-base-1.0.3.tgz" - integrity sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg== - dependencies: - layout-base "^1.0.0" - -cose-base@^2.2.0: - version "2.2.0" - resolved "https://registry.npmjs.org/cose-base/-/cose-base-2.2.0.tgz" - integrity sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g== - dependencies: - layout-base "^2.0.0" - -cosmiconfig@^7.0.1: - version "7.1.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz#1443b9afa596b670082ea46cbd8f6a62b84635f6" - integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA== - dependencies: - "@types/parse-json" "^4.0.0" - import-fresh "^3.2.1" - parse-json "^5.0.0" - path-type "^4.0.0" - yaml "^1.10.0" - -cosmiconfig@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-9.0.0.tgz#34c3fc58287b915f3ae905ab6dc3de258b55ad9d" - integrity sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg== - dependencies: - env-paths "^2.2.1" - import-fresh "^3.3.0" - js-yaml "^4.1.0" - parse-json "^5.2.0" - -create-ecdh@^4.0.0: - version "4.0.4" - resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" - integrity sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A== - dependencies: - bn.js "^4.1.0" - elliptic "^6.5.3" - -create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" - integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== - dependencies: - cipher-base "^1.0.1" - inherits "^2.0.1" - md5.js "^1.3.4" - ripemd160 "^2.0.1" - sha.js "^2.4.0" - -create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" - integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== - dependencies: - cipher-base "^1.0.3" - create-hash "^1.1.0" - inherits "^2.0.1" - ripemd160 "^2.0.0" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - -create-jest@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz#a355c5b3cb1e1af02ba177fe7afd7feee49a5320" - integrity sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q== - dependencies: - "@jest/types" "^29.6.3" - chalk "^4.0.0" - exit "^0.1.2" - graceful-fs "^4.2.9" - jest-config "^29.7.0" - jest-util "^29.7.0" - prompts "^2.0.1" - -create-require@^1.1.0: - version "1.1.1" - resolved "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" - integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== - -cross-env@^7.0.3: - version "7.0.3" - resolved "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz" - integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw== - dependencies: - cross-spawn "^7.0.1" - -cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -crypto-browserify@^3.12.0: - version "3.12.0" - resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" - integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== - dependencies: - browserify-cipher "^1.0.0" - browserify-sign "^4.0.0" - create-ecdh "^4.0.0" - create-hash "^1.1.0" - create-hmac "^1.1.0" - diffie-hellman "^5.0.0" - inherits "^2.0.1" - pbkdf2 "^3.0.3" - public-encrypt "^4.0.0" - randombytes "^2.0.0" - randomfill "^1.0.3" - -crypto-js@^4.2.0: - version "4.2.0" - resolved "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz" - integrity sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q== - -css-loader@^6.7.1, css-loader@^6.7.3: - version "6.11.0" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.11.0.tgz#33bae3bf6363d0a7c2cf9031c96c744ff54d85ba" - integrity sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g== - dependencies: - icss-utils "^5.1.0" - postcss "^8.4.33" - postcss-modules-extract-imports "^3.1.0" - postcss-modules-local-by-default "^4.0.5" - postcss-modules-scope "^3.2.0" - postcss-modules-values "^4.0.0" - postcss-value-parser "^4.2.0" - semver "^7.5.4" - -css-select@^4.1.3: - version "4.3.0" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.3.0.tgz#db7129b2846662fd8628cfc496abb2b59e41529b" - integrity sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ== - dependencies: - boolbase "^1.0.0" - css-what "^6.0.1" - domhandler "^4.3.1" - domutils "^2.8.0" - nth-check "^2.0.1" - -css-what@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" - integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== - -css.escape@^1.5.1: - version "1.5.1" - resolved "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb" - integrity sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg== - -cssesc@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz" - integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== - -cssom@^0.5.0: - version "0.5.0" - resolved "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz#d254fa92cd8b6fbd83811b9fbaed34663cc17c36" - integrity sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw== - -cssom@~0.3.6: - version "0.3.8" - resolved "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" - integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== - -cssstyle@^2.3.0: - version "2.3.0" - resolved "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" - integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== - dependencies: - cssom "~0.3.6" - -csstype@^3.0.2: - version "3.1.2" - resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz" - integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== - -cytoscape-cose-bilkent@^4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz" - integrity sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ== - dependencies: - cose-base "^1.0.0" - -cytoscape-fcose@^2.1.0: - version "2.2.0" - resolved "https://registry.npmjs.org/cytoscape-fcose/-/cytoscape-fcose-2.2.0.tgz" - integrity sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ== - dependencies: - cose-base "^2.2.0" - -cytoscape@^3.23.0: - version "3.26.0" - resolved "https://registry.npmjs.org/cytoscape/-/cytoscape-3.26.0.tgz" - integrity sha512-IV+crL+KBcrCnVVUCZW+zRRRFUZQcrtdOPXki+o4CFUWLdAEYvuZLcBSJC9EBK++suamERKzeY7roq2hdovV3w== - dependencies: - heap "^0.2.6" - lodash "^4.17.21" - -"d3-array@1 - 2": - version "2.12.1" - resolved "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz" - integrity sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ== - dependencies: - internmap "^1.0.0" - -"d3-array@2 - 3", "d3-array@2.10.0 - 3", "d3-array@2.5.0 - 3", d3-array@3, d3-array@^3.2.0: - version "3.2.4" - resolved "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz" - integrity sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg== - dependencies: - internmap "1 - 2" - -d3-axis@3: - version "3.0.0" - resolved "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz" - integrity sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw== - -d3-brush@3: - version "3.0.0" - resolved "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz" - integrity sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ== - dependencies: - d3-dispatch "1 - 3" - d3-drag "2 - 3" - d3-interpolate "1 - 3" - d3-selection "3" - d3-transition "3" - -d3-chord@3: - version "3.0.1" - resolved "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz" - integrity sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g== - dependencies: - d3-path "1 - 3" - -"d3-color@1 - 3", d3-color@3: - version "3.1.0" - resolved "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz" - integrity sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA== - -d3-contour@4: - version "4.0.2" - resolved "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz" - integrity sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA== - dependencies: - d3-array "^3.2.0" - -d3-delaunay@6: - version "6.0.4" - resolved "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz" - integrity sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A== - dependencies: - delaunator "5" - -"d3-dispatch@1 - 3", d3-dispatch@3: - version "3.0.1" - resolved "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz" - integrity sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg== - -"d3-drag@2 - 3", d3-drag@3, d3-drag@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz" - integrity sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg== - dependencies: - d3-dispatch "1 - 3" - d3-selection "3" - -"d3-dsv@1 - 3", d3-dsv@3: - version "3.0.1" - resolved "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz" - integrity sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q== - dependencies: - commander "7" - iconv-lite "0.6" - rw "1" - -"d3-ease@1 - 3", d3-ease@3: - version "3.0.1" - resolved "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz" - integrity sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w== - -d3-fetch@3: - version "3.0.1" - resolved "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz" - integrity sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw== - dependencies: - d3-dsv "1 - 3" - -d3-force@3: - version "3.0.0" - resolved "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz" - integrity sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg== - dependencies: - d3-dispatch "1 - 3" - d3-quadtree "1 - 3" - d3-timer "1 - 3" - -"d3-format@1 - 3", d3-format@3: - version "3.1.0" - resolved "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz" - integrity sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA== - -d3-geo@3: - version "3.1.0" - resolved "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.0.tgz" - integrity sha512-JEo5HxXDdDYXCaWdwLRt79y7giK8SbhZJbFWXqbRTolCHFI5jRqteLzCsq51NKbUoX0PjBVSohxrx+NoOUujYA== - dependencies: - d3-array "2.5.0 - 3" - -d3-hierarchy@3: - version "3.1.2" - resolved "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz" - integrity sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA== - -"d3-interpolate@1 - 3", "d3-interpolate@1.2.0 - 3", d3-interpolate@3: - version "3.0.1" - resolved "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz" - integrity sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g== - dependencies: - d3-color "1 - 3" - -d3-path@1: - version "1.0.9" - resolved "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz" - integrity sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg== - -"d3-path@1 - 3", d3-path@3, d3-path@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz" - integrity sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ== - -d3-polygon@3: - version "3.0.1" - resolved "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz" - integrity sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg== - -"d3-quadtree@1 - 3", d3-quadtree@3: - version "3.0.1" - resolved "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz" - integrity sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw== - -d3-random@3: - version "3.0.1" - resolved "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz" - integrity sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ== - -d3-sankey@^0.12.3: - version "0.12.3" - resolved "https://registry.npmjs.org/d3-sankey/-/d3-sankey-0.12.3.tgz" - integrity sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ== - dependencies: - d3-array "1 - 2" - d3-shape "^1.2.0" - -d3-scale-chromatic@3: - version "3.0.0" - resolved "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz" - integrity sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g== - dependencies: - d3-color "1 - 3" - d3-interpolate "1 - 3" - -d3-scale@4: - version "4.0.2" - resolved "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz" - integrity sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ== - dependencies: - d3-array "2.10.0 - 3" - d3-format "1 - 3" - d3-interpolate "1.2.0 - 3" - d3-time "2.1.1 - 3" - d3-time-format "2 - 4" - -"d3-selection@2 - 3", d3-selection@3, d3-selection@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz" - integrity sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ== - -d3-shape@3: - version "3.2.0" - resolved "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz" - integrity sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA== - dependencies: - d3-path "^3.1.0" - -d3-shape@^1.2.0: - version "1.3.7" - resolved "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz" - integrity sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw== - dependencies: - d3-path "1" - -"d3-time-format@2 - 4", d3-time-format@4: - version "4.1.0" - resolved "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz" - integrity sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg== - dependencies: - d3-time "1 - 3" - -"d3-time@1 - 3", "d3-time@2.1.1 - 3", d3-time@3: - version "3.1.0" - resolved "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz" - integrity sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q== - dependencies: - d3-array "2 - 3" - -"d3-timer@1 - 3", d3-timer@3: - version "3.0.1" - resolved "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz" - integrity sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA== - -"d3-transition@2 - 3", d3-transition@3: - version "3.0.1" - resolved "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz" - integrity sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w== - dependencies: - d3-color "1 - 3" - d3-dispatch "1 - 3" - d3-ease "1 - 3" - d3-interpolate "1 - 3" - d3-timer "1 - 3" - -d3-zoom@3, d3-zoom@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz" - integrity sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw== - dependencies: - d3-dispatch "1 - 3" - d3-drag "2 - 3" - d3-interpolate "1 - 3" - d3-selection "2 - 3" - d3-transition "2 - 3" - -d3@^7.4.0, d3@^7.8.2: - version "7.8.5" - resolved "https://registry.npmjs.org/d3/-/d3-7.8.5.tgz" - integrity sha512-JgoahDG51ncUfJu6wX/1vWQEqOflgXyl4MaHqlcSruTez7yhaRKR9i8VjjcQGeS2en/jnFivXuaIMnseMMt0XA== - dependencies: - d3-array "3" - d3-axis "3" - d3-brush "3" - d3-chord "3" - d3-color "3" - d3-contour "4" - d3-delaunay "6" - d3-dispatch "3" - d3-drag "3" - d3-dsv "3" - d3-ease "3" - d3-fetch "3" - d3-force "3" - d3-format "3" - d3-geo "3" - d3-hierarchy "3" - d3-interpolate "3" - d3-path "3" - d3-polygon "3" - d3-quadtree "3" - d3-random "3" - d3-scale "4" - d3-scale-chromatic "3" - d3-selection "3" - d3-shape "3" - d3-time "3" - d3-time-format "4" - d3-timer "3" - d3-transition "3" - d3-zoom "3" - -dagre-d3-es@7.0.10: - version "7.0.10" - resolved "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.10.tgz" - integrity sha512-qTCQmEhcynucuaZgY5/+ti3X/rnszKZhEQH/ZdWdtP1tA/y3VoHJzcVrO9pjjJCNpigfscAtoUB5ONcd2wNn0A== - dependencies: - d3 "^7.8.2" - lodash-es "^4.17.21" - -damerau-levenshtein@^1.0.8: - version "1.0.8" - resolved "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz" - integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== - -data-urls@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz#9cf24a477ae22bcef5cd5f6f0bfbc1d2d3be9143" - integrity sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ== - dependencies: - abab "^2.0.6" - whatwg-mimetype "^3.0.0" - whatwg-url "^11.0.0" - -dayjs@^1.11.7, dayjs@^1.9.1: - version "1.11.8" - resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.8.tgz" - integrity sha512-LcgxzFoWMEPO7ggRv1Y2N31hUf2R0Vj7fuy/m+Bg1K8rr+KAs1AEy4y9jd5DXe8pbHgX+srkHNS7TH6Q6ZhYeQ== - -debug@2.6.9: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@4, debug@^4.1.0, debug@^4.3.1: - version "4.3.5" - resolved "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz#e83444eceb9fedd4a1da56d671ae2446a01a6e1e" - integrity sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg== - dependencies: - ms "2.1.2" - -debug@^3.2.7: - version "3.2.7" - resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - -debug@^4.0.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: - version "4.3.4" - resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - -decimal.js@^10.4.2: - version "10.4.3" - resolved "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23" - integrity sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA== - -decode-named-character-reference@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz" - integrity sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg== - dependencies: - character-entities "^2.0.0" - -decompress-response@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" - integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== - dependencies: - mimic-response "^3.1.0" - -dedent@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" - integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== - -dedent@^1.0.0: - version "1.5.3" - resolved "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz#99aee19eb9bae55a67327717b6e848d0bf777e5a" - integrity sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ== - -deep-eql@^5.0.1: - version "5.0.2" - resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-5.0.2.tgz#4b756d8d770a9257300825d52a2c2cff99c3a341" - integrity sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q== - -deep-equal@^2.0.5: - version "2.2.1" - resolved "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.1.tgz" - integrity sha512-lKdkdV6EOGoVn65XaOsPdH4rMxTZOnmFyuIkMjM1i5HHCbfjC97dawgTAy0deYNfuqUqW+Q5VrVaQYtUpSd6yQ== - dependencies: - array-buffer-byte-length "^1.0.0" - call-bind "^1.0.2" - es-get-iterator "^1.1.3" - get-intrinsic "^1.2.0" - is-arguments "^1.1.1" - is-array-buffer "^3.0.2" - is-date-object "^1.0.5" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.2" - isarray "^2.0.5" - object-is "^1.1.5" - object-keys "^1.1.1" - object.assign "^4.1.4" - regexp.prototype.flags "^1.5.0" - side-channel "^1.0.4" - which-boxed-primitive "^1.0.2" - which-collection "^1.0.1" - which-typed-array "^1.1.9" - -deep-is@^0.1.3: - version "0.1.4" - resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz" - integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== - -deepmerge@^4.2.2: - version "4.3.1" - resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" - integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== - -default-browser-id@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/default-browser-id/-/default-browser-id-3.0.0.tgz" - integrity sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA== - dependencies: - bplist-parser "^0.2.0" - untildify "^4.0.0" - -default-browser@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/default-browser/-/default-browser-4.0.0.tgz" - integrity sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA== - dependencies: - bundle-name "^3.0.0" - default-browser-id "^3.0.0" - execa "^7.1.1" - titleize "^3.0.0" - -defer-to-connect@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" - integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== - -define-data-property@^1.0.1, define-data-property@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz" - integrity sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ== - dependencies: - get-intrinsic "^1.2.1" - gopd "^1.0.1" - has-property-descriptors "^1.0.0" - -define-data-property@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" - integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== - dependencies: - es-define-property "^1.0.0" - es-errors "^1.3.0" - gopd "^1.0.1" - -define-lazy-prop@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" - integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== - -define-lazy-prop@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz" - integrity sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg== - -define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0, define-properties@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz" - integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== - dependencies: - define-data-property "^1.0.1" - has-property-descriptors "^1.0.0" - object-keys "^1.1.1" - -delaunator@5: - version "5.0.0" - resolved "https://registry.npmjs.org/delaunator/-/delaunator-5.0.0.tgz" - integrity sha512-AyLvtyJdbv/U1GkiS6gUUzclRoAY4Gs75qkMygJJhU75LW4DNuSF2RMzpxs9jw9Oz1BobHjTdkG3zdP55VxAqw== - dependencies: - robust-predicates "^3.0.0" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== - -depd@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" - integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== - -dequal@^2.0.0, dequal@^2.0.2, dequal@^2.0.3: - version "2.0.3" - resolved "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz" - integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== - -des.js@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.1.0.tgz#1d37f5766f3bbff4ee9638e871a8768c173b81da" - integrity sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg== - dependencies: - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - -destroy@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" - integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== - -detect-libc@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz" - integrity sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw== - -detect-libc@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.3.tgz#f0cd503b40f9939b894697d19ad50895e30cf700" - integrity sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw== - -detect-newline@^3.0.0: - version "3.1.0" - resolved "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" - integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== - -devlop@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/devlop/-/devlop-1.1.0.tgz#4db7c2ca4dc6e0e834c30be70c94bbc976dc7018" - integrity sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA== - dependencies: - dequal "^2.0.0" - -didyoumean@^1.2.2: - version "1.2.2" - resolved "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz" - integrity sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw== - -diff-sequences@^29.6.3: - version "29.6.3" - resolved "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921" - integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q== - -diff@^4.0.1: - version "4.0.2" - resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" - integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== - -diff@^5.0.0: - version "5.1.0" - resolved "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz" - integrity sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw== - -diffie-hellman@^5.0.0: - version "5.0.3" - resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" - integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== - dependencies: - bn.js "^4.1.0" - miller-rabin "^4.0.0" - randombytes "^2.0.0" - -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - -dlv@^1.1.3: - version "1.1.3" - resolved "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz" - integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA== - -doctrine@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz" - integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== - dependencies: - esutils "^2.0.2" - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" - -dom-accessibility-api@^0.5.9: - version "0.5.16" - resolved "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz#5a7429e6066eb3664d911e33fb0e45de8eb08453" - integrity sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg== - -dom-accessibility-api@^0.6.3: - version "0.6.3" - resolved "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz#993e925cc1d73f2c662e7d75dd5a5445259a8fd8" - integrity sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w== - -dom-converter@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768" - integrity sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA== - dependencies: - utila "~0.4" - -dom-serializer@^1.0.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.4.1.tgz#de5d41b1aea290215dc45a6dae8adcf1d32e2d30" - integrity sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag== - dependencies: - domelementtype "^2.0.1" - domhandler "^4.2.0" - entities "^2.0.0" - -dom-serializer@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz" - integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg== - dependencies: - domelementtype "^2.3.0" - domhandler "^5.0.2" - entities "^4.2.0" - -domain-browser@^4.22.0: - version "4.23.0" - resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-4.23.0.tgz#427ebb91efcb070f05cffdfb8a4e9a6c25f8c94b" - integrity sha512-ArzcM/II1wCCujdCNyQjXrAFwS4mrLh4C7DZWlaI8mdh7h3BfKdNd3bKXITfl2PT9FtfQqaGvhi1vPRQPimjGA== - -domelementtype@^2.0.1, domelementtype@^2.2.0, domelementtype@^2.3.0: - version "2.3.0" - resolved "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz" - integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== - -domexception@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz#4ad1be56ccadc86fc76d033353999a8037d03673" - integrity sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw== - dependencies: - webidl-conversions "^7.0.0" - -domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.1.tgz#8d792033416f59d68bc03a5aa7b018c1ca89279c" - integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ== - dependencies: - domelementtype "^2.2.0" - -domhandler@^5.0.2, domhandler@^5.0.3: - version "5.0.3" - resolved "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz" - integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== - dependencies: - domelementtype "^2.3.0" - -dompurify@^3.0.5: - version "3.1.7" - resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.1.7.tgz#711a8c96479fb6ced93453732c160c3c72418a6a" - integrity sha512-VaTstWtsneJY8xzy7DekmYWEOZcmzIe3Qb3zPd4STve1OBTa+e+WmS1ITQec1fZYXI3HCsOZZiSMpG6oxoWMWQ== - -domutils@^2.5.2, domutils@^2.8.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" - integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== - dependencies: - dom-serializer "^1.0.1" - domelementtype "^2.2.0" - domhandler "^4.2.0" - -domutils@^3.0.1: - version "3.1.0" - resolved "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz" - integrity sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA== - dependencies: - dom-serializer "^2.0.0" - domelementtype "^2.3.0" - domhandler "^5.0.3" - -dot-case@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" - integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w== - dependencies: - no-case "^3.0.4" - tslib "^2.0.3" - -echarts-for-react@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/echarts-for-react/-/echarts-for-react-3.0.2.tgz" - integrity sha512-DRwIiTzx8JfwPOVgGttDytBqdp5VzCSyMRIxubgU/g2n9y3VLUmF2FK7Icmg/sNVkv4+rktmrLN9w22U2yy3fA== - dependencies: - fast-deep-equal "^3.1.3" - size-sensor "^1.0.1" - -echarts@^5.4.1: - version "5.4.2" - resolved "https://registry.npmjs.org/echarts/-/echarts-5.4.2.tgz" - integrity sha512-2W3vw3oI2tWJdyAz+b8DuWS0nfXtSDqlDmqgin/lfzbkB01cuMEN66KWBlmur3YMp5nEDEEt5s23pllnAzB4EA== - dependencies: - tslib "2.3.0" - zrender "5.4.3" - -ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== - -electron-to-chromium@^1.4.668: - version "1.4.775" - resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.775.tgz" - integrity sha512-JpOfl1aNAiZ88wFzjPczTLwYIoPIsij8S9/XQH9lqMpiJOf23kxea68B8wje4f68t4rOIq4Bh+vP4I65njiJBw== - -electron-to-chromium@^1.4.820: - version "1.4.829" - resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.829.tgz#3034a865b5eac9064c9db8b38ba99b60a446bb73" - integrity sha512-5qp1N2POAfW0u1qGAxXEtz6P7bO1m6gpZr5hdf5ve6lxpLM7MpiM4jIPz7xcrNlClQMafbyUDDWjlIQZ1Mw0Rw== - -electron-to-chromium@^1.5.28: - version "1.5.40" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.40.tgz#5f6aec13751123c5c3185999ebe3e7bcaf828c2b" - integrity sha512-LYm78o6if4zTasnYclgQzxEcgMoIcybWOhkATWepN95uwVVWV0/IW10v+2sIeHE+bIYWipLneTftVyQm45UY7g== - -elkjs@^0.8.2: - version "0.8.2" - resolved "https://registry.npmjs.org/elkjs/-/elkjs-0.8.2.tgz" - integrity sha512-L6uRgvZTH+4OF5NE/MBbzQx/WYpru1xCBE9respNj6qznEewGUIfhzmm7horWWxbNO2M0WckQypGctR8lH79xQ== - -elliptic@^6.5.3, elliptic@^6.5.5: - version "6.5.7" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.7.tgz#8ec4da2cb2939926a1b9a73619d768207e647c8b" - integrity sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q== - dependencies: - bn.js "^4.11.9" - brorand "^1.1.0" - hash.js "^1.0.0" - hmac-drbg "^1.0.1" - inherits "^2.0.4" - minimalistic-assert "^1.0.1" - minimalistic-crypto-utils "^1.0.1" - -emittery@^0.13.1: - version "0.13.1" - resolved "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad" - integrity sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ== - -emoji-mart@^5.5.2: - version "5.5.2" - resolved "https://registry.npmjs.org/emoji-mart/-/emoji-mart-5.5.2.tgz" - integrity sha512-Sqc/nso4cjxhOwWJsp9xkVm8OF5c+mJLZJFoFfzRuKO+yWiN7K8c96xmtughYb0d/fZ8UC6cLIQ/p4BR6Pv3/A== - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -emoji-regex@^9.2.2: - version "9.2.2" - resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz" - integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== - -emojis-list@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" - integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== - -encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== - -encodeurl@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58" - integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== - -end-of-stream@^1.1.0: - version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== - dependencies: - once "^1.4.0" - -endent@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/endent/-/endent-2.1.0.tgz#5aaba698fb569e5e18e69e1ff7a28ff35373cd88" - integrity sha512-r8VyPX7XL8U01Xgnb1CjZ3XV+z90cXIJ9JPE/R9SEC9vpw2P6CfsRPJmp20DppC5N7ZAMCmjYkJIa744Iyg96w== - dependencies: - dedent "^0.7.0" - fast-json-parse "^1.0.3" - objectorarray "^1.0.5" - -enhanced-resolve@^5.12.0: - version "5.16.1" - resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.1.tgz" - integrity sha512-4U5pNsuDl0EhuZpq46M5xPslstkviJuhrdobaRDBk2Jy2KO37FDAJl4lb2KlNabxT0m4MTK2UHNrsAcphE8nyw== - dependencies: - graceful-fs "^4.2.4" - tapable "^2.2.0" - -enhanced-resolve@^5.17.1, enhanced-resolve@^5.7.0: - version "5.17.1" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz#67bfbbcc2f81d511be77d686a90267ef7f898a15" - integrity sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg== - dependencies: - graceful-fs "^4.2.4" - tapable "^2.2.0" - -entities@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" - integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== - -entities@^4.2.0, entities@^4.4.0, entities@^4.5.0: - version "4.5.0" - resolved "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz" - integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== - -env-paths@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" - integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== - -error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -error-stack-parser@^2.0.6: - version "2.1.4" - resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.1.4.tgz#229cb01cdbfa84440bfa91876285b94680188286" - integrity sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ== - dependencies: - stackframe "^1.3.4" - -es-abstract@^1.20.4, es-abstract@^1.22.1: - version "1.22.3" - resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz" - integrity sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA== - dependencies: - array-buffer-byte-length "^1.0.0" - arraybuffer.prototype.slice "^1.0.2" - available-typed-arrays "^1.0.5" - call-bind "^1.0.5" - es-set-tostringtag "^2.0.1" - es-to-primitive "^1.2.1" - function.prototype.name "^1.1.6" - get-intrinsic "^1.2.2" - get-symbol-description "^1.0.0" - globalthis "^1.0.3" - gopd "^1.0.1" - has-property-descriptors "^1.0.0" - has-proto "^1.0.1" - has-symbols "^1.0.3" - hasown "^2.0.0" - internal-slot "^1.0.5" - is-array-buffer "^3.0.2" - is-callable "^1.2.7" - is-negative-zero "^2.0.2" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.2" - is-string "^1.0.7" - is-typed-array "^1.1.12" - is-weakref "^1.0.2" - object-inspect "^1.13.1" - object-keys "^1.1.1" - object.assign "^4.1.4" - regexp.prototype.flags "^1.5.1" - safe-array-concat "^1.0.1" - safe-regex-test "^1.0.0" - string.prototype.trim "^1.2.8" - string.prototype.trimend "^1.0.7" - string.prototype.trimstart "^1.0.7" - typed-array-buffer "^1.0.0" - typed-array-byte-length "^1.0.0" - typed-array-byte-offset "^1.0.0" - typed-array-length "^1.0.4" - unbox-primitive "^1.0.2" - which-typed-array "^1.1.13" - -es-define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" - integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== - dependencies: - get-intrinsic "^1.2.4" - -es-errors@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" - integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== - -es-get-iterator@^1.1.3: - version "1.1.3" - resolved "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz" - integrity sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.3" - has-symbols "^1.0.3" - is-arguments "^1.1.1" - is-map "^2.0.2" - is-set "^2.0.2" - is-string "^1.0.7" - isarray "^2.0.5" - stop-iteration-iterator "^1.0.0" - -es-iterator-helpers@^1.0.12: - version "1.0.15" - resolved "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.15.tgz" - integrity sha512-GhoY8uYqd6iwUl2kgjTm4CZAf6oo5mHK7BPqx3rKgx893YSsy0LGHV6gfqqQvZt/8xM8xeOnfXBCfqclMKkJ5g== - dependencies: - asynciterator.prototype "^1.0.0" - call-bind "^1.0.2" - define-properties "^1.2.1" - es-abstract "^1.22.1" - es-set-tostringtag "^2.0.1" - function-bind "^1.1.1" - get-intrinsic "^1.2.1" - globalthis "^1.0.3" - has-property-descriptors "^1.0.0" - has-proto "^1.0.1" - has-symbols "^1.0.3" - internal-slot "^1.0.5" - iterator.prototype "^1.1.2" - safe-array-concat "^1.0.1" - -es-module-lexer@^1.2.1, es-module-lexer@^1.5.0: - version "1.5.4" - resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.5.4.tgz#a8efec3a3da991e60efa6b633a7cad6ab8d26b78" - integrity sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw== - -es-set-tostringtag@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz" - integrity sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg== - dependencies: - get-intrinsic "^1.1.3" - has "^1.0.3" - has-tostringtag "^1.0.0" - -es-shim-unscopables@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz" - integrity sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w== - dependencies: - has "^1.0.3" - -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - -esbuild-register@^3.5.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/esbuild-register/-/esbuild-register-3.6.0.tgz#cf270cfa677baebbc0010ac024b823cbf723a36d" - integrity sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg== - dependencies: - debug "^4.3.4" - -"esbuild@^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0": - version "0.23.1" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.23.1.tgz#40fdc3f9265ec0beae6f59824ade1bd3d3d2dab8" - integrity sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg== - optionalDependencies: - "@esbuild/aix-ppc64" "0.23.1" - "@esbuild/android-arm" "0.23.1" - "@esbuild/android-arm64" "0.23.1" - "@esbuild/android-x64" "0.23.1" - "@esbuild/darwin-arm64" "0.23.1" - "@esbuild/darwin-x64" "0.23.1" - "@esbuild/freebsd-arm64" "0.23.1" - "@esbuild/freebsd-x64" "0.23.1" - "@esbuild/linux-arm" "0.23.1" - "@esbuild/linux-arm64" "0.23.1" - "@esbuild/linux-ia32" "0.23.1" - "@esbuild/linux-loong64" "0.23.1" - "@esbuild/linux-mips64el" "0.23.1" - "@esbuild/linux-ppc64" "0.23.1" - "@esbuild/linux-riscv64" "0.23.1" - "@esbuild/linux-s390x" "0.23.1" - "@esbuild/linux-x64" "0.23.1" - "@esbuild/netbsd-x64" "0.23.1" - "@esbuild/openbsd-arm64" "0.23.1" - "@esbuild/openbsd-x64" "0.23.1" - "@esbuild/sunos-x64" "0.23.1" - "@esbuild/win32-arm64" "0.23.1" - "@esbuild/win32-ia32" "0.23.1" - "@esbuild/win32-x64" "0.23.1" - -escalade@^3.1.1, escalade@^3.1.2: - version "3.1.2" - resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz" - integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA== - -escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== - -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" - integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== - -escape-string-regexp@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" - integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== - -escape-string-regexp@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - -escape-string-regexp@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz" - integrity sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw== - -escodegen@^2.0.0, escodegen@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.1.0.tgz#ba93bbb7a43986d29d6041f99f5262da773e2e17" - integrity sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w== - dependencies: - esprima "^4.0.1" - estraverse "^5.2.0" - esutils "^2.0.2" - optionalDependencies: - source-map "~0.6.1" - -eslint-config-next@^14.0.4: - version "14.1.0" - resolved "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-14.1.0.tgz" - integrity sha512-SBX2ed7DoRFXC6CQSLc/SbLY9Ut6HxNB2wPTcoIWjUMd7aF7O/SIE7111L8FdZ9TXsNV4pulUDnfthpyPtbFUg== - dependencies: - "@next/eslint-plugin-next" "14.1.0" - "@rushstack/eslint-patch" "^1.3.3" - "@typescript-eslint/parser" "^5.4.2 || ^6.0.0" - eslint-import-resolver-node "^0.3.6" - eslint-import-resolver-typescript "^3.5.2" - eslint-plugin-import "^2.28.1" - eslint-plugin-jsx-a11y "^6.7.1" - eslint-plugin-react "^7.33.2" - eslint-plugin-react-hooks "^4.5.0 || 5.0.0-canary-7118f5dd7-20230705" - -eslint-import-resolver-node@^0.3.6, eslint-import-resolver-node@^0.3.9: - version "0.3.9" - resolved "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz" - integrity sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g== - dependencies: - debug "^3.2.7" - is-core-module "^2.13.0" - resolve "^1.22.4" - -eslint-import-resolver-typescript@^3.5.2: - version "3.5.5" - resolved "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.5.5.tgz" - integrity sha512-TdJqPHs2lW5J9Zpe17DZNQuDnox4xo2o+0tE7Pggain9Rbc19ik8kFtXdxZ250FVx2kF4vlt2RSf4qlUpG7bhw== - dependencies: - debug "^4.3.4" - enhanced-resolve "^5.12.0" - eslint-module-utils "^2.7.4" - get-tsconfig "^4.5.0" - globby "^13.1.3" - is-core-module "^2.11.0" - is-glob "^4.0.3" - synckit "^0.8.5" - -eslint-module-utils@^2.7.4, eslint-module-utils@^2.8.0: - version "2.8.0" - resolved "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz" - integrity sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw== - dependencies: - debug "^3.2.7" - -eslint-plugin-antfu@0.36.0: - version "0.36.0" - resolved "https://registry.npmjs.org/eslint-plugin-antfu/-/eslint-plugin-antfu-0.36.0.tgz" - integrity sha512-qLYtjZC2y6d1fvVtG4nvVGoBUDEuUwQsS4E1RwjoEZyONZAkHYDPfeoeULDlPS0IqumSW8uGR6zGSAXi5rrVMg== - dependencies: - "@typescript-eslint/utils" "^5.53.0" - -eslint-plugin-es@^4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-4.1.0.tgz" - integrity sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ== - dependencies: - eslint-utils "^2.0.0" - regexpp "^3.0.0" - -eslint-plugin-eslint-comments@^3.2.0: - version "3.2.0" - resolved "https://registry.npmjs.org/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.2.0.tgz" - integrity sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ== - dependencies: - escape-string-regexp "^1.0.5" - ignore "^5.0.5" - -eslint-plugin-html@^7.1.0: - version "7.1.0" - resolved "https://registry.npmjs.org/eslint-plugin-html/-/eslint-plugin-html-7.1.0.tgz" - integrity sha512-fNLRraV/e6j8e3XYOC9xgND4j+U7b1Rq+OygMlLcMg+wI/IpVbF+ubQa3R78EjKB9njT6TQOlcK5rFKBVVtdfg== - dependencies: - htmlparser2 "^8.0.1" - -eslint-plugin-import@^2.27.5, eslint-plugin-import@^2.28.1: - version "2.29.1" - resolved "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz" - integrity sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw== - dependencies: - array-includes "^3.1.7" - array.prototype.findlastindex "^1.2.3" - array.prototype.flat "^1.3.2" - array.prototype.flatmap "^1.3.2" - debug "^3.2.7" - doctrine "^2.1.0" - eslint-import-resolver-node "^0.3.9" - eslint-module-utils "^2.8.0" - hasown "^2.0.0" - is-core-module "^2.13.1" - is-glob "^4.0.3" - minimatch "^3.1.2" - object.fromentries "^2.0.7" - object.groupby "^1.0.1" - object.values "^1.1.7" - semver "^6.3.1" - tsconfig-paths "^3.15.0" - -eslint-plugin-jest@^27.2.1: - version "27.2.1" - resolved "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.2.1.tgz" - integrity sha512-l067Uxx7ZT8cO9NJuf+eJHvt6bqJyz2Z29wykyEdz/OtmcELQl2MQGQLX8J94O1cSJWAwUSEvCjwjA7KEK3Hmg== - dependencies: - "@typescript-eslint/utils" "^5.10.0" - -eslint-plugin-jsonc@^2.6.0: - version "2.8.0" - resolved "https://registry.npmjs.org/eslint-plugin-jsonc/-/eslint-plugin-jsonc-2.8.0.tgz" - integrity sha512-K4VsnztnNwpm+V49CcCu5laq8VjclJpuhfI9LFkOrOyK+BKdQHMzkWo43B4X4rYaVrChm4U9kw/tTU5RHh5Wtg== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - jsonc-eslint-parser "^2.0.4" - natural-compare "^1.4.0" - -eslint-plugin-jsx-a11y@^6.7.1: - version "6.7.1" - resolved "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.7.1.tgz" - integrity sha512-63Bog4iIethyo8smBklORknVjB0T2dwB8Mr/hIC+fBS0uyHdYYpzM/Ed+YC8VxTjlXHEWFOdmgwcDn1U2L9VCA== - dependencies: - "@babel/runtime" "^7.20.7" - aria-query "^5.1.3" - array-includes "^3.1.6" - array.prototype.flatmap "^1.3.1" - ast-types-flow "^0.0.7" - axe-core "^4.6.2" - axobject-query "^3.1.1" - damerau-levenshtein "^1.0.8" - emoji-regex "^9.2.2" - has "^1.0.3" - jsx-ast-utils "^3.3.3" - language-tags "=1.0.5" - minimatch "^3.1.2" - object.entries "^1.1.6" - object.fromentries "^2.0.6" - semver "^6.3.0" - -eslint-plugin-markdown@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/eslint-plugin-markdown/-/eslint-plugin-markdown-3.0.0.tgz" - integrity sha512-hRs5RUJGbeHDLfS7ELanT0e29Ocyssf/7kBM+p7KluY5AwngGkDf8Oyu4658/NZSGTTq05FZeWbkxXtbVyHPwg== - dependencies: - mdast-util-from-markdown "^0.8.5" - -eslint-plugin-n@^15.6.1: - version "15.7.0" - resolved "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-15.7.0.tgz" - integrity sha512-jDex9s7D/Qial8AGVIHq4W7NswpUD5DPDL2RH8Lzd9EloWUuvUkHfv4FRLMipH5q2UtyurorBkPeNi1wVWNh3Q== - dependencies: - builtins "^5.0.1" - eslint-plugin-es "^4.1.0" - eslint-utils "^3.0.0" - ignore "^5.1.1" - is-core-module "^2.11.0" - minimatch "^3.1.2" - resolve "^1.22.1" - semver "^7.3.8" - -eslint-plugin-no-only-tests@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/eslint-plugin-no-only-tests/-/eslint-plugin-no-only-tests-3.1.0.tgz" - integrity sha512-Lf4YW/bL6Un1R6A76pRZyE1dl1vr31G/ev8UzIc/geCgFWyrKil8hVjYqWVKGB/UIGmb6Slzs9T0wNezdSVegw== - -eslint-plugin-promise@^6.1.1: - version "6.1.1" - resolved "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz" - integrity sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig== - -"eslint-plugin-react-hooks@^4.5.0 || 5.0.0-canary-7118f5dd7-20230705": - version "5.0.0-canary-7118f5dd7-20230705" - resolved "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.0.0-canary-7118f5dd7-20230705.tgz" - integrity sha512-AZYbMo/NW9chdL7vk6HQzQhT+PvTAEVqWk9ziruUoW2kAOcN5qNyelv70e0F1VNQAbvutOC9oc+xfWycI9FxDw== - -eslint-plugin-react@^7.33.2: - version "7.33.2" - resolved "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz" - integrity sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw== - dependencies: - array-includes "^3.1.6" - array.prototype.flatmap "^1.3.1" - array.prototype.tosorted "^1.1.1" - doctrine "^2.1.0" - es-iterator-helpers "^1.0.12" - estraverse "^5.3.0" - jsx-ast-utils "^2.4.1 || ^3.0.0" - minimatch "^3.1.2" - object.entries "^1.1.6" - object.fromentries "^2.0.6" - object.hasown "^1.1.2" - object.values "^1.1.6" - prop-types "^15.8.1" - resolve "^2.0.0-next.4" - semver "^6.3.1" - string.prototype.matchall "^4.0.8" - -eslint-plugin-storybook@^0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-storybook/-/eslint-plugin-storybook-0.9.0.tgz#8f985899b957748d5780f8e6eb5d37c705976bc8" - integrity sha512-qOT/2vQBo0VqrG/BhZv8IdSsKQiyzJw+2Wqq+WFCiblI/PfxLSrGkF/buiXF+HumwfsCyBdaC94UhqhmYFmAvA== - dependencies: - "@storybook/csf" "^0.0.1" - "@typescript-eslint/utils" "^5.62.0" - requireindex "^1.2.0" - ts-dedent "^2.2.0" - -eslint-plugin-unicorn@^45.0.2: - version "45.0.2" - resolved "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-45.0.2.tgz" - integrity sha512-Y0WUDXRyGDMcKLiwgL3zSMpHrXI00xmdyixEGIg90gHnj0PcHY4moNv3Ppje/kDivdAy5vUeUr7z211ImPv2gw== - dependencies: - "@babel/helper-validator-identifier" "^7.19.1" - "@eslint-community/eslint-utils" "^4.1.2" - ci-info "^3.6.1" - clean-regexp "^1.0.0" - esquery "^1.4.0" - indent-string "^4.0.0" - is-builtin-module "^3.2.0" - jsesc "^3.0.2" - lodash "^4.17.21" - pluralize "^8.0.0" - read-pkg-up "^7.0.1" - regexp-tree "^0.1.24" - regjsparser "^0.9.1" - safe-regex "^2.1.1" - semver "^7.3.8" - strip-indent "^3.0.0" - -eslint-plugin-unused-imports@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-2.0.0.tgz" - integrity sha512-3APeS/tQlTrFa167ThtP0Zm0vctjr4M44HMpeg1P4bK6wItarumq0Ma82xorMKdFsWpphQBlRPzw/pxiVELX1A== - dependencies: - eslint-rule-composer "^0.3.0" - -eslint-plugin-vue@^9.9.0: - version "9.14.1" - resolved "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.14.1.tgz" - integrity sha512-LQazDB1qkNEKejLe/b5a9VfEbtbczcOaui5lQ4Qw0tbRBbQYREyxxOV5BQgNDTqGPs9pxqiEpbMi9ywuIaF7vw== - dependencies: - "@eslint-community/eslint-utils" "^4.3.0" - natural-compare "^1.4.0" - nth-check "^2.0.1" - postcss-selector-parser "^6.0.9" - semver "^7.3.5" - vue-eslint-parser "^9.3.0" - xml-name-validator "^4.0.0" - -eslint-plugin-yml@^1.5.0: - version "1.7.0" - resolved "https://registry.npmjs.org/eslint-plugin-yml/-/eslint-plugin-yml-1.7.0.tgz" - integrity sha512-qq61FQJk+qIgWl0R06bec7UQQEIBrUH22jS+MroTbFUKu+3/iVlGRpZd8mjpOAm/+H/WEDFwy4x/+kKgVGbsWw== - dependencies: - debug "^4.3.2" - lodash "^4.17.21" - natural-compare "^1.4.0" - yaml-eslint-parser "^1.2.1" - -eslint-rule-composer@^0.3.0: - version "0.3.0" - resolved "https://registry.npmjs.org/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz" - integrity sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg== - -eslint-scope@5.1.1, eslint-scope@^5.1.1: - version "5.1.1" - resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - -eslint-scope@^7.1.1: - version "7.2.0" - resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz" - integrity sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw== - dependencies: - esrecurse "^4.3.0" - estraverse "^5.2.0" - -eslint-utils@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz" - integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== - dependencies: - eslint-visitor-keys "^1.1.0" - -eslint-utils@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz" - integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== - dependencies: - eslint-visitor-keys "^2.0.0" - -eslint-visitor-keys@^1.1.0: - version "1.3.0" - resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz" - integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== - -eslint-visitor-keys@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz" - integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== - -eslint-visitor-keys@^3.0.0, eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1: - version "3.4.1" - resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz" - integrity sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA== - -eslint@^8.36.0: - version "8.36.0" - resolved "https://registry.npmjs.org/eslint/-/eslint-8.36.0.tgz" - integrity sha512-Y956lmS7vDqomxlaaQAHVmeb4tNMp2FWIvU/RnU5BD3IKMD/MJPr76xdyr68P8tV1iNMvN2mRK0yy3c+UjL+bw== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@eslint-community/regexpp" "^4.4.0" - "@eslint/eslintrc" "^2.0.1" - "@eslint/js" "8.36.0" - "@humanwhocodes/config-array" "^0.11.8" - "@humanwhocodes/module-importer" "^1.0.1" - "@nodelib/fs.walk" "^1.2.8" - ajv "^6.10.0" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.3.2" - doctrine "^3.0.0" - escape-string-regexp "^4.0.0" - eslint-scope "^7.1.1" - eslint-visitor-keys "^3.3.0" - espree "^9.5.0" - esquery "^1.4.2" - esutils "^2.0.2" - fast-deep-equal "^3.1.3" - file-entry-cache "^6.0.1" - find-up "^5.0.0" - glob-parent "^6.0.2" - globals "^13.19.0" - grapheme-splitter "^1.0.4" - ignore "^5.2.0" - import-fresh "^3.0.0" - imurmurhash "^0.1.4" - is-glob "^4.0.0" - is-path-inside "^3.0.3" - js-sdsl "^4.1.4" - js-yaml "^4.1.0" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" - lodash.merge "^4.6.2" - minimatch "^3.1.2" - natural-compare "^1.4.0" - optionator "^0.9.1" - strip-ansi "^6.0.1" - strip-json-comments "^3.1.0" - text-table "^0.2.0" - -espree@^9.0.0, espree@^9.3.1, espree@^9.5.0, espree@^9.5.2: - version "9.5.2" - resolved "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz" - integrity sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw== - dependencies: - acorn "^8.8.0" - acorn-jsx "^5.3.2" - eslint-visitor-keys "^3.4.1" - -esprima@^4.0.0, esprima@^4.0.1, esprima@~4.0.0: - version "4.0.1" - resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== - -esquery@^1.4.0, esquery@^1.4.2: - version "1.5.0" - resolved "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz" - integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== - dependencies: - estraverse "^5.1.0" - -esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - -estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0: - version "5.3.0" - resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" - integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== - -estree-util-attach-comments@^2.0.0: - version "2.1.1" - resolved "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-2.1.1.tgz" - integrity sha512-+5Ba/xGGS6mnwFbXIuQiDPTbuTxuMCooq3arVv7gPZtYpjp+VXH/NkHAP35OOefPhNG/UGqU3vt/LTABwcHX0w== - dependencies: - "@types/estree" "^1.0.0" - -estree-util-build-jsx@^2.0.0: - version "2.2.2" - resolved "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-2.2.2.tgz" - integrity sha512-m56vOXcOBuaF+Igpb9OPAy7f9w9OIkb5yhjsZuaPm7HoGi4oTOQi0h2+yZ+AtKklYFZ+rPC4n0wYCJCEU1ONqg== - dependencies: - "@types/estree-jsx" "^1.0.0" - estree-util-is-identifier-name "^2.0.0" - estree-walker "^3.0.0" - -estree-util-is-identifier-name@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-2.1.0.tgz" - integrity sha512-bEN9VHRyXAUOjkKVQVvArFym08BTWB0aJPppZZr0UNyAqWsLaVfAqP7hbaTJjzHifmB5ebnR8Wm7r7yGN/HonQ== - -estree-util-to-js@^1.1.0: - version "1.2.0" - resolved "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-1.2.0.tgz" - integrity sha512-IzU74r1PK5IMMGZXUVZbmiu4A1uhiPgW5hm1GjcOfr4ZzHaMPpLNJjR7HjXiIOzi25nZDrgFTobHTkV5Q6ITjA== - dependencies: - "@types/estree-jsx" "^1.0.0" - astring "^1.8.0" - source-map "^0.7.0" - -estree-util-visit@^1.0.0: - version "1.2.1" - resolved "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-1.2.1.tgz" - integrity sha512-xbgqcrkIVbIG+lI/gzbvd9SGTJL4zqJKBFttUl5pP27KhAjtMKbX/mQXJ7qgyXpMgVy/zvpm0xoQQaGL8OloOw== - dependencies: - "@types/estree-jsx" "^1.0.0" - "@types/unist" "^2.0.0" - -estree-walker@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz" - integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== - -estree-walker@^3.0.0, estree-walker@^3.0.3: - version "3.0.3" - resolved "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz" - integrity sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g== - dependencies: - "@types/estree" "^1.0.0" - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - -etag@~1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== - -event-target-shim@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" - integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== - -events@^3.2.0, events@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" - integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== - -evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" - integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== - dependencies: - md5.js "^1.3.4" - safe-buffer "^5.1.1" - -execa@^5.0.0: - version "5.1.1" - resolved "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz" - integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.0" - human-signals "^2.1.0" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.1" - onetime "^5.1.2" - signal-exit "^3.0.3" - strip-final-newline "^2.0.0" - -execa@^7.0.0, execa@^7.1.1: - version "7.1.1" - resolved "https://registry.npmjs.org/execa/-/execa-7.1.1.tgz" - integrity sha512-wH0eMf/UXckdUYnO21+HDztteVv05rq2GXksxT4fCGeHkBhw1DROXh40wcjMcRqDOWE7iPJ4n3M7e2+YFP+76Q== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.1" - human-signals "^4.3.0" - is-stream "^3.0.0" - merge-stream "^2.0.0" - npm-run-path "^5.1.0" - onetime "^6.0.0" - signal-exit "^3.0.7" - strip-final-newline "^3.0.0" - -exit@^0.1.2: - version "0.1.2" - resolved "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" - integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== - -expect@^29.0.0, expect@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz#578874590dcb3214514084c08115d8aee61e11bc" - integrity sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw== - dependencies: - "@jest/expect-utils" "^29.7.0" - jest-get-type "^29.6.3" - jest-matcher-utils "^29.7.0" - jest-message-util "^29.7.0" - jest-util "^29.7.0" - -express@^4.19.2: - version "4.21.1" - resolved "https://registry.yarnpkg.com/express/-/express-4.21.1.tgz#9dae5dda832f16b4eec941a4e44aa89ec481b281" - integrity sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ== - dependencies: - accepts "~1.3.8" - array-flatten "1.1.1" - body-parser "1.20.3" - content-disposition "0.5.4" - content-type "~1.0.4" - cookie "0.7.1" - cookie-signature "1.0.6" - debug "2.6.9" - depd "2.0.0" - encodeurl "~2.0.0" - escape-html "~1.0.3" - etag "~1.8.1" - finalhandler "1.3.1" - fresh "0.5.2" - http-errors "2.0.0" - merge-descriptors "1.0.3" - methods "~1.1.2" - on-finished "2.4.1" - parseurl "~1.3.3" - path-to-regexp "0.1.10" - proxy-addr "~2.0.7" - qs "6.13.0" - range-parser "~1.2.1" - safe-buffer "5.2.1" - send "0.19.0" - serve-static "1.16.2" - setprototypeof "1.2.0" - statuses "2.0.1" - type-is "~1.6.18" - utils-merge "1.0.1" - vary "~1.1.2" - -extend@^3.0.0: - version "3.0.2" - resolved "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - -fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: - version "3.1.3" - resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -fast-glob@^3.2.11, fast-glob@^3.2.12: - version "3.3.2" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" - integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - -fast-glob@^3.2.9, fast-glob@^3.3.0: - version "3.3.1" - resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz" - integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - -fast-json-parse@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/fast-json-parse/-/fast-json-parse-1.0.3.tgz#43e5c61ee4efa9265633046b770fb682a7577c4d" - integrity sha512-FRWsaZRWEJ1ESVNbDWmsAlqDk96gPQezzLghafp5J4GUKjbCz3OkAHuZs5TuPEtkbVQERysLp9xv6c24fBm8Aw== - -fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fast-levenshtein@^2.0.6: - version "2.0.6" - resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" - integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== - -fast-uri@^3.0.1: - version "3.0.3" - resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.0.3.tgz#892a1c91802d5d7860de728f18608a0573142241" - integrity sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw== - -fastq@^1.6.0: - version "1.15.0" - resolved "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz" - integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== - dependencies: - reusify "^1.0.4" - -fault@^1.0.0: - version "1.0.4" - resolved "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz" - integrity sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA== - dependencies: - format "^0.2.0" - -fb-watchman@^2.0.0: - version "2.0.2" - resolved "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz#e9524ee6b5c77e9e5001af0f85f3adbb8623255c" - integrity sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA== - dependencies: - bser "2.1.1" - -file-entry-cache@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz" - integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== - dependencies: - flat-cache "^3.0.4" - -filesize@^10.0.12: - version "10.1.6" - resolved "https://registry.yarnpkg.com/filesize/-/filesize-10.1.6.tgz#31194da825ac58689c0bce3948f33ce83aabd361" - integrity sha512-sJslQKU2uM33qH5nqewAwVB2QgR6w1aMNsYUp3aN5rMRyXEwJGmZvaWzeJFNTOXWlHQyBFCWrdj3fV/fsTOX8w== - -fill-range@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" - integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== - dependencies: - to-regex-range "^5.0.1" - -filter-obj@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/filter-obj/-/filter-obj-2.0.2.tgz#fff662368e505d69826abb113f0f6a98f56e9d5f" - integrity sha512-lO3ttPjHZRfjMcxWKb1j1eDhTFsu4meeR3lnMcnBFhk6RuLhvEiuALu2TlfL310ph4lCYYwgF/ElIjdP739tdg== - -finalhandler@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.3.1.tgz#0c575f1d1d324ddd1da35ad7ece3df7d19088019" - integrity sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ== - dependencies: - debug "2.6.9" - encodeurl "~2.0.0" - escape-html "~1.0.3" - on-finished "2.4.1" - parseurl "~1.3.3" - statuses "2.0.1" - unpipe "~1.0.0" - -find-cache-dir@^3.3.1: - version "3.3.2" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" - integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== - dependencies: - commondir "^1.0.1" - make-dir "^3.0.2" - pkg-dir "^4.1.0" - -find-cache-dir@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-4.0.0.tgz#a30ee0448f81a3990708f6453633c733e2f6eec2" - integrity sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg== - dependencies: - common-path-prefix "^3.0.0" - pkg-dir "^7.0.0" - -find-up@^4.0.0, find-up@^4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - -find-up@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - -find-up@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-6.3.0.tgz#2abab3d3280b2dc7ac10199ef324c4e002c8c790" - integrity sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw== - dependencies: - locate-path "^7.1.0" - path-exists "^5.0.0" - -flat-cache@^3.0.4: - version "3.0.4" - resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz" - integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== - dependencies: - flatted "^3.1.0" - rimraf "^3.0.2" - -flatted@^3.1.0: - version "3.2.7" - resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz" - integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== - -for-each@^0.3.3: - version "0.3.3" - resolved "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz" - integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== - dependencies: - is-callable "^1.1.3" - -foreground-child@^3.1.0: - version "3.1.1" - resolved "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz" - integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== - dependencies: - cross-spawn "^7.0.0" - signal-exit "^4.0.1" - -fork-ts-checker-webpack-plugin@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-8.0.0.tgz#dae45dfe7298aa5d553e2580096ced79b6179504" - integrity sha512-mX3qW3idpueT2klaQXBzrIM/pHw+T0B/V9KHEvNrqijTq9NFnMZU6oreVxDYcf33P8a5cW+67PjodNHthGnNVg== - dependencies: - "@babel/code-frame" "^7.16.7" - chalk "^4.1.2" - chokidar "^3.5.3" - cosmiconfig "^7.0.1" - deepmerge "^4.2.2" - fs-extra "^10.0.0" - memfs "^3.4.1" - minimatch "^3.0.4" - node-abort-controller "^3.0.1" - schema-utils "^3.1.1" - semver "^7.3.5" - tapable "^2.2.1" - -form-data@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" - integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - -format@^0.2.0: - version "0.2.2" - resolved "https://registry.npmjs.org/format/-/format-0.2.2.tgz" - integrity sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww== - -forwarded@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" - integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== - -fraction.js@^4.2.0: - version "4.2.0" - resolved "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz" - integrity sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA== - -fresh@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== - -fs-extra@^10.0.0: - version "10.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" - integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - -fs-extra@^11.1.0: - version "11.2.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.2.0.tgz#e70e17dfad64232287d01929399e0ea7c86b0e5b" - integrity sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - -fs-monkey@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.6.tgz#8ead082953e88d992cf3ff844faa907b26756da2" - integrity sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg== - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" - integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== - -fsevents@^2.3.2, fsevents@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" - integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== - -function-bind@^1.1.1, function-bind@^1.1.2: - version "1.1.2" - resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz" - integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== - -function.prototype.name@^1.1.5, function.prototype.name@^1.1.6: - version "1.1.6" - resolved "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz" - integrity sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - functions-have-names "^1.2.3" - -functions-have-names@^1.2.3: - version "1.2.3" - resolved "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz" - integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== - -gensync@^1.0.0-beta.2: - version "1.0.0-beta.2" - resolved "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" - integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== - -get-caller-file@^2.0.5: - version "2.0.5" - resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - -get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2: - version "1.2.2" - resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz" - integrity sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA== - dependencies: - function-bind "^1.1.2" - has-proto "^1.0.1" - has-symbols "^1.0.3" - hasown "^2.0.0" - -get-intrinsic@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" - integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== - dependencies: - es-errors "^1.3.0" - function-bind "^1.1.2" - has-proto "^1.0.1" - has-symbols "^1.0.3" - hasown "^2.0.0" - -get-package-type@^0.1.0: - version "0.1.0" - resolved "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" - integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== - -get-stream@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" - integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== - dependencies: - pump "^3.0.0" - -get-stream@^6.0.0, get-stream@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz" - integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== - -get-symbol-description@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz" - integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.1" - -get-tsconfig@^4.5.0: - version "4.6.0" - resolved "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.6.0.tgz" - integrity sha512-lgbo68hHTQnFddybKbbs/RDRJnJT5YyGy2kQzVwbq+g67X73i+5MVTval34QxGkOe9X5Ujf1UYpCaphLyltjEg== - dependencies: - resolve-pkg-maps "^1.0.0" - -github-slugger@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/github-slugger/-/github-slugger-2.0.0.tgz#52cf2f9279a21eb6c59dd385b410f0c0adda8f1a" - integrity sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw== - -glob-parent@^5.1.2, glob-parent@~5.1.2: - version "5.1.2" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob-parent@^6.0.2: - version "6.0.2" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz" - integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== - dependencies: - is-glob "^4.0.3" - -glob-to-regexp@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" - integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== - -glob@10.3.10: - version "10.3.10" - resolved "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz" - integrity sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g== - dependencies: - foreground-child "^3.1.0" - jackspeak "^2.3.5" - minimatch "^9.0.1" - minipass "^5.0.0 || ^6.0.2 || ^7.0.0" - path-scurry "^1.10.1" - -glob@7.1.6: - version "7.1.6" - resolved "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^7.1.3, glob@^7.1.4: - version "7.2.3" - resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" - integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.1.1" - once "^1.3.0" - path-is-absolute "^1.0.0" - -globals@^11.1.0: - version "11.12.0" - resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" - integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== - -globals@^13.19.0: - version "13.20.0" - resolved "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz" - integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== - dependencies: - type-fest "^0.20.2" - -globalthis@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz" - integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== - dependencies: - define-properties "^1.1.3" - -globby@^11.1.0: - version "11.1.0" - resolved "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz" - integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== - dependencies: - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.2.9" - ignore "^5.2.0" - merge2 "^1.4.1" - slash "^3.0.0" - -globby@^13.1.3: - version "13.1.4" - resolved "https://registry.npmjs.org/globby/-/globby-13.1.4.tgz" - integrity sha512-iui/IiiW+QrJ1X1hKH5qwlMQyv34wJAYwH1vrf8b9kBA4sNiif3gKsMHa+BrdnOpEudWjpotfa7LrTzB1ERS/g== - dependencies: - dir-glob "^3.0.1" - fast-glob "^3.2.11" - ignore "^5.2.0" - merge2 "^1.4.1" - slash "^4.0.0" - -gopd@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz" - integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== - dependencies: - get-intrinsic "^1.1.3" - -got@^11.8.6: - version "11.8.6" - resolved "https://registry.yarnpkg.com/got/-/got-11.8.6.tgz#276e827ead8772eddbcfc97170590b841823233a" - integrity sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g== - dependencies: - "@sindresorhus/is" "^4.0.0" - "@szmarczak/http-timer" "^4.0.5" - "@types/cacheable-request" "^6.0.1" - "@types/responselike" "^1.0.0" - cacheable-lookup "^5.0.3" - cacheable-request "^7.0.2" - decompress-response "^6.0.0" - http2-wrapper "^1.0.0-beta.5.2" - lowercase-keys "^2.0.0" - p-cancelable "^2.0.0" - responselike "^2.0.0" - -graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.11, graceful-fs@^4.2.4, graceful-fs@^4.2.9: - version "4.2.11" - resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz" - integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== - -grapheme-splitter@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz" - integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== - -has-bigints@^1.0.1, has-bigints@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz" - integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" - integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-property-descriptors@^1.0.0, has-property-descriptors@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz" - integrity sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg== - dependencies: - get-intrinsic "^1.2.2" - -has-property-descriptors@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" - integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== - dependencies: - es-define-property "^1.0.0" - -has-proto@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz" - integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== - -has-symbols@^1.0.2, has-symbols@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz" - integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== - -has-tostringtag@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz" - integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== - dependencies: - has-symbols "^1.0.2" - -has-tostringtag@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc" - integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw== - dependencies: - has-symbols "^1.0.3" - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -hash-base@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" - integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== - dependencies: - inherits "^2.0.4" - readable-stream "^3.6.0" - safe-buffer "^5.2.0" - -hash-base@~3.0: - version "3.0.4" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" - integrity sha512-EeeoJKjTyt868liAlVmcv2ZsUfGHlE3Q+BICOXcZiwN3osr5Q/zFGYmTJpoIzuaSTAwndFy+GqhEwlU4L3j4Ow== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -hash.js@^1.0.0, hash.js@^1.0.3: - version "1.1.7" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" - integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== - dependencies: - inherits "^2.0.3" - minimalistic-assert "^1.0.1" - -hasown@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz" - integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA== - dependencies: - function-bind "^1.1.2" - -hast-util-from-dom@^4.0.0: - version "4.2.0" - resolved "https://registry.npmjs.org/hast-util-from-dom/-/hast-util-from-dom-4.2.0.tgz" - integrity sha512-t1RJW/OpJbCAJQeKi3Qrj1cAOLA0+av/iPFori112+0X7R3wng+jxLA+kXec8K4szqPRGI8vPxbbpEYvvpwaeQ== - dependencies: - hastscript "^7.0.0" - web-namespaces "^2.0.0" - -hast-util-from-html-isomorphic@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/hast-util-from-html-isomorphic/-/hast-util-from-html-isomorphic-1.0.0.tgz" - integrity sha512-Yu480AKeOEN/+l5LA674a+7BmIvtDj24GvOt7MtQWuhzUwlaaRWdEPXAh3Qm5vhuthpAipFb2vTetKXWOjmTvw== - dependencies: - "@types/hast" "^2.0.0" - hast-util-from-dom "^4.0.0" - hast-util-from-html "^1.0.0" - unist-util-remove-position "^4.0.0" - -hast-util-from-html@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-1.0.2.tgz" - integrity sha512-LhrTA2gfCbLOGJq2u/asp4kwuG0y6NhWTXiPKP+n0qNukKy7hc10whqqCFfyvIA1Q5U5d0sp9HhNim9gglEH4A== - dependencies: - "@types/hast" "^2.0.0" - hast-util-from-parse5 "^7.0.0" - parse5 "^7.0.0" - vfile "^5.0.0" - vfile-message "^3.0.0" - -hast-util-from-parse5@^7.0.0: - version "7.1.2" - resolved "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-7.1.2.tgz" - integrity sha512-Nz7FfPBuljzsN3tCQ4kCBKqdNhQE2l0Tn+X1ubgKBPRoiDIu1mL08Cfw4k7q71+Duyaw7DXDN+VTAp4Vh3oCOw== - dependencies: - "@types/hast" "^2.0.0" - "@types/unist" "^2.0.0" - hastscript "^7.0.0" - property-information "^6.0.0" - vfile "^5.0.0" - vfile-location "^4.0.0" - web-namespaces "^2.0.0" - -hast-util-from-parse5@^8.0.0: - version "8.0.1" - resolved "https://registry.yarnpkg.com/hast-util-from-parse5/-/hast-util-from-parse5-8.0.1.tgz#654a5676a41211e14ee80d1b1758c399a0327651" - integrity sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ== - dependencies: - "@types/hast" "^3.0.0" - "@types/unist" "^3.0.0" - devlop "^1.0.0" - hastscript "^8.0.0" - property-information "^6.0.0" - vfile "^6.0.0" - vfile-location "^5.0.0" - web-namespaces "^2.0.0" - -hast-util-heading-rank@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/hast-util-heading-rank/-/hast-util-heading-rank-3.0.0.tgz#2d5c6f2807a7af5c45f74e623498dd6054d2aba8" - integrity sha512-EJKb8oMUXVHcWZTDepnr+WNbfnXKFNf9duMesmr4S8SXTJBJ9M4Yok08pu9vxdJwdlGRhVumk9mEhkEvKGifwA== - dependencies: - "@types/hast" "^3.0.0" - -hast-util-is-element@^2.0.0: - version "2.1.3" - resolved "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-2.1.3.tgz" - integrity sha512-O1bKah6mhgEq2WtVMk+Ta5K7pPMqsBBlmzysLdcwKVrqzZQ0CHqUPiIVspNhAG1rvxpvJjtGee17XfauZYKqVA== - dependencies: - "@types/hast" "^2.0.0" - "@types/unist" "^2.0.0" - -hast-util-is-element@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz#6e31a6532c217e5b533848c7e52c9d9369ca0932" - integrity sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g== - dependencies: - "@types/hast" "^3.0.0" - -hast-util-parse-selector@^2.0.0: - version "2.2.5" - resolved "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz" - integrity sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ== - -hast-util-parse-selector@^3.0.0: - version "3.1.1" - resolved "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-3.1.1.tgz" - integrity sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA== - dependencies: - "@types/hast" "^2.0.0" - -hast-util-parse-selector@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz#352879fa86e25616036037dd8931fb5f34cb4a27" - integrity sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A== - dependencies: - "@types/hast" "^3.0.0" - -hast-util-raw@^9.0.0: - version "9.0.4" - resolved "https://registry.yarnpkg.com/hast-util-raw/-/hast-util-raw-9.0.4.tgz#2da03e37c46eb1a6f1391f02f9b84ae65818f7ed" - integrity sha512-LHE65TD2YiNsHD3YuXcKPHXPLuYh/gjp12mOfU8jxSrm1f/yJpsb0F/KKljS6U9LJoP0Ux+tCe8iJ2AsPzTdgA== - dependencies: - "@types/hast" "^3.0.0" - "@types/unist" "^3.0.0" - "@ungap/structured-clone" "^1.0.0" - hast-util-from-parse5 "^8.0.0" - hast-util-to-parse5 "^8.0.0" - html-void-elements "^3.0.0" - mdast-util-to-hast "^13.0.0" - parse5 "^7.0.0" - unist-util-position "^5.0.0" - unist-util-visit "^5.0.0" - vfile "^6.0.0" - web-namespaces "^2.0.0" - zwitch "^2.0.0" - -hast-util-to-estree@^2.0.0: - version "2.3.3" - resolved "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-2.3.3.tgz" - integrity sha512-ihhPIUPxN0v0w6M5+IiAZZrn0LH2uZomeWwhn7uP7avZC6TE7lIiEh2yBMPr5+zi1aUCXq6VoYRgs2Bw9xmycQ== - dependencies: - "@types/estree" "^1.0.0" - "@types/estree-jsx" "^1.0.0" - "@types/hast" "^2.0.0" - "@types/unist" "^2.0.0" - comma-separated-tokens "^2.0.0" - estree-util-attach-comments "^2.0.0" - estree-util-is-identifier-name "^2.0.0" - hast-util-whitespace "^2.0.0" - mdast-util-mdx-expression "^1.0.0" - mdast-util-mdxjs-esm "^1.0.0" - property-information "^6.0.0" - space-separated-tokens "^2.0.0" - style-to-object "^0.4.1" - unist-util-position "^4.0.0" - zwitch "^2.0.0" - -hast-util-to-parse5@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/hast-util-to-parse5/-/hast-util-to-parse5-8.0.0.tgz#477cd42d278d4f036bc2ea58586130f6f39ee6ed" - integrity sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw== - dependencies: - "@types/hast" "^3.0.0" - comma-separated-tokens "^2.0.0" - devlop "^1.0.0" - property-information "^6.0.0" - space-separated-tokens "^2.0.0" - web-namespaces "^2.0.0" - zwitch "^2.0.0" - -hast-util-to-string@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/hast-util-to-string/-/hast-util-to-string-3.0.1.tgz#a4f15e682849326dd211c97129c94b0c3e76527c" - integrity sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A== - dependencies: - "@types/hast" "^3.0.0" - -hast-util-to-text@^3.1.0: - version "3.1.2" - resolved "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-3.1.2.tgz" - integrity sha512-tcllLfp23dJJ+ju5wCCZHVpzsQQ43+moJbqVX3jNWPB7z/KFC4FyZD6R7y94cHL6MQ33YtMZL8Z0aIXXI4XFTw== - dependencies: - "@types/hast" "^2.0.0" - "@types/unist" "^2.0.0" - hast-util-is-element "^2.0.0" - unist-util-find-after "^4.0.0" - -hast-util-whitespace@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.1.tgz" - integrity sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng== - -hastscript@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz" - integrity sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w== - dependencies: - "@types/hast" "^2.0.0" - comma-separated-tokens "^1.0.0" - hast-util-parse-selector "^2.0.0" - property-information "^5.0.0" - space-separated-tokens "^1.0.0" - -hastscript@^7.0.0: - version "7.2.0" - resolved "https://registry.npmjs.org/hastscript/-/hastscript-7.2.0.tgz" - integrity sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw== - dependencies: - "@types/hast" "^2.0.0" - comma-separated-tokens "^2.0.0" - hast-util-parse-selector "^3.0.0" - property-information "^6.0.0" - space-separated-tokens "^2.0.0" - -hastscript@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-8.0.0.tgz#4ef795ec8dee867101b9f23cc830d4baf4fd781a" - integrity sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw== - dependencies: - "@types/hast" "^3.0.0" - comma-separated-tokens "^2.0.0" - hast-util-parse-selector "^4.0.0" - property-information "^6.0.0" - space-separated-tokens "^2.0.0" - -he@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" - integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== - -heap@^0.2.6: - version "0.2.7" - resolved "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz" - integrity sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg== - -highlight.js@^10.4.1, highlight.js@~10.7.0: - version "10.7.3" - resolved "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz" - integrity sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A== - -hmac-drbg@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" - integrity sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg== - dependencies: - hash.js "^1.0.3" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.1" - -hoist-non-react-statics@^3.3.2: - version "3.3.2" - resolved "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz" - integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== - dependencies: - react-is "^16.7.0" - -hosted-git-info@^2.1.4: - version "2.8.9" - resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz" - integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== - -html-encoding-sniffer@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz#2cb1a8cf0db52414776e5b2a7a04d5dd98158de9" - integrity sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA== - dependencies: - whatwg-encoding "^2.0.0" - -html-entities@^2.1.0: - version "2.5.2" - resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.5.2.tgz#201a3cf95d3a15be7099521620d19dfb4f65359f" - integrity sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA== - -html-escaper@^2.0.0: - version "2.0.2" - resolved "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" - integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== - -html-minifier-terser@^6.0.2: - version "6.1.0" - resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#bfc818934cc07918f6b3669f5774ecdfd48f32ab" - integrity sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw== - dependencies: - camel-case "^4.1.2" - clean-css "^5.2.2" - commander "^8.3.0" - he "^1.2.0" - param-case "^3.0.4" - relateurl "^0.2.7" - terser "^5.10.0" - -html-parse-stringify@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz" - integrity sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg== - dependencies: - void-elements "3.1.0" - -html-tags@^3.1.0: - version "3.3.1" - resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.3.1.tgz#a04026a18c882e4bba8a01a3d39cfe465d40b5ce" - integrity sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ== - -html-void-elements@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-3.0.0.tgz#fc9dbd84af9e747249034d4d62602def6517f1d7" - integrity sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg== - -html-webpack-plugin@^5.5.0: - version "5.6.0" - resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.6.0.tgz#50a8fa6709245608cb00e811eacecb8e0d7b7ea0" - integrity sha512-iwaY4wzbe48AfKLZ/Cc8k0L+FKG6oSNRaZ8x5A/T/IVDGyXcbHncM9TdDa93wn0FsSm82FhTKW7f3vS61thXAw== - dependencies: - "@types/html-minifier-terser" "^6.0.0" - html-minifier-terser "^6.0.2" - lodash "^4.17.21" - pretty-error "^4.0.0" - tapable "^2.0.0" - -htmlparser2@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7" - integrity sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A== - dependencies: - domelementtype "^2.0.1" - domhandler "^4.0.0" - domutils "^2.5.2" - entities "^2.0.0" - -htmlparser2@^8.0.1: - version "8.0.2" - resolved "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz" - integrity sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA== - dependencies: - domelementtype "^2.3.0" - domhandler "^5.0.3" - domutils "^3.0.1" - entities "^4.4.0" - -http-cache-semantics@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" - integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== - -http-errors@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" - integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== - dependencies: - depd "2.0.0" - inherits "2.0.4" - setprototypeof "1.2.0" - statuses "2.0.1" - toidentifier "1.0.1" - -http-proxy-agent@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" - integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w== - dependencies: - "@tootallnate/once" "2" - agent-base "6" - debug "4" - -http2-wrapper@^1.0.0-beta.5.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d" - integrity sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg== - dependencies: - quick-lru "^5.1.1" - resolve-alpn "^1.0.0" - -https-browserify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" - integrity sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg== - -https-proxy-agent@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" - integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== - dependencies: - agent-base "6" - debug "4" - -human-signals@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz" - integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== - -human-signals@^4.3.0: - version "4.3.1" - resolved "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz" - integrity sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ== - -husky@^8.0.3: - version "8.0.3" - resolved "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz" - integrity sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg== - -i18next-resources-to-backend@^1.1.3: - version "1.1.4" - resolved "https://registry.npmjs.org/i18next-resources-to-backend/-/i18next-resources-to-backend-1.1.4.tgz" - integrity sha512-hMyr9AOmIea17AOaVe1srNxK/l3mbk81P7Uf3fdcjlw3ehZy3UNTd0OP3EEi6yu4J02kf9jzhCcjokz6AFlEOg== - dependencies: - "@babel/runtime" "^7.21.5" - -i18next@^22.4.13: - version "22.5.1" - resolved "https://registry.npmjs.org/i18next/-/i18next-22.5.1.tgz" - integrity sha512-8TGPgM3pAD+VRsMtUMNknRz3kzqwp/gPALrWMsDnmC1mKqJwpWyooQRLMcbTwq8z8YwSmuj+ZYvc+xCuEpkssA== - dependencies: - "@babel/runtime" "^7.20.6" - -iconv-lite@0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -iconv-lite@0.6, iconv-lite@0.6.3: - version "0.6.3" - resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz" - integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== - dependencies: - safer-buffer ">= 2.1.2 < 3.0.0" - -icss-utils@^5.0.0, icss-utils@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" - integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== - -ieee754@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== - -ignore@^5.0.5, ignore@^5.1.1, ignore@^5.2.0: - version "5.2.4" - resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz" - integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== - -image-size@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/image-size/-/image-size-1.1.1.tgz#ddd67d4dc340e52ac29ce5f546a09f4e29e840ac" - integrity sha512-541xKlUw6jr/6gGuk92F+mYM5zaFAc5ahphvkqvNe2bQ6gVBkd6bfrmVJ2t4KDAfikAYZyIqTnktX3i6/aQDrQ== - dependencies: - queue "6.0.2" - -immer@^9.0.19: - version "9.0.21" - resolved "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz" - integrity sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA== - -immutable@^4.0.0: - version "4.3.0" - resolved "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz" - integrity sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg== - -import-fresh@^3.0.0, import-fresh@^3.2.1, import-fresh@^3.3.0: - version "3.3.0" - resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" - integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -import-local@^3.0.2: - version "3.1.0" - resolved "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" - integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== - dependencies: - pkg-dir "^4.2.0" - resolve-cwd "^3.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" - integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== - -indent-string@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz" - integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" - integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3, inherits@~2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -inline-style-parser@0.1.1: - version "0.1.1" - resolved "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz" - integrity sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q== - -internal-slot@^1.0.4, internal-slot@^1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz" - integrity sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ== - dependencies: - get-intrinsic "^1.2.0" - has "^1.0.3" - side-channel "^1.0.4" - -"internmap@1 - 2": - version "2.0.3" - resolved "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz" - integrity sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg== - -internmap@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz" - integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw== - -intersection-observer@^0.12.0: - version "0.12.2" - resolved "https://registry.npmjs.org/intersection-observer/-/intersection-observer-0.12.2.tgz" - integrity sha512-7m1vEcPCxXYI8HqnL8CKI6siDyD+eIWSwgB3DZA+ZTogxk9I4CDnj4wilt9x/+/QbHI4YG5YZNmC6458/e9Ktg== - -ipaddr.js@1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" - integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== - -is-absolute-url@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-4.0.1.tgz#16e4d487d4fded05cfe0685e53ec86804a5e94dc" - integrity sha512-/51/TKE88Lmm7Gc4/8btclNXWS+g50wXhYJq8HWIBAGUBnoAdRu1aXeh364t/O7wXDAcTJDP8PNuNKWUDWie+A== - -is-alphabetical@^1.0.0: - version "1.0.4" - resolved "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz" - integrity sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg== - -is-alphabetical@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz" - integrity sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ== - -is-alphanumerical@^1.0.0: - version "1.0.4" - resolved "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz" - integrity sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A== - dependencies: - is-alphabetical "^1.0.0" - is-decimal "^1.0.0" - -is-alphanumerical@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz" - integrity sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw== - dependencies: - is-alphabetical "^2.0.0" - is-decimal "^2.0.0" - -is-arguments@^1.0.4, is-arguments@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" - integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz" - integrity sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.2.0" - is-typed-array "^1.1.10" - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz" - integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== - -is-arrayish@^0.3.1: - version "0.3.2" - resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz" - integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== - -is-async-function@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz" - integrity sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA== - dependencies: - has-tostringtag "^1.0.0" - -is-bigint@^1.0.1: - version "1.0.4" - resolved "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz" - integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== - dependencies: - has-bigints "^1.0.1" - -is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - -is-boolean-object@^1.1.0: - version "1.1.2" - resolved "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz" - integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-buffer@^2.0.0: - version "2.0.5" - resolved "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz" - integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== - -is-builtin-module@^3.2.0: - version "3.2.1" - resolved "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz" - integrity sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A== - dependencies: - builtin-modules "^3.3.0" - -is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: - version "1.2.7" - resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz" - integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== - -is-core-module@^2.11.0, is-core-module@^2.13.0, is-core-module@^2.13.1: - version "2.13.1" - resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz" - integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== - dependencies: - hasown "^2.0.0" - -is-date-object@^1.0.1, is-date-object@^1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz" - integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== - dependencies: - has-tostringtag "^1.0.0" - -is-decimal@^1.0.0: - version "1.0.4" - resolved "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz" - integrity sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw== - -is-decimal@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz" - integrity sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A== - -is-docker@^2.0.0, is-docker@^2.1.1: - version "2.2.1" - resolved "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz" - integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== - -is-docker@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz" - integrity sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ== - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" - integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== - -is-finalizationregistry@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz" - integrity sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw== - dependencies: - call-bind "^1.0.2" - -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - -is-fullwidth-code-point@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz" - integrity sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ== - -is-generator-fn@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" - integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== - -is-generator-function@^1.0.10, is-generator-function@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" - integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== - dependencies: - has-tostringtag "^1.0.0" - -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: - version "4.0.3" - resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-hexadecimal@^1.0.0: - version "1.0.4" - resolved "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz" - integrity sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw== - -is-hexadecimal@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz" - integrity sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg== - -is-inside-container@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz" - integrity sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA== - dependencies: - is-docker "^3.0.0" - -is-map@^2.0.1, is-map@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz" - integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== - -is-nan@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/is-nan/-/is-nan-1.3.2.tgz#043a54adea31748b55b6cd4e09aadafa69bd9e1d" - integrity sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - -is-negative-zero@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz" - integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== - -is-number-object@^1.0.4: - version "1.0.7" - resolved "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz" - integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== - dependencies: - has-tostringtag "^1.0.0" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-path-inside@^3.0.3: - version "3.0.3" - resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz" - integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== - -is-plain-obj@^4.0.0: - version "4.1.0" - resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz" - integrity sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg== - -is-plain-object@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" - integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== - -is-potential-custom-element-name@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" - integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== - -is-reference@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/is-reference/-/is-reference-3.0.1.tgz" - integrity sha512-baJJdQLiYaJdvFbJqXrcGv3WU3QCzBlUcI5QhbesIm6/xPsvmO+2CDoi/GMOFBQEQm+PXkwOPrp9KK5ozZsp2w== - dependencies: - "@types/estree" "*" - -is-regex@^1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz" - integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-set@^2.0.1, is-set@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz" - integrity sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g== - -is-shared-array-buffer@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz" - integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== - dependencies: - call-bind "^1.0.2" - -is-stream@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz" - integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== - -is-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz" - integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== - -is-string@^1.0.5, is-string@^1.0.7: - version "1.0.7" - resolved "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz" - integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== - dependencies: - has-tostringtag "^1.0.0" - -is-symbol@^1.0.2, is-symbol@^1.0.3: - version "1.0.4" - resolved "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz" - integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== - dependencies: - has-symbols "^1.0.2" - -is-typed-array@^1.1.10, is-typed-array@^1.1.12, is-typed-array@^1.1.9: - version "1.1.12" - resolved "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz" - integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== - dependencies: - which-typed-array "^1.1.11" - -is-typed-array@^1.1.3: - version "1.1.13" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.13.tgz#d6c5ca56df62334959322d7d7dd1cca50debe229" - integrity sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw== - dependencies: - which-typed-array "^1.1.14" - -is-weakmap@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz" - integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA== - -is-weakref@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz" - integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== - dependencies: - call-bind "^1.0.2" - -is-weakset@^2.0.1: - version "2.0.2" - resolved "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz" - integrity sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.1" - -is-wsl@^2.2.0: - version "2.2.0" - resolved "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz" - integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== - dependencies: - is-docker "^2.0.0" - -isarray@^2.0.5: - version "2.0.5" - resolved "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz" - integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== - -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" - integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== - -istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: - version "3.2.2" - resolved "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz#2d166c4b0644d43a39f04bf6c2edd1e585f31756" - integrity sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg== - -istanbul-lib-instrument@^5.0.4: - version "5.2.1" - resolved "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d" - integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== - dependencies: - "@babel/core" "^7.12.3" - "@babel/parser" "^7.14.7" - "@istanbuljs/schema" "^0.1.2" - istanbul-lib-coverage "^3.2.0" - semver "^6.3.0" - -istanbul-lib-instrument@^6.0.0: - version "6.0.3" - resolved "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz#fa15401df6c15874bcb2105f773325d78c666765" - integrity sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q== - dependencies: - "@babel/core" "^7.23.9" - "@babel/parser" "^7.23.9" - "@istanbuljs/schema" "^0.1.3" - istanbul-lib-coverage "^3.2.0" - semver "^7.5.4" - -istanbul-lib-report@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz#908305bac9a5bd175ac6a74489eafd0fc2445a7d" - integrity sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw== - dependencies: - istanbul-lib-coverage "^3.0.0" - make-dir "^4.0.0" - supports-color "^7.1.0" - -istanbul-lib-source-maps@^4.0.0: - version "4.0.1" - resolved "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" - integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== - dependencies: - debug "^4.1.1" - istanbul-lib-coverage "^3.0.0" - source-map "^0.6.1" - -istanbul-reports@^3.1.3: - version "3.1.7" - resolved "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz#daed12b9e1dca518e15c056e1e537e741280fa0b" - integrity sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g== - dependencies: - html-escaper "^2.0.0" - istanbul-lib-report "^3.0.0" - -iterator.prototype@^1.1.2: - version "1.1.2" - resolved "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz" - integrity sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w== - dependencies: - define-properties "^1.2.1" - get-intrinsic "^1.2.1" - has-symbols "^1.0.3" - reflect.getprototypeof "^1.0.4" - set-function-name "^2.0.1" - -jackspeak@^2.3.5: - version "2.3.6" - resolved "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz" - integrity sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ== - dependencies: - "@isaacs/cliui" "^8.0.2" - optionalDependencies: - "@pkgjs/parseargs" "^0.11.0" - -jest-changed-files@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz#1c06d07e77c78e1585d020424dedc10d6e17ac3a" - integrity sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w== - dependencies: - execa "^5.0.0" - jest-util "^29.7.0" - p-limit "^3.1.0" - -jest-circus@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz#b6817a45fcc835d8b16d5962d0c026473ee3668a" - integrity sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw== - dependencies: - "@jest/environment" "^29.7.0" - "@jest/expect" "^29.7.0" - "@jest/test-result" "^29.7.0" - "@jest/types" "^29.6.3" - "@types/node" "*" - chalk "^4.0.0" - co "^4.6.0" - dedent "^1.0.0" - is-generator-fn "^2.0.0" - jest-each "^29.7.0" - jest-matcher-utils "^29.7.0" - jest-message-util "^29.7.0" - jest-runtime "^29.7.0" - jest-snapshot "^29.7.0" - jest-util "^29.7.0" - p-limit "^3.1.0" - pretty-format "^29.7.0" - pure-rand "^6.0.0" - slash "^3.0.0" - stack-utils "^2.0.3" - -jest-cli@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz#5592c940798e0cae677eec169264f2d839a37995" - integrity sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg== - dependencies: - "@jest/core" "^29.7.0" - "@jest/test-result" "^29.7.0" - "@jest/types" "^29.6.3" - chalk "^4.0.0" - create-jest "^29.7.0" - exit "^0.1.2" - import-local "^3.0.2" - jest-config "^29.7.0" - jest-util "^29.7.0" - jest-validate "^29.7.0" - yargs "^17.3.1" - -jest-config@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz#bcbda8806dbcc01b1e316a46bb74085a84b0245f" - integrity sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ== - dependencies: - "@babel/core" "^7.11.6" - "@jest/test-sequencer" "^29.7.0" - "@jest/types" "^29.6.3" - babel-jest "^29.7.0" - chalk "^4.0.0" - ci-info "^3.2.0" - deepmerge "^4.2.2" - glob "^7.1.3" - graceful-fs "^4.2.9" - jest-circus "^29.7.0" - jest-environment-node "^29.7.0" - jest-get-type "^29.6.3" - jest-regex-util "^29.6.3" - jest-resolve "^29.7.0" - jest-runner "^29.7.0" - jest-util "^29.7.0" - jest-validate "^29.7.0" - micromatch "^4.0.4" - parse-json "^5.2.0" - pretty-format "^29.7.0" - slash "^3.0.0" - strip-json-comments "^3.1.1" - -jest-diff@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz#017934a66ebb7ecf6f205e84699be10afd70458a" - integrity sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw== - dependencies: - chalk "^4.0.0" - diff-sequences "^29.6.3" - jest-get-type "^29.6.3" - pretty-format "^29.7.0" - -jest-docblock@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz#8fddb6adc3cdc955c93e2a87f61cfd350d5d119a" - integrity sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g== - dependencies: - detect-newline "^3.0.0" - -jest-each@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz#162a9b3f2328bdd991beaabffbb74745e56577d1" - integrity sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ== - dependencies: - "@jest/types" "^29.6.3" - chalk "^4.0.0" - jest-get-type "^29.6.3" - jest-util "^29.7.0" - pretty-format "^29.7.0" - -jest-environment-jsdom@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-29.7.0.tgz#d206fa3551933c3fd519e5dfdb58a0f5139a837f" - integrity sha512-k9iQbsf9OyOfdzWH8HDmrRT0gSIcX+FLNW7IQq94tFX0gynPwqDTW0Ho6iMVNjGz/nb+l/vW3dWM2bbLLpkbXA== - dependencies: - "@jest/environment" "^29.7.0" - "@jest/fake-timers" "^29.7.0" - "@jest/types" "^29.6.3" - "@types/jsdom" "^20.0.0" - "@types/node" "*" - jest-mock "^29.7.0" - jest-util "^29.7.0" - jsdom "^20.0.0" - -jest-environment-node@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz#0b93e111dda8ec120bc8300e6d1fb9576e164376" - integrity sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw== - dependencies: - "@jest/environment" "^29.7.0" - "@jest/fake-timers" "^29.7.0" - "@jest/types" "^29.6.3" - "@types/node" "*" - jest-mock "^29.7.0" - jest-util "^29.7.0" - -jest-get-type@^29.6.3: - version "29.6.3" - resolved "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz#36f499fdcea197c1045a127319c0481723908fd1" - integrity sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw== - -jest-haste-map@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz#3c2396524482f5a0506376e6c858c3bbcc17b104" - integrity sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA== - dependencies: - "@jest/types" "^29.6.3" - "@types/graceful-fs" "^4.1.3" - "@types/node" "*" - anymatch "^3.0.3" - fb-watchman "^2.0.0" - graceful-fs "^4.2.9" - jest-regex-util "^29.6.3" - jest-util "^29.7.0" - jest-worker "^29.7.0" - micromatch "^4.0.4" - walker "^1.0.8" - optionalDependencies: - fsevents "^2.3.2" - -jest-leak-detector@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz#5b7ec0dadfdfec0ca383dc9aa016d36b5ea4c728" - integrity sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw== - dependencies: - jest-get-type "^29.6.3" - pretty-format "^29.7.0" - -jest-matcher-utils@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz#ae8fec79ff249fd592ce80e3ee474e83a6c44f12" - integrity sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g== - dependencies: - chalk "^4.0.0" - jest-diff "^29.7.0" - jest-get-type "^29.6.3" - pretty-format "^29.7.0" - -jest-message-util@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz#8bc392e204e95dfe7564abbe72a404e28e51f7f3" - integrity sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w== - dependencies: - "@babel/code-frame" "^7.12.13" - "@jest/types" "^29.6.3" - "@types/stack-utils" "^2.0.0" - chalk "^4.0.0" - graceful-fs "^4.2.9" - micromatch "^4.0.4" - pretty-format "^29.7.0" - slash "^3.0.0" - stack-utils "^2.0.3" - -jest-mock@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz#4e836cf60e99c6fcfabe9f99d017f3fdd50a6347" - integrity sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw== - dependencies: - "@jest/types" "^29.6.3" - "@types/node" "*" - jest-util "^29.7.0" - -jest-pnp-resolver@^1.2.2: - version "1.2.3" - resolved "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz#930b1546164d4ad5937d5540e711d4d38d4cad2e" - integrity sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w== - -jest-regex-util@^29.6.3: - version "29.6.3" - resolved "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz#4a556d9c776af68e1c5f48194f4d0327d24e8a52" - integrity sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg== - -jest-resolve-dependencies@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz#1b04f2c095f37fc776ff40803dc92921b1e88428" - integrity sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA== - dependencies: - jest-regex-util "^29.6.3" - jest-snapshot "^29.7.0" - -jest-resolve@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz#64d6a8992dd26f635ab0c01e5eef4399c6bcbc30" - integrity sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA== - dependencies: - chalk "^4.0.0" - graceful-fs "^4.2.9" - jest-haste-map "^29.7.0" - jest-pnp-resolver "^1.2.2" - jest-util "^29.7.0" - jest-validate "^29.7.0" - resolve "^1.20.0" - resolve.exports "^2.0.0" - slash "^3.0.0" - -jest-runner@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz#809af072d408a53dcfd2e849a4c976d3132f718e" - integrity sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ== - dependencies: - "@jest/console" "^29.7.0" - "@jest/environment" "^29.7.0" - "@jest/test-result" "^29.7.0" - "@jest/transform" "^29.7.0" - "@jest/types" "^29.6.3" - "@types/node" "*" - chalk "^4.0.0" - emittery "^0.13.1" - graceful-fs "^4.2.9" - jest-docblock "^29.7.0" - jest-environment-node "^29.7.0" - jest-haste-map "^29.7.0" - jest-leak-detector "^29.7.0" - jest-message-util "^29.7.0" - jest-resolve "^29.7.0" - jest-runtime "^29.7.0" - jest-util "^29.7.0" - jest-watcher "^29.7.0" - jest-worker "^29.7.0" - p-limit "^3.1.0" - source-map-support "0.5.13" - -jest-runtime@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz#efecb3141cf7d3767a3a0cc8f7c9990587d3d817" - integrity sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ== - dependencies: - "@jest/environment" "^29.7.0" - "@jest/fake-timers" "^29.7.0" - "@jest/globals" "^29.7.0" - "@jest/source-map" "^29.6.3" - "@jest/test-result" "^29.7.0" - "@jest/transform" "^29.7.0" - "@jest/types" "^29.6.3" - "@types/node" "*" - chalk "^4.0.0" - cjs-module-lexer "^1.0.0" - collect-v8-coverage "^1.0.0" - glob "^7.1.3" - graceful-fs "^4.2.9" - jest-haste-map "^29.7.0" - jest-message-util "^29.7.0" - jest-mock "^29.7.0" - jest-regex-util "^29.6.3" - jest-resolve "^29.7.0" - jest-snapshot "^29.7.0" - jest-util "^29.7.0" - slash "^3.0.0" - strip-bom "^4.0.0" - -jest-snapshot@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz#c2c574c3f51865da1bb329036778a69bf88a6be5" - integrity sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw== - dependencies: - "@babel/core" "^7.11.6" - "@babel/generator" "^7.7.2" - "@babel/plugin-syntax-jsx" "^7.7.2" - "@babel/plugin-syntax-typescript" "^7.7.2" - "@babel/types" "^7.3.3" - "@jest/expect-utils" "^29.7.0" - "@jest/transform" "^29.7.0" - "@jest/types" "^29.6.3" - babel-preset-current-node-syntax "^1.0.0" - chalk "^4.0.0" - expect "^29.7.0" - graceful-fs "^4.2.9" - jest-diff "^29.7.0" - jest-get-type "^29.6.3" - jest-matcher-utils "^29.7.0" - jest-message-util "^29.7.0" - jest-util "^29.7.0" - natural-compare "^1.4.0" - pretty-format "^29.7.0" - semver "^7.5.3" - -jest-util@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz#23c2b62bfb22be82b44de98055802ff3710fc0bc" - integrity sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA== - dependencies: - "@jest/types" "^29.6.3" - "@types/node" "*" - chalk "^4.0.0" - ci-info "^3.2.0" - graceful-fs "^4.2.9" - picomatch "^2.2.3" - -jest-validate@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz#7bf705511c64da591d46b15fce41400d52147d9c" - integrity sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw== - dependencies: - "@jest/types" "^29.6.3" - camelcase "^6.2.0" - chalk "^4.0.0" - jest-get-type "^29.6.3" - leven "^3.1.0" - pretty-format "^29.7.0" - -jest-watcher@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz#7810d30d619c3a62093223ce6bb359ca1b28a2f2" - integrity sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g== - dependencies: - "@jest/test-result" "^29.7.0" - "@jest/types" "^29.6.3" - "@types/node" "*" - ansi-escapes "^4.2.1" - chalk "^4.0.0" - emittery "^0.13.1" - jest-util "^29.7.0" - string-length "^4.0.1" - -jest-worker@^27.4.5: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" - integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== - dependencies: - "@types/node" "*" - merge-stream "^2.0.0" - supports-color "^8.0.0" - -jest-worker@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz#acad073acbbaeb7262bd5389e1bcf43e10058d4a" - integrity sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw== - dependencies: - "@types/node" "*" - jest-util "^29.7.0" - merge-stream "^2.0.0" - supports-color "^8.0.0" - -jest@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz#994676fc24177f088f1c5e3737f5697204ff2613" - integrity sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw== - dependencies: - "@jest/core" "^29.7.0" - "@jest/types" "^29.6.3" - import-local "^3.0.2" - jest-cli "^29.7.0" - -jiti@^1.20.0, jiti@^1.21.0: - version "1.21.6" - resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.6.tgz#6c7f7398dd4b3142767f9a168af2f317a428d268" - integrity sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w== - -js-audio-recorder@^1.0.7: - version "1.0.7" - resolved "https://registry.npmjs.org/js-audio-recorder/-/js-audio-recorder-1.0.7.tgz" - integrity sha512-JiDODCElVHGrFyjGYwYyNi7zCbKk9va9C77w+zCPMmi4C6ix7zsX2h3ddHugmo4dOTOTCym9++b/wVW9nC0IaA== - -js-cookie@^2.x.x: - version "2.2.1" - resolved "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz" - integrity sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ== - -js-cookie@^3.0.1: - version "3.0.5" - resolved "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz" - integrity sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw== - -js-sdsl@^4.1.4: - version "4.4.0" - resolved "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz" - integrity sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg== - -"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-yaml@^3.13.1: - version "3.14.1" - resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" - integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -js-yaml@^4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - -jsdoc-type-pratt-parser@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.1.0.tgz#ff6b4a3f339c34a6c188cbf50a16087858d22113" - integrity sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg== - -jsdom@^20.0.0: - version "20.0.3" - resolved "https://registry.npmjs.org/jsdom/-/jsdom-20.0.3.tgz#886a41ba1d4726f67a8858028c99489fed6ad4db" - integrity sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ== - dependencies: - abab "^2.0.6" - acorn "^8.8.1" - acorn-globals "^7.0.0" - cssom "^0.5.0" - cssstyle "^2.3.0" - data-urls "^3.0.2" - decimal.js "^10.4.2" - domexception "^4.0.0" - escodegen "^2.0.0" - form-data "^4.0.0" - html-encoding-sniffer "^3.0.0" - http-proxy-agent "^5.0.0" - https-proxy-agent "^5.0.1" - is-potential-custom-element-name "^1.0.1" - nwsapi "^2.2.2" - parse5 "^7.1.1" - saxes "^6.0.0" - symbol-tree "^3.2.4" - tough-cookie "^4.1.2" - w3c-xmlserializer "^4.0.0" - webidl-conversions "^7.0.0" - whatwg-encoding "^2.0.0" - whatwg-mimetype "^3.0.0" - whatwg-url "^11.0.0" - ws "^8.11.0" - xml-name-validator "^4.0.0" - -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== - -jsesc@^3.0.2, jsesc@~3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz" - integrity sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g== - -jsesc@~0.5.0: - version "0.5.0" - resolved "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz" - integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== - -json-buffer@3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" - integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== - -json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1: - version "2.3.1" - resolved "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz" - integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-schema-traverse@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" - integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" - integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== - -json5@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz" - integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== - dependencies: - minimist "^1.2.0" - -json5@^2.1.2, json5@^2.2.2, json5@^2.2.3: - version "2.2.3" - resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" - integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== - -jsonc-eslint-parser@^2.0.4, jsonc-eslint-parser@^2.1.0: - version "2.3.0" - resolved "https://registry.npmjs.org/jsonc-eslint-parser/-/jsonc-eslint-parser-2.3.0.tgz" - integrity sha512-9xZPKVYp9DxnM3sd1yAsh/d59iIaswDkai8oTxbursfKYbg/ibjX0IzFt35+VZ8iEW453TVTXztnRvYUQlAfUQ== - dependencies: - acorn "^8.5.0" - eslint-visitor-keys "^3.0.0" - espree "^9.0.0" - semver "^7.3.5" - -jsonfile@^6.0.1, jsonfile@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" - integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== - dependencies: - universalify "^2.0.0" - optionalDependencies: - graceful-fs "^4.1.6" - -"jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.3: - version "3.3.3" - resolved "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz" - integrity sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw== - dependencies: - array-includes "^3.1.5" - object.assign "^4.1.3" - -jwt-decode@^4.0.0: - version "4.0.0" - resolved "https://registry.npmmirror.com/jwt-decode/-/jwt-decode-4.0.0.tgz#2270352425fd413785b2faf11f6e755c5151bd4b" - integrity sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA== - -katex@^0.16.0, katex@^0.16.10: - version "0.16.10" - resolved "https://registry.npmjs.org/katex/-/katex-0.16.10.tgz" - integrity sha512-ZiqaC04tp2O5utMsl2TEZTXxa6WSC4yo0fv5ML++D3QZv/vx2Mct0mTlRx3O+uUkjfuAgOkzsCmq5MiUEsDDdA== - dependencies: - commander "^8.3.0" - -keyv@^4.0.0: - version "4.5.4" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" - integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== - dependencies: - json-buffer "3.0.1" - -khroma@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/khroma/-/khroma-2.0.0.tgz" - integrity sha512-2J8rDNlQWbtiNYThZRvmMv5yt44ZakX+Tz5ZIp/mN1pt4snn+m030Va5Z4v8xA0cQFDXBwO/8i42xL4QPsVk3g== - -kleur@^3.0.3: - version "3.0.3" - resolved "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" - integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== - -kleur@^4.0.3: - version "4.1.5" - resolved "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz" - integrity sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ== - -lamejs@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/lamejs/-/lamejs-1.2.1.tgz" - integrity sha512-s7bxvjvYthw6oPLCm5pFxvA84wUROODB8jEO2+CE1adhKgrIvVOlmMgY8zyugxGrvRaDHNJanOiS21/emty6dQ== - dependencies: - use-strict "1.0.1" - -language-subtag-registry@~0.3.2: - version "0.3.22" - resolved "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz" - integrity sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w== - -language-tags@=1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz" - integrity sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ== - dependencies: - language-subtag-registry "~0.3.2" - -layout-base@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/layout-base/-/layout-base-1.0.2.tgz" - integrity sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg== - -layout-base@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/layout-base/-/layout-base-2.0.1.tgz" - integrity sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg== - -leven@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" - integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== - -levn@^0.4.1: - version "0.4.1" - resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz" - integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== - dependencies: - prelude-ls "^1.2.1" - type-check "~0.4.0" - -lexical@0.16.0, lexical@^0.16.0: - version "0.16.0" - resolved "https://registry.npmjs.org/lexical/-/lexical-0.16.0.tgz" - integrity sha512-Skn45Qhriazq4fpAtwnAB11U//GKc4vjzx54xsV3TkDLDvWpbL4Z9TNRwRoN3g7w8AkWnqjeOSODKkrjgfRSrg== - -lilconfig@2.1.0, lilconfig@^2.0.5, lilconfig@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz" - integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ== - -lines-and-columns@^1.1.6: - version "1.2.4" - resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz" - integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== - -lint-staged@^13.2.2: - version "13.2.2" - resolved "https://registry.npmjs.org/lint-staged/-/lint-staged-13.2.2.tgz" - integrity sha512-71gSwXKy649VrSU09s10uAT0rWCcY3aewhMaHyl2N84oBk4Xs9HgxvUp3AYu+bNsK4NrOYYxvSgg7FyGJ+jGcA== - dependencies: - chalk "5.2.0" - cli-truncate "^3.1.0" - commander "^10.0.0" - debug "^4.3.4" - execa "^7.0.0" - lilconfig "2.1.0" - listr2 "^5.0.7" - micromatch "^4.0.5" - normalize-path "^3.0.0" - object-inspect "^1.12.3" - pidtree "^0.6.0" - string-argv "^0.3.1" - yaml "^2.2.2" - -listr2@^5.0.7: - version "5.0.8" - resolved "https://registry.npmjs.org/listr2/-/listr2-5.0.8.tgz" - integrity sha512-mC73LitKHj9w6v30nLNGPetZIlfpUniNSsxxrbaPcWOjDb92SHPzJPi/t+v1YC/lxKz/AJ9egOjww0qUuFxBpA== - dependencies: - cli-truncate "^2.1.0" - colorette "^2.0.19" - log-update "^4.0.0" - p-map "^4.0.0" - rfdc "^1.3.0" - rxjs "^7.8.0" - through "^2.3.8" - wrap-ansi "^7.0.0" - -loader-runner@^4.2.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" - integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== - -loader-utils@^2.0.0, loader-utils@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c" - integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw== - dependencies: - big.js "^5.2.2" - emojis-list "^3.0.0" - json5 "^2.1.2" - -loader-utils@^3.2.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-3.3.1.tgz#735b9a19fd63648ca7adbd31c2327dfe281304e5" - integrity sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg== - -local-pkg@^0.4.3: - version "0.4.3" - resolved "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.3.tgz" - integrity sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g== - -locate-path@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz" - integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== - dependencies: - p-locate "^4.1.0" - -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - -locate-path@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-7.2.0.tgz#69cb1779bd90b35ab1e771e1f2f89a202c2a8a8a" - integrity sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA== - dependencies: - p-locate "^6.0.0" - -lodash-es@^4.17.21: - version "4.17.21" - resolved "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz" - integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw== - -lodash.castarray@^4.4.0: - version "4.4.0" - resolved "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz" - integrity sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q== - -lodash.debounce@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" - integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== - -lodash.isplainobject@^4.0.6: - version "4.0.6" - resolved "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz" - integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA== - -lodash.merge@^4.6.2: - version "4.6.2" - resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" - integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== - -lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21: - version "4.17.21" - resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - -log-update@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz" - integrity sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg== - dependencies: - ansi-escapes "^4.3.0" - cli-cursor "^3.1.0" - slice-ansi "^4.0.0" - wrap-ansi "^6.2.0" - -longest-streak@^3.0.0: - version "3.1.0" - resolved "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz" - integrity sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g== - -loose-envify@^1.1.0, loose-envify@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - -loupe@^3.1.0, loupe@^3.1.1: - version "3.1.2" - resolved "https://registry.yarnpkg.com/loupe/-/loupe-3.1.2.tgz#c86e0696804a02218f2206124c45d8b15291a240" - integrity sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg== - -lower-case@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" - integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg== - dependencies: - tslib "^2.0.3" - -lowercase-keys@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" - integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== - -lowlight@^1.17.0: - version "1.20.0" - resolved "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz" - integrity sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw== - dependencies: - fault "^1.0.0" - highlight.js "~10.7.0" - -lru-cache@^5.1.1: - version "5.1.1" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" - integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== - dependencies: - yallist "^3.0.2" - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -"lru-cache@^9.1.1 || ^10.0.0": - version "10.2.0" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz" - integrity sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q== - -lz-string@^1.5.0: - version "1.5.0" - resolved "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz#c1ab50f77887b712621201ba9fd4e3a6ed099941" - integrity sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ== - -magic-string@^0.30.5: - version "0.30.12" - resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.12.tgz#9eb11c9d072b9bcb4940a5b2c2e1a217e4ee1a60" - integrity sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw== - dependencies: - "@jridgewell/sourcemap-codec" "^1.5.0" - -magicast@^0.3.4: - version "0.3.5" - resolved "https://registry.yarnpkg.com/magicast/-/magicast-0.3.5.tgz#8301c3c7d66704a0771eb1bad74274f0ec036739" - integrity sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ== - dependencies: - "@babel/parser" "^7.25.4" - "@babel/types" "^7.25.4" - source-map-js "^1.2.0" - -make-dir@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" - integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== - dependencies: - semver "^6.0.0" - -make-dir@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz#c3c2307a771277cd9638305f915c29ae741b614e" - integrity sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw== - dependencies: - semver "^7.5.3" - -make-error@^1.1.1: - version "1.3.6" - resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" - integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== - -makeerror@1.0.12: - version "1.0.12" - resolved "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" - integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== - dependencies: - tmpl "1.0.5" - -map-or-similar@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/map-or-similar/-/map-or-similar-1.5.0.tgz#6de2653174adfb5d9edc33c69d3e92a1b76faf08" - integrity sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg== - -markdown-extensions@^1.0.0: - version "1.1.1" - resolved "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-1.1.1.tgz" - integrity sha512-WWC0ZuMzCyDHYCasEGs4IPvLyTGftYwh6wIEOULOF0HXcqZlhwRzrK0w2VUlxWA98xnvb/jszw4ZSkJ6ADpM6Q== - -markdown-table@^3.0.0: - version "3.0.3" - resolved "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz" - integrity sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw== - -markdown-to-jsx@^7.4.5: - version "7.5.0" - resolved "https://registry.yarnpkg.com/markdown-to-jsx/-/markdown-to-jsx-7.5.0.tgz#42ece0c71e842560a7d8bd9f81e7a34515c72150" - integrity sha512-RrBNcMHiFPcz/iqIj0n3wclzHXjwS7mzjBNWecKKVhNTIxQepIix6Il/wZCn2Cg5Y1ow2Qi84+eJrryFRWBEWw== - -md5.js@^1.3.4: - version "1.3.5" - resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" - integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - -mdast-util-definitions@^5.0.0: - version "5.1.2" - resolved "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-5.1.2.tgz" - integrity sha512-8SVPMuHqlPME/z3gqVwWY4zVXn8lqKv/pAhC57FuJ40ImXyBpmO5ukh98zB2v7Blql2FiHjHv9LVztSIqjY+MA== - dependencies: - "@types/mdast" "^3.0.0" - "@types/unist" "^2.0.0" - unist-util-visit "^4.0.0" - -mdast-util-find-and-replace@^2.0.0: - version "2.2.2" - resolved "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-2.2.2.tgz" - integrity sha512-MTtdFRz/eMDHXzeK6W3dO7mXUlF82Gom4y0oOgvHhh/HXZAGvIQDUvQ0SuUx+j2tv44b8xTHOm8K/9OoRFnXKw== - dependencies: - "@types/mdast" "^3.0.0" - escape-string-regexp "^5.0.0" - unist-util-is "^5.0.0" - unist-util-visit-parents "^5.0.0" - -mdast-util-from-markdown@^0.8.5: - version "0.8.5" - resolved "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz" - integrity sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ== - dependencies: - "@types/mdast" "^3.0.0" - mdast-util-to-string "^2.0.0" - micromark "~2.11.0" - parse-entities "^2.0.0" - unist-util-stringify-position "^2.0.0" - -mdast-util-from-markdown@^1.0.0, mdast-util-from-markdown@^1.1.0, mdast-util-from-markdown@^1.3.0: - version "1.3.1" - resolved "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz" - integrity sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww== - dependencies: - "@types/mdast" "^3.0.0" - "@types/unist" "^2.0.0" - decode-named-character-reference "^1.0.0" - mdast-util-to-string "^3.1.0" - micromark "^3.0.0" - micromark-util-decode-numeric-character-reference "^1.0.0" - micromark-util-decode-string "^1.0.0" - micromark-util-normalize-identifier "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - unist-util-stringify-position "^3.0.0" - uvu "^0.5.0" - -mdast-util-gfm-autolink-literal@^1.0.0: - version "1.0.3" - resolved "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-1.0.3.tgz" - integrity sha512-My8KJ57FYEy2W2LyNom4n3E7hKTuQk/0SES0u16tjA9Z3oFkF4RrC/hPAPgjlSpezsOvI8ObcXcElo92wn5IGA== - dependencies: - "@types/mdast" "^3.0.0" - ccount "^2.0.0" - mdast-util-find-and-replace "^2.0.0" - micromark-util-character "^1.0.0" - -mdast-util-gfm-footnote@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-1.0.2.tgz" - integrity sha512-56D19KOGbE00uKVj3sgIykpwKL179QsVFwx/DCW0u/0+URsryacI4MAdNJl0dh+u2PSsD9FtxPFbHCzJ78qJFQ== - dependencies: - "@types/mdast" "^3.0.0" - mdast-util-to-markdown "^1.3.0" - micromark-util-normalize-identifier "^1.0.0" - -mdast-util-gfm-strikethrough@^1.0.0: - version "1.0.3" - resolved "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-1.0.3.tgz" - integrity sha512-DAPhYzTYrRcXdMjUtUjKvW9z/FNAMTdU0ORyMcbmkwYNbKocDpdk+PX1L1dQgOID/+vVs1uBQ7ElrBQfZ0cuiQ== - dependencies: - "@types/mdast" "^3.0.0" - mdast-util-to-markdown "^1.3.0" - -mdast-util-gfm-table@^1.0.0: - version "1.0.7" - resolved "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-1.0.7.tgz" - integrity sha512-jjcpmNnQvrmN5Vx7y7lEc2iIOEytYv7rTvu+MeyAsSHTASGCCRA79Igg2uKssgOs1i1po8s3plW0sTu1wkkLGg== - dependencies: - "@types/mdast" "^3.0.0" - markdown-table "^3.0.0" - mdast-util-from-markdown "^1.0.0" - mdast-util-to-markdown "^1.3.0" - -mdast-util-gfm-task-list-item@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-1.0.2.tgz" - integrity sha512-PFTA1gzfp1B1UaiJVyhJZA1rm0+Tzn690frc/L8vNX1Jop4STZgOE6bxUhnzdVSB+vm2GU1tIsuQcA9bxTQpMQ== - dependencies: - "@types/mdast" "^3.0.0" - mdast-util-to-markdown "^1.3.0" - -mdast-util-gfm@^2.0.0: - version "2.0.2" - resolved "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-2.0.2.tgz" - integrity sha512-qvZ608nBppZ4icQlhQQIAdc6S3Ffj9RGmzwUKUWuEICFnd1LVkN3EktF7ZHAgfcEdvZB5owU9tQgt99e2TlLjg== - dependencies: - mdast-util-from-markdown "^1.0.0" - mdast-util-gfm-autolink-literal "^1.0.0" - mdast-util-gfm-footnote "^1.0.0" - mdast-util-gfm-strikethrough "^1.0.0" - mdast-util-gfm-table "^1.0.0" - mdast-util-gfm-task-list-item "^1.0.0" - mdast-util-to-markdown "^1.0.0" - -mdast-util-math@^2.0.0: - version "2.0.2" - resolved "https://registry.npmjs.org/mdast-util-math/-/mdast-util-math-2.0.2.tgz" - integrity sha512-8gmkKVp9v6+Tgjtq6SYx9kGPpTf6FVYRa53/DLh479aldR9AyP48qeVOgNZ5X7QUK7nOy4yw7vg6mbiGcs9jWQ== - dependencies: - "@types/mdast" "^3.0.0" - longest-streak "^3.0.0" - mdast-util-to-markdown "^1.3.0" - -mdast-util-mdx-expression@^1.0.0: - version "1.3.2" - resolved "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-1.3.2.tgz" - integrity sha512-xIPmR5ReJDu/DHH1OoIT1HkuybIfRGYRywC+gJtI7qHjCJp/M9jrmBEJW22O8lskDWm562BX2W8TiAwRTb0rKA== - dependencies: - "@types/estree-jsx" "^1.0.0" - "@types/hast" "^2.0.0" - "@types/mdast" "^3.0.0" - mdast-util-from-markdown "^1.0.0" - mdast-util-to-markdown "^1.0.0" - -mdast-util-mdx-jsx@^2.0.0: - version "2.1.4" - resolved "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-2.1.4.tgz" - integrity sha512-DtMn9CmVhVzZx3f+optVDF8yFgQVt7FghCRNdlIaS3X5Bnym3hZwPbg/XW86vdpKjlc1PVj26SpnLGeJBXD3JA== - dependencies: - "@types/estree-jsx" "^1.0.0" - "@types/hast" "^2.0.0" - "@types/mdast" "^3.0.0" - "@types/unist" "^2.0.0" - ccount "^2.0.0" - mdast-util-from-markdown "^1.1.0" - mdast-util-to-markdown "^1.3.0" - parse-entities "^4.0.0" - stringify-entities "^4.0.0" - unist-util-remove-position "^4.0.0" - unist-util-stringify-position "^3.0.0" - vfile-message "^3.0.0" - -mdast-util-mdx@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-2.0.1.tgz" - integrity sha512-38w5y+r8nyKlGvNjSEqWrhG0w5PmnRA+wnBvm+ulYCct7nsGYhFVb0lljS9bQav4psDAS1eGkP2LMVcZBi/aqw== - dependencies: - mdast-util-from-markdown "^1.0.0" - mdast-util-mdx-expression "^1.0.0" - mdast-util-mdx-jsx "^2.0.0" - mdast-util-mdxjs-esm "^1.0.0" - mdast-util-to-markdown "^1.0.0" - -mdast-util-mdxjs-esm@^1.0.0: - version "1.3.1" - resolved "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-1.3.1.tgz" - integrity sha512-SXqglS0HrEvSdUEfoXFtcg7DRl7S2cwOXc7jkuusG472Mmjag34DUDeOJUZtl+BVnyeO1frIgVpHlNRWc2gk/w== - dependencies: - "@types/estree-jsx" "^1.0.0" - "@types/hast" "^2.0.0" - "@types/mdast" "^3.0.0" - mdast-util-from-markdown "^1.0.0" - mdast-util-to-markdown "^1.0.0" - -mdast-util-newline-to-break@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/mdast-util-newline-to-break/-/mdast-util-newline-to-break-1.0.0.tgz" - integrity sha512-491LcYv3gbGhhCrLoeALncQmega2xPh+m3gbsIhVsOX4sw85+ShLFPvPyibxc1Swx/6GtzxgVodq+cGa/47ULg== - dependencies: - "@types/mdast" "^3.0.0" - mdast-util-find-and-replace "^2.0.0" - -mdast-util-phrasing@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-3.0.1.tgz" - integrity sha512-WmI1gTXUBJo4/ZmSk79Wcb2HcjPJBzM1nlI/OUWA8yk2X9ik3ffNbBGsU+09BFmXaL1IBb9fiuvq6/KMiNycSg== - dependencies: - "@types/mdast" "^3.0.0" - unist-util-is "^5.0.0" - -mdast-util-to-hast@^12.1.0: - version "12.3.0" - resolved "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-12.3.0.tgz" - integrity sha512-pits93r8PhnIoU4Vy9bjW39M2jJ6/tdHyja9rrot9uujkN7UTU9SDnE6WNJz/IGyQk3XHX6yNNtrBH6cQzm8Hw== - dependencies: - "@types/hast" "^2.0.0" - "@types/mdast" "^3.0.0" - mdast-util-definitions "^5.0.0" - micromark-util-sanitize-uri "^1.1.0" - trim-lines "^3.0.0" - unist-util-generated "^2.0.0" - unist-util-position "^4.0.0" - unist-util-visit "^4.0.0" - -mdast-util-to-hast@^13.0.0: - version "13.2.0" - resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz#5ca58e5b921cc0a3ded1bc02eed79a4fe4fe41f4" - integrity sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA== - dependencies: - "@types/hast" "^3.0.0" - "@types/mdast" "^4.0.0" - "@ungap/structured-clone" "^1.0.0" - devlop "^1.0.0" - micromark-util-sanitize-uri "^2.0.0" - trim-lines "^3.0.0" - unist-util-position "^5.0.0" - unist-util-visit "^5.0.0" - vfile "^6.0.0" - -mdast-util-to-markdown@^1.0.0, mdast-util-to-markdown@^1.3.0: - version "1.5.0" - resolved "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.5.0.tgz" - integrity sha512-bbv7TPv/WC49thZPg3jXuqzuvI45IL2EVAr/KxF0BSdHsU0ceFHOmwQn6evxAh1GaoK/6GQ1wp4R4oW2+LFL/A== - dependencies: - "@types/mdast" "^3.0.0" - "@types/unist" "^2.0.0" - longest-streak "^3.0.0" - mdast-util-phrasing "^3.0.0" - mdast-util-to-string "^3.0.0" - micromark-util-decode-string "^1.0.0" - unist-util-visit "^4.0.0" - zwitch "^2.0.0" - -mdast-util-to-string@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz" - integrity sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w== - -mdast-util-to-string@^3.0.0, mdast-util-to-string@^3.1.0: - version "3.2.0" - resolved "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz" - integrity sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg== - dependencies: - "@types/mdast" "^3.0.0" - -media-typer@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" - integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== - -memfs@^3.4.1, memfs@^3.4.12: - version "3.6.0" - resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.6.0.tgz#d7a2110f86f79dd950a8b6df6d57bc984aa185f6" - integrity sha512-EGowvkkgbMcIChjMTMkESFDbZeSh8xZ7kNSF0hAiAN4Jh6jgHCRS0Ga/+C8y6Au+oqpezRHCfPsmJ2+DwAgiwQ== - dependencies: - fs-monkey "^1.0.4" - -"memoize-one@>=3.1.1 <6": - version "5.2.1" - resolved "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz" - integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q== - -memoizerific@^1.11.3: - version "1.11.3" - resolved "https://registry.yarnpkg.com/memoizerific/-/memoizerific-1.11.3.tgz#7c87a4646444c32d75438570905f2dbd1b1a805a" - integrity sha512-/EuHYwAPdLtXwAwSZkh/Gutery6pD2KYd44oQLhAvQp/50mpyduZh8Q7PYHXTCJ+wuXxt7oij2LXyIJOOYFPog== - dependencies: - map-or-similar "^1.5.0" - -merge-descriptors@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.3.tgz#d80319a65f3c7935351e5cfdac8f9318504dbed5" - integrity sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ== - -merge-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz" - integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== - -merge2@^1.3.0, merge2@^1.4.1: - version "1.4.1" - resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - -mermaid@10.4.0: - version "10.4.0" - resolved "https://registry.npmjs.org/mermaid/-/mermaid-10.4.0.tgz" - integrity sha512-4QCQLp79lvz7UZxow5HUX7uWTPJOaQBVExduo91tliXC7v78i6kssZOPHxLL+Xs30KU72cpPn3g3imw/xm/gaw== - dependencies: - "@braintree/sanitize-url" "^6.0.1" - "@types/d3-scale" "^4.0.3" - "@types/d3-scale-chromatic" "^3.0.0" - cytoscape "^3.23.0" - cytoscape-cose-bilkent "^4.1.0" - cytoscape-fcose "^2.1.0" - d3 "^7.4.0" - d3-sankey "^0.12.3" - dagre-d3-es "7.0.10" - dayjs "^1.11.7" - dompurify "^3.0.5" - elkjs "^0.8.2" - khroma "^2.0.0" - lodash-es "^4.17.21" - mdast-util-from-markdown "^1.3.0" - non-layered-tidy-tree-layout "^2.0.2" - stylis "^4.1.3" - ts-dedent "^2.2.0" - uuid "^9.0.0" - web-worker "^1.2.0" - -methods@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== - -micromark-core-commonmark@^1.0.0, micromark-core-commonmark@^1.0.1: - version "1.1.0" - resolved "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz" - integrity sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw== - dependencies: - decode-named-character-reference "^1.0.0" - micromark-factory-destination "^1.0.0" - micromark-factory-label "^1.0.0" - micromark-factory-space "^1.0.0" - micromark-factory-title "^1.0.0" - micromark-factory-whitespace "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-chunked "^1.0.0" - micromark-util-classify-character "^1.0.0" - micromark-util-html-tag-name "^1.0.0" - micromark-util-normalize-identifier "^1.0.0" - micromark-util-resolve-all "^1.0.0" - micromark-util-subtokenize "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.1" - uvu "^0.5.0" - -micromark-extension-gfm-autolink-literal@^1.0.0: - version "1.0.5" - resolved "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-1.0.5.tgz" - integrity sha512-z3wJSLrDf8kRDOh2qBtoTRD53vJ+CWIyo7uyZuxf/JAbNJjiHsOpG1y5wxk8drtv3ETAHutCu6N3thkOOgueWg== - dependencies: - micromark-util-character "^1.0.0" - micromark-util-sanitize-uri "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - -micromark-extension-gfm-footnote@^1.0.0: - version "1.1.2" - resolved "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-1.1.2.tgz" - integrity sha512-Yxn7z7SxgyGWRNa4wzf8AhYYWNrwl5q1Z8ii+CSTTIqVkmGZF1CElX2JI8g5yGoM3GAman9/PVCUFUSJ0kB/8Q== - dependencies: - micromark-core-commonmark "^1.0.0" - micromark-factory-space "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-normalize-identifier "^1.0.0" - micromark-util-sanitize-uri "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - uvu "^0.5.0" - -micromark-extension-gfm-strikethrough@^1.0.0: - version "1.0.7" - resolved "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-1.0.7.tgz" - integrity sha512-sX0FawVE1o3abGk3vRjOH50L5TTLr3b5XMqnP9YDRb34M0v5OoZhG+OHFz1OffZ9dlwgpTBKaT4XW/AsUVnSDw== - dependencies: - micromark-util-chunked "^1.0.0" - micromark-util-classify-character "^1.0.0" - micromark-util-resolve-all "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - uvu "^0.5.0" - -micromark-extension-gfm-table@^1.0.0: - version "1.0.7" - resolved "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-1.0.7.tgz" - integrity sha512-3ZORTHtcSnMQEKtAOsBQ9/oHp9096pI/UvdPtN7ehKvrmZZ2+bbWhi0ln+I9drmwXMt5boocn6OlwQzNXeVeqw== - dependencies: - micromark-factory-space "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - uvu "^0.5.0" - -micromark-extension-gfm-tagfilter@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-1.0.2.tgz" - integrity sha512-5XWB9GbAUSHTn8VPU8/1DBXMuKYT5uOgEjJb8gN3mW0PNW5OPHpSdojoqf+iq1xo7vWzw/P8bAHY0n6ijpXF7g== - dependencies: - micromark-util-types "^1.0.0" - -micromark-extension-gfm-task-list-item@^1.0.0: - version "1.0.5" - resolved "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-1.0.5.tgz" - integrity sha512-RMFXl2uQ0pNQy6Lun2YBYT9g9INXtWJULgbt01D/x8/6yJ2qpKyzdZD3pi6UIkzF++Da49xAelVKUeUMqd5eIQ== - dependencies: - micromark-factory-space "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - uvu "^0.5.0" - -micromark-extension-gfm@^2.0.0: - version "2.0.3" - resolved "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-2.0.3.tgz" - integrity sha512-vb9OoHqrhCmbRidQv/2+Bc6pkP0FrtlhurxZofvOEy5o8RtuuvTq+RQ1Vw5ZDNrVraQZu3HixESqbG+0iKk/MQ== - dependencies: - micromark-extension-gfm-autolink-literal "^1.0.0" - micromark-extension-gfm-footnote "^1.0.0" - micromark-extension-gfm-strikethrough "^1.0.0" - micromark-extension-gfm-table "^1.0.0" - micromark-extension-gfm-tagfilter "^1.0.0" - micromark-extension-gfm-task-list-item "^1.0.0" - micromark-util-combine-extensions "^1.0.0" - micromark-util-types "^1.0.0" - -micromark-extension-math@^2.0.0: - version "2.1.2" - resolved "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-2.1.2.tgz" - integrity sha512-es0CcOV89VNS9wFmyn+wyFTKweXGW4CEvdaAca6SWRWPyYCbBisnjaHLjWO4Nszuiud84jCpkHsqAJoa768Pvg== - dependencies: - "@types/katex" "^0.16.0" - katex "^0.16.0" - micromark-factory-space "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - uvu "^0.5.0" - -micromark-extension-mdx-expression@^1.0.0: - version "1.0.8" - resolved "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-1.0.8.tgz" - integrity sha512-zZpeQtc5wfWKdzDsHRBY003H2Smg+PUi2REhqgIhdzAa5xonhP03FcXxqFSerFiNUr5AWmHpaNPQTBVOS4lrXw== - dependencies: - "@types/estree" "^1.0.0" - micromark-factory-mdx-expression "^1.0.0" - micromark-factory-space "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-events-to-acorn "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - uvu "^0.5.0" - -micromark-extension-mdx-jsx@^1.0.0: - version "1.0.5" - resolved "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-1.0.5.tgz" - integrity sha512-gPH+9ZdmDflbu19Xkb8+gheqEDqkSpdCEubQyxuz/Hn8DOXiXvrXeikOoBA71+e8Pfi0/UYmU3wW3H58kr7akA== - dependencies: - "@types/acorn" "^4.0.0" - "@types/estree" "^1.0.0" - estree-util-is-identifier-name "^2.0.0" - micromark-factory-mdx-expression "^1.0.0" - micromark-factory-space "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - uvu "^0.5.0" - vfile-message "^3.0.0" - -micromark-extension-mdx-md@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-1.0.1.tgz" - integrity sha512-7MSuj2S7xjOQXAjjkbjBsHkMtb+mDGVW6uI2dBL9snOBCbZmoNgDAeZ0nSn9j3T42UE/g2xVNMn18PJxZvkBEA== - dependencies: - micromark-util-types "^1.0.0" - -micromark-extension-mdxjs-esm@^1.0.0: - version "1.0.5" - resolved "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-1.0.5.tgz" - integrity sha512-xNRBw4aoURcyz/S69B19WnZAkWJMxHMT5hE36GtDAyhoyn/8TuAeqjFJQlwk+MKQsUD7b3l7kFX+vlfVWgcX1w== - dependencies: - "@types/estree" "^1.0.0" - micromark-core-commonmark "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-events-to-acorn "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - unist-util-position-from-estree "^1.1.0" - uvu "^0.5.0" - vfile-message "^3.0.0" - -micromark-extension-mdxjs@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-1.0.1.tgz" - integrity sha512-7YA7hF6i5eKOfFUzZ+0z6avRG52GpWR8DL+kN47y3f2KhxbBZMhmxe7auOeaTBrW2DenbbZTf1ea9tA2hDpC2Q== - dependencies: - acorn "^8.0.0" - acorn-jsx "^5.0.0" - micromark-extension-mdx-expression "^1.0.0" - micromark-extension-mdx-jsx "^1.0.0" - micromark-extension-mdx-md "^1.0.0" - micromark-extension-mdxjs-esm "^1.0.0" - micromark-util-combine-extensions "^1.0.0" - micromark-util-types "^1.0.0" - -micromark-factory-destination@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz" - integrity sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg== - dependencies: - micromark-util-character "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - -micromark-factory-label@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz" - integrity sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w== - dependencies: - micromark-util-character "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - uvu "^0.5.0" - -micromark-factory-mdx-expression@^1.0.0: - version "1.0.9" - resolved "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-1.0.9.tgz" - integrity sha512-jGIWzSmNfdnkJq05c7b0+Wv0Kfz3NJ3N4cBjnbO4zjXIlxJr+f8lk+5ZmwFvqdAbUy2q6B5rCY//g0QAAaXDWA== - dependencies: - "@types/estree" "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-events-to-acorn "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - unist-util-position-from-estree "^1.0.0" - uvu "^0.5.0" - vfile-message "^3.0.0" - -micromark-factory-space@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz" - integrity sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ== - dependencies: - micromark-util-character "^1.0.0" - micromark-util-types "^1.0.0" - -micromark-factory-title@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz" - integrity sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ== - dependencies: - micromark-factory-space "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - -micromark-factory-whitespace@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz" - integrity sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ== - dependencies: - micromark-factory-space "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - -micromark-util-character@^1.0.0: - version "1.2.0" - resolved "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz" - integrity sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg== - dependencies: - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - -micromark-util-character@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/micromark-util-character/-/micromark-util-character-2.1.0.tgz#31320ace16b4644316f6bf057531689c71e2aee1" - integrity sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ== - dependencies: - micromark-util-symbol "^2.0.0" - micromark-util-types "^2.0.0" - -micromark-util-chunked@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz" - integrity sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ== - dependencies: - micromark-util-symbol "^1.0.0" - -micromark-util-classify-character@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz" - integrity sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw== - dependencies: - micromark-util-character "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - -micromark-util-combine-extensions@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz" - integrity sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA== - dependencies: - micromark-util-chunked "^1.0.0" - micromark-util-types "^1.0.0" - -micromark-util-decode-numeric-character-reference@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz" - integrity sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw== - dependencies: - micromark-util-symbol "^1.0.0" - -micromark-util-decode-string@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz" - integrity sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ== - dependencies: - decode-named-character-reference "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-decode-numeric-character-reference "^1.0.0" - micromark-util-symbol "^1.0.0" - -micromark-util-encode@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz" - integrity sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw== - -micromark-util-encode@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz#0921ac7953dc3f1fd281e3d1932decfdb9382ab1" - integrity sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA== - -micromark-util-events-to-acorn@^1.0.0: - version "1.2.3" - resolved "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-1.2.3.tgz" - integrity sha512-ij4X7Wuc4fED6UoLWkmo0xJQhsktfNh1J0m8g4PbIMPlx+ek/4YdW5mvbye8z/aZvAPUoxgXHrwVlXAPKMRp1w== - dependencies: - "@types/acorn" "^4.0.0" - "@types/estree" "^1.0.0" - "@types/unist" "^2.0.0" - estree-util-visit "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - uvu "^0.5.0" - vfile-message "^3.0.0" - -micromark-util-html-tag-name@^1.0.0: - version "1.2.0" - resolved "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz" - integrity sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q== - -micromark-util-normalize-identifier@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz" - integrity sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q== - dependencies: - micromark-util-symbol "^1.0.0" - -micromark-util-resolve-all@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz" - integrity sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA== - dependencies: - micromark-util-types "^1.0.0" - -micromark-util-sanitize-uri@^1.0.0, micromark-util-sanitize-uri@^1.1.0: - version "1.2.0" - resolved "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz" - integrity sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A== - dependencies: - micromark-util-character "^1.0.0" - micromark-util-encode "^1.0.0" - micromark-util-symbol "^1.0.0" - -micromark-util-sanitize-uri@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz#ec8fbf0258e9e6d8f13d9e4770f9be64342673de" - integrity sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw== - dependencies: - micromark-util-character "^2.0.0" - micromark-util-encode "^2.0.0" - micromark-util-symbol "^2.0.0" - -micromark-util-subtokenize@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz" - integrity sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A== - dependencies: - micromark-util-chunked "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - uvu "^0.5.0" - -micromark-util-symbol@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz" - integrity sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag== - -micromark-util-symbol@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz#12225c8f95edf8b17254e47080ce0862d5db8044" - integrity sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw== - -micromark-util-types@^1.0.0, micromark-util-types@^1.0.1: - version "1.1.0" - resolved "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz" - integrity sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg== - -micromark-util-types@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/micromark-util-types/-/micromark-util-types-2.0.0.tgz#63b4b7ffeb35d3ecf50d1ca20e68fc7caa36d95e" - integrity sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w== - -micromark@^3.0.0: - version "3.2.0" - resolved "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz" - integrity sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA== - dependencies: - "@types/debug" "^4.0.0" - debug "^4.0.0" - decode-named-character-reference "^1.0.0" - micromark-core-commonmark "^1.0.1" - micromark-factory-space "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-chunked "^1.0.0" - micromark-util-combine-extensions "^1.0.0" - micromark-util-decode-numeric-character-reference "^1.0.0" - micromark-util-encode "^1.0.0" - micromark-util-normalize-identifier "^1.0.0" - micromark-util-resolve-all "^1.0.0" - micromark-util-sanitize-uri "^1.0.0" - micromark-util-subtokenize "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.1" - uvu "^0.5.0" - -micromark@~2.11.0: - version "2.11.4" - resolved "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz" - integrity sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA== - dependencies: - debug "^4.0.0" - parse-entities "^2.0.0" - -micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5: - version "4.0.8" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" - integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== - dependencies: - braces "^3.0.3" - picomatch "^2.3.1" - -miller-rabin@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" - integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== - dependencies: - bn.js "^4.0.0" - brorand "^1.0.1" - -mime-db@1.52.0: - version "1.52.0" - resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - -mime-types@^2.1.12, mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.24, mime-types@~2.1.34: - version "2.1.35" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" - integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== - dependencies: - mime-db "1.52.0" - -mime@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== - -mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - -mimic-fn@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz" - integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== - -mimic-response@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" - integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== - -mimic-response@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" - integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== - -min-indent@^1.0.0, min-indent@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz" - integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== - -minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== - -minimalistic-crypto-utils@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" - integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== - -minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: - version "3.1.2" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - -minimatch@^9.0.1: - version "9.0.3" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz" - integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== - dependencies: - brace-expansion "^2.0.1" - -minimist@^1.2.0, minimist@^1.2.6: - version "1.2.8" - resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" - integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== - -"minipass@^5.0.0 || ^6.0.2 || ^7.0.0": - version "7.0.4" - resolved "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz" - integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== - -mkdirp@^0.5.6: - version "0.5.6" - resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz" - integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== - dependencies: - minimist "^1.2.6" - -mri@^1.1.0: - version "1.2.0" - resolved "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz" - integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA== - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== - -ms@2.1.2, ms@^2.1.1: - version "2.1.2" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -ms@2.1.3: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -mz@^2.7.0: - version "2.7.0" - resolved "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz" - integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== - dependencies: - any-promise "^1.0.0" - object-assign "^4.0.1" - thenify-all "^1.0.0" - -nanoid@^3.3.6: - version "3.3.6" - resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz" - integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== - -nanoid@^3.3.7: - version "3.3.7" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" - integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== - -natural-compare-lite@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz" - integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" - integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== - -negotiator@0.6.3, negotiator@^0.6.3: - version "0.6.3" - resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz" - integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== - -neo-async@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" - integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== - -next@^14.1.1: - version "14.2.4" - resolved "https://registry.npmjs.org/next/-/next-14.2.4.tgz" - integrity sha512-R8/V7vugY+822rsQGQCjoLhMuC9oFj9SOi4Cl4b2wjDrseD0LRZ10W7R6Czo4w9ZznVSshKjuIomsRjvm9EKJQ== - dependencies: - "@next/env" "14.2.4" - "@swc/helpers" "0.5.5" - busboy "1.6.0" - caniuse-lite "^1.0.30001579" - graceful-fs "^4.2.11" - postcss "8.4.31" - styled-jsx "5.1.1" - optionalDependencies: - "@next/swc-darwin-arm64" "14.2.4" - "@next/swc-darwin-x64" "14.2.4" - "@next/swc-linux-arm64-gnu" "14.2.4" - "@next/swc-linux-arm64-musl" "14.2.4" - "@next/swc-linux-x64-gnu" "14.2.4" - "@next/swc-linux-x64-musl" "14.2.4" - "@next/swc-win32-arm64-msvc" "14.2.4" - "@next/swc-win32-ia32-msvc" "14.2.4" - "@next/swc-win32-x64-msvc" "14.2.4" - -no-case@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" - integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg== - dependencies: - lower-case "^2.0.2" - tslib "^2.0.3" - -node-abort-controller@^3.0.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/node-abort-controller/-/node-abort-controller-3.1.1.tgz#a94377e964a9a37ac3976d848cb5c765833b8548" - integrity sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ== - -node-int64@^0.4.0: - version "0.4.0" - resolved "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" - integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== - -node-polyfill-webpack-plugin@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/node-polyfill-webpack-plugin/-/node-polyfill-webpack-plugin-2.0.1.tgz#141d86f177103a8517c71d99b7c6a46edbb1bb58" - integrity sha512-ZUMiCnZkP1LF0Th2caY6J/eKKoA0TefpoVa68m/LQU1I/mE8rGt4fNYGgNuCcK+aG8P8P43nbeJ2RqJMOL/Y1A== - dependencies: - assert "^2.0.0" - browserify-zlib "^0.2.0" - buffer "^6.0.3" - console-browserify "^1.2.0" - constants-browserify "^1.0.0" - crypto-browserify "^3.12.0" - domain-browser "^4.22.0" - events "^3.3.0" - filter-obj "^2.0.2" - https-browserify "^1.0.0" - os-browserify "^0.3.0" - path-browserify "^1.0.1" - process "^0.11.10" - punycode "^2.1.1" - querystring-es3 "^0.2.1" - readable-stream "^4.0.0" - stream-browserify "^3.0.0" - stream-http "^3.2.0" - string_decoder "^1.3.0" - timers-browserify "^2.0.12" - tty-browserify "^0.0.1" - type-fest "^2.14.0" - url "^0.11.0" - util "^0.12.4" - vm-browserify "^1.1.2" - -node-releases@^2.0.14: - version "2.0.14" - resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz" - integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw== - -node-releases@^2.0.18: - version "2.0.18" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.18.tgz#f010e8d35e2fe8d6b2944f03f70213ecedc4ca3f" - integrity sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g== - -non-layered-tidy-tree-layout@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/non-layered-tidy-tree-layout/-/non-layered-tidy-tree-layout-2.0.2.tgz" - integrity sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw== - -normalize-package-data@^2.5.0: - version "2.5.0" - resolved "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz" - integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== - dependencies: - hosted-git-info "^2.1.4" - resolve "^1.10.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - -normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -normalize-range@^0.1.2: - version "0.1.2" - resolved "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz" - integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== - -normalize-url@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" - integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== - -normalize-wheel@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/normalize-wheel/-/normalize-wheel-1.0.1.tgz#aec886affdb045070d856447df62ecf86146ec45" - integrity sha512-1OnlAPZ3zgrk8B91HyRj+eVv+kS5u+Z0SCsak6Xil/kmgEia50ga7zfkumayonZrImffAxPU/5WcyGhzetHNPA== - -npm-run-path@^4.0.1: - version "4.0.1" - resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz" - integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== - dependencies: - path-key "^3.0.0" - -npm-run-path@^5.1.0: - version "5.1.0" - resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz" - integrity sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q== - dependencies: - path-key "^4.0.0" - -nth-check@^2.0.1: - version "2.1.1" - resolved "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz" - integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== - dependencies: - boolbase "^1.0.0" - -nwsapi@^2.2.2: - version "2.2.12" - resolved "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.12.tgz#fb6af5c0ec35b27b4581eb3bbad34ec9e5c696f8" - integrity sha512-qXDmcVlZV4XRtKFzddidpfVP4oMSGhga+xdMc25mv8kaLUHtgzCDhUxkrN8exkGdTlLNaXj7CV3GtON7zuGZ+w== - -object-assign@^4.0.1, object-assign@^4.1.1: - version "4.1.1" - resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" - integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== - -object-hash@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz" - integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== - -object-inspect@^1.12.3, object-inspect@^1.13.1, object-inspect@^1.9.0: - version "1.13.1" - resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz" - integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== - -object-is@^1.1.5: - version "1.1.5" - resolved "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz" - integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object.assign@^4.1.3, object.assign@^4.1.4: - version "4.1.4" - resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz" - integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - has-symbols "^1.0.3" - object-keys "^1.1.1" - -object.entries@^1.1.6: - version "1.1.6" - resolved "https://registry.npmjs.org/object.entries/-/object.entries-1.1.6.tgz" - integrity sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - -object.fromentries@^2.0.6, object.fromentries@^2.0.7: - version "2.0.7" - resolved "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz" - integrity sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - -object.groupby@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.1.tgz" - integrity sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" - -object.hasown@^1.1.2: - version "1.1.3" - resolved "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.3.tgz" - integrity sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA== - dependencies: - define-properties "^1.2.0" - es-abstract "^1.22.1" - -object.values@^1.1.6, object.values@^1.1.7: - version "1.1.7" - resolved "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz" - integrity sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - -objectorarray@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/objectorarray/-/objectorarray-1.0.5.tgz#2c05248bbefabd8f43ad13b41085951aac5e68a5" - integrity sha512-eJJDYkhJFFbBBAxeh8xW+weHlkI28n2ZdQV/J/DNfWfSKlGEf2xcfAbZTv3riEXHAhL9SVOTs2pRmXiSTf78xg== - -on-finished@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" - integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== - dependencies: - ee-first "1.1.1" - -once@^1.3.0, once@^1.3.1, once@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== - dependencies: - wrappy "1" - -onetime@^5.1.0, onetime@^5.1.2: - version "5.1.2" - resolved "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== - dependencies: - mimic-fn "^2.1.0" - -onetime@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz" - integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ== - dependencies: - mimic-fn "^4.0.0" - -open@^8.0.4: - version "8.4.2" - resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" - integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== - dependencies: - define-lazy-prop "^2.0.0" - is-docker "^2.1.1" - is-wsl "^2.2.0" - -open@^9.1.0: - version "9.1.0" - resolved "https://registry.npmjs.org/open/-/open-9.1.0.tgz" - integrity sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg== - dependencies: - default-browser "^4.0.0" - define-lazy-prop "^3.0.0" - is-inside-container "^1.0.0" - is-wsl "^2.2.0" - -optionator@^0.9.1: - version "0.9.1" - resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz" - integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== - dependencies: - deep-is "^0.1.3" - fast-levenshtein "^2.0.6" - levn "^0.4.1" - prelude-ls "^1.2.1" - type-check "^0.4.0" - word-wrap "^1.2.3" - -os-browserify@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" - integrity sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A== - -p-cancelable@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf" - integrity sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg== - -p-limit@^2.2.0: - version "2.3.0" - resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - -p-limit@^3.0.2, p-limit@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - -p-limit@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-4.0.0.tgz#914af6544ed32bfa54670b061cafcbd04984b644" - integrity sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ== - dependencies: - yocto-queue "^1.0.0" - -p-locate@^4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz" - integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== - dependencies: - p-limit "^2.2.0" - -p-locate@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz" - integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== - dependencies: - p-limit "^3.0.2" - -p-locate@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-6.0.0.tgz#3da9a49d4934b901089dca3302fa65dc5a05c04f" - integrity sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw== - dependencies: - p-limit "^4.0.0" - -p-map@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz" - integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== - dependencies: - aggregate-error "^3.0.0" - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -pako@~1.0.5: - version "1.0.11" - resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" - integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== - -papaparse@^5.3.1: - version "5.4.1" - resolved "https://registry.npmjs.org/papaparse/-/papaparse-5.4.1.tgz" - integrity sha512-HipMsgJkZu8br23pW15uvo6sib6wne/4woLZPlFf3rpDyMe9ywEXUsuD7+6K9PRkJlVT51j/sCOYDKGGS3ZJrw== - -param-case@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5" - integrity sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A== - dependencies: - dot-case "^3.0.4" - tslib "^2.0.3" - -parent-module@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz" - integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== - dependencies: - callsites "^3.0.0" - -parse-asn1@^5.0.0, parse-asn1@^5.1.7: - version "5.1.7" - resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.7.tgz#73cdaaa822125f9647165625eb45f8a051d2df06" - integrity sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg== - dependencies: - asn1.js "^4.10.1" - browserify-aes "^1.2.0" - evp_bytestokey "^1.0.3" - hash-base "~3.0" - pbkdf2 "^3.1.2" - safe-buffer "^5.2.1" - -parse-entities@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz" - integrity sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ== - dependencies: - character-entities "^1.0.0" - character-entities-legacy "^1.0.0" - character-reference-invalid "^1.0.0" - is-alphanumerical "^1.0.0" - is-decimal "^1.0.0" - is-hexadecimal "^1.0.0" - -parse-entities@^4.0.0: - version "4.0.1" - resolved "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.1.tgz" - integrity sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w== - dependencies: - "@types/unist" "^2.0.0" - character-entities "^2.0.0" - character-entities-legacy "^3.0.0" - character-reference-invalid "^2.0.0" - decode-named-character-reference "^1.0.0" - is-alphanumerical "^2.0.0" - is-decimal "^2.0.0" - is-hexadecimal "^2.0.0" - -parse-json@^5.0.0, parse-json@^5.2.0: - version "5.2.0" - resolved "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz" - integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== - dependencies: - "@babel/code-frame" "^7.0.0" - error-ex "^1.3.1" - json-parse-even-better-errors "^2.3.0" - lines-and-columns "^1.1.6" - -parse5@^7.0.0, parse5@^7.1.1: - version "7.1.2" - resolved "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz" - integrity sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw== - dependencies: - entities "^4.4.0" - -parseurl@~1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" - integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== - -pascal-case@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.2.tgz#b48e0ef2b98e205e7c1dae747d0b1508237660eb" - integrity sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g== - dependencies: - no-case "^3.0.4" - tslib "^2.0.3" - -path-browserify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" - integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-exists@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-5.0.0.tgz#a6aad9489200b21fab31e49cf09277e5116fb9e7" - integrity sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" - integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== - -path-key@^3.0.0, path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - -path-key@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz" - integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== - -path-parse@^1.0.7: - version "1.0.7" - resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== - -path-scurry@^1.10.1: - version "1.10.1" - resolved "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz" - integrity sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ== - dependencies: - lru-cache "^9.1.1 || ^10.0.0" - minipass "^5.0.0 || ^6.0.2 || ^7.0.0" - -path-to-regexp@0.1.10: - version "0.1.10" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.10.tgz#67e9108c5c0551b9e5326064387de4763c4d5f8b" - integrity sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w== - -path-type@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" - integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== - -pathval@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pathval/-/pathval-2.0.0.tgz#7e2550b422601d4f6b8e26f1301bc8f15a741a25" - integrity sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA== - -pbkdf2@^3.0.3, pbkdf2@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" - integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== - dependencies: - create-hash "^1.1.2" - create-hmac "^1.1.4" - ripemd160 "^2.0.1" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - -periscopic@^3.0.0: - version "3.1.0" - resolved "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz" - integrity sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw== - dependencies: - "@types/estree" "^1.0.0" - estree-walker "^3.0.0" - is-reference "^3.0.0" - -picocolors@^1.0.0, picocolors@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz" - integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew== - -picocolors@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" - integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== - -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3, picomatch@^2.3.1: - version "2.3.1" - resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - -pidtree@^0.6.0: - version "0.6.0" - resolved "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz" - integrity sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g== - -pify@^2.3.0: - version "2.3.0" - resolved "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz" - integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== - -pinyin-pro@^3.23.0: - version "3.23.0" - resolved "https://registry.npmjs.org/pinyin-pro/-/pinyin-pro-3.23.0.tgz" - integrity sha512-YDwKw31PPxsr1RQzDMmHuv4Z3exaTHrVQNdVgolyhoIrsRuM3QhsoAtzYPXIaVxb5MyWCSIiEbkwvXMfy1imNA== - -pirates@^4.0.1: - version "4.0.5" - resolved "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz" - integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== - -pirates@^4.0.4: - version "4.0.6" - resolved "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" - integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== - -pkg-dir@^4.1.0, pkg-dir@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" - integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== - dependencies: - find-up "^4.0.0" - -pkg-dir@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-7.0.0.tgz#8f0c08d6df4476756c5ff29b3282d0bab7517d11" - integrity sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA== - dependencies: - find-up "^6.3.0" - -pluralize@^8.0.0: - version "8.0.0" - resolved "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz" - integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA== - -pnp-webpack-plugin@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.7.0.tgz#65741384f6d8056f36e2255a8d67ffc20866f5c9" - integrity sha512-2Rb3vm+EXble/sMXNSu6eoBx8e79gKqhNq9F5ZWW6ERNCTE/Q0wQNne5541tE5vKjfM8hpNCYL+LGc1YTfI0dg== - dependencies: - ts-pnp "^1.1.6" - -polished@^4.2.2: - version "4.3.1" - resolved "https://registry.yarnpkg.com/polished/-/polished-4.3.1.tgz#5a00ae32715609f83d89f6f31d0f0261c6170548" - integrity sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA== - dependencies: - "@babel/runtime" "^7.17.8" - -portfinder@^1.0.28: - version "1.0.32" - resolved "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz" - integrity sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg== - dependencies: - async "^2.6.4" - debug "^3.2.7" - mkdirp "^0.5.6" - -possible-typed-array-names@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz#89bb63c6fada2c3e90adc4a647beeeb39cc7bf8f" - integrity sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q== - -postcss-import@^15.1.0: - version "15.1.0" - resolved "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz" - integrity sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew== - dependencies: - postcss-value-parser "^4.0.0" - read-cache "^1.0.0" - resolve "^1.1.7" - -postcss-js@^4.0.1: - version "4.0.1" - resolved "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz" - integrity sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw== - dependencies: - camelcase-css "^2.0.1" - -postcss-load-config@^4.0.1: - version "4.0.1" - resolved "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.1.tgz" - integrity sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA== - dependencies: - lilconfig "^2.0.5" - yaml "^2.1.1" - -postcss-loader@^8.1.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-8.1.1.tgz#2822589e7522927344954acb55bbf26e8b195dfe" - integrity sha512-0IeqyAsG6tYiDRCYKQJLAmgQr47DX6N7sFSWvQxt6AcupX8DIdmykuk/o/tx0Lze3ErGHJEp5OSRxrelC6+NdQ== - dependencies: - cosmiconfig "^9.0.0" - jiti "^1.20.0" - semver "^7.5.4" - -postcss-modules-extract-imports@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz#b4497cb85a9c0c4b5aabeb759bb25e8d89f15002" - integrity sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q== - -postcss-modules-local-by-default@^4.0.5: - version "4.0.5" - resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz#f1b9bd757a8edf4d8556e8d0f4f894260e3df78f" - integrity sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw== - dependencies: - icss-utils "^5.0.0" - postcss-selector-parser "^6.0.2" - postcss-value-parser "^4.1.0" - -postcss-modules-scope@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz#a43d28289a169ce2c15c00c4e64c0858e43457d5" - integrity sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ== - dependencies: - postcss-selector-parser "^6.0.4" - -postcss-modules-values@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" - integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ== - dependencies: - icss-utils "^5.0.0" - -postcss-nested@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz" - integrity sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ== - dependencies: - postcss-selector-parser "^6.0.11" - -postcss-selector-parser@6.0.10, postcss-selector-parser@^6.0.9: - version "6.0.10" - resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz" - integrity sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w== - dependencies: - cssesc "^3.0.0" - util-deprecate "^1.0.2" - -postcss-selector-parser@^6.0.11: - version "6.0.13" - resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz" - integrity sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ== - dependencies: - cssesc "^3.0.0" - util-deprecate "^1.0.2" - -postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: - version "6.1.2" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz#27ecb41fb0e3b6ba7a1ec84fff347f734c7929de" - integrity sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg== - dependencies: - cssesc "^3.0.0" - util-deprecate "^1.0.2" - -postcss-value-parser@^4.0.0, postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: - version "4.2.0" - resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz" - integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== - -postcss@8.4.31, postcss@^8.4.23, postcss@^8.4.31: - version "8.4.31" - resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz" - integrity sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ== - dependencies: - nanoid "^3.3.6" - picocolors "^1.0.0" - source-map-js "^1.0.2" - -postcss@^8.2.14, postcss@^8.4.33, postcss@^8.4.38: - version "8.4.47" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.47.tgz#5bf6c9a010f3e724c503bf03ef7947dcb0fea365" - integrity sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ== - dependencies: - nanoid "^3.3.7" - picocolors "^1.1.0" - source-map-js "^1.2.1" - -prelude-ls@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" - integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== - -pretty-error@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-4.0.0.tgz#90a703f46dd7234adb46d0f84823e9d1cb8f10d6" - integrity sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw== - dependencies: - lodash "^4.17.20" - renderkid "^3.0.0" - -pretty-format@^27.0.2: - version "27.5.1" - resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e" - integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ== - dependencies: - ansi-regex "^5.0.1" - ansi-styles "^5.0.0" - react-is "^17.0.1" - -pretty-format@^29.0.0, pretty-format@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812" - integrity sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ== - dependencies: - "@jest/schemas" "^29.6.3" - ansi-styles "^5.0.0" - react-is "^18.0.0" - -prismjs@^1.27.0: - version "1.29.0" - resolved "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz" - integrity sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q== - -prismjs@~1.27.0: - version "1.27.0" - resolved "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz" - integrity sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA== - -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - -process@^0.11.10: - version "0.11.10" - resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" - integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== - -prompts@^2.0.1: - version "2.4.2" - resolved "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" - integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== - dependencies: - kleur "^3.0.3" - sisteransi "^1.0.5" - -prop-types@^15.0.0, prop-types@^15.5.8, prop-types@^15.7.2, prop-types@^15.8.1: - version "15.8.1" - resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz" - integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== - dependencies: - loose-envify "^1.4.0" - object-assign "^4.1.1" - react-is "^16.13.1" - -property-information@^5.0.0: - version "5.6.0" - resolved "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz" - integrity sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA== - dependencies: - xtend "^4.0.0" - -property-information@^6.0.0: - version "6.2.0" - resolved "https://registry.npmjs.org/property-information/-/property-information-6.2.0.tgz" - integrity sha512-kma4U7AFCTwpqq5twzC1YVIDXSqg6qQK6JN0smOw8fgRy1OkMi0CYSzFmsy6dnqSenamAtj0CyXMUJ1Mf6oROg== - -proxy-addr@~2.0.7: - version "2.0.7" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" - integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== - dependencies: - forwarded "0.2.0" - ipaddr.js "1.9.1" - -psl@^1.1.33: - version "1.9.0" - resolved "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" - integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== - -public-encrypt@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" - integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== - dependencies: - bn.js "^4.1.0" - browserify-rsa "^4.0.0" - create-hash "^1.1.0" - parse-asn1 "^5.0.0" - randombytes "^2.0.1" - safe-buffer "^5.1.2" - -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -punycode@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - integrity sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ== - -punycode@^2.1.0: - version "2.3.0" - resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz" - integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== - -punycode@^2.1.1: - version "2.3.1" - resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" - integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== - -pure-rand@^6.0.0: - version "6.1.0" - resolved "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz#d173cf23258231976ccbdb05247c9787957604f2" - integrity sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA== - -qrcode.react@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/qrcode.react/-/qrcode.react-3.1.0.tgz" - integrity sha512-oyF+Urr3oAMUG/OiOuONL3HXM+53wvuH3mtIWQrYmsXoAq0DkvZp2RYUWFSMFtbdOpuS++9v+WAkzNVkMlNW6Q== - -qs@6.13.0, qs@^6.12.3: - version "6.13.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.13.0.tgz#6ca3bd58439f7e245655798997787b0d88a51906" - integrity sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg== - dependencies: - side-channel "^1.0.6" - -qs@^6.11.1: - version "6.11.2" - resolved "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz" - integrity sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA== - dependencies: - side-channel "^1.0.4" - -querystring-es3@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" - integrity sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA== - -querystringify@^2.1.1: - version "2.2.0" - resolved "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" - integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== - -queue-microtask@^1.2.2: - version "1.2.3" - resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - -queue@6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/queue/-/queue-6.0.2.tgz#b91525283e2315c7553d2efa18d83e76432fed65" - integrity sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA== - dependencies: - inherits "~2.0.3" - -quick-lru@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" - integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== - -randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - -randomfill@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" - integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== - dependencies: - randombytes "^2.0.5" - safe-buffer "^5.1.0" - -range-parser@^1.2.1, range-parser@~1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" - integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== - -raw-body@2.5.2: - version "2.5.2" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" - integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== - dependencies: - bytes "3.1.2" - http-errors "2.0.0" - iconv-lite "0.4.24" - unpipe "1.0.0" - -rc-input@~1.3.5: - version "1.3.6" - resolved "https://registry.npmjs.org/rc-input/-/rc-input-1.3.6.tgz" - integrity sha512-/HjTaKi8/Ts4zNbYaB5oWCquxFyFQO4Co1MnMgoCeGJlpe7k8Eir2HN0a0F9IHDmmo+GYiGgPpz7w/d/krzsJA== - dependencies: - "@babel/runtime" "^7.11.1" - classnames "^2.2.1" - rc-util "^5.18.1" - -rc-resize-observer@^1.0.0: - version "1.4.0" - resolved "https://registry.npmjs.org/rc-resize-observer/-/rc-resize-observer-1.4.0.tgz" - integrity sha512-PnMVyRid9JLxFavTjeDXEXo65HCRqbmLBw9xX9gfC4BZiSzbLXKzW3jPz+J0P71pLbD5tBMTT+mkstV5gD0c9Q== - dependencies: - "@babel/runtime" "^7.20.7" - classnames "^2.2.1" - rc-util "^5.38.0" - resize-observer-polyfill "^1.5.1" - -rc-textarea@^1.5.2: - version "1.5.2" - resolved "https://registry.npmjs.org/rc-textarea/-/rc-textarea-1.5.2.tgz" - integrity sha512-VVwKYtkp5whZVhP+llX8zM8TtI3dv+BDA0FUbmBMGLaW/tuBJ7Yh35yPabO63V+Bi68xv17eI4hy+/4p2G0gFg== - dependencies: - "@babel/runtime" "^7.10.1" - classnames "^2.2.1" - rc-input "~1.3.5" - rc-resize-observer "^1.0.0" - rc-util "^5.27.0" - -rc-util@^5.18.1, rc-util@^5.27.0, rc-util@^5.38.0: - version "5.38.1" - resolved "https://registry.npmjs.org/rc-util/-/rc-util-5.38.1.tgz" - integrity sha512-e4ZMs7q9XqwTuhIK7zBIVFltUtMSjphuPPQXHoHlzRzNdOwUxDejo0Zls5HYaJfRKNURcsS/ceKVULlhjBrxng== - dependencies: - "@babel/runtime" "^7.18.3" - react-is "^18.2.0" - -react-18-input-autosize@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/react-18-input-autosize/-/react-18-input-autosize-3.0.0.tgz" - integrity sha512-7tsUc9PJWg6Vsp8qYuzlKKBf7hbCoTBdNfjYZSprEPbxf3meuhjklg9QPBe9rIyoR3uDAzmG7NpoJ1+kP5ns+w== - dependencies: - prop-types "^15.5.8" - -react-colorful@^5.1.2: - version "5.6.1" - resolved "https://registry.yarnpkg.com/react-colorful/-/react-colorful-5.6.1.tgz#7dc2aed2d7c72fac89694e834d179e32f3da563b" - integrity sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw== - -react-confetti@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/react-confetti/-/react-confetti-6.1.0.tgz#03dc4340d955acd10b174dbf301f374a06e29ce6" - integrity sha512-7Ypx4vz0+g8ECVxr88W9zhcQpbeujJAVqL14ZnXJ3I23mOI9/oBVTQ3dkJhUmB0D6XOtCZEM6N0Gm9PMngkORw== - dependencies: - tween-functions "^1.2.0" - -react-docgen-typescript@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/react-docgen-typescript/-/react-docgen-typescript-2.2.2.tgz#4611055e569edc071204aadb20e1c93e1ab1659c" - integrity sha512-tvg2ZtOpOi6QDwsb3GZhOjDkkX0h8Z2gipvTg6OVMUyoYoURhEiRNePT8NZItTVCDh39JJHnLdfCOkzoLbFnTg== - -react-docgen@^7.0.0: - version "7.0.3" - resolved "https://registry.yarnpkg.com/react-docgen/-/react-docgen-7.0.3.tgz#f811b785f07b1f2023cb899b6bcf9d522b21b95d" - integrity sha512-i8aF1nyKInZnANZ4uZrH49qn1paRgBZ7wZiCNBMnenlPzEv0mRl+ShpTVEI6wZNl8sSc79xZkivtgLKQArcanQ== - dependencies: - "@babel/core" "^7.18.9" - "@babel/traverse" "^7.18.9" - "@babel/types" "^7.18.9" - "@types/babel__core" "^7.18.0" - "@types/babel__traverse" "^7.18.0" - "@types/doctrine" "^0.0.9" - "@types/resolve" "^1.20.2" - doctrine "^3.0.0" - resolve "^1.22.1" - strip-indent "^4.0.0" - -"react-dom@^16.8.0 || ^17.0.0 || ^18.0.0": - version "18.3.1" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.3.1.tgz#c2265d79511b57d479b3dd3fdfa51536494c5cb4" - integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw== - dependencies: - loose-envify "^1.1.0" - scheduler "^0.23.2" - -react-dom@~18.2.0: - version "18.2.0" - resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz" - integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== - dependencies: - loose-envify "^1.1.0" - scheduler "^0.23.0" - -react-easy-crop@^5.0.8: - version "5.0.8" - resolved "https://registry.yarnpkg.com/react-easy-crop/-/react-easy-crop-5.0.8.tgz#6cf5be061c0ec6dc0c6ee7413974c34e35bf7475" - integrity sha512-KjulxXhR5iM7+ATN2sGCum/IyDxGw7xT0dFoGcqUP+ysaPU5Ka7gnrDa2tUHFHUoMNyPrVZ05QA+uvMgC5ym/g== - dependencies: - normalize-wheel "^1.0.1" - tslib "^2.0.1" - -react-element-to-jsx-string@^15.0.0: - version "15.0.0" - resolved "https://registry.yarnpkg.com/react-element-to-jsx-string/-/react-element-to-jsx-string-15.0.0.tgz#1cafd5b6ad41946ffc8755e254da3fc752a01ac6" - integrity sha512-UDg4lXB6BzlobN60P8fHWVPX3Kyw8ORrTeBtClmIlGdkOOE+GYQSFvmEU5iLLpwp/6v42DINwNcwOhOLfQ//FQ== - dependencies: - "@base2/pretty-print-object" "1.0.1" - is-plain-object "5.0.0" - react-is "18.1.0" - -react-error-boundary@^3.1.4: - version "3.1.4" - resolved "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-3.1.4.tgz" - integrity sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA== - dependencies: - "@babel/runtime" "^7.12.5" - -react-error-boundary@^4.0.2: - version "4.0.9" - resolved "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-4.0.9.tgz" - integrity sha512-f6DcHVdTDZmc9ixmRmuLDZpkdghYR/HKZdUzMLHD58s4cR2C4R6y4ktYztCosM6pyeK4/C8IofwqxgID25W6kw== - dependencies: - "@babel/runtime" "^7.12.5" - -react-headless-pagination@^1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/react-headless-pagination/-/react-headless-pagination-1.1.4.tgz" - integrity sha512-Z5d55g3gM2BQMvHJUGm1jbbQ5Bgtq54kNlI5ca1NTwdVR8ZNunN0EdOtNKNobsFRKuZGkQ24VTIu6ulNq190Iw== - dependencies: - classnames "2.3.1" - -react-hook-form@^7.51.4: - version "7.51.4" - resolved "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.51.4.tgz" - integrity sha512-V14i8SEkh+V1gs6YtD0hdHYnoL4tp/HX/A45wWQN15CYr9bFRmmRdYStSO5L65lCCZRF+kYiSKhm9alqbcdiVA== - -react-i18next@^12.2.0: - version "12.3.1" - resolved "https://registry.npmjs.org/react-i18next/-/react-i18next-12.3.1.tgz" - integrity sha512-5v8E2XjZDFzK7K87eSwC7AJcAkcLt5xYZ4+yTPDAW1i7C93oOY1dnr4BaQM7un4Hm+GmghuiPvevWwlca5PwDA== - dependencies: - "@babel/runtime" "^7.20.6" - html-parse-stringify "^3.0.1" - -react-infinite-scroll-component@^6.1.0: - version "6.1.0" - resolved "https://registry.npmjs.org/react-infinite-scroll-component/-/react-infinite-scroll-component-6.1.0.tgz" - integrity sha512-SQu5nCqy8DxQWpnUVLx7V7b7LcA37aM7tvoWjTLZp1dk6EJibM5/4EJKzOnl07/BsM1Y40sKLuqjCwwH/xV0TQ== - dependencies: - throttle-debounce "^2.1.0" - -react-is@18.1.0: - version "18.1.0" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.1.0.tgz#61aaed3096d30eacf2a2127118b5b41387d32a67" - integrity sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg== - -react-is@^16.13.1, react-is@^16.7.0: - version "16.13.1" - resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" - integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== - -react-is@^17.0.1: - version "17.0.2" - resolved "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" - integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== - -react-is@^18.0.0, react-is@^18.2.0: - version "18.2.0" - resolved "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz" - integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== - -react-markdown@^8.0.6: - version "8.0.7" - resolved "https://registry.npmjs.org/react-markdown/-/react-markdown-8.0.7.tgz" - integrity sha512-bvWbzG4MtOU62XqBx3Xx+zB2raaFFsq4mYiAzfjXJMEz2sixgeAfraA3tvzULF02ZdOMUOKTBFFaZJDDrq+BJQ== - dependencies: - "@types/hast" "^2.0.0" - "@types/prop-types" "^15.0.0" - "@types/unist" "^2.0.0" - comma-separated-tokens "^2.0.0" - hast-util-whitespace "^2.0.0" - prop-types "^15.0.0" - property-information "^6.0.0" - react-is "^18.0.0" - remark-parse "^10.0.0" - remark-rehype "^10.0.0" - space-separated-tokens "^2.0.0" - style-to-object "^0.4.0" - unified "^10.0.0" - unist-util-visit "^4.0.0" - vfile "^5.0.0" - -react-multi-email@^1.0.14: - version "1.0.16" - resolved "https://registry.npmjs.org/react-multi-email/-/react-multi-email-1.0.16.tgz" - integrity sha512-dgg4TY3P5FWz6c4ghgxH1bjZOgYL3S/HN+EUNe6dqHbLMVzeyud1ztDUlqvft4NX1sUxKx2IF2zDq1yAJQA5yQ== - -react-papaparse@^4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/react-papaparse/-/react-papaparse-4.1.0.tgz" - integrity sha512-sGJqK+OE2rVVQPxQUCCDW2prLIglv9kTdizhNe2awXvKo0gLShmhpRN3BwA+ujw5M2gSJ/KGNEwtgII0OsLgkg== - dependencies: - "@types/papaparse" "^5.3.1" - papaparse "^5.3.1" - -react-refresh@^0.14.0: - version "0.14.2" - resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.2.tgz#3833da01ce32da470f1f936b9d477da5c7028bf9" - integrity sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA== - -react-slider@^2.0.4: - version "2.0.5" - resolved "https://registry.npmjs.org/react-slider/-/react-slider-2.0.5.tgz" - integrity sha512-MU5gaK1yYCKnbDDN3CMiVcgkKZwMvdqK2xUEW7fFU37NAzRgS1FZbF9N7vP08E3XXNVhiuZnwVzUa3PYQAZIMg== - dependencies: - prop-types "^15.8.1" - -react-sortablejs@^6.1.4: - version "6.1.4" - resolved "https://registry.npmjs.org/react-sortablejs/-/react-sortablejs-6.1.4.tgz" - integrity sha512-fc7cBosfhnbh53Mbm6a45W+F735jwZ1UFIYSrIqcO/gRIFoDyZeMtgKlpV4DdyQfbCzdh5LoALLTDRxhMpTyXQ== - dependencies: - classnames "2.3.1" - tiny-invariant "1.2.0" - -react-syntax-highlighter@^15.5.0: - version "15.5.0" - resolved "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.5.0.tgz" - integrity sha512-+zq2myprEnQmH5yw6Gqc8lD55QHnpKaU8TOcFeC/Lg/MQSs8UknEA0JC4nTZGFAXC2J2Hyj/ijJ7NlabyPi2gg== - dependencies: - "@babel/runtime" "^7.3.1" - highlight.js "^10.4.1" - lowlight "^1.17.0" - prismjs "^1.27.0" - refractor "^3.6.0" - -react-tooltip@5.8.3: - version "5.8.3" - resolved "https://registry.npmjs.org/react-tooltip/-/react-tooltip-5.8.3.tgz" - integrity sha512-h7maAlm2Xeymc14gWKhhrzsENeB83N65EzZ+AcQIGrOpNE0yefVRJIHhNcWHEJ0FEtf7VZXxtsj5glVXKxEtvA== - dependencies: - "@floating-ui/dom" "1.1.1" - classnames "^2.3.2" - -react-window-infinite-loader@^1.0.9: - version "1.0.9" - resolved "https://registry.npmjs.org/react-window-infinite-loader/-/react-window-infinite-loader-1.0.9.tgz" - integrity sha512-5Hg89IdU4Vrp0RT8kZYKeTIxWZYhNkVXeI1HbKo01Vm/Z7qztDvXljwx16sMzsa9yapRJQW3ODZfMUw38SOWHw== - -react-window@^1.8.9: - version "1.8.9" - resolved "https://registry.npmjs.org/react-window/-/react-window-1.8.9.tgz" - integrity sha512-+Eqx/fj1Aa5WnhRfj9dJg4VYATGwIUP2ItwItiJ6zboKWA6EX3lYDAXfGF2hyNqplEprhbtjbipiADEcwQ823Q== - dependencies: - "@babel/runtime" "^7.0.0" - memoize-one ">=3.1.1 <6" - -"react@^16.8.0 || ^17.0.0 || ^18.0.0": - version "18.3.1" - resolved "https://registry.yarnpkg.com/react/-/react-18.3.1.tgz#49ab892009c53933625bd16b2533fc754cab2891" - integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== - dependencies: - loose-envify "^1.1.0" - -react@~18.2.0: - version "18.2.0" - resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz" - integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== - dependencies: - loose-envify "^1.1.0" - -reactflow@^11.11.3: - version "11.11.3" - resolved "https://registry.npmjs.org/reactflow/-/reactflow-11.11.3.tgz" - integrity sha512-wusd1Xpn1wgsSEv7UIa4NNraCwH9syBtubBy4xVNXg3b+CDKM+sFaF3hnMx0tr0et4km9urIDdNvwm34QiZong== - dependencies: - "@reactflow/background" "11.3.13" - "@reactflow/controls" "11.2.13" - "@reactflow/core" "11.11.3" - "@reactflow/minimap" "11.7.13" - "@reactflow/node-resizer" "2.2.13" - "@reactflow/node-toolbar" "1.3.13" - -read-cache@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz" - integrity sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA== - dependencies: - pify "^2.3.0" - -read-pkg-up@^7.0.1: - version "7.0.1" - resolved "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz" - integrity sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg== - dependencies: - find-up "^4.1.0" - read-pkg "^5.2.0" - type-fest "^0.8.1" - -read-pkg@^5.2.0: - version "5.2.0" - resolved "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz" - integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg== - dependencies: - "@types/normalize-package-data" "^2.4.0" - normalize-package-data "^2.5.0" - parse-json "^5.0.0" - type-fest "^0.6.0" - -readable-stream@^2.3.8: - version "2.3.8" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" - integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -readable-stream@^3.5.0, readable-stream@^3.6.0: - version "3.6.2" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" - integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readable-stream@^4.0.0: - version "4.5.2" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-4.5.2.tgz#9e7fc4c45099baeed934bff6eb97ba6cf2729e09" - integrity sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g== - dependencies: - abort-controller "^3.0.0" - buffer "^6.0.3" - events "^3.3.0" - process "^0.11.10" - string_decoder "^1.3.0" - -readdirp@~3.6.0: - version "3.6.0" - resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz" - integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== - dependencies: - picomatch "^2.2.1" - -recast@^0.23.5: - version "0.23.9" - resolved "https://registry.yarnpkg.com/recast/-/recast-0.23.9.tgz#587c5d3a77c2cfcb0c18ccce6da4361528c2587b" - integrity sha512-Hx/BGIbwj+Des3+xy5uAtAbdCyqK9y9wbBcDFDYanLS9JnMqf7OeF87HQwUimE87OEc72mr6tkKUKMBBL+hF9Q== - dependencies: - ast-types "^0.16.1" - esprima "~4.0.0" - source-map "~0.6.1" - tiny-invariant "^1.3.3" - tslib "^2.0.1" - -recordrtc@^5.6.2: - version "5.6.2" - resolved "https://registry.npmjs.org/recordrtc/-/recordrtc-5.6.2.tgz" - integrity sha512-1QNKKNtl7+KcwD1lyOgP3ZlbiJ1d0HtXnypUy7yq49xEERxk31PHvE9RCciDrulPCY7WJ+oz0R9hpNxgsIurGQ== - -redent@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f" - integrity sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg== - dependencies: - indent-string "^4.0.0" - strip-indent "^3.0.0" - -reflect.getprototypeof@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz" - integrity sha512-ECkTw8TmJwW60lOTR+ZkODISW6RQ8+2CL3COqtiJKLd6MmB45hN51HprHFziKLGkAuTGQhBb91V8cy+KHlaCjw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" - globalthis "^1.0.3" - which-builtin-type "^1.1.3" - -refractor@^3.6.0: - version "3.6.0" - resolved "https://registry.npmjs.org/refractor/-/refractor-3.6.0.tgz" - integrity sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA== - dependencies: - hastscript "^6.0.0" - parse-entities "^2.0.0" - prismjs "~1.27.0" - -regenerate-unicode-properties@^10.2.0: - version "10.2.0" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz#626e39df8c372338ea9b8028d1f99dc3fd9c3db0" - integrity sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA== - dependencies: - regenerate "^1.4.2" - -regenerate@^1.4.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" - integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== - -regenerator-runtime@^0.13.11: - version "0.13.11" - resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz" - integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== - -regenerator-runtime@^0.14.0: - version "0.14.1" - resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" - integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== - -regenerator-transform@^0.15.2: - version "0.15.2" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.2.tgz#5bbae58b522098ebdf09bca2f83838929001c7a4" - integrity sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg== - dependencies: - "@babel/runtime" "^7.8.4" - -regex-parser@^2.2.11: - version "2.3.0" - resolved "https://registry.yarnpkg.com/regex-parser/-/regex-parser-2.3.0.tgz#4bb61461b1a19b8b913f3960364bb57887f920ee" - integrity sha512-TVILVSz2jY5D47F4mA4MppkBrafEaiUWJO/TcZHEIuI13AqoZMkK1WMA4Om1YkYbTx+9Ki1/tSUXbceyr9saRg== - -regexp-tree@^0.1.24, regexp-tree@~0.1.1: - version "0.1.27" - resolved "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz" - integrity sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA== - -regexp.prototype.flags@^1.5.0, regexp.prototype.flags@^1.5.1: - version "1.5.1" - resolved "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz" - integrity sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - set-function-name "^2.0.0" - -regexpp@^3.0.0: - version "3.2.0" - resolved "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz" - integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== - -regexpu-core@^6.1.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-6.1.1.tgz#b469b245594cb2d088ceebc6369dceb8c00becac" - integrity sha512-k67Nb9jvwJcJmVpw0jPttR1/zVfnKf8Km0IPatrU/zJ5XeG3+Slx0xLXs9HByJSzXzrlz5EDvN6yLNMDc2qdnw== - dependencies: - regenerate "^1.4.2" - regenerate-unicode-properties "^10.2.0" - regjsgen "^0.8.0" - regjsparser "^0.11.0" - unicode-match-property-ecmascript "^2.0.0" - unicode-match-property-value-ecmascript "^2.1.0" - -regjsgen@^0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.8.0.tgz#df23ff26e0c5b300a6470cad160a9d090c3a37ab" - integrity sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q== - -regjsparser@^0.11.0: - version "0.11.1" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.11.1.tgz#ae55c74f646db0c8fcb922d4da635e33da405149" - integrity sha512-1DHODs4B8p/mQHU9kr+jv8+wIC9mtG4eBHxWxIq5mhjE3D5oORhCc6deRKzTjs9DcfRFmj9BHSDguZklqCGFWQ== - dependencies: - jsesc "~3.0.2" - -regjsparser@^0.9.1: - version "0.9.1" - resolved "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz" - integrity sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ== - dependencies: - jsesc "~0.5.0" - -rehype-external-links@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/rehype-external-links/-/rehype-external-links-3.0.0.tgz#2b28b5cda1932f83f045b6f80a3e1b15f168c6f6" - integrity sha512-yp+e5N9V3C6bwBeAC4n796kc86M4gJCdlVhiMTxIrJG5UHDMh+PJANf9heqORJbt1nrCbDwIlAZKjANIaVBbvw== - dependencies: - "@types/hast" "^3.0.0" - "@ungap/structured-clone" "^1.0.0" - hast-util-is-element "^3.0.0" - is-absolute-url "^4.0.0" - space-separated-tokens "^2.0.0" - unist-util-visit "^5.0.0" - -rehype-katex@^6.0.2: - version "6.0.3" - resolved "https://registry.npmjs.org/rehype-katex/-/rehype-katex-6.0.3.tgz" - integrity sha512-ByZlRwRUcWegNbF70CVRm2h/7xy7jQ3R9LaY4VVSvjnoVWwWVhNL60DiZsBpC5tSzYQOCvDbzncIpIjPZWodZA== - dependencies: - "@types/hast" "^2.0.0" - "@types/katex" "^0.14.0" - hast-util-from-html-isomorphic "^1.0.0" - hast-util-to-text "^3.1.0" - katex "^0.16.0" - unist-util-visit "^4.0.0" - -rehype-raw@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/rehype-raw/-/rehype-raw-7.0.0.tgz#59d7348fd5dbef3807bbaa1d443efd2dd85ecee4" - integrity sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww== - dependencies: - "@types/hast" "^3.0.0" - hast-util-raw "^9.0.0" - vfile "^6.0.0" - -rehype-slug@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/rehype-slug/-/rehype-slug-6.0.0.tgz#1d21cf7fc8a83ef874d873c15e6adaee6344eaf1" - integrity sha512-lWyvf/jwu+oS5+hL5eClVd3hNdmwM1kAC0BUvEGD19pajQMIzcNUd/k9GsfQ+FfECvX+JE+e9/btsKH0EjJT6A== - dependencies: - "@types/hast" "^3.0.0" - github-slugger "^2.0.0" - hast-util-heading-rank "^3.0.0" - hast-util-to-string "^3.0.0" - unist-util-visit "^5.0.0" - -relateurl@^0.2.7: - version "0.2.7" - resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" - integrity sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog== - -remark-breaks@^3.0.2: - version "3.0.3" - resolved "https://registry.npmjs.org/remark-breaks/-/remark-breaks-3.0.3.tgz" - integrity sha512-C7VkvcUp1TPUc2eAYzsPdaUh8Xj4FSbQnYA5A9f80diApLZscTDeG7efiWP65W8hV2sEy3JuGVU0i6qr5D8Hug== - dependencies: - "@types/mdast" "^3.0.0" - mdast-util-newline-to-break "^1.0.0" - unified "^10.0.0" - -remark-gfm@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/remark-gfm/-/remark-gfm-3.0.1.tgz" - integrity sha512-lEFDoi2PICJyNrACFOfDD3JlLkuSbOa5Wd8EPt06HUdptv8Gn0bxYTdbU/XXQ3swAPkEaGxxPN9cbnMHvVu1Ig== - dependencies: - "@types/mdast" "^3.0.0" - mdast-util-gfm "^2.0.0" - micromark-extension-gfm "^2.0.0" - unified "^10.0.0" - -remark-math@^5.1.1: - version "5.1.1" - resolved "https://registry.npmjs.org/remark-math/-/remark-math-5.1.1.tgz" - integrity sha512-cE5T2R/xLVtfFI4cCePtiRn+e6jKMtFDR3P8V3qpv8wpKjwvHoBA4eJzvX+nVrnlNy0911bdGmuspCSwetfYHw== - dependencies: - "@types/mdast" "^3.0.0" - mdast-util-math "^2.0.0" - micromark-extension-math "^2.0.0" - unified "^10.0.0" - -remark-mdx@^2.0.0: - version "2.3.0" - resolved "https://registry.npmjs.org/remark-mdx/-/remark-mdx-2.3.0.tgz" - integrity sha512-g53hMkpM0I98MU266IzDFMrTD980gNF3BJnkyFcmN+dD873mQeD5rdMO3Y2X+x8umQfbSE0PcoEDl7ledSA+2g== - dependencies: - mdast-util-mdx "^2.0.0" - micromark-extension-mdxjs "^1.0.0" - -remark-parse@^10.0.0: - version "10.0.2" - resolved "https://registry.npmjs.org/remark-parse/-/remark-parse-10.0.2.tgz" - integrity sha512-3ydxgHa/ZQzG8LvC7jTXccARYDcRld3VfcgIIFs7bI6vbRSxJJmzgLEIIoYKyrfhaY+ujuWaf/PJiMZXoiCXgw== - dependencies: - "@types/mdast" "^3.0.0" - mdast-util-from-markdown "^1.0.0" - unified "^10.0.0" - -remark-rehype@^10.0.0: - version "10.1.0" - resolved "https://registry.npmjs.org/remark-rehype/-/remark-rehype-10.1.0.tgz" - integrity sha512-EFmR5zppdBp0WQeDVZ/b66CWJipB2q2VLNFMabzDSGR66Z2fQii83G5gTBbgGEnEEA0QRussvrFHxk1HWGJskw== - dependencies: - "@types/hast" "^2.0.0" - "@types/mdast" "^3.0.0" - mdast-util-to-hast "^12.1.0" - unified "^10.0.0" - -renderkid@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-3.0.0.tgz#5fd823e4d6951d37358ecc9a58b1f06836b6268a" - integrity sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg== - dependencies: - css-select "^4.1.3" - dom-converter "^0.2.0" - htmlparser2 "^6.1.0" - lodash "^4.17.21" - strip-ansi "^6.0.1" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== - -require-from-string@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" - integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== - -requireindex@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/requireindex/-/requireindex-1.2.0.tgz#3463cdb22ee151902635aa6c9535d4de9c2ef1ef" - integrity sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww== - -requires-port@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" - integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== - -resize-observer-polyfill@^1.5.1: - version "1.5.1" - resolved "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz" - integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg== - -resolve-alpn@^1.0.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9" - integrity sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g== - -resolve-cwd@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" - integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== - dependencies: - resolve-from "^5.0.0" - -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - -resolve-from@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" - integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== - -resolve-pkg-maps@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz" - integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw== - -resolve-url-loader@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-5.0.0.tgz#ee3142fb1f1e0d9db9524d539cfa166e9314f795" - integrity sha512-uZtduh8/8srhBoMx//5bwqjQ+rfYOUq8zC9NrMUGtjBiGTtFJM42s58/36+hTqeqINcnYe08Nj3LkK9lW4N8Xg== - dependencies: - adjust-sourcemap-loader "^4.0.0" - convert-source-map "^1.7.0" - loader-utils "^2.0.0" - postcss "^8.2.14" - source-map "0.6.1" - -resolve.exports@^2.0.0: - version "2.0.2" - resolved "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz#f8c934b8e6a13f539e38b7098e2e36134f01e800" - integrity sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg== - -resolve@^1.1.7, resolve@^1.10.0, resolve@^1.14.2, resolve@^1.20.0, resolve@^1.22.1, resolve@^1.22.2, resolve@^1.22.4, resolve@^1.22.8: - version "1.22.8" - resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz" - integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== - dependencies: - is-core-module "^2.13.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -resolve@^2.0.0-next.4: - version "2.0.0-next.5" - resolved "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz" - integrity sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA== - dependencies: - is-core-module "^2.13.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -responselike@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.1.tgz#9a0bc8fdc252f3fb1cca68b016591059ba1422bc" - integrity sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw== - dependencies: - lowercase-keys "^2.0.0" - -restore-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz" - integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== - dependencies: - onetime "^5.1.0" - signal-exit "^3.0.2" - -reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== - -rfdc@^1.3.0: - version "1.3.0" - resolved "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz" - integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== - -rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - -ripemd160@^2.0.0, ripemd160@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" - integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - -robust-predicates@^3.0.0: - version "3.0.2" - resolved "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz" - integrity sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg== - -run-applescript@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/run-applescript/-/run-applescript-5.0.0.tgz" - integrity sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg== - dependencies: - execa "^5.0.0" - -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== - dependencies: - queue-microtask "^1.2.2" - -rw@1: - version "1.3.3" - resolved "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz" - integrity sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ== - -rxjs@^7.8.0: - version "7.8.1" - resolved "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz" - integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== - dependencies: - tslib "^2.1.0" - -sade@^1.7.3: - version "1.8.1" - resolved "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz" - integrity sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A== - dependencies: - mri "^1.1.0" - -safe-array-concat@^1.0.1: - version "1.1.0" - resolved "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.0.tgz" - integrity sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg== - dependencies: - call-bind "^1.0.5" - get-intrinsic "^1.2.2" - has-symbols "^1.0.3" - isarray "^2.0.5" - -safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@^5.2.1, safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -safe-regex-test@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz" - integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.3" - is-regex "^1.1.4" - -safe-regex@^2.1.1: - version "2.1.1" - resolved "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz" - integrity sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A== - dependencies: - regexp-tree "~0.1.1" - -"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": - version "2.1.2" - resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -sass-loader@^13.2.0: - version "13.3.3" - resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-13.3.3.tgz#60df5e858788cffb1a3215e5b92e9cba61e7e133" - integrity sha512-mt5YN2F1MOZr3d/wBRcZxeFgwgkH44wVc2zohO2YF6JiOMkiXe4BYRZpSu2sO1g71mo/j16txzUhsKZlqjVGzA== - dependencies: - neo-async "^2.6.2" - -sass@^1.61.0: - version "1.62.1" - resolved "https://registry.npmjs.org/sass/-/sass-1.62.1.tgz" - integrity sha512-NHpxIzN29MXvWiuswfc1W3I0N8SXBd8UR26WntmDlRYf0bSADnwnOjsyMZ3lMezSlArD33Vs3YFhp7dWvL770A== - dependencies: - chokidar ">=3.0.0 <4.0.0" - immutable "^4.0.0" - source-map-js ">=0.6.2 <2.0.0" - -saxes@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz#fe5b4a4768df4f14a201b1ba6a65c1f3d9988cc5" - integrity sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA== - dependencies: - xmlchars "^2.2.0" - -scheduler@^0.23.0: - version "0.23.0" - resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz" - integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw== - dependencies: - loose-envify "^1.1.0" - -scheduler@^0.23.2: - version "0.23.2" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.2.tgz#414ba64a3b282892e944cf2108ecc078d115cdc3" - integrity sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ== - dependencies: - loose-envify "^1.1.0" - -schema-utils@^3.1.1, schema-utils@^3.2.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe" - integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== - dependencies: - "@types/json-schema" "^7.0.8" - ajv "^6.12.5" - ajv-keywords "^3.5.2" - -schema-utils@^4.0.0, schema-utils@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.2.0.tgz#70d7c93e153a273a805801882ebd3bff20d89c8b" - integrity sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw== - dependencies: - "@types/json-schema" "^7.0.9" - ajv "^8.9.0" - ajv-formats "^2.1.1" - ajv-keywords "^5.1.0" - -screenfull@^5.0.0: - version "5.2.0" - resolved "https://registry.npmjs.org/screenfull/-/screenfull-5.2.0.tgz" - integrity sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA== - -"semver@2 || 3 || 4 || 5": - version "5.7.2" - resolved "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz" - integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== - -semver@^6.0.0, semver@^6.3.0, semver@^6.3.1: - version "6.3.1" - resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" - integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== - -semver@^7.0.0, semver@^7.3.5, semver@^7.3.6, semver@^7.3.7, semver@^7.3.8, semver@^7.5.4: - version "7.6.0" - resolved "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz" - integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg== - dependencies: - lru-cache "^6.0.0" - -semver@^7.5.3, semver@^7.6.2, semver@^7.6.3: - version "7.6.3" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" - integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== - -send@0.19.0: - version "0.19.0" - resolved "https://registry.yarnpkg.com/send/-/send-0.19.0.tgz#bbc5a388c8ea6c048967049dbeac0e4a3f09d7f8" - integrity sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw== - dependencies: - debug "2.6.9" - depd "2.0.0" - destroy "1.2.0" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - fresh "0.5.2" - http-errors "2.0.0" - mime "1.6.0" - ms "2.1.3" - on-finished "2.4.1" - range-parser "~1.2.1" - statuses "2.0.1" - -serialize-javascript@^6.0.1: - version "6.0.2" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2" - integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g== - dependencies: - randombytes "^2.1.0" - -serve-static@1.16.2: - version "1.16.2" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.16.2.tgz#b6a5343da47f6bdd2673848bf45754941e803296" - integrity sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw== - dependencies: - encodeurl "~2.0.0" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "0.19.0" - -server-only@^0.0.1: - version "0.0.1" - resolved "https://registry.npmjs.org/server-only/-/server-only-0.0.1.tgz" - integrity sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA== - -set-function-length@^1.1.1: - version "1.2.0" - resolved "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.0.tgz" - integrity sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w== - dependencies: - define-data-property "^1.1.1" - function-bind "^1.1.2" - get-intrinsic "^1.2.2" - gopd "^1.0.1" - has-property-descriptors "^1.0.1" - -set-function-length@^1.2.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" - integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== - dependencies: - define-data-property "^1.1.4" - es-errors "^1.3.0" - function-bind "^1.1.2" - get-intrinsic "^1.2.4" - gopd "^1.0.1" - has-property-descriptors "^1.0.2" - -set-function-name@^2.0.0, set-function-name@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz" - integrity sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA== - dependencies: - define-data-property "^1.0.1" - functions-have-names "^1.2.3" - has-property-descriptors "^1.0.0" - -setimmediate@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== - -setprototypeof@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" - integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== - -sha.js@^2.4.0, sha.js@^2.4.8: - version "2.4.11" - resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" - integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -sharp@^0.33.2: - version "0.33.2" - resolved "https://registry.npmjs.org/sharp/-/sharp-0.33.2.tgz" - integrity sha512-WlYOPyyPDiiM07j/UO+E720ju6gtNtHjEGg5vovUk1Lgxyjm2LFO+37Nt/UI3MMh2l6hxTWQWi7qk3cXJTutcQ== - dependencies: - color "^4.2.3" - detect-libc "^2.0.2" - semver "^7.5.4" - optionalDependencies: - "@img/sharp-darwin-arm64" "0.33.2" - "@img/sharp-darwin-x64" "0.33.2" - "@img/sharp-libvips-darwin-arm64" "1.0.1" - "@img/sharp-libvips-darwin-x64" "1.0.1" - "@img/sharp-libvips-linux-arm" "1.0.1" - "@img/sharp-libvips-linux-arm64" "1.0.1" - "@img/sharp-libvips-linux-s390x" "1.0.1" - "@img/sharp-libvips-linux-x64" "1.0.1" - "@img/sharp-libvips-linuxmusl-arm64" "1.0.1" - "@img/sharp-libvips-linuxmusl-x64" "1.0.1" - "@img/sharp-linux-arm" "0.33.2" - "@img/sharp-linux-arm64" "0.33.2" - "@img/sharp-linux-s390x" "0.33.2" - "@img/sharp-linux-x64" "0.33.2" - "@img/sharp-linuxmusl-arm64" "0.33.2" - "@img/sharp-linuxmusl-x64" "0.33.2" - "@img/sharp-wasm32" "0.33.2" - "@img/sharp-win32-ia32" "0.33.2" - "@img/sharp-win32-x64" "0.33.2" - -sharp@^0.33.3: - version "0.33.5" - resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.33.5.tgz#13e0e4130cc309d6a9497596715240b2ec0c594e" - integrity sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw== - dependencies: - color "^4.2.3" - detect-libc "^2.0.3" - semver "^7.6.3" - optionalDependencies: - "@img/sharp-darwin-arm64" "0.33.5" - "@img/sharp-darwin-x64" "0.33.5" - "@img/sharp-libvips-darwin-arm64" "1.0.4" - "@img/sharp-libvips-darwin-x64" "1.0.4" - "@img/sharp-libvips-linux-arm" "1.0.5" - "@img/sharp-libvips-linux-arm64" "1.0.4" - "@img/sharp-libvips-linux-s390x" "1.0.4" - "@img/sharp-libvips-linux-x64" "1.0.4" - "@img/sharp-libvips-linuxmusl-arm64" "1.0.4" - "@img/sharp-libvips-linuxmusl-x64" "1.0.4" - "@img/sharp-linux-arm" "0.33.5" - "@img/sharp-linux-arm64" "0.33.5" - "@img/sharp-linux-s390x" "0.33.5" - "@img/sharp-linux-x64" "0.33.5" - "@img/sharp-linuxmusl-arm64" "0.33.5" - "@img/sharp-linuxmusl-x64" "0.33.5" - "@img/sharp-wasm32" "0.33.5" - "@img/sharp-win32-ia32" "0.33.5" - "@img/sharp-win32-x64" "0.33.5" - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== - dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" - -side-channel@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2" - integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA== - dependencies: - call-bind "^1.0.7" - es-errors "^1.3.0" - get-intrinsic "^1.2.4" - object-inspect "^1.13.1" - -signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: - version "3.0.7" - resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== - -signal-exit@^4.0.1: - version "4.1.0" - resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz" - integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== - -simple-swizzle@^0.2.2: - version "0.2.2" - resolved "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz" - integrity sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg== - dependencies: - is-arrayish "^0.3.1" - -sisteransi@^1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" - integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== - -size-sensor@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/size-sensor/-/size-sensor-1.0.1.tgz" - integrity sha512-QTy7MnuugCFXIedXRpUSk9gUnyNiaxIdxGfUjr8xxXOqIB3QvBUYP9+b51oCg2C4dnhaeNk/h57TxjbvoJrJUA== - -slash@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== - -slash@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz" - integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== - -slice-ansi@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz" - integrity sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ== - dependencies: - ansi-styles "^4.0.0" - astral-regex "^2.0.0" - is-fullwidth-code-point "^3.0.0" - -slice-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz" - integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== - dependencies: - ansi-styles "^4.0.0" - astral-regex "^2.0.0" - is-fullwidth-code-point "^3.0.0" - -slice-ansi@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz" - integrity sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ== - dependencies: - ansi-styles "^6.0.0" - is-fullwidth-code-point "^4.0.0" - -sortablejs@^1.15.0: - version "1.15.0" - resolved "https://registry.npmjs.org/sortablejs/-/sortablejs-1.15.0.tgz" - integrity sha512-bv9qgVMjUMf89wAvM6AxVvS/4MX3sPeN0+agqShejLU5z5GX4C75ow1O2e5k4L6XItUyAK3gH6AxSbXrOM5e8w== - -"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.2, source-map-js@^1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz" - integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg== - -source-map-js@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" - integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== - -source-map-support@0.5.13: - version "0.5.13" - resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" - integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map-support@~0.5.20: - version "0.5.21" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" - integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -source-map@^0.7.0, source-map@^0.7.3: - version "0.7.4" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz" - integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== - -space-separated-tokens@^1.0.0: - version "1.1.5" - resolved "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz" - integrity sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA== - -space-separated-tokens@^2.0.0: - version "2.0.2" - resolved "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz" - integrity sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q== - -spdx-correct@^3.0.0: - version "3.2.0" - resolved "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz" - integrity sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA== - dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" - -spdx-exceptions@^2.1.0: - version "2.3.0" - resolved "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz" - integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== - -spdx-expression-parse@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz" - integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.13" - resolved "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz" - integrity sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w== - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== - -stack-utils@^2.0.3: - version "2.0.6" - resolved "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f" - integrity sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ== - dependencies: - escape-string-regexp "^2.0.0" - -stackframe@^1.3.4: - version "1.3.4" - resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.3.4.tgz#b881a004c8c149a5e8efef37d51b16e412943310" - integrity sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw== - -state-local@^1.0.6: - version "1.0.7" - resolved "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz" - integrity sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w== - -statuses@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" - integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== - -stop-iteration-iterator@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz" - integrity sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ== - dependencies: - internal-slot "^1.0.4" - -storybook@^8.3.5: - version "8.3.5" - resolved "https://registry.yarnpkg.com/storybook/-/storybook-8.3.5.tgz#aef0542c08e245b7ac22742c1e1633a125063b8e" - integrity sha512-hYQVtP2l+3kO8oKDn4fjXXQYxgTRsj/LaV6lUMJH0zt+OhVmDXKJLxmdUP4ieTm0T8wEbSYosFavgPcQZlxRfw== - dependencies: - "@storybook/core" "8.3.5" - -stream-browserify@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-3.0.0.tgz#22b0a2850cdf6503e73085da1fc7b7d0c2122f2f" - integrity sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA== - dependencies: - inherits "~2.0.4" - readable-stream "^3.5.0" - -stream-http@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-3.2.0.tgz#1872dfcf24cb15752677e40e5c3f9cc1926028b5" - integrity sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A== - dependencies: - builtin-status-codes "^3.0.0" - inherits "^2.0.4" - readable-stream "^3.6.0" - xtend "^4.0.2" - -streamsearch@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz" - integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== - -string-argv@^0.3.1: - version "0.3.2" - resolved "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz" - integrity sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q== - -string-length@^4.0.1: - version "4.0.2" - resolved "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" - integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== - dependencies: - char-regex "^1.0.2" - strip-ansi "^6.0.0" - -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@4.2.3, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3, string-width@^5.0.0, string-width@^5.0.1, string-width@^5.1.2: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string.prototype.matchall@^4.0.8: - version "4.0.10" - resolved "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz" - integrity sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" - has-symbols "^1.0.3" - internal-slot "^1.0.5" - regexp.prototype.flags "^1.5.0" - set-function-name "^2.0.0" - side-channel "^1.0.4" - -string.prototype.trim@^1.2.8: - version "1.2.8" - resolved "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz" - integrity sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - -string.prototype.trimend@^1.0.7: - version "1.0.7" - resolved "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz" - integrity sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - -string.prototype.trimstart@^1.0.7: - version "1.0.7" - resolved "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz" - integrity sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - -string_decoder@^1.1.1, string_decoder@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -stringify-entities@^4.0.0: - version "4.0.3" - resolved "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.3.tgz" - integrity sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g== - dependencies: - character-entities-html4 "^2.0.0" - character-entities-legacy "^3.0.0" - -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": - version "6.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^7.0.1, strip-ansi@^7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" - integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== - dependencies: - ansi-regex "^6.0.1" - -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" - integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== - -strip-bom@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" - integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== - -strip-final-newline@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz" - integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== - -strip-final-newline@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz" - integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw== - -strip-indent@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz" - integrity sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ== - dependencies: - min-indent "^1.0.0" - -strip-indent@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-4.0.0.tgz#b41379433dd06f5eae805e21d631e07ee670d853" - integrity sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA== - dependencies: - min-indent "^1.0.1" - -strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: - version "3.1.1" - resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - -style-loader@^3.3.1: - version "3.3.4" - resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.4.tgz#f30f786c36db03a45cbd55b6a70d930c479090e7" - integrity sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w== - -style-to-object@^0.4.0, style-to-object@^0.4.1: - version "0.4.1" - resolved "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.1.tgz" - integrity sha512-HFpbb5gr2ypci7Qw+IOhnP2zOU7e77b+rzM+wTzXzfi1PrtBCX0E7Pk4wL4iTLnhzZ+JgEGAhX81ebTg/aYjQw== - dependencies: - inline-style-parser "0.1.1" - -styled-jsx@5.1.1: - version "5.1.1" - resolved "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz" - integrity sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw== - dependencies: - client-only "0.0.1" - -styled-jsx@^5.1.6: - version "5.1.6" - resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-5.1.6.tgz#83b90c077e6c6a80f7f5e8781d0f311b2fe41499" - integrity sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA== - dependencies: - client-only "0.0.1" - -stylis@^4.1.3: - version "4.3.0" - resolved "https://registry.npmjs.org/stylis/-/stylis-4.3.0.tgz" - integrity sha512-E87pIogpwUsUwXw7dNyU4QDjdgVMy52m+XEOPEKUn161cCzWjjhPSQhByfd1CcNvrOLnXQ6OnnZDwnJrz/Z4YQ== - -sucrase@^3.32.0: - version "3.32.0" - resolved "https://registry.npmjs.org/sucrase/-/sucrase-3.32.0.tgz" - integrity sha512-ydQOU34rpSyj2TGyz4D2p8rbktIOZ8QY9s+DGLvFU1i5pWJE8vkpruCjGCMHsdXwnD7JDcS+noSwM/a7zyNFDQ== - dependencies: - "@jridgewell/gen-mapping" "^0.3.2" - commander "^4.0.0" - glob "7.1.6" - lines-and-columns "^1.1.6" - mz "^2.7.0" - pirates "^4.0.1" - ts-interface-checker "^0.1.9" - -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -supports-color@^8.0.0: - version "8.1.1" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - -supports-preserve-symlinks-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz" - integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== - -swr@^2.1.0: - version "2.1.5" - resolved "https://registry.npmjs.org/swr/-/swr-2.1.5.tgz" - integrity sha512-/OhfZMcEpuz77KavXST5q6XE9nrOBOVcBLWjMT+oAE/kQHyE3PASrevXCtQDZ8aamntOfFkbVJp7Il9tNBQWrw== - dependencies: - use-sync-external-store "^1.2.0" - -symbol-tree@^3.2.4: - version "3.2.4" - resolved "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" - integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== - -synckit@^0.8.5: - version "0.8.5" - resolved "https://registry.npmjs.org/synckit/-/synckit-0.8.5.tgz" - integrity sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q== - dependencies: - "@pkgr/utils" "^2.3.1" - tslib "^2.5.0" - -tabbable@^6.0.1: - version "6.2.0" - resolved "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz" - integrity sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew== - -tailwind-merge@^2.4.0: - version "2.4.0" - resolved "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.4.0.tgz#1345209dc1f484f15159c9180610130587703042" - integrity sha512-49AwoOQNKdqKPd9CViyH5wJoSKsCDjUlzL8DxuGp3P1FsGY36NJDAa18jLZcaHAUUuTj+JB8IAo8zWgBNvBF7A== - -tailwindcss@^3.4.4: - version "3.4.4" - resolved "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.4.tgz#351d932273e6abfa75ce7d226b5bf3a6cb257c05" - integrity sha512-ZoyXOdJjISB7/BcLTR6SEsLgKtDStYyYZVLsUtWChO4Ps20CBad7lfJKVDiejocV4ME1hLmyY0WJE3hSDcmQ2A== - dependencies: - "@alloc/quick-lru" "^5.2.0" - arg "^5.0.2" - chokidar "^3.5.3" - didyoumean "^1.2.2" - dlv "^1.1.3" - fast-glob "^3.3.0" - glob-parent "^6.0.2" - is-glob "^4.0.3" - jiti "^1.21.0" - lilconfig "^2.1.0" - micromatch "^4.0.5" - normalize-path "^3.0.0" - object-hash "^3.0.0" - picocolors "^1.0.0" - postcss "^8.4.23" - postcss-import "^15.1.0" - postcss-js "^4.0.1" - postcss-load-config "^4.0.1" - postcss-nested "^6.0.1" - postcss-selector-parser "^6.0.11" - resolve "^1.22.2" - sucrase "^3.32.0" - -tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0, tapable@^2.2.1: - version "2.2.1" - resolved "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz" - integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== - -telejson@^7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/telejson/-/telejson-7.2.0.tgz#3994f6c9a8f8d7f2dba9be2c7c5bbb447e876f32" - integrity sha512-1QTEcJkJEhc8OnStBx/ILRu5J2p0GjvWsBx56bmZRqnrkdBMUe+nX92jxV+p3dB4CP6PZCdJMQJwCggkNBMzkQ== - dependencies: - memoizerific "^1.11.3" - -terser-webpack-plugin@^5.3.1, terser-webpack-plugin@^5.3.10: - version "5.3.10" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz#904f4c9193c6fd2a03f693a2150c62a92f40d199" - integrity sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w== - dependencies: - "@jridgewell/trace-mapping" "^0.3.20" - jest-worker "^27.4.5" - schema-utils "^3.1.1" - serialize-javascript "^6.0.1" - terser "^5.26.0" - -terser@^5.10.0, terser@^5.26.0: - version "5.36.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.36.0.tgz#8b0dbed459ac40ff7b4c9fd5a3a2029de105180e" - integrity sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w== - dependencies: - "@jridgewell/source-map" "^0.3.3" - acorn "^8.8.2" - commander "^2.20.0" - source-map-support "~0.5.20" - -test-exclude@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" - integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== - dependencies: - "@istanbuljs/schema" "^0.1.2" - glob "^7.1.4" - minimatch "^3.0.4" - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" - integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== - -thenify-all@^1.0.0: - version "1.6.0" - resolved "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz" - integrity sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA== - dependencies: - thenify ">= 3.1.0 < 4" - -"thenify@>= 3.1.0 < 4": - version "3.3.1" - resolved "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz" - integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== - dependencies: - any-promise "^1.0.0" - -throttle-debounce@^2.1.0: - version "2.3.0" - resolved "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-2.3.0.tgz" - integrity sha512-H7oLPV0P7+jgvrk+6mwwwBDmxTaxnu9HMXmloNLXwnNO0ZxZ31Orah2n8lU1eMPvsaowP2CX+USCgyovXfdOFQ== - -through@^2.3.8: - version "2.3.8" - resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz" - integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== - -timers-browserify@^2.0.12: - version "2.0.12" - resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.12.tgz#44a45c11fbf407f34f97bccd1577c652361b00ee" - integrity sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ== - dependencies: - setimmediate "^1.0.4" - -tiny-invariant@1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.2.0.tgz" - integrity sha512-1Uhn/aqw5C6RI4KejVeTg6mIS7IqxnLJ8Mv2tV5rTc0qWobay7pDUz6Wi392Cnc8ak1H0F2cjoRzb2/AW4+Fvg== - -tiny-invariant@^1.3.1, tiny-invariant@^1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.3.tgz#46680b7a873a0d5d10005995eb90a70d74d60127" - integrity sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg== - -tinyrainbow@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/tinyrainbow/-/tinyrainbow-1.2.0.tgz#5c57d2fc0fb3d1afd78465c33ca885d04f02abb5" - integrity sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ== - -tinyspy@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/tinyspy/-/tinyspy-3.0.2.tgz#86dd3cf3d737b15adcf17d7887c84a75201df20a" - integrity sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q== - -titleize@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz" - integrity sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ== - -tmpl@1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" - integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== - -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -toggle-selection@^1.0.6: - version "1.0.6" - resolved "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz" - integrity sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ== - -toidentifier@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" - integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== - -tough-cookie@^4.1.2: - version "4.1.4" - resolved "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz#945f1461b45b5a8c76821c33ea49c3ac192c1b36" - integrity sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag== - dependencies: - psl "^1.1.33" - punycode "^2.1.1" - universalify "^0.2.0" - url-parse "^1.5.3" - -tr46@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz#555c4e297a950617e8eeddef633c87d4d9d6cbf9" - integrity sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA== - dependencies: - punycode "^2.1.1" - -trim-lines@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz" - integrity sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg== - -trough@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/trough/-/trough-2.1.0.tgz" - integrity sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g== - -ts-dedent@^2.0.0, ts-dedent@^2.2.0: - version "2.2.0" - resolved "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz" - integrity sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ== - -ts-interface-checker@^0.1.9: - version "0.1.13" - resolved "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz" - integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA== - -ts-node@^10.9.2: - version "10.9.2" - resolved "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz#70f021c9e185bccdca820e26dc413805c101c71f" - integrity sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ== - dependencies: - "@cspotcode/source-map-support" "^0.8.0" - "@tsconfig/node10" "^1.0.7" - "@tsconfig/node12" "^1.0.7" - "@tsconfig/node14" "^1.0.0" - "@tsconfig/node16" "^1.0.2" - acorn "^8.4.1" - acorn-walk "^8.1.1" - arg "^4.1.0" - create-require "^1.1.0" - diff "^4.0.1" - make-error "^1.1.1" - v8-compile-cache-lib "^3.0.1" - yn "3.1.1" - -ts-pnp@^1.1.6: - version "1.2.0" - resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92" - integrity sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw== - -tsconfig-paths-webpack-plugin@^4.0.1: - version "4.1.0" - resolved "https://registry.yarnpkg.com/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-4.1.0.tgz#3c6892c5e7319c146eee1e7302ed9e6f2be4f763" - integrity sha512-xWFISjviPydmtmgeUAuXp4N1fky+VCtfhOkDUFIv5ea7p4wuTomI4QTrXvFBX2S4jZsmyTSrStQl+E+4w+RzxA== - dependencies: - chalk "^4.1.0" - enhanced-resolve "^5.7.0" - tsconfig-paths "^4.1.2" - -tsconfig-paths@^3.15.0: - version "3.15.0" - resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz" - integrity sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg== - dependencies: - "@types/json5" "^0.0.29" - json5 "^1.0.2" - minimist "^1.2.6" - strip-bom "^3.0.0" - -tsconfig-paths@^4.0.0, tsconfig-paths@^4.1.2, tsconfig-paths@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz#ef78e19039133446d244beac0fd6a1632e2d107c" - integrity sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg== - dependencies: - json5 "^2.2.2" - minimist "^1.2.6" - strip-bom "^3.0.0" - -tslib@2.3.0: - version "2.3.0" - resolved "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz" - integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg== - -tslib@^1.8.1, tslib@^1.9.3: - version "1.14.1" - resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - -tslib@^2.0.0, tslib@^2.0.3: - version "2.8.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.0.tgz#d124c86c3c05a40a91e6fdea4021bd31d377971b" - integrity sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA== - -tslib@^2.0.1: - version "2.7.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.7.0.tgz#d9b40c5c40ab59e8738f297df3087bf1a2690c01" - integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA== - -tslib@^2.1.0, tslib@^2.4.0, tslib@^2.4.1, tslib@^2.5.0: - version "2.5.3" - resolved "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz" - integrity sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w== - -tsutils@^3.21.0: - version "3.21.0" - resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz" - integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== - dependencies: - tslib "^1.8.1" - -tty-browserify@^0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.1.tgz#3f05251ee17904dfd0677546670db9651682b811" - integrity sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw== - -tween-functions@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/tween-functions/-/tween-functions-1.2.0.tgz#1ae3a50e7c60bb3def774eac707acbca73bbc3ff" - integrity sha512-PZBtLYcCLtEcjL14Fzb1gSxPBeL7nWvGhO5ZFPGqziCcr8uvHp0NDmdjBchp6KHL+tExcg0m3NISmKxhU394dA== - -type-check@^0.4.0, type-check@~0.4.0: - version "0.4.0" - resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz" - integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== - dependencies: - prelude-ls "^1.2.1" - -type-detect@4.0.8: - version "4.0.8" - resolved "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" - integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== - -type-fest@^0.20.2: - version "0.20.2" - resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz" - integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== - -type-fest@^0.21.3: - version "0.21.3" - resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz" - integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== - -type-fest@^0.6.0: - version "0.6.0" - resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz" - integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== - -type-fest@^0.8.1: - version "0.8.1" - resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz" - integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== - -type-fest@^2.14.0, type-fest@^2.19.0, type-fest@~2.19: - version "2.19.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b" - integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA== - -type-is@~1.6.18: - version "1.6.18" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" - integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== - dependencies: - media-typer "0.3.0" - mime-types "~2.1.24" - -typed-array-buffer@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz" - integrity sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.2.1" - is-typed-array "^1.1.10" - -typed-array-byte-length@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz" - integrity sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA== - dependencies: - call-bind "^1.0.2" - for-each "^0.3.3" - has-proto "^1.0.1" - is-typed-array "^1.1.10" - -typed-array-byte-offset@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz" - integrity sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg== - dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - for-each "^0.3.3" - has-proto "^1.0.1" - is-typed-array "^1.1.10" - -typed-array-length@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz" - integrity sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng== - dependencies: - call-bind "^1.0.2" - for-each "^0.3.3" - is-typed-array "^1.1.9" - -typescript@4.9.5: - version "4.9.5" - resolved "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz" - integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== - -uglify-js@^3.17.4: - version "3.17.4" - resolved "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz" - integrity sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g== - -unbox-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz" - integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== - dependencies: - call-bind "^1.0.2" - has-bigints "^1.0.2" - has-symbols "^1.0.3" - which-boxed-primitive "^1.0.2" - -undici-types@~6.19.2: - version "6.19.8" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" - integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== - -unicode-canonical-property-names-ecmascript@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz#cb3173fe47ca743e228216e4a3ddc4c84d628cc2" - integrity sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg== - -unicode-match-property-ecmascript@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3" - integrity sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q== - dependencies: - unicode-canonical-property-names-ecmascript "^2.0.0" - unicode-property-aliases-ecmascript "^2.0.0" - -unicode-match-property-value-ecmascript@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz#a0401aee72714598f739b68b104e4fe3a0cb3c71" - integrity sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg== - -unicode-property-aliases-ecmascript@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz#43d41e3be698bd493ef911077c9b131f827e8ccd" - integrity sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w== - -unified@^10.0.0: - version "10.1.2" - resolved "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz" - integrity sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q== - dependencies: - "@types/unist" "^2.0.0" - bail "^2.0.0" - extend "^3.0.0" - is-buffer "^2.0.0" - is-plain-obj "^4.0.0" - trough "^2.0.0" - vfile "^5.0.0" - -unist-util-find-after@^4.0.0: - version "4.0.1" - resolved "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-4.0.1.tgz" - integrity sha512-QO/PuPMm2ERxC6vFXEPtmAutOopy5PknD+Oq64gGwxKtk4xwo9Z97t9Av1obPmGU0IyTa6EKYUfTrK2QJS3Ozw== - dependencies: - "@types/unist" "^2.0.0" - unist-util-is "^5.0.0" - -unist-util-generated@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-2.0.1.tgz" - integrity sha512-qF72kLmPxAw0oN2fwpWIqbXAVyEqUzDHMsbtPvOudIlUzXYFIeQIuxXQCRCFh22B7cixvU0MG7m3MW8FTq/S+A== - -unist-util-is@^5.0.0: - version "5.2.1" - resolved "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz" - integrity sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw== - dependencies: - "@types/unist" "^2.0.0" - -unist-util-is@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-6.0.0.tgz#b775956486aff107a9ded971d996c173374be424" - integrity sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw== - dependencies: - "@types/unist" "^3.0.0" - -unist-util-position-from-estree@^1.0.0, unist-util-position-from-estree@^1.1.0: - version "1.1.2" - resolved "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-1.1.2.tgz" - integrity sha512-poZa0eXpS+/XpoQwGwl79UUdea4ol2ZuCYguVaJS4qzIOMDzbqz8a3erUCOmubSZkaOuGamb3tX790iwOIROww== - dependencies: - "@types/unist" "^2.0.0" - -unist-util-position@^4.0.0: - version "4.0.4" - resolved "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.4.tgz" - integrity sha512-kUBE91efOWfIVBo8xzh/uZQ7p9ffYRtUbMRZBNFYwf0RK8koUMx6dGUfwylLOKmaT2cs4wSW96QoYUSXAyEtpg== - dependencies: - "@types/unist" "^2.0.0" - -unist-util-position@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-5.0.0.tgz#678f20ab5ca1207a97d7ea8a388373c9cf896be4" - integrity sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA== - dependencies: - "@types/unist" "^3.0.0" - -unist-util-remove-position@^4.0.0: - version "4.0.2" - resolved "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-4.0.2.tgz" - integrity sha512-TkBb0HABNmxzAcfLf4qsIbFbaPDvMO6wa3b3j4VcEzFVaw1LBKwnW4/sRJ/atSLSzoIg41JWEdnE7N6DIhGDGQ== - dependencies: - "@types/unist" "^2.0.0" - unist-util-visit "^4.0.0" - -unist-util-stringify-position@^2.0.0: - version "2.0.3" - resolved "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz" - integrity sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g== - dependencies: - "@types/unist" "^2.0.2" - -unist-util-stringify-position@^3.0.0: - version "3.0.3" - resolved "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz" - integrity sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg== - dependencies: - "@types/unist" "^2.0.0" - -unist-util-stringify-position@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz#449c6e21a880e0855bf5aabadeb3a740314abac2" - integrity sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ== - dependencies: - "@types/unist" "^3.0.0" - -unist-util-visit-parents@^5.0.0, unist-util-visit-parents@^5.1.1: - version "5.1.3" - resolved "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz" - integrity sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg== - dependencies: - "@types/unist" "^2.0.0" - unist-util-is "^5.0.0" - -unist-util-visit-parents@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz#4d5f85755c3b8f0dc69e21eca5d6d82d22162815" - integrity sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw== - dependencies: - "@types/unist" "^3.0.0" - unist-util-is "^6.0.0" - -unist-util-visit@^4.0.0: - version "4.1.2" - resolved "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz" - integrity sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg== - dependencies: - "@types/unist" "^2.0.0" - unist-util-is "^5.0.0" - unist-util-visit-parents "^5.1.1" - -unist-util-visit@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-5.0.0.tgz#a7de1f31f72ffd3519ea71814cccf5fd6a9217d6" - integrity sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg== - dependencies: - "@types/unist" "^3.0.0" - unist-util-is "^6.0.0" - unist-util-visit-parents "^6.0.0" - -universalify@^0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0" - integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg== - -universalify@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" - integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== - -unpipe@1.0.0, unpipe@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== - -unplugin@^1.3.1: - version "1.14.1" - resolved "https://registry.yarnpkg.com/unplugin/-/unplugin-1.14.1.tgz#c76d6155a661e43e6a897bce6b767a1ecc344c1a" - integrity sha512-lBlHbfSFPToDYp9pjXlUEFVxYLaue9f9T1HC+4OHlmj+HnMDdz9oZY+erXfoCe/5V/7gKUSY2jpXPb9S7f0f/w== - dependencies: - acorn "^8.12.1" - webpack-virtual-modules "^0.6.2" - -untildify@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz" - integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== - -update-browserslist-db@^1.0.13: - version "1.0.16" - resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz" - integrity sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ== - dependencies: - escalade "^3.1.2" - picocolors "^1.0.1" - -update-browserslist-db@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz#7ca61c0d8650766090728046e416a8cde682859e" - integrity sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ== - dependencies: - escalade "^3.1.2" - picocolors "^1.0.1" - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -url-parse@^1.5.3: - version "1.5.10" - resolved "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1" - integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ== - dependencies: - querystringify "^2.1.1" - requires-port "^1.0.0" - -url@^0.11.0: - version "0.11.4" - resolved "https://registry.yarnpkg.com/url/-/url-0.11.4.tgz#adca77b3562d56b72746e76b330b7f27b6721f3c" - integrity sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg== - dependencies: - punycode "^1.4.1" - qs "^6.12.3" - -use-context-selector@^1.4.1: - version "1.4.1" - resolved "https://registry.npmjs.org/use-context-selector/-/use-context-selector-1.4.1.tgz" - integrity sha512-Io2ArvcRO+6MWIhkdfMFt+WKQX+Vb++W8DS2l03z/Vw/rz3BclKpM0ynr4LYGyU85Eke+Yx5oIhTY++QR0ZDoA== - -use-strict@1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/use-strict/-/use-strict-1.0.1.tgz" - integrity sha512-IeiWvvEXfW5ltKVMkxq6FvNf2LojMKvB2OCeja6+ct24S1XOmQw2dGr2JyndwACWAGJva9B7yPHwAmeA9QCqAQ== - -use-sync-external-store@1.2.0, use-sync-external-store@^1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz" - integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== - -util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" - integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== - -util@^0.12.4, util@^0.12.5: - version "0.12.5" - resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc" - integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== - dependencies: - inherits "^2.0.3" - is-arguments "^1.0.4" - is-generator-function "^1.0.7" - is-typed-array "^1.1.3" - which-typed-array "^1.1.2" - -utila@~0.4: - version "0.4.0" - resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" - integrity sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA== - -utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== - -uuid@^9.0.0, uuid@^9.0.1: - version "9.0.1" - resolved "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz" - integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== - -uvu@^0.5.0: - version "0.5.6" - resolved "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz" - integrity sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA== - dependencies: - dequal "^2.0.0" - diff "^5.0.0" - kleur "^4.0.3" - sade "^1.7.3" - -v8-compile-cache-lib@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" - integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== - -v8-to-istanbul@^9.0.1: - version "9.3.0" - resolved "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz#b9572abfa62bd556c16d75fdebc1a411d5ff3175" - integrity sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA== - dependencies: - "@jridgewell/trace-mapping" "^0.3.12" - "@types/istanbul-lib-coverage" "^2.0.1" - convert-source-map "^2.0.0" - -validate-npm-package-license@^3.0.1: - version "3.0.4" - resolved "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz" - integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== - dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" - -vary@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== - -vfile-location@^4.0.0: - version "4.1.0" - resolved "https://registry.npmjs.org/vfile-location/-/vfile-location-4.1.0.tgz" - integrity sha512-YF23YMyASIIJXpktBa4vIGLJ5Gs88UB/XePgqPmTa7cDA+JeO3yclbpheQYCHjVHBn/yePzrXuygIL+xbvRYHw== - dependencies: - "@types/unist" "^2.0.0" - vfile "^5.0.0" - -vfile-location@^5.0.0: - version "5.0.3" - resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-5.0.3.tgz#cb9eacd20f2b6426d19451e0eafa3d0a846225c3" - integrity sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg== - dependencies: - "@types/unist" "^3.0.0" - vfile "^6.0.0" - -vfile-message@^3.0.0: - version "3.1.4" - resolved "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.4.tgz" - integrity sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw== - dependencies: - "@types/unist" "^2.0.0" - unist-util-stringify-position "^3.0.0" - -vfile-message@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-4.0.2.tgz#c883c9f677c72c166362fd635f21fc165a7d1181" - integrity sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw== - dependencies: - "@types/unist" "^3.0.0" - unist-util-stringify-position "^4.0.0" - -vfile@^5.0.0: - version "5.3.7" - resolved "https://registry.npmjs.org/vfile/-/vfile-5.3.7.tgz" - integrity sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g== - dependencies: - "@types/unist" "^2.0.0" - is-buffer "^2.0.0" - unist-util-stringify-position "^3.0.0" - vfile-message "^3.0.0" - -vfile@^6.0.0: - version "6.0.2" - resolved "https://registry.yarnpkg.com/vfile/-/vfile-6.0.2.tgz#ef49548ea3d270097a67011921411130ceae7deb" - integrity sha512-zND7NlS8rJYb/sPqkb13ZvbbUoExdbi4w3SfRrMq6R3FvnLQmmfpajJNITuuYm6AZ5uao9vy4BAos3EXBPf2rg== - dependencies: - "@types/unist" "^3.0.0" - unist-util-stringify-position "^4.0.0" - vfile-message "^4.0.0" - -vite-code-inspector-plugin@0.13.0: - version "0.13.0" - resolved "https://registry.npmjs.org/vite-code-inspector-plugin/-/vite-code-inspector-plugin-0.13.0.tgz" - integrity sha512-hvIn9G+IFzQHVVynWh2wGTBHo51CBJRqQBzYryeuuaL0BK0w8my2/tlpSAae5ofQxOBXBMhyXC2gWgYUJnNWrA== - dependencies: - code-inspector-core "0.13.0" - -vm-browserify@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" - integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== - -void-elements@3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz" - integrity sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w== - -vue-eslint-parser@^9.3.0: - version "9.3.0" - resolved "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.3.0.tgz" - integrity sha512-48IxT9d0+wArT1+3wNIy0tascRoywqSUe2E1YalIC1L8jsUGe5aJQItWfRok7DVFGz3UYvzEI7n5wiTXsCMAcQ== - dependencies: - debug "^4.3.4" - eslint-scope "^7.1.1" - eslint-visitor-keys "^3.3.0" - espree "^9.3.1" - esquery "^1.4.0" - lodash "^4.17.21" - semver "^7.3.6" - -w3c-xmlserializer@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz#aebdc84920d806222936e3cdce408e32488a3073" - integrity sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw== - dependencies: - xml-name-validator "^4.0.0" - -walker@^1.0.8: - version "1.0.8" - resolved "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" - integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== - dependencies: - makeerror "1.0.12" - -watchpack@^2.4.1: - version "2.4.2" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.2.tgz#2feeaed67412e7c33184e5a79ca738fbd38564da" - integrity sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw== - dependencies: - glob-to-regexp "^0.4.1" - graceful-fs "^4.1.2" - -web-namespaces@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz" - integrity sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ== - -web-worker@^1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz" - integrity sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA== - -webidl-conversions@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a" - integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g== - -webpack-code-inspector-plugin@0.13.0: - version "0.13.0" - resolved "https://registry.npmjs.org/webpack-code-inspector-plugin/-/webpack-code-inspector-plugin-0.13.0.tgz" - integrity sha512-T3ZZ84NX0cVmwff5zyYhB9OuroZYsyaQpSgFicgiuYAWCsQePYApM/R3bHdvcECkBXO50hAVtr9SjWRTu1+Ntg== - dependencies: - code-inspector-core "0.13.0" - -webpack-dev-middleware@^6.1.2: - version "6.1.3" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-6.1.3.tgz#79f4103f8c898564c9e96c3a9c2422de50f249bc" - integrity sha512-A4ChP0Qj8oGociTs6UdlRUGANIGrCDL3y+pmQMc+dSsraXHCatFpmMey4mYELA+juqwUqwQsUgJJISXl1KWmiw== - dependencies: - colorette "^2.0.10" - memfs "^3.4.12" - mime-types "^2.1.31" - range-parser "^1.2.1" - schema-utils "^4.0.0" - -webpack-hot-middleware@^2.25.1: - version "2.26.1" - resolved "https://registry.yarnpkg.com/webpack-hot-middleware/-/webpack-hot-middleware-2.26.1.tgz#87214f1e3f9f3acab9271fef9e6ed7b637d719c0" - integrity sha512-khZGfAeJx6I8K9zKohEWWYN6KDlVw2DHownoe+6Vtwj1LP9WFgegXnVMSkZ/dBEBtXFwrkkydsaPFlB7f8wU2A== - dependencies: - ansi-html-community "0.0.8" - html-entities "^2.1.0" - strip-ansi "^6.0.0" - -webpack-sources@^3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" - integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== - -webpack-virtual-modules@^0.6.0, webpack-virtual-modules@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz#057faa9065c8acf48f24cb57ac0e77739ab9a7e8" - integrity sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ== - -webpack@5: - version "5.95.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.95.0.tgz#8fd8c454fa60dad186fbe36c400a55848307b4c0" - integrity sha512-2t3XstrKULz41MNMBF+cJ97TyHdyQ8HCt//pqErqDvNjU9YQBnZxIHa11VXsi7F3mb5/aO2tuDxdeTPdU7xu9Q== - dependencies: - "@types/estree" "^1.0.5" - "@webassemblyjs/ast" "^1.12.1" - "@webassemblyjs/wasm-edit" "^1.12.1" - "@webassemblyjs/wasm-parser" "^1.12.1" - acorn "^8.7.1" - acorn-import-attributes "^1.9.5" - browserslist "^4.21.10" - chrome-trace-event "^1.0.2" - enhanced-resolve "^5.17.1" - es-module-lexer "^1.2.1" - eslint-scope "5.1.1" - events "^3.2.0" - glob-to-regexp "^0.4.1" - graceful-fs "^4.2.11" - json-parse-even-better-errors "^2.3.1" - loader-runner "^4.2.0" - mime-types "^2.1.27" - neo-async "^2.6.2" - schema-utils "^3.2.0" - tapable "^2.1.1" - terser-webpack-plugin "^5.3.10" - watchpack "^2.4.1" - webpack-sources "^3.2.3" - -whatwg-encoding@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz#e7635f597fd87020858626805a2729fa7698ac53" - integrity sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg== - dependencies: - iconv-lite "0.6.3" - -whatwg-mimetype@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz#5fa1a7623867ff1af6ca3dc72ad6b8a4208beba7" - integrity sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q== - -whatwg-url@^11.0.0: - version "11.0.0" - resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz#0a849eebb5faf2119b901bb76fd795c2848d4018" - integrity sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ== - dependencies: - tr46 "^3.0.0" - webidl-conversions "^7.0.0" - -which-boxed-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz" - integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== - dependencies: - is-bigint "^1.0.1" - is-boolean-object "^1.1.0" - is-number-object "^1.0.4" - is-string "^1.0.5" - is-symbol "^1.0.3" - -which-builtin-type@^1.1.3: - version "1.1.3" - resolved "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz" - integrity sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw== - dependencies: - function.prototype.name "^1.1.5" - has-tostringtag "^1.0.0" - is-async-function "^2.0.0" - is-date-object "^1.0.5" - is-finalizationregistry "^1.0.2" - is-generator-function "^1.0.10" - is-regex "^1.1.4" - is-weakref "^1.0.2" - isarray "^2.0.5" - which-boxed-primitive "^1.0.2" - which-collection "^1.0.1" - which-typed-array "^1.1.9" - -which-collection@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz" - integrity sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A== - dependencies: - is-map "^2.0.1" - is-set "^2.0.1" - is-weakmap "^2.0.1" - is-weakset "^2.0.1" - -which-typed-array@^1.1.11, which-typed-array@^1.1.13, which-typed-array@^1.1.9: - version "1.1.13" - resolved "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz" - integrity sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow== - dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.4" - for-each "^0.3.3" - gopd "^1.0.1" - has-tostringtag "^1.0.0" - -which-typed-array@^1.1.14, which-typed-array@^1.1.2: - version "1.1.15" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.15.tgz#264859e9b11a649b388bfaaf4f767df1f779b38d" - integrity sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA== - dependencies: - available-typed-arrays "^1.0.7" - call-bind "^1.0.7" - for-each "^0.3.3" - gopd "^1.0.1" - has-tostringtag "^1.0.2" - -which@^2.0.1: - version "2.0.2" - resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -word-wrap@^1.2.3: - version "1.2.5" - resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz" - integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== - -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": - version "7.0.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^6.2.0: - version "6.2.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz" - integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^8.1.0: - version "8.1.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz" - integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== - dependencies: - ansi-styles "^6.1.0" - string-width "^5.0.1" - strip-ansi "^7.0.1" - -wrappy@1: - version "1.0.2" - resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" - integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== - -write-file-atomic@^4.0.2: - version "4.0.2" - resolved "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd" - integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg== - dependencies: - imurmurhash "^0.1.4" - signal-exit "^3.0.7" - -ws@^8.11.0, ws@^8.2.3: - version "8.18.0" - resolved "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc" - integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw== - -xml-name-validator@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz" - integrity sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw== - -xmlchars@^2.2.0: - version "2.2.0" - resolved "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" - integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== - -xtend@^4.0.0, xtend@^4.0.2: - version "4.0.2" - resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz" - integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== - -y18n@^5.0.5: - version "5.0.8" - resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" - integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== - -yallist@^3.0.2: - version "3.1.1" - resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" - integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yaml-eslint-parser@^1.1.0, yaml-eslint-parser@^1.2.1: - version "1.2.2" - resolved "https://registry.npmjs.org/yaml-eslint-parser/-/yaml-eslint-parser-1.2.2.tgz" - integrity sha512-pEwzfsKbTrB8G3xc/sN7aw1v6A6c/pKxLAkjclnAyo5g5qOh6eL9WGu0o3cSDQZKrTNk4KL4lQSwZW+nBkANEg== - dependencies: - eslint-visitor-keys "^3.0.0" - lodash "^4.17.21" - yaml "^2.0.0" - -yaml@^1.10.0: - version "1.10.2" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" - integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== - -yaml@^2.0.0, yaml@^2.1.1, yaml@^2.2.2: - version "2.3.1" - resolved "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz" - integrity sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ== - -yargs-parser@^21.1.1: - version "21.1.1" - resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" - integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== - -yargs@^17.3.1: - version "17.7.2" - resolved "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" - integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== - dependencies: - cliui "^8.0.1" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.3" - y18n "^5.0.5" - yargs-parser "^21.1.1" - -yn@3.1.1: - version "3.1.1" - resolved "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" - integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== - -yocto-queue@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.1.1.tgz#fef65ce3ac9f8a32ceac5a634f74e17e5b232110" - integrity sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g== - -zod@^3.23.6: - version "3.23.6" - resolved "https://registry.npmjs.org/zod/-/zod-3.23.6.tgz" - integrity sha512-RTHJlZhsRbuA8Hmp/iNL7jnfc4nZishjsanDAfEY1QpDQZCahUp3xDzl+zfweE9BklxMUcgBgS1b7Lvie/ZVwA== - -zrender@5.4.3: - version "5.4.3" - resolved "https://registry.npmjs.org/zrender/-/zrender-5.4.3.tgz" - integrity sha512-DRUM4ZLnoaT0PBVvGBDO9oWIDBKFdAVieNWxWwK0niYzJCMwGchRk21/hsE+RKkIveH3XHCyvXcJDkgLVvfizQ== - dependencies: - tslib "2.3.0" - -zundo@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/zundo/-/zundo-2.1.0.tgz" - integrity sha512-IMhYXDZWbyGu/p3rQb1d3orhCfAyi9hGkx6N579ZtO7mWrzvBdNyGEcxciv1jtIYPKBqLSAgzKqjLguau09f9g== - -zustand@^4.4.1, zustand@^4.5.2: - version "4.5.4" - resolved "https://registry.npmjs.org/zustand/-/zustand-4.5.4.tgz" - integrity sha512-/BPMyLKJPtFEvVL0E9E9BTUM63MNyhPGlvxk1XjrfWTUlV+BR8jufjsovHzrtR6YNcBEcL7cMHovL1n9xHawEg== - dependencies: - use-sync-external-store "1.2.0" - -zwitch@^2.0.0: - version "2.0.4" - resolved "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz" - integrity sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A== From f3d501e7d5c8abf871f75cf6a476c31fcc4e0b3a Mon Sep 17 00:00:00 2001 From: AkaraChen <akarachen@outlook.com> Date: Mon, 21 Oct 2024 09:45:52 +0800 Subject: [PATCH 091/346] fix: gen-icon script phantom deps --- .../components/base/icons/{script.js => script.mjs} | 11 ++++++----- web/package.json | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) rename web/app/components/base/icons/{script.js => script.mjs} (94%) diff --git a/web/app/components/base/icons/script.js b/web/app/components/base/icons/script.mjs similarity index 94% rename from web/app/components/base/icons/script.js rename to web/app/components/base/icons/script.mjs index 0ff6a2a483..1952a15251 100644 --- a/web/app/components/base/icons/script.js +++ b/web/app/components/base/icons/script.mjs @@ -1,8 +1,9 @@ -const path = require('node:path') -const { open, readdir, access, mkdir, writeFile, appendFile, rm } = require('node:fs/promises') -const { parseXml } = require('@rgrove/parse-xml') -const camelCase = require('lodash/camelCase') -const template = require('lodash/template') +import path from 'node:path' +import { access, appendFile, mkdir, open, readdir, rm, writeFile } from 'node:fs/promises' +import { parseXml } from '@rgrove/parse-xml' +import { camelCase, template } from 'lodash-es' + +const __dirname = path.dirname(new URL(import.meta.url).pathname) const generateDir = async (currentPath) => { try { diff --git a/web/package.json b/web/package.json index b8b57e42a4..5e42a7c670 100644 --- a/web/package.json +++ b/web/package.json @@ -13,7 +13,7 @@ "fix": "next lint --fix", "eslint-fix": "eslint --fix", "prepare": "cd ../ && node -e \"if (process.env.NODE_ENV !== 'production'){process.exit(1)} \" || husky install ./web/.husky", - "gen-icons": "node ./app/components/base/icons/script.js", + "gen-icons": "node ./app/components/base/icons/script.mjs", "uglify-embed": "node ./bin/uglify-embed", "check-i18n": "node ./i18n/check-i18n.js", "auto-gen-i18n": "node ./i18n/auto-gen-i18n.js", From f6ae13abade842b346a50355ef62b5f497f2bc33 Mon Sep 17 00:00:00 2001 From: AkaraChen <akarachen@outlook.com> Date: Mon, 21 Oct 2024 11:14:30 +0800 Subject: [PATCH 092/346] ci: migrate to pnpm --- .github/workflows/style.yml | 6 +++--- .github/workflows/tool-test-sdks.yaml | 6 +++--- .github/workflows/translate-i18n-base-on-english.yml | 2 +- .github/workflows/web-tests.yml | 6 +++--- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/style.yml b/.github/workflows/style.yml index 7eb60aa51e..5c4ee18bc9 100644 --- a/.github/workflows/style.yml +++ b/.github/workflows/style.yml @@ -76,16 +76,16 @@ jobs: if: steps.changed-files.outputs.any_changed == 'true' with: node-version: 20 - cache: yarn + cache: pnpm cache-dependency-path: ./web/package.json - name: Web dependencies if: steps.changed-files.outputs.any_changed == 'true' - run: yarn install --frozen-lockfile + run: pnpm install --frozen-lockfile - name: Web style check if: steps.changed-files.outputs.any_changed == 'true' - run: yarn run lint + run: pnpm run lint superlinter: diff --git a/.github/workflows/tool-test-sdks.yaml b/.github/workflows/tool-test-sdks.yaml index fb4bcb9d66..d3a4592eb5 100644 --- a/.github/workflows/tool-test-sdks.yaml +++ b/.github/workflows/tool-test-sdks.yaml @@ -32,10 +32,10 @@ jobs: with: node-version: ${{ matrix.node-version }} cache: '' - cache-dependency-path: 'yarn.lock' + cache-dependency-path: 'pnpm-lock.yaml' - name: Install Dependencies - run: yarn install + run: pnpm install - name: Test - run: yarn test + run: pnpm test diff --git a/.github/workflows/translate-i18n-base-on-english.yml b/.github/workflows/translate-i18n-base-on-english.yml index c5183bceec..b45793a05f 100644 --- a/.github/workflows/translate-i18n-base-on-english.yml +++ b/.github/workflows/translate-i18n-base-on-english.yml @@ -38,7 +38,7 @@ jobs: - name: Install dependencies if: env.FILES_CHANGED == 'true' - run: yarn install --frozen-lockfile + run: pnpm install --frozen-lockfile - name: Run npm script if: env.FILES_CHANGED == 'true' diff --git a/.github/workflows/web-tests.yml b/.github/workflows/web-tests.yml index 5aee64b8e6..d9f310c811 100644 --- a/.github/workflows/web-tests.yml +++ b/.github/workflows/web-tests.yml @@ -34,13 +34,13 @@ jobs: if: steps.changed-files.outputs.any_changed == 'true' with: node-version: 20 - cache: yarn + cache: pnpm cache-dependency-path: ./web/package.json - name: Install dependencies if: steps.changed-files.outputs.any_changed == 'true' - run: yarn install --frozen-lockfile + run: pnpm install --frozen-lockfile - name: Run tests if: steps.changed-files.outputs.any_changed == 'true' - run: yarn test + run: pnpm test From 9577cbac27b19de833e09f01b32c969815b93d6a Mon Sep 17 00:00:00 2001 From: AkaraChen <akarachen@outlook.com> Date: Mon, 21 Oct 2024 11:27:01 +0800 Subject: [PATCH 093/346] build: docker use pnpm --- web/Dockerfile | 14 ++++++++------ web/README.md | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/web/Dockerfile b/web/Dockerfile index 29f7675f4a..0610300361 100644 --- a/web/Dockerfile +++ b/web/Dockerfile @@ -6,6 +6,9 @@ LABEL maintainer="takatost@gmail.com" # RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories RUN apk add --no-cache tzdata +RUN npm install -g pnpm@9.12.2 +ENV PNPM_HOME="/pnpm" +ENV PATH="$PNPM_HOME:$PATH" # install packages @@ -14,12 +17,12 @@ FROM base AS packages WORKDIR /app/web COPY package.json . -COPY yarn.lock . +COPY pnpm-lock.yaml . # if you located in China, you can use taobao registry to speed up -# RUN yarn install --frozen-lockfile --registry https://registry.npmmirror.com/ +# RUN pnpm install --frozen-lockfile --registry https://registry.npmmirror.com/ -RUN yarn install --frozen-lockfile +RUN pnpm install --frozen-lockfile # build resources FROM base AS builder @@ -27,7 +30,7 @@ WORKDIR /app/web COPY --from=packages /app/web/ . COPY . . -RUN yarn build +RUN pnpm build # production stage @@ -57,8 +60,7 @@ COPY docker/entrypoint.sh ./entrypoint.sh # global runtime packages -RUN yarn global add pm2 \ - && yarn cache clean \ +RUN pnpm add -g pm2 \ && mkdir /.pm2 \ && chown -R 1001:0 /.pm2 /app/web \ && chmod -R g=u /.pm2 /app/web diff --git a/web/README.md b/web/README.md index 64a460e355..ddba8ed28a 100644 --- a/web/README.md +++ b/web/README.md @@ -77,7 +77,7 @@ This project uses [Storybook](https://storybook.js.org/) for UI component develo To start the storybook server, run: ```bash -yarn storybook +pnpm storybook ``` Open [http://localhost:6006](http://localhost:6006) with your browser to see the result. From a6776190bd86c3e1554be73583d46be43a50ff09 Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Wed, 16 Oct 2024 15:17:55 +0800 Subject: [PATCH 094/346] chore: update remix icon --- .../header/account-setting/index.tsx | 8 +- web/package.json | 2 +- web/yarn.lock | 14208 ++++++++++++++++ 3 files changed, 14213 insertions(+), 5 deletions(-) create mode 100644 web/yarn.lock diff --git a/web/app/components/header/account-setting/index.tsx b/web/app/components/header/account-setting/index.tsx index 56647e8fec..c530d3268f 100644 --- a/web/app/components/header/account-setting/index.tsx +++ b/web/app/components/header/account-setting/index.tsx @@ -2,8 +2,8 @@ import { useTranslation } from 'react-i18next' import { useEffect, useRef, useState } from 'react' import { - RiBrainFill, - RiBrainLine, + RiBrain2Fill, + RiBrain2Line, RiColorFilterFill, RiColorFilterLine, RiDatabase2Fill, @@ -63,8 +63,8 @@ export default function AccountSetting({ { key: 'provider', name: t('common.settings.provider'), - icon: <RiBrainLine className={iconClassName} />, - activeIcon: <RiBrainFill className={iconClassName} />, + icon: <RiBrain2Line className={iconClassName} />, + activeIcon: <RiBrain2Fill className={iconClassName} />, }, { key: 'members', diff --git a/web/package.json b/web/package.json index 5e42a7c670..03e714d05a 100644 --- a/web/package.json +++ b/web/package.json @@ -37,7 +37,7 @@ "@mdx-js/react": "^2.3.0", "@monaco-editor/react": "^4.6.0", "@next/mdx": "^14.0.4", - "@remixicon/react": "^4.2.0", + "@remixicon/react": "^4.3.0", "@sentry/react": "^7.54.0", "@sentry/utils": "^7.54.0", "@svgdotjs/svg.js": "^3.2.4", diff --git a/web/yarn.lock b/web/yarn.lock new file mode 100644 index 0000000000..ab4fb0aec6 --- /dev/null +++ b/web/yarn.lock @@ -0,0 +1,14208 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@adobe/css-tools@^4.4.0": + version "4.4.0" + resolved "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.0.tgz#728c484f4e10df03d5a3acd0d8adcbbebff8ad63" + integrity sha512-Ff9+ksdQQB3rMncgqDK78uLznstjyfIf2Arnh22pW8kBpLs6rpKDwgnZT46hin5Hl1WzazzK64DOrhSwYpS7bQ== + +"@alloc/quick-lru@^5.2.0": + version "5.2.0" + resolved "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz" + integrity sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw== + +"@ampproject/remapping@^2.2.0": + version "2.3.0" + resolved "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz#ed441b6fa600072520ce18b43d2c8cc8caecc7f4" + integrity sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw== + dependencies: + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.24" + +"@antfu/eslint-config-basic@0.36.0": + version "0.36.0" + resolved "https://registry.npmjs.org/@antfu/eslint-config-basic/-/eslint-config-basic-0.36.0.tgz" + integrity sha512-2b3ZB7pO00nxAERDXo82iYPjLQ4l/AOMm0CTKmGmqWbN3RB33EIQWzYheZRboSbAVzWpI1/3rg/Gu+7xYVMYHA== + dependencies: + eslint-plugin-antfu "0.36.0" + eslint-plugin-eslint-comments "^3.2.0" + eslint-plugin-html "^7.1.0" + eslint-plugin-import "^2.27.5" + eslint-plugin-jsonc "^2.6.0" + eslint-plugin-markdown "^3.0.0" + eslint-plugin-n "^15.6.1" + eslint-plugin-no-only-tests "^3.1.0" + eslint-plugin-promise "^6.1.1" + eslint-plugin-unicorn "^45.0.2" + eslint-plugin-unused-imports "^2.0.0" + eslint-plugin-yml "^1.5.0" + jsonc-eslint-parser "^2.1.0" + yaml-eslint-parser "^1.1.0" + +"@antfu/eslint-config-ts@0.36.0": + version "0.36.0" + resolved "https://registry.npmjs.org/@antfu/eslint-config-ts/-/eslint-config-ts-0.36.0.tgz" + integrity sha512-I/h2ZOPBIqgnALG2fQp6lOBsOXk51QwLDumyEayt7GRnitdP4o9D8i+YAPowrMJ8M3kU7puQUyhWuJmZLgo57A== + dependencies: + "@antfu/eslint-config-basic" "0.36.0" + "@typescript-eslint/eslint-plugin" "^5.53.0" + "@typescript-eslint/parser" "^5.53.0" + eslint-plugin-jest "^27.2.1" + +"@antfu/eslint-config-vue@0.36.0": + version "0.36.0" + resolved "https://registry.npmjs.org/@antfu/eslint-config-vue/-/eslint-config-vue-0.36.0.tgz" + integrity sha512-YuTcNlVlrEWX1ESOiPgr+e2Walfd6xt3Toa0kAKJxq2aBS1RWqIi1l3zIVGCHaX72lOrSXNmQ7bryaZyGADGDg== + dependencies: + "@antfu/eslint-config-basic" "0.36.0" + "@antfu/eslint-config-ts" "0.36.0" + eslint-plugin-vue "^9.9.0" + local-pkg "^0.4.3" + +"@antfu/eslint-config@^0.36.0": + version "0.36.0" + resolved "https://registry.npmjs.org/@antfu/eslint-config/-/eslint-config-0.36.0.tgz" + integrity sha512-otZ9PfKRT3gnGMMX1gS8URTNPMPCZ69K5jHZvLkYojru0gLBZ3IO5fCvjEZpWqOyIUHtAgg6NWELf1DbEF+NDw== + dependencies: + "@antfu/eslint-config-vue" "0.36.0" + "@typescript-eslint/eslint-plugin" "^5.53.0" + "@typescript-eslint/parser" "^5.53.0" + eslint-plugin-eslint-comments "^3.2.0" + eslint-plugin-html "^7.1.0" + eslint-plugin-import "^2.27.5" + eslint-plugin-jsonc "^2.6.0" + eslint-plugin-n "^15.6.1" + eslint-plugin-promise "^6.1.1" + eslint-plugin-unicorn "^45.0.2" + eslint-plugin-vue "^9.9.0" + eslint-plugin-yml "^1.5.0" + jsonc-eslint-parser "^2.1.0" + yaml-eslint-parser "^1.1.0" + +"@babel/code-frame@^7.0.0": + version "7.21.4" + resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz" + integrity sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g== + dependencies: + "@babel/highlight" "^7.18.6" + +"@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz#882fd9e09e8ee324e496bd040401c6f046ef4465" + integrity sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA== + dependencies: + "@babel/highlight" "^7.24.7" + picocolors "^1.0.0" + +"@babel/code-frame@^7.16.7", "@babel/code-frame@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.25.7.tgz#438f2c524071531d643c6f0188e1e28f130cebc7" + integrity sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g== + dependencies: + "@babel/highlight" "^7.25.7" + picocolors "^1.0.0" + +"@babel/compat-data@^7.22.6", "@babel/compat-data@^7.25.7", "@babel/compat-data@^7.25.8": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.25.8.tgz#0376e83df5ab0eb0da18885c0140041f0747a402" + integrity sha512-ZsysZyXY4Tlx+Q53XdnOFmqwfB9QDTHYxaZYajWRoBLuLEAwI2UIbtxOjWh/cFaa9IKUlcB+DDuoskLuKu56JA== + +"@babel/compat-data@^7.24.8": + version "7.24.9" + resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.9.tgz#53eee4e68f1c1d0282aa0eb05ddb02d033fc43a0" + integrity sha512-e701mcfApCJqMMueQI0Fb68Amflj83+dvAvHawoBpAz+GDjCIyGHzNwnefjsWJ3xiYAqqiQFoWbspGYBdb2/ng== + +"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.23.9": + version "7.24.9" + resolved "https://registry.npmjs.org/@babel/core/-/core-7.24.9.tgz#dc07c9d307162c97fa9484ea997ade65841c7c82" + integrity sha512-5e3FI4Q3M3Pbr21+5xJwCv6ZT6KmGkI0vw3Tozy5ODAQFTIWe37iT8Cr7Ice2Ntb+M3iSKCEWMB1MBgKrW3whg== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.24.7" + "@babel/generator" "^7.24.9" + "@babel/helper-compilation-targets" "^7.24.8" + "@babel/helper-module-transforms" "^7.24.9" + "@babel/helpers" "^7.24.8" + "@babel/parser" "^7.24.8" + "@babel/template" "^7.24.7" + "@babel/traverse" "^7.24.8" + "@babel/types" "^7.24.9" + convert-source-map "^2.0.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.3" + semver "^6.3.1" + +"@babel/core@^7.18.9", "@babel/core@^7.24.4": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.25.8.tgz#a57137d2a51bbcffcfaeba43cb4dd33ae3e0e1c6" + integrity sha512-Oixnb+DzmRT30qu9d3tJSQkxuygWm32DFykT4bRoORPa9hZ/L4KhVB/XiRm6KG+roIEM7DBQlmg27kw2HZkdZg== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.25.7" + "@babel/generator" "^7.25.7" + "@babel/helper-compilation-targets" "^7.25.7" + "@babel/helper-module-transforms" "^7.25.7" + "@babel/helpers" "^7.25.7" + "@babel/parser" "^7.25.8" + "@babel/template" "^7.25.7" + "@babel/traverse" "^7.25.7" + "@babel/types" "^7.25.8" + convert-source-map "^2.0.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.3" + semver "^6.3.1" + +"@babel/generator@^7.24.8", "@babel/generator@^7.24.9", "@babel/generator@^7.7.2": + version "7.24.10" + resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.24.10.tgz#a4ab681ec2a78bbb9ba22a3941195e28a81d8e76" + integrity sha512-o9HBZL1G2129luEUlG1hB4N/nlYNWHnpwlND9eOMclRqqu1YDy2sSYVCFUZwl8I1Gxh+QSRrP2vD7EpUmFVXxg== + dependencies: + "@babel/types" "^7.24.9" + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.25" + jsesc "^2.5.1" + +"@babel/generator@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.25.7.tgz#de86acbeb975a3e11ee92dd52223e6b03b479c56" + integrity sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA== + dependencies: + "@babel/types" "^7.25.7" + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.25" + jsesc "^3.0.2" + +"@babel/helper-annotate-as-pure@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.7.tgz#63f02dbfa1f7cb75a9bdb832f300582f30bb8972" + integrity sha512-4xwU8StnqnlIhhioZf1tqnVWeQ9pvH/ujS8hRfw/WOza+/a+1qv69BWNy+oY231maTCWgKWhfBU7kDpsds6zAA== + dependencies: + "@babel/types" "^7.25.7" + +"@babel/helper-builder-binary-assignment-operator-visitor@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.25.7.tgz#d721650c1f595371e0a23ee816f1c3c488c0d622" + integrity sha512-12xfNeKNH7jubQNm7PAkzlLwEmCs1tfuX3UjIw6vP6QXi+leKh6+LyC/+Ed4EIQermwd58wsyh070yjDHFlNGg== + dependencies: + "@babel/traverse" "^7.25.7" + "@babel/types" "^7.25.7" + +"@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.7.tgz#11260ac3322dda0ef53edfae6e97b961449f5fa4" + integrity sha512-DniTEax0sv6isaw6qSQSfV4gVRNtw2rte8HHM45t9ZR0xILaufBRNkpMifCRiAPyvL4ACD6v0gfCwCmtOQaV4A== + dependencies: + "@babel/compat-data" "^7.25.7" + "@babel/helper-validator-option" "^7.25.7" + browserslist "^4.24.0" + lru-cache "^5.1.1" + semver "^6.3.1" + +"@babel/helper-compilation-targets@^7.24.8": + version "7.24.8" + resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.8.tgz#b607c3161cd9d1744977d4f97139572fe778c271" + integrity sha512-oU+UoqCHdp+nWVDkpldqIQL/i/bvAv53tRqLG/s+cOXxe66zOYLU7ar/Xs3LdmBihrUMEUhwu6dMZwbNOYDwvw== + dependencies: + "@babel/compat-data" "^7.24.8" + "@babel/helper-validator-option" "^7.24.8" + browserslist "^4.23.1" + lru-cache "^5.1.1" + semver "^6.3.1" + +"@babel/helper-create-class-features-plugin@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.7.tgz#5d65074c76cae75607421c00d6bd517fe1892d6b" + integrity sha512-bD4WQhbkx80mAyj/WCm4ZHcF4rDxkoLFO6ph8/5/mQ3z4vAzltQXAmbc7GvVJx5H+lk5Mi5EmbTeox5nMGCsbw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.25.7" + "@babel/helper-member-expression-to-functions" "^7.25.7" + "@babel/helper-optimise-call-expression" "^7.25.7" + "@babel/helper-replace-supers" "^7.25.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.25.7" + "@babel/traverse" "^7.25.7" + semver "^6.3.1" + +"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.7.tgz#dcb464f0e2cdfe0c25cc2a0a59c37ab940ce894e" + integrity sha512-byHhumTj/X47wJ6C6eLpK7wW/WBEcnUeb7D0FNc/jFQnQVw7DOso3Zz5u9x/zLrFVkHa89ZGDbkAa1D54NdrCQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.25.7" + regexpu-core "^6.1.1" + semver "^6.3.1" + +"@babel/helper-define-polyfill-provider@^0.6.2": + version "0.6.2" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz#18594f789c3594acb24cfdb4a7f7b7d2e8bd912d" + integrity sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ== + dependencies: + "@babel/helper-compilation-targets" "^7.22.6" + "@babel/helper-plugin-utils" "^7.22.5" + debug "^4.1.1" + lodash.debounce "^4.0.8" + resolve "^1.14.2" + +"@babel/helper-environment-visitor@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz#4b31ba9551d1f90781ba83491dd59cf9b269f7d9" + integrity sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ== + dependencies: + "@babel/types" "^7.24.7" + +"@babel/helper-function-name@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz#75f1e1725742f39ac6584ee0b16d94513da38dd2" + integrity sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA== + dependencies: + "@babel/template" "^7.24.7" + "@babel/types" "^7.24.7" + +"@babel/helper-hoist-variables@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz#b4ede1cde2fd89436397f30dc9376ee06b0f25ee" + integrity sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ== + dependencies: + "@babel/types" "^7.24.7" + +"@babel/helper-member-expression-to-functions@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.7.tgz#541a33b071f0355a63a0fa4bdf9ac360116b8574" + integrity sha512-O31Ssjd5K6lPbTX9AAYpSKrZmLeagt9uwschJd+Ixo6QiRyfpvgtVQp8qrDR9UNFjZ8+DO34ZkdrN+BnPXemeA== + dependencies: + "@babel/traverse" "^7.25.7" + "@babel/types" "^7.25.7" + +"@babel/helper-module-imports@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz#f2f980392de5b84c3328fc71d38bd81bbb83042b" + integrity sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA== + dependencies: + "@babel/traverse" "^7.24.7" + "@babel/types" "^7.24.7" + +"@babel/helper-module-imports@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.25.7.tgz#dba00d9523539152906ba49263e36d7261040472" + integrity sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw== + dependencies: + "@babel/traverse" "^7.25.7" + "@babel/types" "^7.25.7" + +"@babel/helper-module-transforms@^7.24.9": + version "7.24.9" + resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.9.tgz#e13d26306b89eea569180868e652e7f514de9d29" + integrity sha512-oYbh+rtFKj/HwBQkFlUzvcybzklmVdVV3UU+mN7n2t/q3yGHbuVdNxyFvSBO1tfvjyArpHNcWMAzsSPdyI46hw== + dependencies: + "@babel/helper-environment-visitor" "^7.24.7" + "@babel/helper-module-imports" "^7.24.7" + "@babel/helper-simple-access" "^7.24.7" + "@babel/helper-split-export-declaration" "^7.24.7" + "@babel/helper-validator-identifier" "^7.24.7" + +"@babel/helper-module-transforms@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.25.7.tgz#2ac9372c5e001b19bc62f1fe7d96a18cb0901d1a" + integrity sha512-k/6f8dKG3yDz/qCwSM+RKovjMix563SLxQFo0UhRNo239SP6n9u5/eLtKD6EAjwta2JHJ49CsD8pms2HdNiMMQ== + dependencies: + "@babel/helper-module-imports" "^7.25.7" + "@babel/helper-simple-access" "^7.25.7" + "@babel/helper-validator-identifier" "^7.25.7" + "@babel/traverse" "^7.25.7" + +"@babel/helper-optimise-call-expression@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.7.tgz#1de1b99688e987af723eed44fa7fc0ee7b97d77a" + integrity sha512-VAwcwuYhv/AT+Vfr28c9y6SHzTan1ryqrydSTFGjU0uDJHw3uZ+PduI8plCLkRsDnqK2DMEDmwrOQRsK/Ykjng== + dependencies: + "@babel/types" "^7.25.7" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.24.7", "@babel/helper-plugin-utils@^7.8.0": + version "7.24.8" + resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz#94ee67e8ec0e5d44ea7baeb51e571bd26af07878" + integrity sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg== + +"@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.7.tgz#8ec5b21812d992e1ef88a9b068260537b6f0e36c" + integrity sha512-eaPZai0PiqCi09pPs3pAFfl/zYgGaE6IdXtYvmf0qlcDTd3WCtO7JWCcRd64e0EQrcYgiHibEZnOGsSY4QSgaw== + +"@babel/helper-remap-async-to-generator@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.7.tgz#9efdc39df5f489bcd15533c912b6c723a0a65021" + integrity sha512-kRGE89hLnPfcz6fTrlNU+uhgcwv0mBE4Gv3P9Ke9kLVJYpi4AMVVEElXvB5CabrPZW4nCM8P8UyyjrzCM0O2sw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.25.7" + "@babel/helper-wrap-function" "^7.25.7" + "@babel/traverse" "^7.25.7" + +"@babel/helper-replace-supers@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.25.7.tgz#38cfda3b6e990879c71d08d0fef9236b62bd75f5" + integrity sha512-iy8JhqlUW9PtZkd4pHM96v6BdJ66Ba9yWSE4z0W4TvSZwLBPkyDsiIU3ENe4SmrzRBs76F7rQXTy1lYC49n6Lw== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.25.7" + "@babel/helper-optimise-call-expression" "^7.25.7" + "@babel/traverse" "^7.25.7" + +"@babel/helper-simple-access@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz#bcade8da3aec8ed16b9c4953b74e506b51b5edb3" + integrity sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg== + dependencies: + "@babel/traverse" "^7.24.7" + "@babel/types" "^7.24.7" + +"@babel/helper-simple-access@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.25.7.tgz#5eb9f6a60c5d6b2e0f76057004f8dacbddfae1c0" + integrity sha512-FPGAkJmyoChQeM+ruBGIDyrT2tKfZJO8NcxdC+CWNJi7N8/rZpSxK7yvBJ5O/nF1gfu5KzN7VKG3YVSLFfRSxQ== + dependencies: + "@babel/traverse" "^7.25.7" + "@babel/types" "^7.25.7" + +"@babel/helper-skip-transparent-expression-wrappers@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.7.tgz#382831c91038b1a6d32643f5f49505b8442cb87c" + integrity sha512-pPbNbchZBkPMD50K0p3JGcFMNLVUCuU/ABybm/PGNj4JiHrpmNyqqCphBk4i19xXtNV0JhldQJJtbSW5aUvbyA== + dependencies: + "@babel/traverse" "^7.25.7" + "@babel/types" "^7.25.7" + +"@babel/helper-split-export-declaration@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz#83949436890e07fa3d6873c61a96e3bbf692d856" + integrity sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA== + dependencies: + "@babel/types" "^7.24.7" + +"@babel/helper-string-parser@^7.24.8": + version "7.24.8" + resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz#5b3329c9a58803d5df425e5785865881a81ca48d" + integrity sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ== + +"@babel/helper-string-parser@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.25.7.tgz#d50e8d37b1176207b4fe9acedec386c565a44a54" + integrity sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g== + +"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": + version "7.19.1" + resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz" + integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== + +"@babel/helper-validator-identifier@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz#75b889cfaf9e35c2aaf42cf0d72c8e91719251db" + integrity sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w== + +"@babel/helper-validator-identifier@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.7.tgz#77b7f60c40b15c97df735b38a66ba1d7c3e93da5" + integrity sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg== + +"@babel/helper-validator-option@^7.24.8": + version "7.24.8" + resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz#3725cdeea8b480e86d34df15304806a06975e33d" + integrity sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q== + +"@babel/helper-validator-option@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.25.7.tgz#97d1d684448228b30b506d90cace495d6f492729" + integrity sha512-ytbPLsm+GjArDYXJ8Ydr1c/KJuutjF2besPNbIZnZ6MKUxi/uTA22t2ymmA4WFjZFpjiAMO0xuuJPqK2nvDVfQ== + +"@babel/helper-wrap-function@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.25.7.tgz#9f6021dd1c4fdf4ad515c809967fc4bac9a70fe7" + integrity sha512-MA0roW3JF2bD1ptAaJnvcabsVlNQShUaThyJbCDD4bCp8NEgiFvpoqRI2YS22hHlc2thjO/fTg2ShLMC3jygAg== + dependencies: + "@babel/template" "^7.25.7" + "@babel/traverse" "^7.25.7" + "@babel/types" "^7.25.7" + +"@babel/helpers@^7.24.8": + version "7.24.8" + resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.8.tgz#2820d64d5d6686cca8789dd15b074cd862795873" + integrity sha512-gV2265Nkcz7weJJfvDoAEVzC1e2OTDpkGbEsebse8koXUJUXPsCMi7sRo/+SPMuMZ9MtUPnGwITTnQnU5YjyaQ== + dependencies: + "@babel/template" "^7.24.7" + "@babel/types" "^7.24.8" + +"@babel/helpers@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.25.7.tgz#091b52cb697a171fe0136ab62e54e407211f09c2" + integrity sha512-Sv6pASx7Esm38KQpF/U/OXLwPPrdGHNKoeblRxgZRLXnAtnkEe4ptJPDtAZM7fBLadbc1Q07kQpSiGQ0Jg6tRA== + dependencies: + "@babel/template" "^7.25.7" + "@babel/types" "^7.25.7" + +"@babel/highlight@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz" + integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== + dependencies: + "@babel/helper-validator-identifier" "^7.18.6" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/highlight@^7.24.7": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz#a05ab1df134b286558aae0ed41e6c5f731bf409d" + integrity sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw== + dependencies: + "@babel/helper-validator-identifier" "^7.24.7" + chalk "^2.4.2" + js-tokens "^4.0.0" + picocolors "^1.0.0" + +"@babel/highlight@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.25.7.tgz#20383b5f442aa606e7b5e3043b0b1aafe9f37de5" + integrity sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw== + dependencies: + "@babel/helper-validator-identifier" "^7.25.7" + chalk "^2.4.2" + js-tokens "^4.0.0" + picocolors "^1.0.0" + +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.24.7", "@babel/parser@^7.24.8": + version "7.24.8" + resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.24.8.tgz#58a4dbbcad7eb1d48930524a3fd93d93e9084c6f" + integrity sha512-WzfbgXOkGzZiXXCqk43kKwZjzwx4oulxZi3nq2TYL9mOjQv6kYwul9mz6ID36njuL7Xkp6nJEfok848Zj10j/w== + +"@babel/parser@^7.24.4": + version "7.24.4" + resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.24.4.tgz" + integrity sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg== + +"@babel/parser@^7.25.4": + version "7.25.6" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.25.6.tgz#85660c5ef388cbbf6e3d2a694ee97a38f18afe2f" + integrity sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q== + dependencies: + "@babel/types" "^7.25.6" + +"@babel/parser@^7.25.7", "@babel/parser@^7.25.8": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.25.8.tgz#f6aaf38e80c36129460c1657c0762db584c9d5e2" + integrity sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ== + dependencies: + "@babel/types" "^7.25.8" + +"@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.7.tgz#93969ac50ef4d68b2504b01b758af714e4cbdd64" + integrity sha512-UV9Lg53zyebzD1DwQoT9mzkEKa922LNUp5YkTJ6Uta0RbyXaQNUgcvSt7qIu1PpPzVb6rd10OVNTzkyBGeVmxQ== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + "@babel/traverse" "^7.25.7" + +"@babel/plugin-bugfix-safari-class-field-initializer-scope@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.7.tgz#a338d611adb9dcd599b8b1efa200c88ebeffe046" + integrity sha512-GDDWeVLNxRIkQTnJn2pDOM1pkCgYdSqPeT1a9vh9yIqu2uzzgw1zcqEb+IJOhy+dTBMlNdThrDIksr2o09qrrQ== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.7.tgz#c5f755e911dfac7ef6957300c0f9c4a8c18c06f4" + integrity sha512-wxyWg2RYaSUYgmd9MR0FyRGyeOMQE/Uzr1wzd/g5cf5bwi9A4v6HFdDm7y1MgDtod/fLOSTZY6jDgV0xU9d5bA== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.7.tgz#3b7ea04492ded990978b6deaa1dfca120ad4455a" + integrity sha512-Xwg6tZpLxc4iQjorYsyGMyfJE7nP5MV8t/Ka58BgiA7Jw0fRqQNcANlLfdJ/yvBt9z9LD2We+BEkT7vLqZRWng== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.25.7" + "@babel/plugin-transform-optional-chaining" "^7.25.7" + +"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.7.tgz#9622b1d597a703aa3a921e6f58c9c2d9a028d2c5" + integrity sha512-UVATLMidXrnH+GMUIuxq55nejlj02HP7F5ETyBONzP6G87fPBogG4CH6kxrSrdIuAjdwNO9VzyaYsrZPscWUrw== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + "@babel/traverse" "^7.25.7" + +"@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2": + version "7.21.0-placeholder-for-preset-env.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz#7844f9289546efa9febac2de4cfe358a050bd703" + integrity sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w== + +"@babel/plugin-syntax-async-generators@^7.8.4": + version "7.8.4" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-bigint@^7.8.3": + version "7.8.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" + integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-class-properties@^7.8.3": + version "7.12.13" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" + integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-syntax-dynamic-import@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" + integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-import-assertions@^7.24.1", "@babel/plugin-syntax-import-assertions@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.25.7.tgz#8ce248f9f4ed4b7ed4cb2e0eb4ed9efd9f52921f" + integrity sha512-ZvZQRmME0zfJnDQnVBKYzHxXT7lYBB3Revz1GuS7oLXWMgqUPX4G+DDbT30ICClht9WKV34QVrZhSw6WdklwZQ== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-syntax-import-attributes@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.25.7.tgz#d78dd0499d30df19a598e63ab895e21b909bc43f" + integrity sha512-AqVo+dguCgmpi/3mYBdu9lkngOBlQ2w2vnNpa6gfiCxQZLzV4ZbhsXitJ2Yblkoe1VQwtHSaNmIaGll/26YWRw== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-syntax-import-meta@^7.8.3": + version "7.10.4" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" + integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-json-strings@^7.8.3": + version "7.8.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-jsx@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.7.tgz#5352d398d11ea5e7ef330c854dea1dae0bf18165" + integrity sha512-ruZOnKO+ajVL/MVx+PwNBPOkrnXTXoWMtte1MBpegfCArhqOe3Bj52avVj1huLLxNKYKXYaSxZ2F+woK1ekXfw== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-syntax-jsx@^7.7.2": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz#39a1fa4a7e3d3d7f34e2acc6be585b718d30e02d" + integrity sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ== + dependencies: + "@babel/helper-plugin-utils" "^7.24.7" + +"@babel/plugin-syntax-logical-assignment-operators@^7.8.3": + version "7.10.4" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" + integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.8.3": + version "7.10.4" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-object-rest-spread@^7.8.3": + version "7.8.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.8.3": + version "7.8.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.3": + version "7.8.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-top-level-await@^7.8.3": + version "7.14.5" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" + integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-typescript@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.7.tgz#bfc05b0cc31ebd8af09964650cee723bb228108b" + integrity sha512-rR+5FDjpCHqqZN2bzZm18bVYGaejGq5ZkpVCJLXor/+zlSrSoc4KWcHI0URVWjl/68Dyr1uwZUz/1njycEAv9g== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-syntax-typescript@^7.7.2": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.7.tgz#58d458271b4d3b6bb27ee6ac9525acbb259bad1c" + integrity sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA== + dependencies: + "@babel/helper-plugin-utils" "^7.24.7" + +"@babel/plugin-syntax-unicode-sets-regex@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz#d49a3b3e6b52e5be6740022317580234a6a47357" + integrity sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-arrow-functions@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.7.tgz#1b9ed22e6890a0e9ff470371c73b8c749bcec386" + integrity sha512-EJN2mKxDwfOUCPxMO6MUI58RN3ganiRAG/MS/S3HfB6QFNjroAMelQo/gybyYq97WerCBAZoyrAoW8Tzdq2jWg== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-transform-async-generator-functions@^7.25.8": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.8.tgz#3331de02f52cc1f2c75b396bec52188c85b0b1ec" + integrity sha512-9ypqkozyzpG+HxlH4o4gdctalFGIjjdufzo7I2XPda0iBnZ6a+FO0rIEQcdSPXp02CkvGsII1exJhmROPQd5oA== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-remap-async-to-generator" "^7.25.7" + "@babel/traverse" "^7.25.7" + +"@babel/plugin-transform-async-to-generator@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.7.tgz#a44c7323f8d4285a6c568dd43c5c361d6367ec52" + integrity sha512-ZUCjAavsh5CESCmi/xCpX1qcCaAglzs/7tmuvoFnJgA1dM7gQplsguljoTg+Ru8WENpX89cQyAtWoaE0I3X3Pg== + dependencies: + "@babel/helper-module-imports" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-remap-async-to-generator" "^7.25.7" + +"@babel/plugin-transform-block-scoped-functions@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.25.7.tgz#e0b8843d5571719a2f1bf7e284117a3379fcc17c" + integrity sha512-xHttvIM9fvqW+0a3tZlYcZYSBpSWzGBFIt/sYG3tcdSzBB8ZeVgz2gBP7Df+sM0N1850jrviYSSeUuc+135dmQ== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-transform-block-scoping@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.7.tgz#6dab95e98adf780ceef1b1c3ab0e55cd20dd410a" + integrity sha512-ZEPJSkVZaeTFG/m2PARwLZQ+OG0vFIhPlKHK/JdIMy8DbRJ/htz6LRrTFtdzxi9EHmcwbNPAKDnadpNSIW+Aow== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-transform-class-properties@^7.24.1", "@babel/plugin-transform-class-properties@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.7.tgz#a389cfca7a10ac80e3ff4c75fca08bd097ad1523" + integrity sha512-mhyfEW4gufjIqYFo9krXHJ3ElbFLIze5IDp+wQTxoPd+mwFb1NxatNAwmv8Q8Iuxv7Zc+q8EkiMQwc9IhyGf4g== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-transform-class-static-block@^7.25.8": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.25.8.tgz#a8af22028920fe404668031eceb4c3aadccb5262" + integrity sha512-e82gl3TCorath6YLf9xUwFehVvjvfqFhdOo4+0iVIVju+6XOi5XHkqB3P2AXnSwoeTX0HBoXq5gJFtvotJzFnQ== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-transform-classes@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.7.tgz#5103206cf80d02283bbbd044509ea3b65d0906bb" + integrity sha512-9j9rnl+YCQY0IGoeipXvnk3niWicIB6kCsWRGLwX241qSXpbA4MKxtp/EdvFxsc4zI5vqfLxzOd0twIJ7I99zg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.25.7" + "@babel/helper-compilation-targets" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-replace-supers" "^7.25.7" + "@babel/traverse" "^7.25.7" + globals "^11.1.0" + +"@babel/plugin-transform-computed-properties@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.7.tgz#7f621f0aa1354b5348a935ab12e3903842466f65" + integrity sha512-QIv+imtM+EtNxg/XBKL3hiWjgdLjMOmZ+XzQwSgmBfKbfxUjBzGgVPklUuE55eq5/uVoh8gg3dqlrwR/jw3ZeA== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + "@babel/template" "^7.25.7" + +"@babel/plugin-transform-destructuring@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.7.tgz#f6f26a9feefb5aa41fd45b6f5838901b5333d560" + integrity sha512-xKcfLTlJYUczdaM1+epcdh1UGewJqr9zATgrNHcLBcV2QmfvPPEixo/sK/syql9cEmbr7ulu5HMFG5vbbt/sEA== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-transform-dotall-regex@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.7.tgz#9d775c4a3ff1aea64045300fcd4309b4a610ef02" + integrity sha512-kXzXMMRzAtJdDEgQBLF4oaiT6ZCU3oWHgpARnTKDAqPkDJ+bs3NrZb310YYevR5QlRo3Kn7dzzIdHbZm1VzJdQ== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-transform-duplicate-keys@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.7.tgz#fbba7d1155eab76bd4f2a038cbd5d65883bd7a93" + integrity sha512-by+v2CjoL3aMnWDOyCIg+yxU9KXSRa9tN6MbqggH5xvymmr9p4AMjYkNlQy4brMceBnUyHZ9G8RnpvT8wP7Cfg== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-transform-duplicate-named-capturing-groups-regex@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.7.tgz#102b31608dcc22c08fbca1894e104686029dc141" + integrity sha512-HvS6JF66xSS5rNKXLqkk7L9c/jZ/cdIVIcoPVrnl8IsVpLggTjXs8OWekbLHs/VtYDDh5WXnQyeE3PPUGm22MA== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-transform-dynamic-import@^7.25.8": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.8.tgz#f1edbe75b248cf44c70c8ca8ed3818a668753aaa" + integrity sha512-gznWY+mr4ZQL/EWPcbBQUP3BXS5FwZp8RUOw06BaRn8tQLzN4XLIxXejpHN9Qo8x8jjBmAAKp6FoS51AgkSA/A== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-transform-exponentiation-operator@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.25.7.tgz#5961a3a23a398faccd6cddb34a2182807d75fb5f" + integrity sha512-yjqtpstPfZ0h/y40fAXRv2snciYr0OAoMXY/0ClC7tm4C/nG5NJKmIItlaYlLbIVAWNfrYuy9dq1bE0SbX0PEg== + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-transform-export-namespace-from@^7.24.1", "@babel/plugin-transform-export-namespace-from@^7.25.8": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.8.tgz#d1988c3019a380b417e0516418b02804d3858145" + integrity sha512-sPtYrduWINTQTW7FtOy99VCTWp4H23UX7vYcut7S4CIMEXU+54zKX9uCoGkLsWXteyaMXzVHgzWbLfQ1w4GZgw== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-transform-for-of@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.7.tgz#0acfea0f27aa290818b5b48a5a44b3f03fc13669" + integrity sha512-n/TaiBGJxYFWvpJDfsxSj9lEEE44BFM1EPGz4KEiTipTgkoFVVcCmzAL3qA7fdQU96dpo4gGf5HBx/KnDvqiHw== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.25.7" + +"@babel/plugin-transform-function-name@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.7.tgz#7e394ccea3693902a8b50ded8b6ae1fa7b8519fd" + integrity sha512-5MCTNcjCMxQ63Tdu9rxyN6cAWurqfrDZ76qvVPrGYdBxIj+EawuuxTu/+dgJlhK5eRz3v1gLwp6XwS8XaX2NiQ== + dependencies: + "@babel/helper-compilation-targets" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" + "@babel/traverse" "^7.25.7" + +"@babel/plugin-transform-json-strings@^7.25.8": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.8.tgz#6fb3ec383a2ea92652289fdba653e3f9de722694" + integrity sha512-4OMNv7eHTmJ2YXs3tvxAfa/I43di+VcF+M4Wt66c88EAED1RoGaf1D64cL5FkRpNL+Vx9Hds84lksWvd/wMIdA== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-transform-literals@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.7.tgz#70cbdc742f2cfdb1a63ea2cbd018d12a60b213c3" + integrity sha512-fwzkLrSu2fESR/cm4t6vqd7ebNIopz2QHGtjoU+dswQo/P6lwAG04Q98lliE3jkz/XqnbGFLnUcE0q0CVUf92w== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-transform-logical-assignment-operators@^7.25.8": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.8.tgz#01868ff92daa9e525b4c7902aa51979082a05710" + integrity sha512-f5W0AhSbbI+yY6VakT04jmxdxz+WsID0neG7+kQZbCOjuyJNdL5Nn4WIBm4hRpKnUcO9lP0eipUhFN12JpoH8g== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-transform-member-expression-literals@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.7.tgz#0a36c3fbd450cc9e6485c507f005fa3d1bc8fca5" + integrity sha512-Std3kXwpXfRV0QtQy5JJcRpkqP8/wG4XL7hSKZmGlxPlDqmpXtEPRmhF7ztnlTCtUN3eXRUJp+sBEZjaIBVYaw== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-transform-modules-amd@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.7.tgz#bb4e543b5611f6c8c685a2fd485408713a3adf3d" + integrity sha512-CgselSGCGzjQvKzghCvDTxKHP3iooenLpJDO842ehn5D2G5fJB222ptnDwQho0WjEvg7zyoxb9P+wiYxiJX5yA== + dependencies: + "@babel/helper-module-transforms" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-transform-modules-commonjs@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.25.7.tgz#173f0c791bb7407c092ce6d77ee90eb3f2d1d2fd" + integrity sha512-L9Gcahi0kKFYXvweO6n0wc3ZG1ChpSFdgG+eV1WYZ3/dGbJK7vvk91FgGgak8YwRgrCuihF8tE/Xg07EkL5COg== + dependencies: + "@babel/helper-module-transforms" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-simple-access" "^7.25.7" + +"@babel/plugin-transform-modules-systemjs@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.7.tgz#8b14d319a177cc9c85ef8b0512afd429d9e2e60b" + integrity sha512-t9jZIvBmOXJsiuyOwhrIGs8dVcD6jDyg2icw1VL4A/g+FnWyJKwUfSSU2nwJuMV2Zqui856El9u+ElB+j9fV1g== + dependencies: + "@babel/helper-module-transforms" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-validator-identifier" "^7.25.7" + "@babel/traverse" "^7.25.7" + +"@babel/plugin-transform-modules-umd@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.7.tgz#00ee7a7e124289549381bfb0e24d87fd7f848367" + integrity sha512-p88Jg6QqsaPh+EB7I9GJrIqi1Zt4ZBHUQtjw3z1bzEXcLh6GfPqzZJ6G+G1HBGKUNukT58MnKG7EN7zXQBCODw== + dependencies: + "@babel/helper-module-transforms" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-transform-named-capturing-groups-regex@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.7.tgz#a2f3f6d7f38693b462542951748f0a72a34d196d" + integrity sha512-BtAT9LzCISKG3Dsdw5uso4oV1+v2NlVXIIomKJgQybotJY3OwCwJmkongjHgwGKoZXd0qG5UZ12JUlDQ07W6Ow== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-transform-new-target@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.7.tgz#52b2bde523b76c548749f38dc3054f1f45e82bc9" + integrity sha512-CfCS2jDsbcZaVYxRFo2qtavW8SpdzmBXC2LOI4oO0rP+JSRDxxF3inF4GcPsLgfb5FjkhXG5/yR/lxuRs2pySA== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-transform-nullish-coalescing-operator@^7.25.8": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.8.tgz#befb4900c130bd52fccf2b926314557987f1b552" + integrity sha512-Z7WJJWdQc8yCWgAmjI3hyC+5PXIubH9yRKzkl9ZEG647O9szl9zvmKLzpbItlijBnVhTUf1cpyWBsZ3+2wjWPQ== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-transform-numeric-separator@^7.24.1", "@babel/plugin-transform-numeric-separator@^7.25.8": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.8.tgz#91e370486371637bd42161052f2602c701386891" + integrity sha512-rm9a5iEFPS4iMIy+/A/PiS0QN0UyjPIeVvbU5EMZFKJZHt8vQnasbpo3T3EFcxzCeYO0BHfc4RqooCZc51J86Q== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-transform-object-rest-spread@^7.24.1", "@babel/plugin-transform-object-rest-spread@^7.25.8": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.8.tgz#0904ac16bcce41df4db12d915d6780f85c7fb04b" + integrity sha512-LkUu0O2hnUKHKE7/zYOIjByMa4VRaV2CD/cdGz0AxU9we+VA3kDDggKEzI0Oz1IroG+6gUP6UmWEHBMWZU316g== + dependencies: + "@babel/helper-compilation-targets" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" + "@babel/plugin-transform-parameters" "^7.25.7" + +"@babel/plugin-transform-object-super@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.7.tgz#582a9cea8cf0a1e02732be5b5a703a38dedf5661" + integrity sha512-pWT6UXCEW3u1t2tcAGtE15ornCBvopHj9Bps9D2DsH15APgNVOTwwczGckX+WkAvBmuoYKRCFa4DK+jM8vh5AA== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-replace-supers" "^7.25.7" + +"@babel/plugin-transform-optional-catch-binding@^7.25.8": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.8.tgz#2649b86a3bb202c6894ec81a6ddf41b94d8f3103" + integrity sha512-EbQYweoMAHOn7iJ9GgZo14ghhb9tTjgOc88xFgYngifx7Z9u580cENCV159M4xDh3q/irbhSjZVpuhpC2gKBbg== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-transform-optional-chaining@^7.25.7", "@babel/plugin-transform-optional-chaining@^7.25.8": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.8.tgz#f46283b78adcc5b6ab988a952f989e7dce70653f" + integrity sha512-q05Bk7gXOxpTHoQ8RSzGSh/LHVB9JEIkKnk3myAWwZHnYiTGYtbdrYkIsS8Xyh4ltKf7GNUSgzs/6P2bJtBAQg== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.25.7" + +"@babel/plugin-transform-parameters@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.7.tgz#80c38b03ef580f6d6bffe1c5254bb35986859ac7" + integrity sha512-FYiTvku63me9+1Nz7TOx4YMtW3tWXzfANZtrzHhUZrz4d47EEtMQhzFoZWESfXuAMMT5mwzD4+y1N8ONAX6lMQ== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-transform-private-methods@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.7.tgz#c790a04f837b4bd61d6b0317b43aa11ff67dce80" + integrity sha512-KY0hh2FluNxMLwOCHbxVOKfdB5sjWG4M183885FmaqWWiGMhRZq4DQRKH6mHdEucbJnyDyYiZNwNG424RymJjA== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-transform-private-property-in-object@^7.25.8": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.8.tgz#1234f856ce85e061f9688764194e51ea7577c434" + integrity sha512-8Uh966svuB4V8RHHg0QJOB32QK287NBksJOByoKmHMp1TAobNniNalIkI2i5IPj5+S9NYCG4VIjbEuiSN8r+ow== + dependencies: + "@babel/helper-annotate-as-pure" "^7.25.7" + "@babel/helper-create-class-features-plugin" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-transform-property-literals@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.7.tgz#a8612b4ea4e10430f00012ecf0155662c7d6550d" + integrity sha512-lQEeetGKfFi0wHbt8ClQrUSUMfEeI3MMm74Z73T9/kuz990yYVtfofjf3NuA42Jy3auFOpbjDyCSiIkTs1VIYw== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-transform-react-display-name@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.25.7.tgz#2753e875a1b702fb1d806c4f5d4c194d64cadd88" + integrity sha512-r0QY7NVU8OnrwE+w2IWiRom0wwsTbjx4+xH2RTd7AVdof3uurXOF+/mXHQDRk+2jIvWgSaCHKMgggfvM4dyUGA== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-transform-react-jsx-development@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.25.7.tgz#2fbd77887b8fa2942d7cb61edf1029ea1b048554" + integrity sha512-5yd3lH1PWxzW6IZj+p+Y4OLQzz0/LzlOG8vGqonHfVR3euf1vyzyMUJk9Ac+m97BH46mFc/98t9PmYLyvgL3qg== + dependencies: + "@babel/plugin-transform-react-jsx" "^7.25.7" + +"@babel/plugin-transform-react-jsx@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.25.7.tgz#f5e2af6020a562fe048dd343e571c4428e6c5632" + integrity sha512-vILAg5nwGlR9EXE8JIOX4NHXd49lrYbN8hnjffDtoULwpL9hUx/N55nqh2qd0q6FyNDfjl9V79ecKGvFbcSA0Q== + dependencies: + "@babel/helper-annotate-as-pure" "^7.25.7" + "@babel/helper-module-imports" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" + "@babel/plugin-syntax-jsx" "^7.25.7" + "@babel/types" "^7.25.7" + +"@babel/plugin-transform-react-pure-annotations@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.25.7.tgz#6d0b8dadb2d3c5cbb8ade68c5efd49470b0d65f7" + integrity sha512-6YTHJ7yjjgYqGc8S+CbEXhLICODk0Tn92j+vNJo07HFk9t3bjFgAKxPLFhHwF2NjmQVSI1zBRfBWUeVBa2osfA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-transform-regenerator@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.7.tgz#6eb006e6d26f627bc2f7844a9f19770721ad6f3e" + integrity sha512-mgDoQCRjrY3XK95UuV60tZlFCQGXEtMg8H+IsW72ldw1ih1jZhzYXbJvghmAEpg5UVhhnCeia1CkGttUvCkiMQ== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + regenerator-transform "^0.15.2" + +"@babel/plugin-transform-reserved-words@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.7.tgz#dc56b25e02afaabef3ce0c5b06b0916e8523e995" + integrity sha512-3OfyfRRqiGeOvIWSagcwUTVk2hXBsr/ww7bLn6TRTuXnexA+Udov2icFOxFX9abaj4l96ooYkcNN1qi2Zvqwng== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-transform-runtime@^7.24.3": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.25.7.tgz#435a4fab67273f00047dc806e05069c9c6344e12" + integrity sha512-Y9p487tyTzB0yDYQOtWnC+9HGOuogtP3/wNpun1xJXEEvI6vip59BSBTsHnekZLqxmPcgsrAKt46HAAb//xGhg== + dependencies: + "@babel/helper-module-imports" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" + babel-plugin-polyfill-corejs2 "^0.4.10" + babel-plugin-polyfill-corejs3 "^0.10.6" + babel-plugin-polyfill-regenerator "^0.6.1" + semver "^6.3.1" + +"@babel/plugin-transform-shorthand-properties@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.7.tgz#92690a9c671915602d91533c278cc8f6bf12275f" + integrity sha512-uBbxNwimHi5Bv3hUccmOFlUy3ATO6WagTApenHz9KzoIdn0XeACdB12ZJ4cjhuB2WSi80Ez2FWzJnarccriJeA== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-transform-spread@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.7.tgz#df83e899a9fc66284ee601a7b738568435b92998" + integrity sha512-Mm6aeymI0PBh44xNIv/qvo8nmbkpZze1KvR8MkEqbIREDxoiWTi18Zr2jryfRMwDfVZF9foKh060fWgni44luw== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.25.7" + +"@babel/plugin-transform-sticky-regex@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.7.tgz#341c7002bef7f29037be7fb9684e374442dd0d17" + integrity sha512-ZFAeNkpGuLnAQ/NCsXJ6xik7Id+tHuS+NT+ue/2+rn/31zcdnupCdmunOizEaP0JsUmTFSTOPoQY7PkK2pttXw== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-transform-template-literals@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.7.tgz#e566c581bb16d8541dd8701093bb3457adfce16b" + integrity sha512-SI274k0nUsFFmyQupiO7+wKATAmMFf8iFgq2O+vVFXZ0SV9lNfT1NGzBEhjquFmD8I9sqHLguH+gZVN3vww2AA== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-transform-typeof-symbol@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.7.tgz#debb1287182efd20488f126be343328c679b66eb" + integrity sha512-OmWmQtTHnO8RSUbL0NTdtpbZHeNTnm68Gj5pA4Y2blFNh+V4iZR68V1qL9cI37J21ZN7AaCnkfdHtLExQPf2uA== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-transform-typescript@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.25.7.tgz#8fc7c3d28ddd36bce45b9b48594129d0e560cfbe" + integrity sha512-VKlgy2vBzj8AmEzunocMun2fF06bsSWV+FvVXohtL6FGve/+L217qhHxRTVGHEDO/YR8IANcjzgJsd04J8ge5Q== + dependencies: + "@babel/helper-annotate-as-pure" "^7.25.7" + "@babel/helper-create-class-features-plugin" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.25.7" + "@babel/plugin-syntax-typescript" "^7.25.7" + +"@babel/plugin-transform-unicode-escapes@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.7.tgz#973592b6d13a914794e1de8cf1383e50e0f87f81" + integrity sha512-BN87D7KpbdiABA+t3HbVqHzKWUDN3dymLaTnPFAMyc8lV+KN3+YzNhVRNdinaCPA4AUqx7ubXbQ9shRjYBl3SQ== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-transform-unicode-property-regex@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.7.tgz#25349197cce964b1343f74fa7cfdf791a1b1919e" + integrity sha512-IWfR89zcEPQGB/iB408uGtSPlQd3Jpq11Im86vUgcmSTcoWAiQMCTOa2K2yNNqFJEBVICKhayctee65Ka8OB0w== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-transform-unicode-regex@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.7.tgz#f93a93441baf61f713b6d5552aaa856bfab34809" + integrity sha512-8JKfg/hiuA3qXnlLx8qtv5HWRbgyFx2hMMtpDDuU2rTckpKkGu4ycK5yYHwuEa16/quXfoxHBIApEsNyMWnt0g== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/plugin-transform-unicode-sets-regex@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.7.tgz#d1b3295d29e0f8f4df76abc909ad1ebee919560c" + integrity sha512-YRW8o9vzImwmh4Q3Rffd09bH5/hvY0pxg+1H1i0f7APoUeg12G7+HhLj9ZFNIrYkgBXhIijPJ+IXypN0hLTIbw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" + +"@babel/preset-env@^7.24.4": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.25.8.tgz#dc6b719627fb29cd9cccbbbe041802fd575b524c" + integrity sha512-58T2yulDHMN8YMUxiLq5YmWUnlDCyY1FsHM+v12VMx+1/FlrUj5tY50iDCpofFQEM8fMYOaY9YRvym2jcjn1Dg== + dependencies: + "@babel/compat-data" "^7.25.8" + "@babel/helper-compilation-targets" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-validator-option" "^7.25.7" + "@babel/plugin-bugfix-firefox-class-in-computed-class-key" "^7.25.7" + "@babel/plugin-bugfix-safari-class-field-initializer-scope" "^7.25.7" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.25.7" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.25.7" + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly" "^7.25.7" + "@babel/plugin-proposal-private-property-in-object" "7.21.0-placeholder-for-preset-env.2" + "@babel/plugin-syntax-import-assertions" "^7.25.7" + "@babel/plugin-syntax-import-attributes" "^7.25.7" + "@babel/plugin-syntax-unicode-sets-regex" "^7.18.6" + "@babel/plugin-transform-arrow-functions" "^7.25.7" + "@babel/plugin-transform-async-generator-functions" "^7.25.8" + "@babel/plugin-transform-async-to-generator" "^7.25.7" + "@babel/plugin-transform-block-scoped-functions" "^7.25.7" + "@babel/plugin-transform-block-scoping" "^7.25.7" + "@babel/plugin-transform-class-properties" "^7.25.7" + "@babel/plugin-transform-class-static-block" "^7.25.8" + "@babel/plugin-transform-classes" "^7.25.7" + "@babel/plugin-transform-computed-properties" "^7.25.7" + "@babel/plugin-transform-destructuring" "^7.25.7" + "@babel/plugin-transform-dotall-regex" "^7.25.7" + "@babel/plugin-transform-duplicate-keys" "^7.25.7" + "@babel/plugin-transform-duplicate-named-capturing-groups-regex" "^7.25.7" + "@babel/plugin-transform-dynamic-import" "^7.25.8" + "@babel/plugin-transform-exponentiation-operator" "^7.25.7" + "@babel/plugin-transform-export-namespace-from" "^7.25.8" + "@babel/plugin-transform-for-of" "^7.25.7" + "@babel/plugin-transform-function-name" "^7.25.7" + "@babel/plugin-transform-json-strings" "^7.25.8" + "@babel/plugin-transform-literals" "^7.25.7" + "@babel/plugin-transform-logical-assignment-operators" "^7.25.8" + "@babel/plugin-transform-member-expression-literals" "^7.25.7" + "@babel/plugin-transform-modules-amd" "^7.25.7" + "@babel/plugin-transform-modules-commonjs" "^7.25.7" + "@babel/plugin-transform-modules-systemjs" "^7.25.7" + "@babel/plugin-transform-modules-umd" "^7.25.7" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.25.7" + "@babel/plugin-transform-new-target" "^7.25.7" + "@babel/plugin-transform-nullish-coalescing-operator" "^7.25.8" + "@babel/plugin-transform-numeric-separator" "^7.25.8" + "@babel/plugin-transform-object-rest-spread" "^7.25.8" + "@babel/plugin-transform-object-super" "^7.25.7" + "@babel/plugin-transform-optional-catch-binding" "^7.25.8" + "@babel/plugin-transform-optional-chaining" "^7.25.8" + "@babel/plugin-transform-parameters" "^7.25.7" + "@babel/plugin-transform-private-methods" "^7.25.7" + "@babel/plugin-transform-private-property-in-object" "^7.25.8" + "@babel/plugin-transform-property-literals" "^7.25.7" + "@babel/plugin-transform-regenerator" "^7.25.7" + "@babel/plugin-transform-reserved-words" "^7.25.7" + "@babel/plugin-transform-shorthand-properties" "^7.25.7" + "@babel/plugin-transform-spread" "^7.25.7" + "@babel/plugin-transform-sticky-regex" "^7.25.7" + "@babel/plugin-transform-template-literals" "^7.25.7" + "@babel/plugin-transform-typeof-symbol" "^7.25.7" + "@babel/plugin-transform-unicode-escapes" "^7.25.7" + "@babel/plugin-transform-unicode-property-regex" "^7.25.7" + "@babel/plugin-transform-unicode-regex" "^7.25.7" + "@babel/plugin-transform-unicode-sets-regex" "^7.25.7" + "@babel/preset-modules" "0.1.6-no-external-plugins" + babel-plugin-polyfill-corejs2 "^0.4.10" + babel-plugin-polyfill-corejs3 "^0.10.6" + babel-plugin-polyfill-regenerator "^0.6.1" + core-js-compat "^3.38.1" + semver "^6.3.1" + +"@babel/preset-modules@0.1.6-no-external-plugins": + version "0.1.6-no-external-plugins" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz#ccb88a2c49c817236861fee7826080573b8a923a" + integrity sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/types" "^7.4.4" + esutils "^2.0.2" + +"@babel/preset-react@^7.24.1": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.25.7.tgz#081cbe1dea363b732764d06a0fdda67ffa17735d" + integrity sha512-GjV0/mUEEXpi1U5ZgDprMRRgajGMRW3G5FjMr5KLKD8nT2fTG8+h/klV3+6Dm5739QE+K5+2e91qFKAYI3pmRg== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-validator-option" "^7.25.7" + "@babel/plugin-transform-react-display-name" "^7.25.7" + "@babel/plugin-transform-react-jsx" "^7.25.7" + "@babel/plugin-transform-react-jsx-development" "^7.25.7" + "@babel/plugin-transform-react-pure-annotations" "^7.25.7" + +"@babel/preset-typescript@^7.24.1": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.25.7.tgz#43c5b68eccb856ae5b52274b77b1c3c413cde1b7" + integrity sha512-rkkpaXJZOFN45Fb+Gki0c+KMIglk4+zZXOoMJuyEK8y8Kkc8Jd3BDmP7qPsz0zQMJj+UD7EprF+AqAXcILnexw== + dependencies: + "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-validator-option" "^7.25.7" + "@babel/plugin-syntax-jsx" "^7.25.7" + "@babel/plugin-transform-modules-commonjs" "^7.25.7" + "@babel/plugin-transform-typescript" "^7.25.7" + +"@babel/runtime@^7.0.0", "@babel/runtime@^7.10.1", "@babel/runtime@^7.11.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.18.3", "@babel/runtime@^7.20.6", "@babel/runtime@^7.20.7", "@babel/runtime@^7.21.0", "@babel/runtime@^7.21.5", "@babel/runtime@^7.22.3", "@babel/runtime@^7.3.1": + version "7.22.3" + resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.3.tgz" + integrity sha512-XsDuspWKLUsxwCp6r7EhsExHtYfbe5oAGQ19kqngTdCPUoPQzOPdUbD/pB9PJiwb2ptYKQDjSJT3R6dC+EPqfQ== + dependencies: + regenerator-runtime "^0.13.11" + +"@babel/runtime@^7.17.8", "@babel/runtime@^7.24.4", "@babel/runtime@^7.8.4": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.7.tgz#7ffb53c37a8f247c8c4d335e89cdf16a2e0d0fb6" + integrity sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w== + dependencies: + regenerator-runtime "^0.14.0" + +"@babel/runtime@^7.9.2": + version "7.24.8" + resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.8.tgz#5d958c3827b13cc6d05e038c07fb2e5e3420d82e" + integrity sha512-5F7SDGs1T72ZczbRwbGO9lQi0NLjQxzl6i4lJxLxfW9U5UluCSyEJeniWvnhl3/euNiqQVbo8zruhsDfid0esA== + dependencies: + regenerator-runtime "^0.14.0" + +"@babel/template@^7.24.7", "@babel/template@^7.3.3": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz#02efcee317d0609d2c07117cb70ef8fb17ab7315" + integrity sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig== + dependencies: + "@babel/code-frame" "^7.24.7" + "@babel/parser" "^7.24.7" + "@babel/types" "^7.24.7" + +"@babel/template@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.25.7.tgz#27f69ce382855d915b14ab0fe5fb4cbf88fa0769" + integrity sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA== + dependencies: + "@babel/code-frame" "^7.25.7" + "@babel/parser" "^7.25.7" + "@babel/types" "^7.25.7" + +"@babel/traverse@^7.18.9", "@babel/traverse@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.7.tgz#83e367619be1cab8e4f2892ef30ba04c26a40fa8" + integrity sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg== + dependencies: + "@babel/code-frame" "^7.25.7" + "@babel/generator" "^7.25.7" + "@babel/parser" "^7.25.7" + "@babel/template" "^7.25.7" + "@babel/types" "^7.25.7" + debug "^4.3.1" + globals "^11.1.0" + +"@babel/traverse@^7.24.7", "@babel/traverse@^7.24.8": + version "7.24.8" + resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.8.tgz#6c14ed5232b7549df3371d820fbd9abfcd7dfab7" + integrity sha512-t0P1xxAPzEDcEPmjprAQq19NWum4K0EQPjMwZQZbHt+GiZqvjCHjj755Weq1YRPVzBI+3zSfvScfpnuIecVFJQ== + dependencies: + "@babel/code-frame" "^7.24.7" + "@babel/generator" "^7.24.8" + "@babel/helper-environment-visitor" "^7.24.7" + "@babel/helper-function-name" "^7.24.7" + "@babel/helper-hoist-variables" "^7.24.7" + "@babel/helper-split-export-declaration" "^7.24.7" + "@babel/parser" "^7.24.8" + "@babel/types" "^7.24.8" + debug "^4.3.1" + globals "^11.1.0" + +"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.24.7", "@babel/types@^7.24.8", "@babel/types@^7.24.9", "@babel/types@^7.3.3": + version "7.24.9" + resolved "https://registry.npmjs.org/@babel/types/-/types-7.24.9.tgz#228ce953d7b0d16646e755acf204f4cf3d08cc73" + integrity sha512-xm8XrMKz0IlUdocVbYJe0Z9xEgidU7msskG8BbhnTPK/HZ2z/7FP7ykqPgrUH+C+r414mNfNWam1f2vqOjqjYQ== + dependencies: + "@babel/helper-string-parser" "^7.24.8" + "@babel/helper-validator-identifier" "^7.24.7" + to-fast-properties "^2.0.0" + +"@babel/types@^7.18.9", "@babel/types@^7.25.7", "@babel/types@^7.25.8", "@babel/types@^7.4.4": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.25.8.tgz#5cf6037258e8a9bcad533f4979025140cb9993e1" + integrity sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg== + dependencies: + "@babel/helper-string-parser" "^7.25.7" + "@babel/helper-validator-identifier" "^7.25.7" + to-fast-properties "^2.0.0" + +"@babel/types@^7.25.4", "@babel/types@^7.25.6": + version "7.25.6" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.25.6.tgz#893942ddb858f32ae7a004ec9d3a76b3463ef8e6" + integrity sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw== + dependencies: + "@babel/helper-string-parser" "^7.24.8" + "@babel/helper-validator-identifier" "^7.24.7" + to-fast-properties "^2.0.0" + +"@base2/pretty-print-object@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@base2/pretty-print-object/-/pretty-print-object-1.0.1.tgz#371ba8be66d556812dc7fb169ebc3c08378f69d4" + integrity sha512-4iri8i1AqYHJE2DstZYkyEprg6Pq6sKx3xn5FpySk9sNhH7qN2LLlHJCfDTZRILNwQNPD7mATWM0TBui7uC1pA== + +"@bcoe/v8-coverage@^0.2.3": + version "0.2.3" + resolved "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" + integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== + +"@braintree/sanitize-url@^6.0.1": + version "6.0.4" + resolved "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-6.0.4.tgz" + integrity sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A== + +"@chromatic-com/storybook@^1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@chromatic-com/storybook/-/storybook-1.9.0.tgz#d95eb3474783bcc17a830a7627c3f099c1f75ba5" + integrity sha512-vYQ+TcfktEE3GHnLZXHCzXF/sN9dw+KivH8a5cmPyd9YtQs7fZtHrEgsIjWpYycXiweKMo1Lm1RZsjxk8DH3rA== + dependencies: + chromatic "^11.4.0" + filesize "^10.0.12" + jsonfile "^6.1.0" + react-confetti "^6.1.0" + strip-ansi "^7.1.0" + +"@cspotcode/source-map-support@^0.8.0": + version "0.8.1" + resolved "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" + integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== + dependencies: + "@jridgewell/trace-mapping" "0.3.9" + +"@dagrejs/dagre@^1.1.2": + version "1.1.2" + resolved "https://registry.npmjs.org/@dagrejs/dagre/-/dagre-1.1.2.tgz" + integrity sha512-F09dphqvHsbe/6C2t2unbmpr5q41BNPEfJCdn8Z7aEBpVSy/zFQ/b4SWsweQjWNsYMDvE2ffNUN8X0CeFsEGNw== + dependencies: + "@dagrejs/graphlib" "2.2.2" + +"@dagrejs/graphlib@2.2.2": + version "2.2.2" + resolved "https://registry.npmjs.org/@dagrejs/graphlib/-/graphlib-2.2.2.tgz" + integrity sha512-CbyGpCDKsiTg/wuk79S7Muoj8mghDGAESWGxcSyhHX5jD35vYMBZochYVFzlHxynpE9unpu6O+4ZuhrLxASsOg== + +"@emnapi/runtime@^0.45.0": + version "0.45.0" + resolved "https://registry.yarnpkg.com/@emnapi/runtime/-/runtime-0.45.0.tgz#e754de04c683263f34fd0c7f32adfe718bbe4ddd" + integrity sha512-Txumi3td7J4A/xTTwlssKieHKTGl3j4A1tglBx72auZ49YK7ePY6XZricgIg9mnZT4xPfA+UPCUdnhRuEFDL+w== + dependencies: + tslib "^2.4.0" + +"@emnapi/runtime@^1.2.0": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@emnapi/runtime/-/runtime-1.3.1.tgz#0fcaa575afc31f455fd33534c19381cfce6c6f60" + integrity sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw== + dependencies: + tslib "^2.4.0" + +"@emoji-mart/data@^1.1.2": + version "1.1.2" + resolved "https://registry.npmjs.org/@emoji-mart/data/-/data-1.1.2.tgz" + integrity sha512-1HP8BxD2azjqWJvxIaWAMyTySeZY0Osr83ukYjltPVkNXeJvTz7yDrPLBtnrD5uqJ3tg4CcLuuBW09wahqL/fg== + +"@esbuild/aix-ppc64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz#51299374de171dbd80bb7d838e1cfce9af36f353" + integrity sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ== + +"@esbuild/android-arm64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz#58565291a1fe548638adb9c584237449e5e14018" + integrity sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw== + +"@esbuild/android-arm@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.23.1.tgz#5eb8c652d4c82a2421e3395b808e6d9c42c862ee" + integrity sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ== + +"@esbuild/android-x64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.23.1.tgz#ae19d665d2f06f0f48a6ac9a224b3f672e65d517" + integrity sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg== + +"@esbuild/darwin-arm64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz#05b17f91a87e557b468a9c75e9d85ab10c121b16" + integrity sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q== + +"@esbuild/darwin-x64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz#c58353b982f4e04f0d022284b8ba2733f5ff0931" + integrity sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw== + +"@esbuild/freebsd-arm64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz#f9220dc65f80f03635e1ef96cfad5da1f446f3bc" + integrity sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA== + +"@esbuild/freebsd-x64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz#69bd8511fa013b59f0226d1609ac43f7ce489730" + integrity sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g== + +"@esbuild/linux-arm64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.23.1.tgz#8050af6d51ddb388c75653ef9871f5ccd8f12383" + integrity sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g== + +"@esbuild/linux-arm@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz#ecaabd1c23b701070484990db9a82f382f99e771" + integrity sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ== + +"@esbuild/linux-ia32@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.23.1.tgz#3ed2273214178109741c09bd0687098a0243b333" + integrity sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ== + +"@esbuild/linux-loong64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.23.1.tgz#a0fdf440b5485c81b0fbb316b08933d217f5d3ac" + integrity sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw== + +"@esbuild/linux-mips64el@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.23.1.tgz#e11a2806346db8375b18f5e104c5a9d4e81807f6" + integrity sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q== + +"@esbuild/linux-ppc64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz#06a2744c5eaf562b1a90937855b4d6cf7c75ec96" + integrity sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw== + +"@esbuild/linux-riscv64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz#65b46a2892fc0d1af4ba342af3fe0fa4a8fe08e7" + integrity sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA== + +"@esbuild/linux-s390x@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.23.1.tgz#e71ea18c70c3f604e241d16e4e5ab193a9785d6f" + integrity sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw== + +"@esbuild/linux-x64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz#d47f97391e80690d4dfe811a2e7d6927ad9eed24" + integrity sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ== + +"@esbuild/netbsd-x64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz#44e743c9778d57a8ace4b72f3c6b839a3b74a653" + integrity sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA== + +"@esbuild/openbsd-arm64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.1.tgz#05c5a1faf67b9881834758c69f3e51b7dee015d7" + integrity sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q== + +"@esbuild/openbsd-x64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.23.1.tgz#2e58ae511bacf67d19f9f2dcd9e8c5a93f00c273" + integrity sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA== + +"@esbuild/sunos-x64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz#adb022b959d18d3389ac70769cef5a03d3abd403" + integrity sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA== + +"@esbuild/win32-arm64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.23.1.tgz#84906f50c212b72ec360f48461d43202f4c8b9a2" + integrity sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A== + +"@esbuild/win32-ia32@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.23.1.tgz#5e3eacc515820ff729e90d0cb463183128e82fac" + integrity sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ== + +"@esbuild/win32-x64@0.23.1": + version "0.23.1" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz#81fd50d11e2c32b2d6241470e3185b70c7b30699" + integrity sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg== + +"@eslint-community/eslint-utils@^4.1.2", "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.3.0": + version "4.4.0" + resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz" + integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== + dependencies: + eslint-visitor-keys "^3.3.0" + +"@eslint-community/regexpp@^4.4.0": + version "4.5.1" + resolved "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz" + integrity sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ== + +"@eslint/eslintrc@^2.0.1": + version "2.0.3" + resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz" + integrity sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^9.5.2" + globals "^13.19.0" + ignore "^5.2.0" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.1.2" + strip-json-comments "^3.1.1" + +"@eslint/js@8.36.0": + version "8.36.0" + resolved "https://registry.npmjs.org/@eslint/js/-/js-8.36.0.tgz" + integrity sha512-lxJ9R5ygVm8ZWgYdUweoq5ownDlJ4upvoWmO4eLxBYHdMo+vZ/Rx0EN6MbKWDJOSUGrqJy2Gt+Dyv/VKml0fjg== + +"@faker-js/faker@^7.6.0": + version "7.6.0" + resolved "https://registry.npmjs.org/@faker-js/faker/-/faker-7.6.0.tgz" + integrity sha512-XK6BTq1NDMo9Xqw/YkYyGjSsg44fbNwYRx7QK2CuoQgyy+f1rrTDHoExVM5PsyXCtfl2vs2vVJ0MN0yN6LppRw== + +"@floating-ui/core@^1.1.0", "@floating-ui/core@^1.4.1": + version "1.4.1" + resolved "https://registry.npmjs.org/@floating-ui/core/-/core-1.4.1.tgz" + integrity sha512-jk3WqquEJRlcyu7997NtR5PibI+y5bi+LS3hPmguVClypenMsCY3CBa3LAQnozRCtCrYWSEtAdiskpamuJRFOQ== + dependencies: + "@floating-ui/utils" "^0.1.1" + +"@floating-ui/dom@1.1.1": + version "1.1.1" + resolved "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.1.1.tgz" + integrity sha512-TpIO93+DIujg3g7SykEAGZMDtbJRrmnYRCNYSjJlvIbGhBjRSNTLVbNeDQBrzy9qDgUbiWdc7KA0uZHZ2tJmiw== + dependencies: + "@floating-ui/core" "^1.1.0" + +"@floating-ui/dom@^1.5.1": + version "1.5.1" + resolved "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.5.1.tgz" + integrity sha512-KwvVcPSXg6mQygvA1TjbN/gh///36kKtllIF8SUm0qpFj8+rvYrpvlYdL1JoA71SHpDqgSSdGOSoQ0Mp3uY5aw== + dependencies: + "@floating-ui/core" "^1.4.1" + "@floating-ui/utils" "^0.1.1" + +"@floating-ui/react-dom@^2.0.1": + version "2.0.2" + resolved "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.2.tgz" + integrity sha512-5qhlDvjaLmAst/rKb3VdlCinwTF4EYMiVxuuc/HVUjs46W0zgtbMmAZ1UTsDrRTxRmUEzl92mOtWbeeXL26lSQ== + dependencies: + "@floating-ui/dom" "^1.5.1" + +"@floating-ui/react@^0.25.2": + version "0.25.2" + resolved "https://registry.npmjs.org/@floating-ui/react/-/react-0.25.2.tgz" + integrity sha512-3e10G9LFOgl32/SMWLBOwT7oVCtB+d5zBsU2GxTSVOvRgZexwno5MlYbc0BaXr+TR5EEGpqe9tg9OUbjlrVRnQ== + dependencies: + "@floating-ui/react-dom" "^2.0.1" + "@floating-ui/utils" "^0.1.1" + tabbable "^6.0.1" + +"@floating-ui/utils@^0.1.1": + version "0.1.1" + resolved "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.1.tgz" + integrity sha512-m0G6wlnhm/AX0H12IOWtK8gASEMffnX08RtKkCgTdHb9JpHKGloI7icFfLg9ZmQeavcvR0PKmzxClyuFPSjKWw== + +"@formatjs/intl-localematcher@^0.5.4": + version "0.5.4" + resolved "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.4.tgz" + integrity sha512-zTwEpWOzZ2CiKcB93BLngUX59hQkuZjT2+SAQEscSm52peDW/getsawMcWF1rGRpMCX6D7nSJA3CzJ8gn13N/g== + dependencies: + tslib "^2.4.0" + +"@headlessui/react@^1.7.13": + version "1.7.15" + resolved "https://registry.npmjs.org/@headlessui/react/-/react-1.7.15.tgz" + integrity sha512-OTO0XtoRQ6JPB1cKNFYBZv2Q0JMqMGNhYP1CjPvcJvjz8YGokz8oAj89HIYZGN0gZzn/4kk9iUpmMF4Q21Gsqw== + dependencies: + client-only "^0.0.1" + +"@heroicons/react@^2.0.16": + version "2.0.18" + resolved "https://registry.npmjs.org/@heroicons/react/-/react-2.0.18.tgz" + integrity sha512-7TyMjRrZZMBPa+/5Y8lN0iyvUU/01PeMGX2+RE7cQWpEUIcb4QotzUObFkJDejj/HUH4qjP/eQ0gzzKs2f+6Yw== + +"@hookform/resolvers@^3.3.4": + version "3.3.4" + resolved "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-3.3.4.tgz" + integrity sha512-o5cgpGOuJYrd+iMKvkttOclgwRW86EsWJZZRC23prf0uU2i48Htq4PuT73AVb9ionFyZrwYEITuOFGF+BydEtQ== + +"@humanwhocodes/config-array@^0.11.8": + version "0.11.10" + resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz" + integrity sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ== + dependencies: + "@humanwhocodes/object-schema" "^1.2.1" + debug "^4.1.1" + minimatch "^3.0.5" + +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== + +"@humanwhocodes/object-schema@^1.2.1": + version "1.2.1" + resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz" + integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== + +"@img/sharp-darwin-arm64@0.33.2": + version "0.33.2" + resolved "https://registry.yarnpkg.com/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.2.tgz#0a52a82c2169112794dac2c71bfba9e90f7c5bd1" + integrity sha512-itHBs1rPmsmGF9p4qRe++CzCgd+kFYktnsoR1sbIAfsRMrJZau0Tt1AH9KVnufc2/tU02Gf6Ibujx+15qRE03w== + optionalDependencies: + "@img/sharp-libvips-darwin-arm64" "1.0.1" + +"@img/sharp-darwin-arm64@0.33.5": + version "0.33.5" + resolved "https://registry.yarnpkg.com/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz#ef5b5a07862805f1e8145a377c8ba6e98813ca08" + integrity sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ== + optionalDependencies: + "@img/sharp-libvips-darwin-arm64" "1.0.4" + +"@img/sharp-darwin-x64@0.33.2": + version "0.33.2" + resolved "https://registry.yarnpkg.com/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.2.tgz#982e26bb9d38a81f75915c4032539aed621d1c21" + integrity sha512-/rK/69Rrp9x5kaWBjVN07KixZanRr+W1OiyKdXcbjQD6KbW+obaTeBBtLUAtbBsnlTTmWthw99xqoOS7SsySDg== + optionalDependencies: + "@img/sharp-libvips-darwin-x64" "1.0.1" + +"@img/sharp-darwin-x64@0.33.5": + version "0.33.5" + resolved "https://registry.yarnpkg.com/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz#e03d3451cd9e664faa72948cc70a403ea4063d61" + integrity sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q== + optionalDependencies: + "@img/sharp-libvips-darwin-x64" "1.0.4" + +"@img/sharp-libvips-darwin-arm64@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.1.tgz#81e83ffc2c497b3100e2f253766490f8fad479cd" + integrity sha512-kQyrSNd6lmBV7O0BUiyu/OEw9yeNGFbQhbxswS1i6rMDwBBSX+e+rPzu3S+MwAiGU3HdLze3PanQ4Xkfemgzcw== + +"@img/sharp-libvips-darwin-arm64@1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz#447c5026700c01a993c7804eb8af5f6e9868c07f" + integrity sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg== + +"@img/sharp-libvips-darwin-x64@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.1.tgz#fc1fcd9d78a178819eefe2c1a1662067a83ab1d6" + integrity sha512-eVU/JYLPVjhhrd8Tk6gosl5pVlvsqiFlt50wotCvdkFGf+mDNBJxMh+bvav+Wt3EBnNZWq8Sp2I7XfSjm8siog== + +"@img/sharp-libvips-darwin-x64@1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz#e0456f8f7c623f9dbfbdc77383caa72281d86062" + integrity sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ== + +"@img/sharp-libvips-linux-arm64@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.1.tgz#26eb8c556a9b0db95f343fc444abc3effb67ebcf" + integrity sha512-bnGG+MJjdX70mAQcSLxgeJco11G+MxTz+ebxlz8Y3dxyeb3Nkl7LgLI0mXupoO+u1wRNx/iRj5yHtzA4sde1yA== + +"@img/sharp-libvips-linux-arm64@1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz#979b1c66c9a91f7ff2893556ef267f90ebe51704" + integrity sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA== + +"@img/sharp-libvips-linux-arm@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.1.tgz#2a377b959ff7dd6528deee486c25461296a4fa8b" + integrity sha512-FtdMvR4R99FTsD53IA3LxYGghQ82t3yt0ZQ93WMZ2xV3dqrb0E8zq4VHaTOuLEAuA83oDawHV3fd+BsAPadHIQ== + +"@img/sharp-libvips-linux-arm@1.0.5": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz#99f922d4e15216ec205dcb6891b721bfd2884197" + integrity sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g== + +"@img/sharp-libvips-linux-s390x@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.1.tgz#af28ac9ba929204467ecdf843330d791e9421e10" + integrity sha512-3+rzfAR1YpMOeA2zZNp+aYEzGNWK4zF3+sdMxuCS3ey9HhDbJ66w6hDSHDMoap32DueFwhhs3vwooAB2MaK4XQ== + +"@img/sharp-libvips-linux-s390x@1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz#f8a5eb1f374a082f72b3f45e2fb25b8118a8a5ce" + integrity sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA== + +"@img/sharp-libvips-linux-x64@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.1.tgz#4273d182aa51912e655e1214ea47983d7c1f7f8d" + integrity sha512-3NR1mxFsaSgMMzz1bAnnKbSAI+lHXVTqAHgc1bgzjHuXjo4hlscpUxc0vFSAPKI3yuzdzcZOkq7nDPrP2F8Jgw== + +"@img/sharp-libvips-linux-x64@1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz#d4c4619cdd157774906e15770ee119931c7ef5e0" + integrity sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw== + +"@img/sharp-libvips-linuxmusl-arm64@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.1.tgz#d150c92151cea2e8d120ad168b9c358d09c77ce8" + integrity sha512-5aBRcjHDG/T6jwC3Edl3lP8nl9U2Yo8+oTl5drd1dh9Z1EBfzUKAJFUDTDisDjUwc7N4AjnPGfCA3jl3hY8uDg== + +"@img/sharp-libvips-linuxmusl-arm64@1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz#166778da0f48dd2bded1fa3033cee6b588f0d5d5" + integrity sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA== + +"@img/sharp-libvips-linuxmusl-x64@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.1.tgz#e297c1a4252c670d93b0f9e51fca40a7a5b6acfd" + integrity sha512-dcT7inI9DBFK6ovfeWRe3hG30h51cBAP5JXlZfx6pzc/Mnf9HFCQDLtYf4MCBjxaaTfjCCjkBxcy3XzOAo5txw== + +"@img/sharp-libvips-linuxmusl-x64@1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz#93794e4d7720b077fcad3e02982f2f1c246751ff" + integrity sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw== + +"@img/sharp-linux-arm64@0.33.2": + version "0.33.2" + resolved "https://registry.yarnpkg.com/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.2.tgz#af3409f801a9bee1d11d0c7e971dcd6180f80022" + integrity sha512-pz0NNo882vVfqJ0yNInuG9YH71smP4gRSdeL09ukC2YLE6ZyZePAlWKEHgAzJGTiOh8Qkaov6mMIMlEhmLdKew== + optionalDependencies: + "@img/sharp-libvips-linux-arm64" "1.0.1" + +"@img/sharp-linux-arm64@0.33.5": + version "0.33.5" + resolved "https://registry.yarnpkg.com/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz#edb0697e7a8279c9fc829a60fc35644c4839bb22" + integrity sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA== + optionalDependencies: + "@img/sharp-libvips-linux-arm64" "1.0.4" + +"@img/sharp-linux-arm@0.33.2": + version "0.33.2" + resolved "https://registry.yarnpkg.com/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.2.tgz#181f7466e6ac074042a38bfb679eb82505e17083" + integrity sha512-Fndk/4Zq3vAc4G/qyfXASbS3HBZbKrlnKZLEJzPLrXoJuipFNNwTes71+Ki1hwYW5lch26niRYoZFAtZVf3EGA== + optionalDependencies: + "@img/sharp-libvips-linux-arm" "1.0.1" + +"@img/sharp-linux-arm@0.33.5": + version "0.33.5" + resolved "https://registry.yarnpkg.com/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz#422c1a352e7b5832842577dc51602bcd5b6f5eff" + integrity sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ== + optionalDependencies: + "@img/sharp-libvips-linux-arm" "1.0.5" + +"@img/sharp-linux-s390x@0.33.2": + version "0.33.2" + resolved "https://registry.yarnpkg.com/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.2.tgz#9c171f49211f96fba84410b3e237b301286fa00f" + integrity sha512-MBoInDXDppMfhSzbMmOQtGfloVAflS2rP1qPcUIiITMi36Mm5YR7r0ASND99razjQUpHTzjrU1flO76hKvP5RA== + optionalDependencies: + "@img/sharp-libvips-linux-s390x" "1.0.1" + +"@img/sharp-linux-s390x@0.33.5": + version "0.33.5" + resolved "https://registry.yarnpkg.com/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz#f5c077926b48e97e4a04d004dfaf175972059667" + integrity sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q== + optionalDependencies: + "@img/sharp-libvips-linux-s390x" "1.0.4" + +"@img/sharp-linux-x64@0.33.2": + version "0.33.2" + resolved "https://registry.yarnpkg.com/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.2.tgz#b956dfc092adc58c2bf0fae2077e6f01a8b2d5d7" + integrity sha512-xUT82H5IbXewKkeF5aiooajoO1tQV4PnKfS/OZtb5DDdxS/FCI/uXTVZ35GQ97RZXsycojz/AJ0asoz6p2/H/A== + optionalDependencies: + "@img/sharp-libvips-linux-x64" "1.0.1" + +"@img/sharp-linux-x64@0.33.5": + version "0.33.5" + resolved "https://registry.yarnpkg.com/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz#d806e0afd71ae6775cc87f0da8f2d03a7c2209cb" + integrity sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA== + optionalDependencies: + "@img/sharp-libvips-linux-x64" "1.0.4" + +"@img/sharp-linuxmusl-arm64@0.33.2": + version "0.33.2" + resolved "https://registry.yarnpkg.com/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.2.tgz#10e0ec5a79d1234c6a71df44c9f3b0bef0bc0f15" + integrity sha512-F+0z8JCu/UnMzg8IYW1TMeiViIWBVg7IWP6nE0p5S5EPQxlLd76c8jYemG21X99UzFwgkRo5yz2DS+zbrnxZeA== + optionalDependencies: + "@img/sharp-libvips-linuxmusl-arm64" "1.0.1" + +"@img/sharp-linuxmusl-arm64@0.33.5": + version "0.33.5" + resolved "https://registry.yarnpkg.com/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz#252975b915894fb315af5deea174651e208d3d6b" + integrity sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g== + optionalDependencies: + "@img/sharp-libvips-linuxmusl-arm64" "1.0.4" + +"@img/sharp-linuxmusl-x64@0.33.2": + version "0.33.2" + resolved "https://registry.yarnpkg.com/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.2.tgz#29e0030c24aa27c38201b1fc84e3d172899fcbe0" + integrity sha512-+ZLE3SQmSL+Fn1gmSaM8uFusW5Y3J9VOf+wMGNnTtJUMUxFhv+P4UPaYEYT8tqnyYVaOVGgMN/zsOxn9pSsO2A== + optionalDependencies: + "@img/sharp-libvips-linuxmusl-x64" "1.0.1" + +"@img/sharp-linuxmusl-x64@0.33.5": + version "0.33.5" + resolved "https://registry.yarnpkg.com/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz#3f4609ac5d8ef8ec7dadee80b560961a60fd4f48" + integrity sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw== + optionalDependencies: + "@img/sharp-libvips-linuxmusl-x64" "1.0.4" + +"@img/sharp-wasm32@0.33.2": + version "0.33.2" + resolved "https://registry.yarnpkg.com/@img/sharp-wasm32/-/sharp-wasm32-0.33.2.tgz#38d7c740a22de83a60ad1e6bcfce17462b0d4230" + integrity sha512-fLbTaESVKuQcpm8ffgBD7jLb/CQLcATju/jxtTXR1XCLwbOQt+OL5zPHSDMmp2JZIeq82e18yE0Vv7zh6+6BfQ== + dependencies: + "@emnapi/runtime" "^0.45.0" + +"@img/sharp-wasm32@0.33.5": + version "0.33.5" + resolved "https://registry.yarnpkg.com/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz#6f44f3283069d935bb5ca5813153572f3e6f61a1" + integrity sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg== + dependencies: + "@emnapi/runtime" "^1.2.0" + +"@img/sharp-win32-ia32@0.33.2": + version "0.33.2" + resolved "https://registry.yarnpkg.com/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.2.tgz#09456314e223f68e5417c283b45c399635c16202" + integrity sha512-okBpql96hIGuZ4lN3+nsAjGeggxKm7hIRu9zyec0lnfB8E7Z6p95BuRZzDDXZOl2e8UmR4RhYt631i7mfmKU8g== + +"@img/sharp-win32-ia32@0.33.5": + version "0.33.5" + resolved "https://registry.yarnpkg.com/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz#1a0c839a40c5351e9885628c85f2e5dfd02b52a9" + integrity sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ== + +"@img/sharp-win32-x64@0.33.2": + version "0.33.2" + resolved "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.2.tgz" + integrity sha512-E4magOks77DK47FwHUIGH0RYWSgRBfGdK56kIHSVeB9uIS4pPFr4N2kIVsXdQQo4LzOsENKV5KAhRlRL7eMAdg== + +"@img/sharp-win32-x64@0.33.5": + version "0.33.5" + resolved "https://registry.yarnpkg.com/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz#56f00962ff0c4e0eb93d34a047d29fa995e3e342" + integrity sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg== + +"@isaacs/cliui@^8.0.2": + version "8.0.2" + resolved "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz" + integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== + dependencies: + string-width "^5.1.2" + string-width-cjs "npm:string-width@^4.2.0" + strip-ansi "^7.0.1" + strip-ansi-cjs "npm:strip-ansi@^6.0.1" + wrap-ansi "^8.1.0" + wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" + +"@istanbuljs/load-nyc-config@^1.0.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" + integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== + dependencies: + camelcase "^5.3.1" + find-up "^4.1.0" + get-package-type "^0.1.0" + js-yaml "^3.13.1" + resolve-from "^5.0.0" + +"@istanbuljs/schema@^0.1.2", "@istanbuljs/schema@^0.1.3": + version "0.1.3" + resolved "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" + integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== + +"@jest/console@^29.7.0": + version "29.7.0" + resolved "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz#cd4822dbdb84529265c5a2bdb529a3c9cc950ffc" + integrity sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg== + dependencies: + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + jest-message-util "^29.7.0" + jest-util "^29.7.0" + slash "^3.0.0" + +"@jest/core@^29.7.0": + version "29.7.0" + resolved "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz#b6cccc239f30ff36609658c5a5e2291757ce448f" + integrity sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg== + dependencies: + "@jest/console" "^29.7.0" + "@jest/reporters" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + ci-info "^3.2.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + jest-changed-files "^29.7.0" + jest-config "^29.7.0" + jest-haste-map "^29.7.0" + jest-message-util "^29.7.0" + jest-regex-util "^29.6.3" + jest-resolve "^29.7.0" + jest-resolve-dependencies "^29.7.0" + jest-runner "^29.7.0" + jest-runtime "^29.7.0" + jest-snapshot "^29.7.0" + jest-util "^29.7.0" + jest-validate "^29.7.0" + jest-watcher "^29.7.0" + micromatch "^4.0.4" + pretty-format "^29.7.0" + slash "^3.0.0" + strip-ansi "^6.0.0" + +"@jest/environment@^29.7.0": + version "29.7.0" + resolved "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz#24d61f54ff1f786f3cd4073b4b94416383baf2a7" + integrity sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw== + dependencies: + "@jest/fake-timers" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + jest-mock "^29.7.0" + +"@jest/expect-utils@^29.7.0": + version "29.7.0" + resolved "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz#023efe5d26a8a70f21677d0a1afc0f0a44e3a1c6" + integrity sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA== + dependencies: + jest-get-type "^29.6.3" + +"@jest/expect@^29.7.0": + version "29.7.0" + resolved "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz#76a3edb0cb753b70dfbfe23283510d3d45432bf2" + integrity sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ== + dependencies: + expect "^29.7.0" + jest-snapshot "^29.7.0" + +"@jest/fake-timers@^29.7.0": + version "29.7.0" + resolved "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz#fd91bf1fffb16d7d0d24a426ab1a47a49881a565" + integrity sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ== + dependencies: + "@jest/types" "^29.6.3" + "@sinonjs/fake-timers" "^10.0.2" + "@types/node" "*" + jest-message-util "^29.7.0" + jest-mock "^29.7.0" + jest-util "^29.7.0" + +"@jest/globals@^29.7.0": + version "29.7.0" + resolved "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz#8d9290f9ec47ff772607fa864ca1d5a2efae1d4d" + integrity sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ== + dependencies: + "@jest/environment" "^29.7.0" + "@jest/expect" "^29.7.0" + "@jest/types" "^29.6.3" + jest-mock "^29.7.0" + +"@jest/reporters@^29.7.0": + version "29.7.0" + resolved "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz#04b262ecb3b8faa83b0b3d321623972393e8f4c7" + integrity sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg== + dependencies: + "@bcoe/v8-coverage" "^0.2.3" + "@jest/console" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" + "@jridgewell/trace-mapping" "^0.3.18" + "@types/node" "*" + chalk "^4.0.0" + collect-v8-coverage "^1.0.0" + exit "^0.1.2" + glob "^7.1.3" + graceful-fs "^4.2.9" + istanbul-lib-coverage "^3.0.0" + istanbul-lib-instrument "^6.0.0" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.0" + istanbul-reports "^3.1.3" + jest-message-util "^29.7.0" + jest-util "^29.7.0" + jest-worker "^29.7.0" + slash "^3.0.0" + string-length "^4.0.1" + strip-ansi "^6.0.0" + v8-to-istanbul "^9.0.1" + +"@jest/schemas@^29.6.3": + version "29.6.3" + resolved "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz#430b5ce8a4e0044a7e3819663305a7b3091c8e03" + integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA== + dependencies: + "@sinclair/typebox" "^0.27.8" + +"@jest/source-map@^29.6.3": + version "29.6.3" + resolved "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz#d90ba772095cf37a34a5eb9413f1b562a08554c4" + integrity sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw== + dependencies: + "@jridgewell/trace-mapping" "^0.3.18" + callsites "^3.0.0" + graceful-fs "^4.2.9" + +"@jest/test-result@^29.7.0": + version "29.7.0" + resolved "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz#8db9a80aa1a097bb2262572686734baed9b1657c" + integrity sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA== + dependencies: + "@jest/console" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" + +"@jest/test-sequencer@^29.7.0": + version "29.7.0" + resolved "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz#6cef977ce1d39834a3aea887a1726628a6f072ce" + integrity sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw== + dependencies: + "@jest/test-result" "^29.7.0" + graceful-fs "^4.2.9" + jest-haste-map "^29.7.0" + slash "^3.0.0" + +"@jest/transform@^29.7.0": + version "29.7.0" + resolved "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz#df2dd9c346c7d7768b8a06639994640c642e284c" + integrity sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw== + dependencies: + "@babel/core" "^7.11.6" + "@jest/types" "^29.6.3" + "@jridgewell/trace-mapping" "^0.3.18" + babel-plugin-istanbul "^6.1.1" + chalk "^4.0.0" + convert-source-map "^2.0.0" + fast-json-stable-stringify "^2.1.0" + graceful-fs "^4.2.9" + jest-haste-map "^29.7.0" + jest-regex-util "^29.6.3" + jest-util "^29.7.0" + micromatch "^4.0.4" + pirates "^4.0.4" + slash "^3.0.0" + write-file-atomic "^4.0.2" + +"@jest/types@^29.6.3": + version "29.6.3" + resolved "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz#1131f8cf634e7e84c5e77bab12f052af585fba59" + integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw== + dependencies: + "@jest/schemas" "^29.6.3" + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^17.0.8" + chalk "^4.0.0" + +"@jridgewell/gen-mapping@^0.3.2", "@jridgewell/gen-mapping@^0.3.5": + version "0.3.5" + resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz" + integrity sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg== + dependencies: + "@jridgewell/set-array" "^1.2.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.24" + +"@jridgewell/resolve-uri@^3.0.3": + version "3.1.2" + resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" + integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== + +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.0" + resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz" + integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== + +"@jridgewell/set-array@^1.2.1": + version "1.2.1" + resolved "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz" + integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== + +"@jridgewell/source-map@^0.3.3": + version "0.3.6" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.6.tgz#9d71ca886e32502eb9362c9a74a46787c36df81a" + integrity sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ== + dependencies: + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.25" + +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": + version "1.4.15" + resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + +"@jridgewell/sourcemap-codec@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" + integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== + +"@jridgewell/trace-mapping@0.3.9": + version "0.3.9" + resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" + integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.20", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": + version "0.3.25" + resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz" + integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + +"@lexical/clipboard@0.16.0": + version "0.16.0" + resolved "https://registry.npmjs.org/@lexical/clipboard/-/clipboard-0.16.0.tgz" + integrity sha512-eYMJ6jCXpWBVC05Mu9HLMysrBbfi++xFfsm+Yo7A6kYGrqYUhpXqjJkYnw1xdZYL3bV73Oe4ByVJuq42GU+Mqw== + dependencies: + "@lexical/html" "0.16.0" + "@lexical/list" "0.16.0" + "@lexical/selection" "0.16.0" + "@lexical/utils" "0.16.0" + lexical "0.16.0" + +"@lexical/code@0.16.0": + version "0.16.0" + resolved "https://registry.npmjs.org/@lexical/code/-/code-0.16.0.tgz" + integrity sha512-1EKCBSFV745UI2zn5v75sKcvVdmd+y2JtZhw8CItiQkRnBLv4l4d/RZYy+cKOuXJGsoBrKtxXn5sl7HebwQbPw== + dependencies: + "@lexical/utils" "0.16.0" + lexical "0.16.0" + prismjs "^1.27.0" + +"@lexical/devtools-core@0.16.0": + version "0.16.0" + resolved "https://registry.npmjs.org/@lexical/devtools-core/-/devtools-core-0.16.0.tgz" + integrity sha512-Jt8p0J0UoMHf3UMh3VdyrXbLLwpEZuMqihTmbPRpwo+YQ6NGQU35QgwY2K0DpPAThpxL/Cm7uaFqGOy8Kjrhqw== + dependencies: + "@lexical/html" "0.16.0" + "@lexical/link" "0.16.0" + "@lexical/mark" "0.16.0" + "@lexical/table" "0.16.0" + "@lexical/utils" "0.16.0" + lexical "0.16.0" + +"@lexical/dragon@0.16.0": + version "0.16.0" + resolved "https://registry.npmjs.org/@lexical/dragon/-/dragon-0.16.0.tgz" + integrity sha512-Yr29SFZzOPs+S6UrEZaXnnso1fJGVfZOXVJQZbyzlspqJpSHXVH7InOXYHWN6JSWQ8Hs/vU3ksJXwqz+0TCp2g== + dependencies: + lexical "0.16.0" + +"@lexical/hashtag@0.16.0": + version "0.16.0" + resolved "https://registry.npmjs.org/@lexical/hashtag/-/hashtag-0.16.0.tgz" + integrity sha512-2EdAvxYVYqb0nv6vgxCRgE8ip7yez5p0y0oeUyxmdbcfZdA+Jl90gYH3VdevmZ5Bk3wE0/fIqiLD+Bb5smqjCQ== + dependencies: + "@lexical/utils" "0.16.0" + lexical "0.16.0" + +"@lexical/history@0.16.0": + version "0.16.0" + resolved "https://registry.npmjs.org/@lexical/history/-/history-0.16.0.tgz" + integrity sha512-xwFxgDZGviyGEqHmgt6A6gPhsyU/yzlKRk9TBUVByba3khuTknlJ1a80H5jb+OYcrpiElml7iVuGYt+oC7atCA== + dependencies: + "@lexical/utils" "0.16.0" + lexical "0.16.0" + +"@lexical/html@0.16.0": + version "0.16.0" + resolved "https://registry.npmjs.org/@lexical/html/-/html-0.16.0.tgz" + integrity sha512-okxn3q/1qkUpCZNEFRI39XeJj4YRjb6prm3WqZgP4d39DI1W24feeTZJjYRCW+dc3NInwFaolU3pNA2MGkjRtg== + dependencies: + "@lexical/selection" "0.16.0" + "@lexical/utils" "0.16.0" + lexical "0.16.0" + +"@lexical/link@0.16.0": + version "0.16.0" + resolved "https://registry.npmjs.org/@lexical/link/-/link-0.16.0.tgz" + integrity sha512-ppvJSh/XGqlzbeymOiwcXJcUcrqgQqTK2QXTBAZq7JThtb0WsJxYd2CSLSN+Ycu23prnwqOqILcU0+34+gAVFw== + dependencies: + "@lexical/utils" "0.16.0" + lexical "0.16.0" + +"@lexical/list@0.16.0": + version "0.16.0" + resolved "https://registry.npmjs.org/@lexical/list/-/list-0.16.0.tgz" + integrity sha512-nBx/DMM7nCgnOzo1JyNnVaIrk/Xi5wIPNi8jixrEV6w9Om2K6dHutn/79Xzp2dQlNGSLHEDjky6N2RyFgmXh0g== + dependencies: + "@lexical/utils" "0.16.0" + lexical "0.16.0" + +"@lexical/mark@0.16.0": + version "0.16.0" + resolved "https://registry.npmjs.org/@lexical/mark/-/mark-0.16.0.tgz" + integrity sha512-WMR4nqygSgIQ6Vdr5WAzohxBGjH+m44dBNTbWTGZGVlRvPzvBT6tieCoxFqpceIq/ko67HGTCNoFj2cMKVwgIA== + dependencies: + "@lexical/utils" "0.16.0" + lexical "0.16.0" + +"@lexical/markdown@0.16.0": + version "0.16.0" + resolved "https://registry.npmjs.org/@lexical/markdown/-/markdown-0.16.0.tgz" + integrity sha512-7HQLFrBbpY68mcq4A6C1qIGmjgA+fAByditi2WRe7tD2eoIKb/B5baQAnDKis0J+m5kTaCBmdlT6csSzyOPzeQ== + dependencies: + "@lexical/code" "0.16.0" + "@lexical/link" "0.16.0" + "@lexical/list" "0.16.0" + "@lexical/rich-text" "0.16.0" + "@lexical/text" "0.16.0" + "@lexical/utils" "0.16.0" + lexical "0.16.0" + +"@lexical/offset@0.16.0": + version "0.16.0" + resolved "https://registry.npmjs.org/@lexical/offset/-/offset-0.16.0.tgz" + integrity sha512-4TqPEC2qA7sgO8Tm65nOWnhJ8dkl22oeuGv9sUB+nhaiRZnw3R45mDelg23r56CWE8itZnvueE7TKvV+F3OXtQ== + dependencies: + lexical "0.16.0" + +"@lexical/overflow@0.16.0": + version "0.16.0" + resolved "https://registry.npmjs.org/@lexical/overflow/-/overflow-0.16.0.tgz" + integrity sha512-a7gtIRxleEuMN9dj2yO4CdezBBfIr9Mq+m7G5z62+xy7VL7cfMfF+xWjy3EmDYDXS4vOQgAXAUgO4oKz2AKGhQ== + dependencies: + lexical "0.16.0" + +"@lexical/plain-text@0.16.0": + version "0.16.0" + resolved "https://registry.npmjs.org/@lexical/plain-text/-/plain-text-0.16.0.tgz" + integrity sha512-BK7/GSOZUHRJTbNPkpb9a/xN9z+FBCdunTsZhnOY8pQ7IKws3kuMO2Tk1zXfTd882ZNAxFdDKNdLYDSeufrKpw== + dependencies: + "@lexical/clipboard" "0.16.0" + "@lexical/selection" "0.16.0" + "@lexical/utils" "0.16.0" + lexical "0.16.0" + +"@lexical/react@^0.16.0": + version "0.16.0" + resolved "https://registry.npmjs.org/@lexical/react/-/react-0.16.0.tgz" + integrity sha512-WKFQbI0/m1YkLjL5t90YLJwjGcl5QRe6mkfm3ljQuL7Ioj3F92ZN/J2gHFVJ9iC8/lJs6Zzw6oFjiP8hQxJf9Q== + dependencies: + "@lexical/clipboard" "0.16.0" + "@lexical/code" "0.16.0" + "@lexical/devtools-core" "0.16.0" + "@lexical/dragon" "0.16.0" + "@lexical/hashtag" "0.16.0" + "@lexical/history" "0.16.0" + "@lexical/link" "0.16.0" + "@lexical/list" "0.16.0" + "@lexical/mark" "0.16.0" + "@lexical/markdown" "0.16.0" + "@lexical/overflow" "0.16.0" + "@lexical/plain-text" "0.16.0" + "@lexical/rich-text" "0.16.0" + "@lexical/selection" "0.16.0" + "@lexical/table" "0.16.0" + "@lexical/text" "0.16.0" + "@lexical/utils" "0.16.0" + "@lexical/yjs" "0.16.0" + lexical "0.16.0" + react-error-boundary "^3.1.4" + +"@lexical/rich-text@0.16.0": + version "0.16.0" + resolved "https://registry.npmjs.org/@lexical/rich-text/-/rich-text-0.16.0.tgz" + integrity sha512-AGTD6yJZ+kj2TNah1r7/6vyufs6fZANeSvv9x5eG+WjV4uyUJYkd1qR8C5gFZHdkyr+bhAcsAXvS039VzAxRrQ== + dependencies: + "@lexical/clipboard" "0.16.0" + "@lexical/selection" "0.16.0" + "@lexical/utils" "0.16.0" + lexical "0.16.0" + +"@lexical/selection@0.16.0": + version "0.16.0" + resolved "https://registry.npmjs.org/@lexical/selection/-/selection-0.16.0.tgz" + integrity sha512-trT9gQVJ2j6AwAe7tHJ30SRuxCpV6yR9LFtggxphHsXSvJYnoHC0CXh1TF2jHl8Gd5OsdWseexGLBE4Y0V3gwQ== + dependencies: + lexical "0.16.0" + +"@lexical/table@0.16.0": + version "0.16.0" + resolved "https://registry.npmjs.org/@lexical/table/-/table-0.16.0.tgz" + integrity sha512-A66K779kxdr0yH2RwT2itsMnkzyFLFNPXyiWGLobCH8ON4QPuBouZvjbRHBe8Pe64yJ0c1bRDxSbTqUi9Wt3Gg== + dependencies: + "@lexical/utils" "0.16.0" + lexical "0.16.0" + +"@lexical/text@0.16.0": + version "0.16.0" + resolved "https://registry.npmjs.org/@lexical/text/-/text-0.16.0.tgz" + integrity sha512-9ilaOhuNIIGHKC8g8j3K/mEvJ09af9B6RKbm3GNoRcf/WNHD4dEFWNTEvgo/3zCzAS8EUBI6UINmfQQWlMjdIQ== + dependencies: + lexical "0.16.0" + +"@lexical/utils@0.16.0": + version "0.16.0" + resolved "https://registry.npmjs.org/@lexical/utils/-/utils-0.16.0.tgz" + integrity sha512-GWmFEmd7o3GHqJBaEwzuZQbfTNI3Gg8ReGuHMHABgrkhZ8j2NggoRBlxsQLG0f7BewfTMVwbye22yBPq78775w== + dependencies: + "@lexical/list" "0.16.0" + "@lexical/selection" "0.16.0" + "@lexical/table" "0.16.0" + lexical "0.16.0" + +"@lexical/yjs@0.16.0": + version "0.16.0" + resolved "https://registry.npmjs.org/@lexical/yjs/-/yjs-0.16.0.tgz" + integrity sha512-YIJr87DfAXTwoVHDjR7cci//hr4r/a61Nn95eo2JNwbTqQo65Gp8rwJivqVxNfvKZmRdwHTKgvdEDoBmI/tGog== + dependencies: + "@lexical/offset" "0.16.0" + lexical "0.16.0" + +"@mdx-js/loader@^2.3.0": + version "2.3.0" + resolved "https://registry.npmjs.org/@mdx-js/loader/-/loader-2.3.0.tgz" + integrity sha512-IqsscXh7Q3Rzb+f5DXYk0HU71PK+WuFsEhf+mSV3fOhpLcEpgsHvTQ2h0T6TlZ5gHOaBeFjkXwB52by7ypMyNg== + dependencies: + "@mdx-js/mdx" "^2.0.0" + source-map "^0.7.0" + +"@mdx-js/mdx@^2.0.0": + version "2.3.0" + resolved "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-2.3.0.tgz" + integrity sha512-jLuwRlz8DQfQNiUCJR50Y09CGPq3fLtmtUQfVrj79E0JWu3dvsVcxVIcfhR5h0iXu+/z++zDrYeiJqifRynJkA== + dependencies: + "@types/estree-jsx" "^1.0.0" + "@types/mdx" "^2.0.0" + estree-util-build-jsx "^2.0.0" + estree-util-is-identifier-name "^2.0.0" + estree-util-to-js "^1.1.0" + estree-walker "^3.0.0" + hast-util-to-estree "^2.0.0" + markdown-extensions "^1.0.0" + periscopic "^3.0.0" + remark-mdx "^2.0.0" + remark-parse "^10.0.0" + remark-rehype "^10.0.0" + unified "^10.0.0" + unist-util-position-from-estree "^1.0.0" + unist-util-stringify-position "^3.0.0" + unist-util-visit "^4.0.0" + vfile "^5.0.0" + +"@mdx-js/react@^2.3.0": + version "2.3.0" + resolved "https://registry.npmjs.org/@mdx-js/react/-/react-2.3.0.tgz" + integrity sha512-zQH//gdOmuu7nt2oJR29vFhDv88oGPmVw6BggmrHeMI+xgEkp1B2dX9/bMBSYtK0dyLX/aOmesKS09g222K1/g== + dependencies: + "@types/mdx" "^2.0.0" + "@types/react" ">=16" + +"@mdx-js/react@^3.0.0": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@mdx-js/react/-/react-3.0.1.tgz#997a19b3a5b783d936c75ae7c47cfe62f967f746" + integrity sha512-9ZrPIU4MGf6et1m1ov3zKf+q9+deetI51zprKB1D/z3NOb+rUxxtEl3mCjW5wTGh6VhRdwPueh1oRzi6ezkA8A== + dependencies: + "@types/mdx" "^2.0.0" + +"@monaco-editor/loader@^1.4.0": + version "1.4.0" + resolved "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.4.0.tgz" + integrity sha512-00ioBig0x642hytVspPl7DbQyaSWRaolYie/UFNjoTdvoKPzo6xrXLhTk9ixgIKcLH5b5vDOjVNiGyY+uDCUlg== + dependencies: + state-local "^1.0.6" + +"@monaco-editor/react@^4.6.0": + version "4.6.0" + resolved "https://registry.npmjs.org/@monaco-editor/react/-/react-4.6.0.tgz" + integrity sha512-RFkU9/i7cN2bsq/iTkurMWOEErmYcY6JiQI3Jn+WeR/FGISH8JbHERjpS9oRuSOPvDMJI0Z8nJeKkbOs9sBYQw== + dependencies: + "@monaco-editor/loader" "^1.4.0" + +"@next/env@14.2.4": + version "14.2.4" + resolved "https://registry.npmjs.org/@next/env/-/env-14.2.4.tgz" + integrity sha512-3EtkY5VDkuV2+lNmKlbkibIJxcO4oIHEhBWne6PaAp+76J9KoSsGvNikp6ivzAT8dhhBMYrm6op2pS1ApG0Hzg== + +"@next/eslint-plugin-next@14.1.0": + version "14.1.0" + resolved "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.1.0.tgz" + integrity sha512-x4FavbNEeXx/baD/zC/SdrvkjSby8nBn8KcCREqk6UuwvwoAPZmaV8TFCAuo/cpovBRTIY67mHhe86MQQm/68Q== + dependencies: + glob "10.3.10" + +"@next/mdx@^14.0.4": + version "14.1.0" + resolved "https://registry.npmjs.org/@next/mdx/-/mdx-14.1.0.tgz" + integrity sha512-YLYsViq91+H8+3oCtK1iuMWdeN14K70Hy6/tYScY+nfo5bQ84A/A+vA6UdNC9MkbWQ/373hQubx2p4JvUjlb2Q== + dependencies: + source-map "^0.7.0" + +"@next/swc-darwin-arm64@14.2.4": + version "14.2.4" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.4.tgz#da9f04c34a3d5f0b8401ed745768420e4a604036" + integrity sha512-AH3mO4JlFUqsYcwFUHb1wAKlebHU/Hv2u2kb1pAuRanDZ7pD/A/KPD98RHZmwsJpdHQwfEc/06mgpSzwrJYnNg== + +"@next/swc-darwin-x64@14.2.4": + version "14.2.4" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.4.tgz#46dedb29ec5503bf171a72a3ecb8aac6e738e9d6" + integrity sha512-QVadW73sWIO6E2VroyUjuAxhWLZWEpiFqHdZdoQ/AMpN9YWGuHV8t2rChr0ahy+irKX5mlDU7OY68k3n4tAZTg== + +"@next/swc-linux-arm64-gnu@14.2.4": + version "14.2.4" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.4.tgz#c9697ab9eb422bd1d7ffd0eb0779cc2aefa9d4a1" + integrity sha512-KT6GUrb3oyCfcfJ+WliXuJnD6pCpZiosx2X3k66HLR+DMoilRb76LpWPGb4tZprawTtcnyrv75ElD6VncVamUQ== + +"@next/swc-linux-arm64-musl@14.2.4": + version "14.2.4" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.4.tgz#cbbceb2008571c743b5a310a488d2e166d200a75" + integrity sha512-Alv8/XGSs/ytwQcbCHwze1HmiIkIVhDHYLjczSVrf0Wi2MvKn/blt7+S6FJitj3yTlMwMxII1gIJ9WepI4aZ/A== + +"@next/swc-linux-x64-gnu@14.2.4": + version "14.2.4" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.4.tgz#d79184223f857bacffb92f643cb2943a43632568" + integrity sha512-ze0ShQDBPCqxLImzw4sCdfnB3lRmN3qGMB2GWDRlq5Wqy4G36pxtNOo2usu/Nm9+V2Rh/QQnrRc2l94kYFXO6Q== + +"@next/swc-linux-x64-musl@14.2.4": + version "14.2.4" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.4.tgz#6b6c3e5ac02ca5e63394d280ec8ee607491902df" + integrity sha512-8dwC0UJoc6fC7PX70csdaznVMNr16hQrTDAMPvLPloazlcaWfdPogq+UpZX6Drqb1OBlwowz8iG7WR0Tzk/diQ== + +"@next/swc-win32-arm64-msvc@14.2.4": + version "14.2.4" + resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.4.tgz#dbad3906e870dba84c5883d9d4c4838472e0697f" + integrity sha512-jxyg67NbEWkDyvM+O8UDbPAyYRZqGLQDTPwvrBBeOSyVWW/jFQkQKQ70JDqDSYg1ZDdl+E3nkbFbq8xM8E9x8A== + +"@next/swc-win32-ia32-msvc@14.2.4": + version "14.2.4" + resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.4.tgz#6074529b91ba49132922ce89a2e16d25d2ec235d" + integrity sha512-twrmN753hjXRdcrZmZttb/m5xaCBFa48Dt3FbeEItpJArxriYDunWxJn+QFXdJ3hPkm4u7CKxncVvnmgQMY1ag== + +"@next/swc-win32-x64-msvc@14.2.4": + version "14.2.4" + resolved "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.4.tgz" + integrity sha512-tkLrjBzqFTP8DVrAAQmZelEahfR9OxWpFR++vAI9FBhCiIxtwHwBHC23SBHCTURBtwB4kc/x44imVOnkKGNVGg== + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": + version "1.2.8" + resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@pkgjs/parseargs@^0.11.0": + version "0.11.0" + resolved "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz" + integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== + +"@pkgr/utils@^2.3.1": + version "2.4.1" + resolved "https://registry.npmjs.org/@pkgr/utils/-/utils-2.4.1.tgz" + integrity sha512-JOqwkgFEyi+OROIyq7l4Jy28h/WwhDnG/cPkXG2Z1iFbubB6jsHW1NDvmyOzTBxHr3yg68YGirmh1JUgMqa+9w== + dependencies: + cross-spawn "^7.0.3" + fast-glob "^3.2.12" + is-glob "^4.0.3" + open "^9.1.0" + picocolors "^1.0.0" + tslib "^2.5.0" + +"@pmmmwh/react-refresh-webpack-plugin@^0.5.11": + version "0.5.15" + resolved "https://registry.yarnpkg.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.15.tgz#f126be97c30b83ed777e2aeabd518bc592e6e7c4" + integrity sha512-LFWllMA55pzB9D34w/wXUCf8+c+IYKuJDgxiZ3qMhl64KRMBHYM1I3VdGaD2BV5FNPV2/S2596bppxHbv2ZydQ== + dependencies: + ansi-html "^0.0.9" + core-js-pure "^3.23.3" + error-stack-parser "^2.0.6" + html-entities "^2.1.0" + loader-utils "^2.0.4" + schema-utils "^4.2.0" + source-map "^0.7.3" + +"@reactflow/background@11.3.13": + version "11.3.13" + resolved "https://registry.npmjs.org/@reactflow/background/-/background-11.3.13.tgz" + integrity sha512-hkvpVEhgvfTDyCvdlitw4ioKCYLaaiRXnuEG+1QM3Np+7N1DiWF1XOv5I8AFyNoJL07yXEkbECUTsHvkBvcG5A== + dependencies: + "@reactflow/core" "11.11.3" + classcat "^5.0.3" + zustand "^4.4.1" + +"@reactflow/controls@11.2.13": + version "11.2.13" + resolved "https://registry.npmjs.org/@reactflow/controls/-/controls-11.2.13.tgz" + integrity sha512-3xgEg6ALIVkAQCS4NiBjb7ad8Cb3D8CtA7Vvl4Hf5Ar2PIVs6FOaeft9s2iDZGtsWP35ECDYId1rIFVhQL8r+A== + dependencies: + "@reactflow/core" "11.11.3" + classcat "^5.0.3" + zustand "^4.4.1" + +"@reactflow/core@11.11.3": + version "11.11.3" + resolved "https://registry.npmjs.org/@reactflow/core/-/core-11.11.3.tgz" + integrity sha512-+adHdUa7fJSEM93fWfjQwyWXeI92a1eLKwWbIstoCakHpL8UjzwhEh6sn+mN2h/59MlVI7Ehr1iGTt3MsfcIFA== + dependencies: + "@types/d3" "^7.4.0" + "@types/d3-drag" "^3.0.1" + "@types/d3-selection" "^3.0.3" + "@types/d3-zoom" "^3.0.1" + classcat "^5.0.3" + d3-drag "^3.0.0" + d3-selection "^3.0.0" + d3-zoom "^3.0.0" + zustand "^4.4.1" + +"@reactflow/minimap@11.7.13": + version "11.7.13" + resolved "https://registry.npmjs.org/@reactflow/minimap/-/minimap-11.7.13.tgz" + integrity sha512-m2MvdiGSyOu44LEcERDEl1Aj6x//UQRWo3HEAejNU4HQTlJnYrSN8tgrYF8TxC1+c/9UdyzQY5VYgrTwW4QWdg== + dependencies: + "@reactflow/core" "11.11.3" + "@types/d3-selection" "^3.0.3" + "@types/d3-zoom" "^3.0.1" + classcat "^5.0.3" + d3-selection "^3.0.0" + d3-zoom "^3.0.0" + zustand "^4.4.1" + +"@reactflow/node-resizer@2.2.13": + version "2.2.13" + resolved "https://registry.npmjs.org/@reactflow/node-resizer/-/node-resizer-2.2.13.tgz" + integrity sha512-X7ceQ2s3jFLgbkg03n2RYr4hm3jTVrzkW2W/8ANv/SZfuVmF8XJxlERuD8Eka5voKqLda0ywIZGAbw9GoHLfUQ== + dependencies: + "@reactflow/core" "11.11.3" + classcat "^5.0.4" + d3-drag "^3.0.0" + d3-selection "^3.0.0" + zustand "^4.4.1" + +"@reactflow/node-toolbar@1.3.13": + version "1.3.13" + resolved "https://registry.npmjs.org/@reactflow/node-toolbar/-/node-toolbar-1.3.13.tgz" + integrity sha512-aknvNICO10uWdthFSpgD6ctY/CTBeJUMV9co8T9Ilugr08Nb89IQ4uD0dPmr031ewMQxixtYIkw+sSDDzd2aaQ== + dependencies: + "@reactflow/core" "11.11.3" + classcat "^5.0.3" + zustand "^4.4.1" + +"@remixicon/react@^4.3.0": + version "4.3.0" + resolved "https://registry.npmjs.org/@remixicon/react/-/react-4.3.0.tgz#8ab34d03fccca53bf66f87c6e3f943ef5c65684f" + integrity sha512-mAVDn8pAa9dURltGwiYrf7bPIqjG4ZAnCUHfjpgz3g+HLSDNXOaJ67Z5wmjVB5KMGpp9JbbTN5vsp2z+ajVLWg== + +"@rgrove/parse-xml@^4.1.0": + version "4.1.0" + resolved "https://registry.npmjs.org/@rgrove/parse-xml/-/parse-xml-4.1.0.tgz" + integrity sha512-pBiltENdy8SfI0AeR1e5TRpS9/9Gl0eiOEt6ful2jQfzsgvZYWqsKiBWaOCLdocQuk0wS7KOHI37n0C1pnKqTw== + +"@rushstack/eslint-patch@^1.3.3": + version "1.7.2" + resolved "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.7.2.tgz" + integrity sha512-RbhOOTCNoCrbfkRyoXODZp75MlpiHMgbE5MEBZAnnnLyQNgrigEj4p0lzsMDyc1zVsJDLrivB58tgg3emX0eEA== + +"@sentry-internal/tracing@7.54.0": + version "7.54.0" + resolved "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.54.0.tgz" + integrity sha512-JsyhZ0wWZ+VqbHJg+azqRGdYJDkcI5R9+pnkO6SzbzxrRewqMAIwzkpPee3oI7vG99uhMEkOkMjHu0nQGwkOQw== + dependencies: + "@sentry/core" "7.54.0" + "@sentry/types" "7.54.0" + "@sentry/utils" "7.54.0" + tslib "^1.9.3" + +"@sentry/browser@7.54.0": + version "7.54.0" + resolved "https://registry.npmjs.org/@sentry/browser/-/browser-7.54.0.tgz" + integrity sha512-EvLAw03N9WE2m1CMl2/1YMeIs1icw9IEOVJhWmf3uJEysNJOFWXu6ZzdtHEz1E6DiJYhc1HzDya0ExZeJxNARA== + dependencies: + "@sentry-internal/tracing" "7.54.0" + "@sentry/core" "7.54.0" + "@sentry/replay" "7.54.0" + "@sentry/types" "7.54.0" + "@sentry/utils" "7.54.0" + tslib "^1.9.3" + +"@sentry/core@7.54.0": + version "7.54.0" + resolved "https://registry.npmjs.org/@sentry/core/-/core-7.54.0.tgz" + integrity sha512-MAn0E2EwgNn1pFQn4qxhU+1kz6edullWg6VE5wCmtpXWOVw6sILBUsQpeIG5djBKMcneJCdOlz5jeqcKPrLvZQ== + dependencies: + "@sentry/types" "7.54.0" + "@sentry/utils" "7.54.0" + tslib "^1.9.3" + +"@sentry/react@^7.54.0": + version "7.54.0" + resolved "https://registry.npmjs.org/@sentry/react/-/react-7.54.0.tgz" + integrity sha512-qUbwmRRpTh05m2rbC8A2zAFQYsoHhwIpxT5UXxh0P64ZlA3cSg1/DmTTgwnd1l+7gzKrc31UikXQ4y0YDbMNKg== + dependencies: + "@sentry/browser" "7.54.0" + "@sentry/types" "7.54.0" + "@sentry/utils" "7.54.0" + hoist-non-react-statics "^3.3.2" + tslib "^1.9.3" + +"@sentry/replay@7.54.0": + version "7.54.0" + resolved "https://registry.npmjs.org/@sentry/replay/-/replay-7.54.0.tgz" + integrity sha512-C0F0568ybphzGmKGe23duB6n5wJcgM7WLYhoeqW3o2bHeqpj1dGPSka/K3s9KzGaAgzn1zeOUYXJsOs+T/XdsA== + dependencies: + "@sentry/core" "7.54.0" + "@sentry/types" "7.54.0" + "@sentry/utils" "7.54.0" + +"@sentry/types@7.54.0": + version "7.54.0" + resolved "https://registry.npmjs.org/@sentry/types/-/types-7.54.0.tgz" + integrity sha512-D+i9xogBeawvQi2r0NOrM7zYcUaPuijeME4O9eOTrDF20tj71hWtJLilK+KTGLYFtpGg1h+9bPaz7OHEIyVopg== + +"@sentry/utils@7.54.0", "@sentry/utils@^7.54.0": + version "7.54.0" + resolved "https://registry.npmjs.org/@sentry/utils/-/utils-7.54.0.tgz" + integrity sha512-3Yf5KlKjIcYLddOexSt2ovu2TWlR4Fi7M+aCK8yUTzwNzf/xwFSWOstHlD/WiDy9HvfhWAOB/ukNTuAeJmtasw== + dependencies: + "@sentry/types" "7.54.0" + tslib "^1.9.3" + +"@sinclair/typebox@^0.27.8": + version "0.27.8" + resolved "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" + integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== + +"@sindresorhus/is@^4.0.0": + version "4.6.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f" + integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw== + +"@sinonjs/commons@^3.0.0": + version "3.0.1" + resolved "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz#1029357e44ca901a615585f6d27738dbc89084cd" + integrity sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ== + dependencies: + type-detect "4.0.8" + +"@sinonjs/fake-timers@^10.0.2": + version "10.3.0" + resolved "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz#55fdff1ecab9f354019129daf4df0dd4d923ea66" + integrity sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA== + dependencies: + "@sinonjs/commons" "^3.0.0" + +"@storybook/addon-actions@8.3.5": + version "8.3.5" + resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-8.3.5.tgz#03fdb891114439ed47cb7df6ef21826530449db7" + integrity sha512-t8D5oo+4XfD+F8091wLa2y/CDd/W2lExCeol5Vm1tp5saO+u6f2/d7iykLhTowWV84Uohi3D073uFeyTAlGebg== + dependencies: + "@storybook/global" "^5.0.0" + "@types/uuid" "^9.0.1" + dequal "^2.0.2" + polished "^4.2.2" + uuid "^9.0.0" + +"@storybook/addon-backgrounds@8.3.5": + version "8.3.5" + resolved "https://registry.yarnpkg.com/@storybook/addon-backgrounds/-/addon-backgrounds-8.3.5.tgz#479ecb6181441e7f8429569bd7cefdb74058c12f" + integrity sha512-IQGjDujuw8+iSqKREdkL8I5E/5CAHZbfOWd4A75PQK2D6qZ0fu/xRwTOQOH4jP6xn/abvfACOdL6A0d5bU90ag== + dependencies: + "@storybook/global" "^5.0.0" + memoizerific "^1.11.3" + ts-dedent "^2.0.0" + +"@storybook/addon-controls@8.3.5": + version "8.3.5" + resolved "https://registry.yarnpkg.com/@storybook/addon-controls/-/addon-controls-8.3.5.tgz#d9b7aec16e2673a473ab018b3b453cd114628181" + integrity sha512-2eCVobUUvY1Rq7sp1U8Mx8t44VXwvi0E+hqyrsqOx5TTSC/FUQ+hNAX6GSYUcFIyQQ1ORpKNlUjAAdjxBv1ZHQ== + dependencies: + "@storybook/global" "^5.0.0" + dequal "^2.0.2" + lodash "^4.17.21" + ts-dedent "^2.0.0" + +"@storybook/addon-docs@8.3.5": + version "8.3.5" + resolved "https://registry.yarnpkg.com/@storybook/addon-docs/-/addon-docs-8.3.5.tgz#df9e3310b7a63355184f5a2a7f2e2aa396588765" + integrity sha512-MOVfo1bY8kXTzbvmWnx3UuSO4WNykFz7Edvb3mxltNyuW7UDRZGuIuSe32ddT/EtLJfurrC9Ja3yBy4KBUGnMA== + dependencies: + "@mdx-js/react" "^3.0.0" + "@storybook/blocks" "8.3.5" + "@storybook/csf-plugin" "8.3.5" + "@storybook/global" "^5.0.0" + "@storybook/react-dom-shim" "8.3.5" + "@types/react" "^16.8.0 || ^17.0.0 || ^18.0.0" + fs-extra "^11.1.0" + react "^16.8.0 || ^17.0.0 || ^18.0.0" + react-dom "^16.8.0 || ^17.0.0 || ^18.0.0" + rehype-external-links "^3.0.0" + rehype-slug "^6.0.0" + ts-dedent "^2.0.0" + +"@storybook/addon-essentials@^8.3.5": + version "8.3.5" + resolved "https://registry.yarnpkg.com/@storybook/addon-essentials/-/addon-essentials-8.3.5.tgz#59599a75e3f72d1048d715f3ec35a4c07149b2f8" + integrity sha512-hXTtPuN4/IsXjUrkMPAuz1qKAl8DovdXpjQgjQs7jSAVx3kc4BZaGqJ3gaVenKtO8uDchmA92BoQygpkc8eWhw== + dependencies: + "@storybook/addon-actions" "8.3.5" + "@storybook/addon-backgrounds" "8.3.5" + "@storybook/addon-controls" "8.3.5" + "@storybook/addon-docs" "8.3.5" + "@storybook/addon-highlight" "8.3.5" + "@storybook/addon-measure" "8.3.5" + "@storybook/addon-outline" "8.3.5" + "@storybook/addon-toolbars" "8.3.5" + "@storybook/addon-viewport" "8.3.5" + ts-dedent "^2.0.0" + +"@storybook/addon-highlight@8.3.5": + version "8.3.5" + resolved "https://registry.yarnpkg.com/@storybook/addon-highlight/-/addon-highlight-8.3.5.tgz#62293e7b39844ded33bb4ba7ee79c3c96d997fe2" + integrity sha512-ku0epul9aReCR3Gv/emwYnsqg3vgux5OmYMjoDcJC7s+LyfweSzLV/f5t9gSHazikJElh5TehtVkWbC4QfbGSw== + dependencies: + "@storybook/global" "^5.0.0" + +"@storybook/addon-interactions@^8.3.5": + version "8.3.5" + resolved "https://registry.yarnpkg.com/@storybook/addon-interactions/-/addon-interactions-8.3.5.tgz#c971925937aeb6d66bf108dc27a90a4a9cbbf8f4" + integrity sha512-GtTy/A+mG7vDOahQr2avT4dpWtCRiFDSYcWyuQOZm10y8VDDw157HQM+FuhxjV9Owrrohy9F24oBUwRG8H3b5A== + dependencies: + "@storybook/global" "^5.0.0" + "@storybook/instrumenter" "8.3.5" + "@storybook/test" "8.3.5" + polished "^4.2.2" + ts-dedent "^2.2.0" + +"@storybook/addon-links@^8.3.5": + version "8.3.5" + resolved "https://registry.yarnpkg.com/@storybook/addon-links/-/addon-links-8.3.5.tgz#1621afd8be06af6de5e942644053d5136cc5bb83" + integrity sha512-giRCpn6cfJMYPnVJkojoQDO5ae6098fgY9YgAhwaJej/9dufNcioFdbiyfK1vyzbG6TGeTmJ9ncWCXgWRtzxPQ== + dependencies: + "@storybook/csf" "^0.1.11" + "@storybook/global" "^5.0.0" + ts-dedent "^2.0.0" + +"@storybook/addon-measure@8.3.5": + version "8.3.5" + resolved "https://registry.yarnpkg.com/@storybook/addon-measure/-/addon-measure-8.3.5.tgz#4eef622137f9ee615eb179e5e2af050ea0f7ab8b" + integrity sha512-6GVehgbHhFIFS69xSfRV+12VK0cnuIAtZdp1J3eUCc2ATrcigqVjTM6wzZz6kBuX6O3dcusr7Wg46KtNliqLqg== + dependencies: + "@storybook/global" "^5.0.0" + tiny-invariant "^1.3.1" + +"@storybook/addon-onboarding@^8.3.5": + version "8.3.5" + resolved "https://registry.yarnpkg.com/@storybook/addon-onboarding/-/addon-onboarding-8.3.5.tgz#dc1c4098b2df602d8b0cd7b66c3daf4b0d92edb4" + integrity sha512-QE/+6KEYO5tGziMdo+81oor0KNVnbPsfDpnhtClu+t1XC2F2nKQpDISujwLSYm9voEk1D/NxYWMbQ6eTDR/ViA== + dependencies: + react-confetti "^6.1.0" + +"@storybook/addon-outline@8.3.5": + version "8.3.5" + resolved "https://registry.yarnpkg.com/@storybook/addon-outline/-/addon-outline-8.3.5.tgz#274a497b9a6b391bf3c47aa61e19ddc28cbae395" + integrity sha512-dwmK6GzjEnQP9Yo0VnBUQtJkXZlXdfjWyskZ/IlUVc+IFdeeCtIiMyA92oMfHo8eXt0k1g21ZqMaIn7ZltOuHw== + dependencies: + "@storybook/global" "^5.0.0" + ts-dedent "^2.0.0" + +"@storybook/addon-themes@^8.3.5": + version "8.3.5" + resolved "https://registry.yarnpkg.com/@storybook/addon-themes/-/addon-themes-8.3.5.tgz#fef6a783612a091675e96fc37c93b24ba406f4f3" + integrity sha512-kXHKAZvAtMoOR1XFGTo5/T8anE9x7W8Ddpof2wyi+du5HscFiEW7TesWdvNgBUR7wAaiR21aW2S4jC72a6gTCw== + dependencies: + ts-dedent "^2.0.0" + +"@storybook/addon-toolbars@8.3.5": + version "8.3.5" + resolved "https://registry.yarnpkg.com/@storybook/addon-toolbars/-/addon-toolbars-8.3.5.tgz#7328fed0f4a24c6828ba23e06b9cddd0d3e00e2b" + integrity sha512-Ml2gc9q8WbteDvmuAZGgBxt5SqWMXzuTkMjlsA8EB53hlkN1w9esX4s8YtBeNqC3HKoUzcdq8uexSBqU8fDbSA== + +"@storybook/addon-viewport@8.3.5": + version "8.3.5" + resolved "https://registry.yarnpkg.com/@storybook/addon-viewport/-/addon-viewport-8.3.5.tgz#10f10871eba32cf6c484db199241122184a4324b" + integrity sha512-FSWydoPiVWFXEittG7O1YgvuaqoU9Vb+qoq9XfP/hvQHHMDcMZvC40JaV8AnJeTXaM7ngIjcn9XDEfGbFfOzXw== + dependencies: + memoizerific "^1.11.3" + +"@storybook/blocks@8.3.5", "@storybook/blocks@^8.3.5": + version "8.3.5" + resolved "https://registry.yarnpkg.com/@storybook/blocks/-/blocks-8.3.5.tgz#35e20efb0c13a235832dd945520ff8ac61f40717" + integrity sha512-8cHTdTywolTHlgwN8I7YH7saWAIjGzV617AwjhJ95AKlC0VtpO1gAFcAgCqr4DU9eMc+LZuvbnaU/RSvA5eCCQ== + dependencies: + "@storybook/csf" "^0.1.11" + "@storybook/global" "^5.0.0" + "@storybook/icons" "^1.2.10" + "@types/lodash" "^4.14.167" + color-convert "^2.0.1" + dequal "^2.0.2" + lodash "^4.17.21" + markdown-to-jsx "^7.4.5" + memoizerific "^1.11.3" + polished "^4.2.2" + react-colorful "^5.1.2" + telejson "^7.2.0" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + +"@storybook/builder-webpack5@8.3.5": + version "8.3.5" + resolved "https://registry.yarnpkg.com/@storybook/builder-webpack5/-/builder-webpack5-8.3.5.tgz#86eba6b8f3546aa1a4b264bb0253e8444b69c6f8" + integrity sha512-rhmfdiSlDn3Arki7IMYk11PO29rYuYM4LZ8GlNqREU7VUl/8Vngo/jFIa4pKaIns3ql1RrwzO1wm9JvuL/4ydA== + dependencies: + "@storybook/core-webpack" "8.3.5" + "@types/node" "^22.0.0" + "@types/semver" "^7.3.4" + browser-assert "^1.2.1" + case-sensitive-paths-webpack-plugin "^2.4.0" + cjs-module-lexer "^1.2.3" + constants-browserify "^1.0.0" + css-loader "^6.7.1" + es-module-lexer "^1.5.0" + express "^4.19.2" + fork-ts-checker-webpack-plugin "^8.0.0" + fs-extra "^11.1.0" + html-webpack-plugin "^5.5.0" + magic-string "^0.30.5" + path-browserify "^1.0.1" + process "^0.11.10" + semver "^7.3.7" + style-loader "^3.3.1" + terser-webpack-plugin "^5.3.1" + ts-dedent "^2.0.0" + url "^0.11.0" + util "^0.12.4" + util-deprecate "^1.0.2" + webpack "5" + webpack-dev-middleware "^6.1.2" + webpack-hot-middleware "^2.25.1" + webpack-virtual-modules "^0.6.0" + +"@storybook/components@^8.3.5": + version "8.3.5" + resolved "https://registry.yarnpkg.com/@storybook/components/-/components-8.3.5.tgz#6a8e7f95f1b1f45df7ffcbdeeb3eef3c6cce0d3f" + integrity sha512-Rq28YogakD3FO4F8KwAtGpo1g3t4V/gfCLqTQ8B6oQUFoxLqegkWk/DlwCzvoJndXuQJfdSyM6+r1JcA4Nql5A== + +"@storybook/core-webpack@8.3.5": + version "8.3.5" + resolved "https://registry.yarnpkg.com/@storybook/core-webpack/-/core-webpack-8.3.5.tgz#3e058fdb4bd73ca5deee5b3ce5621f599dfa248d" + integrity sha512-mN8BHNc6lSGUf/nKgDr6XoTt1cX+Tap9RnKMUiROCDzfVlJPeJBrG4qrTOok7AwObzeDl9DNFyun6+pVgXJe7A== + dependencies: + "@types/node" "^22.0.0" + ts-dedent "^2.0.0" + +"@storybook/core@8.3.5": + version "8.3.5" + resolved "https://registry.yarnpkg.com/@storybook/core/-/core-8.3.5.tgz#d77c93bb67c2df12e3bf84ae7def4693891b225d" + integrity sha512-GOGfTvdioNa/n+Huwg4u/dsyYyBcM+gEcdxi3B7i5x4yJ3I912KoVshumQAOF2myKSRdI8h8aGWdx7nnjd0+5Q== + dependencies: + "@storybook/csf" "^0.1.11" + "@types/express" "^4.17.21" + better-opn "^3.0.2" + browser-assert "^1.2.1" + esbuild "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0" + esbuild-register "^3.5.0" + express "^4.19.2" + jsdoc-type-pratt-parser "^4.0.0" + process "^0.11.10" + recast "^0.23.5" + semver "^7.6.2" + util "^0.12.5" + ws "^8.2.3" + +"@storybook/csf-plugin@8.3.5": + version "8.3.5" + resolved "https://registry.yarnpkg.com/@storybook/csf-plugin/-/csf-plugin-8.3.5.tgz#198946c438be8915b63abde04a19f26610a6d88a" + integrity sha512-ODVqNXwJt90hG7QW8I9w/XUyOGlr0l7XltmIJgXwB/2cYDvaGu3JV5Ybg7O0fxPV8uXk7JlRuUD8ZYv5Low6pA== + dependencies: + unplugin "^1.3.1" + +"@storybook/csf@^0.0.1": + version "0.0.1" + resolved "https://registry.yarnpkg.com/@storybook/csf/-/csf-0.0.1.tgz#95901507dc02f0bc6f9ac8ee1983e2fc5bb98ce6" + integrity sha512-USTLkZze5gkel8MYCujSRBVIrUQ3YPBrLOx7GNk/0wttvVtlzWXAq9eLbQ4p/NicGxP+3T7KPEMVV//g+yubpw== + dependencies: + lodash "^4.17.15" + +"@storybook/csf@^0.1.11": + version "0.1.11" + resolved "https://registry.yarnpkg.com/@storybook/csf/-/csf-0.1.11.tgz#ad685a4fe564a47a6b73571c2e7c07b526f4f71b" + integrity sha512-dHYFQH3mA+EtnCkHXzicbLgsvzYjcDJ1JWsogbItZogkPHgSJM/Wr71uMkcvw8v9mmCyP4NpXJuu6bPoVsOnzg== + dependencies: + type-fest "^2.19.0" + +"@storybook/global@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@storybook/global/-/global-5.0.0.tgz#b793d34b94f572c1d7d9e0f44fac4e0dbc9572ed" + integrity sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ== + +"@storybook/icons@^1.2.10": + version "1.2.12" + resolved "https://registry.yarnpkg.com/@storybook/icons/-/icons-1.2.12.tgz#3e4c939113b67df7ab17b78f805dbb57f4acf0db" + integrity sha512-UxgyK5W3/UV4VrI3dl6ajGfHM4aOqMAkFLWe2KibeQudLf6NJpDrDMSHwZj+3iKC4jFU7dkKbbtH2h/al4sW3Q== + +"@storybook/instrumenter@8.3.5": + version "8.3.5" + resolved "https://registry.yarnpkg.com/@storybook/instrumenter/-/instrumenter-8.3.5.tgz#ba3c6adcd928ef98859ac4ed1e5addb1164659ea" + integrity sha512-NLDXai5y2t1ITgHVK9chyL0rMFZbICCOGcnTbyWhkLbiEWZKPJ8FuB8+g+Ba6zwtCve1A1Cnb4O2LOWy7TgWQw== + dependencies: + "@storybook/global" "^5.0.0" + "@vitest/utils" "^2.0.5" + util "^0.12.4" + +"@storybook/manager-api@^8.3.5": + version "8.3.5" + resolved "https://registry.yarnpkg.com/@storybook/manager-api/-/manager-api-8.3.5.tgz#73560ffc3774901e503e31aefac91cd4a1579bbb" + integrity sha512-fEQoKKi7h7pzh2z9RfuzatJxubrsfL/CB99fNXQ0wshMSY/7O4ckd18pK4fzG9ErnCtLAO9qsim4N/4eQC+/8Q== + +"@storybook/nextjs@^8.3.5": + version "8.3.5" + resolved "https://registry.yarnpkg.com/@storybook/nextjs/-/nextjs-8.3.5.tgz#0861d87e5abcb41eddef8b8e7b4e7634bab059ce" + integrity sha512-YMjDSVd7BHIvj6oLMEFMKRvfZ83INxZinxtrx4ZZXGe+5iP8j7rcV7D67lxKQKWNy36d9Foj4pjT85yYj5s+ZQ== + dependencies: + "@babel/core" "^7.24.4" + "@babel/plugin-syntax-bigint" "^7.8.3" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-syntax-import-assertions" "^7.24.1" + "@babel/plugin-transform-class-properties" "^7.24.1" + "@babel/plugin-transform-export-namespace-from" "^7.24.1" + "@babel/plugin-transform-numeric-separator" "^7.24.1" + "@babel/plugin-transform-object-rest-spread" "^7.24.1" + "@babel/plugin-transform-runtime" "^7.24.3" + "@babel/preset-env" "^7.24.4" + "@babel/preset-react" "^7.24.1" + "@babel/preset-typescript" "^7.24.1" + "@babel/runtime" "^7.24.4" + "@pmmmwh/react-refresh-webpack-plugin" "^0.5.11" + "@storybook/builder-webpack5" "8.3.5" + "@storybook/preset-react-webpack" "8.3.5" + "@storybook/react" "8.3.5" + "@storybook/test" "8.3.5" + "@types/node" "^22.0.0" + "@types/semver" "^7.3.4" + babel-loader "^9.1.3" + css-loader "^6.7.3" + find-up "^5.0.0" + fs-extra "^11.1.0" + image-size "^1.0.0" + loader-utils "^3.2.1" + node-polyfill-webpack-plugin "^2.0.1" + pnp-webpack-plugin "^1.7.0" + postcss "^8.4.38" + postcss-loader "^8.1.1" + react-refresh "^0.14.0" + resolve-url-loader "^5.0.0" + sass-loader "^13.2.0" + semver "^7.3.5" + style-loader "^3.3.1" + styled-jsx "^5.1.6" + ts-dedent "^2.0.0" + tsconfig-paths "^4.0.0" + tsconfig-paths-webpack-plugin "^4.0.1" + optionalDependencies: + sharp "^0.33.3" + +"@storybook/preset-react-webpack@8.3.5": + version "8.3.5" + resolved "https://registry.yarnpkg.com/@storybook/preset-react-webpack/-/preset-react-webpack-8.3.5.tgz#5886d265027e7854cb4d15d8ca728990894ac4f8" + integrity sha512-laS9CiZrZ4CSnBTBfkBba3hmlDhzcjIfCvx8/rk3SZ+zh93NpqXixzRt6m0UH2po63dpdu21nXrsW5Cfs88Ypw== + dependencies: + "@storybook/core-webpack" "8.3.5" + "@storybook/react" "8.3.5" + "@storybook/react-docgen-typescript-plugin" "1.0.6--canary.9.0c3f3b7.0" + "@types/node" "^22.0.0" + "@types/semver" "^7.3.4" + find-up "^5.0.0" + fs-extra "^11.1.0" + magic-string "^0.30.5" + react-docgen "^7.0.0" + resolve "^1.22.8" + semver "^7.3.7" + tsconfig-paths "^4.2.0" + webpack "5" + +"@storybook/preview-api@^8.3.5": + version "8.3.5" + resolved "https://registry.yarnpkg.com/@storybook/preview-api/-/preview-api-8.3.5.tgz#d30debc89793a912cdd26aea1e18b92527f2cf76" + integrity sha512-VPqpudE8pmjTLvdNJoW/2//nqElDgUOmIn3QxbbCmdZTHDg5tFtxuqwdlNfArF0TxvTSBDIulXt/Q6K56TAfTg== + +"@storybook/react-docgen-typescript-plugin@1.0.6--canary.9.0c3f3b7.0": + version "1.0.6--canary.9.0c3f3b7.0" + resolved "https://registry.yarnpkg.com/@storybook/react-docgen-typescript-plugin/-/react-docgen-typescript-plugin-1.0.6--canary.9.0c3f3b7.0.tgz#7f10f3c641f32e4513a8b6ffb5036933e7059534" + integrity sha512-KUqXC3oa9JuQ0kZJLBhVdS4lOneKTOopnNBK4tUAgoxWQ3u/IjzdueZjFr7gyBrXMoU6duutk3RQR9u8ZpYJ4Q== + dependencies: + debug "^4.1.1" + endent "^2.0.1" + find-cache-dir "^3.3.1" + flat-cache "^3.0.4" + micromatch "^4.0.2" + react-docgen-typescript "^2.2.2" + tslib "^2.0.0" + +"@storybook/react-dom-shim@8.3.5": + version "8.3.5" + resolved "https://registry.yarnpkg.com/@storybook/react-dom-shim/-/react-dom-shim-8.3.5.tgz#dda5356d3bf55623b9b1429fac7bf185e59c58fd" + integrity sha512-Hf0UitJ/K0C7ajooooUK/PxOR4ihUWqsC7iCV1Gqth8U37dTeLMbaEO4PBwu0VQ+Ufg0N8BJLWfg7o6G4hrODw== + +"@storybook/react@8.3.5", "@storybook/react@^8.3.5": + version "8.3.5" + resolved "https://registry.yarnpkg.com/@storybook/react/-/react-8.3.5.tgz#d4e333b09f275f06b38fb1367234ad1619fbe4fa" + integrity sha512-kuBPe/wBin10SWr4EWPKxiTRGQ4RD2etGEVWVQLqVpOuJp/J2hVvXQHtCfZXU4TZT5x4PBbPRswbr58+XlF+kQ== + dependencies: + "@storybook/components" "^8.3.5" + "@storybook/global" "^5.0.0" + "@storybook/manager-api" "^8.3.5" + "@storybook/preview-api" "^8.3.5" + "@storybook/react-dom-shim" "8.3.5" + "@storybook/theming" "^8.3.5" + "@types/escodegen" "^0.0.6" + "@types/estree" "^0.0.51" + "@types/node" "^22.0.0" + acorn "^7.4.1" + acorn-jsx "^5.3.1" + acorn-walk "^7.2.0" + escodegen "^2.1.0" + html-tags "^3.1.0" + prop-types "^15.7.2" + react-element-to-jsx-string "^15.0.0" + semver "^7.3.7" + ts-dedent "^2.0.0" + type-fest "~2.19" + util-deprecate "^1.0.2" + +"@storybook/test@8.3.5", "@storybook/test@^8.3.5": + version "8.3.5" + resolved "https://registry.yarnpkg.com/@storybook/test/-/test-8.3.5.tgz#0dffc9d4a1eaa9552e69457b16b5085e36883c8a" + integrity sha512-1BXWsUGWk9FiKKelZZ55FDJdeoL8uRBHbjTYBRM2xJLhdNSvGzI4Tb3bkmxPpGn72Ua6AyldhlTxr2BpUFKOHA== + dependencies: + "@storybook/csf" "^0.1.11" + "@storybook/global" "^5.0.0" + "@storybook/instrumenter" "8.3.5" + "@testing-library/dom" "10.4.0" + "@testing-library/jest-dom" "6.5.0" + "@testing-library/user-event" "14.5.2" + "@vitest/expect" "2.0.5" + "@vitest/spy" "2.0.5" + util "^0.12.4" + +"@storybook/theming@^8.3.5": + version "8.3.5" + resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-8.3.5.tgz#c6b807193099a8f9d1afb5d71a59037c0ef54e85" + integrity sha512-9HmDDyC691oqfg4RziIM9ElsS2HITaxmH7n/yeUPtuirkPdAQzqOzhvH/Sa0qOhifzs8VjR+Gd/a/ZQ+S38r7w== + +"@svgdotjs/svg.js@^3.2.4": + version "3.2.4" + resolved "https://registry.yarnpkg.com/@svgdotjs/svg.js/-/svg.js-3.2.4.tgz#4716be92a64c66b29921b63f7235fcfb953fb13a" + integrity sha512-BjJ/7vWNowlX3Z8O4ywT58DqbNRyYlkk6Yz/D13aB7hGmfQTvGX4Tkgtm/ApYlu9M7lCQi15xUEidqMUmdMYwg== + +"@swc/counter@^0.1.3": + version "0.1.3" + resolved "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz" + integrity sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ== + +"@swc/helpers@0.5.5": + version "0.5.5" + resolved "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz" + integrity sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A== + dependencies: + "@swc/counter" "^0.1.3" + tslib "^2.4.0" + +"@szmarczak/http-timer@^4.0.5": + version "4.0.6" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.6.tgz#b4a914bb62e7c272d4e5989fe4440f812ab1d807" + integrity sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w== + dependencies: + defer-to-connect "^2.0.0" + +"@tailwindcss/line-clamp@^0.4.4": + version "0.4.4" + resolved "https://registry.npmjs.org/@tailwindcss/line-clamp/-/line-clamp-0.4.4.tgz" + integrity sha512-5U6SY5z8N42VtrCrKlsTAA35gy2VSyYtHWCsg1H87NU1SXnEfekTVlrga9fzUDrrHcGi2Lb5KenUWb4lRQT5/g== + +"@tailwindcss/typography@^0.5.9": + version "0.5.9" + resolved "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.9.tgz" + integrity sha512-t8Sg3DyynFysV9f4JDOVISGsjazNb48AeIYQwcL+Bsq5uf4RYL75C1giZ43KISjeDGBaTN3Kxh7Xj/vRSMJUUg== + dependencies: + lodash.castarray "^4.4.0" + lodash.isplainobject "^4.0.6" + lodash.merge "^4.6.2" + postcss-selector-parser "6.0.10" + +"@testing-library/dom@10.4.0": + version "10.4.0" + resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-10.4.0.tgz#82a9d9462f11d240ecadbf406607c6ceeeff43a8" + integrity sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/runtime" "^7.12.5" + "@types/aria-query" "^5.0.1" + aria-query "5.3.0" + chalk "^4.1.0" + dom-accessibility-api "^0.5.9" + lz-string "^1.5.0" + pretty-format "^27.0.2" + +"@testing-library/dom@^10.3.2": + version "10.3.2" + resolved "https://registry.npmjs.org/@testing-library/dom/-/dom-10.3.2.tgz#0285f643510d5ff4a0b12e4efa7f734a78d80aa3" + integrity sha512-0bxIdP9mmPiOJ6wHLj8bdJRq+51oddObeCGdEf6PNEhYd93ZYAN+lPRnEOVFtheVwDM7+p+tza3LAQgp0PTudg== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/runtime" "^7.12.5" + "@types/aria-query" "^5.0.1" + aria-query "5.3.0" + chalk "^4.1.0" + dom-accessibility-api "^0.5.9" + lz-string "^1.5.0" + pretty-format "^27.0.2" + +"@testing-library/jest-dom@6.5.0": + version "6.5.0" + resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-6.5.0.tgz#50484da3f80fb222a853479f618a9ce5c47bfe54" + integrity sha512-xGGHpBXYSHUUr6XsKBfs85TWlYKpTc37cSBBVrXcib2MkHLboWlkClhWF37JKlDb9KEq3dHs+f2xR7XJEWGBxA== + dependencies: + "@adobe/css-tools" "^4.4.0" + aria-query "^5.0.0" + chalk "^3.0.0" + css.escape "^1.5.1" + dom-accessibility-api "^0.6.3" + lodash "^4.17.21" + redent "^3.0.0" + +"@testing-library/jest-dom@^6.4.6": + version "6.4.6" + resolved "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.4.6.tgz#ec1df8108651bed5475534955565bed88c6732ce" + integrity sha512-8qpnGVincVDLEcQXWaHOf6zmlbwTKc6Us6PPu4CRnPXCzo2OGBS5cwgMMOWdxDpEz1mkbvXHpEy99M5Yvt682w== + dependencies: + "@adobe/css-tools" "^4.4.0" + "@babel/runtime" "^7.9.2" + aria-query "^5.0.0" + chalk "^3.0.0" + css.escape "^1.5.1" + dom-accessibility-api "^0.6.3" + lodash "^4.17.21" + redent "^3.0.0" + +"@testing-library/react@^16.0.0": + version "16.0.0" + resolved "https://registry.npmjs.org/@testing-library/react/-/react-16.0.0.tgz#0a1e0c7a3de25841c3591b8cb7fb0cf0c0a27321" + integrity sha512-guuxUKRWQ+FgNX0h0NS0FIq3Q3uLtWVpBzcLOggmfMoUpgBnzBzvLLd4fbm6yS8ydJd94cIfY4yP9qUQjM2KwQ== + dependencies: + "@babel/runtime" "^7.12.5" + +"@testing-library/user-event@14.5.2": + version "14.5.2" + resolved "https://registry.yarnpkg.com/@testing-library/user-event/-/user-event-14.5.2.tgz#db7257d727c891905947bd1c1a99da20e03c2ebd" + integrity sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ== + +"@tootallnate/once@2": + version "2.0.0" + resolved "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" + integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== + +"@tsconfig/node10@^1.0.7": + version "1.0.11" + resolved "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz#6ee46400685f130e278128c7b38b7e031ff5b2f2" + integrity sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw== + +"@tsconfig/node12@^1.0.7": + version "1.0.11" + resolved "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" + integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== + +"@tsconfig/node14@^1.0.0": + version "1.0.3" + resolved "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" + integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== + +"@tsconfig/node16@^1.0.2": + version "1.0.4" + resolved "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" + integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== + +"@types/acorn@^4.0.0": + version "4.0.6" + resolved "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz" + integrity sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ== + dependencies: + "@types/estree" "*" + +"@types/aria-query@^5.0.1": + version "5.0.4" + resolved "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz#1a31c3d378850d2778dabb6374d036dcba4ba708" + integrity sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw== + +"@types/babel__core@^7.1.14", "@types/babel__core@^7.18.0": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017" + integrity sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA== + dependencies: + "@babel/parser" "^7.20.7" + "@babel/types" "^7.20.7" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + +"@types/babel__generator@*": + version "7.6.8" + resolved "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz#f836c61f48b1346e7d2b0d93c6dacc5b9535d3ab" + integrity sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw== + dependencies: + "@babel/types" "^7.0.0" + +"@types/babel__template@*": + version "7.4.4" + resolved "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz#5672513701c1b2199bc6dad636a9d7491586766f" + integrity sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + +"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6", "@types/babel__traverse@^7.18.0": + version "7.20.6" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.6.tgz#8dc9f0ae0f202c08d8d4dab648912c8d6038e3f7" + integrity sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg== + dependencies: + "@babel/types" "^7.20.7" + +"@types/body-parser@*": + version "1.19.5" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.5.tgz#04ce9a3b677dc8bd681a17da1ab9835dc9d3ede4" + integrity sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/cacheable-request@^6.0.1": + version "6.0.3" + resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.3.tgz#a430b3260466ca7b5ca5bfd735693b36e7a9d183" + integrity sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw== + dependencies: + "@types/http-cache-semantics" "*" + "@types/keyv" "^3.1.4" + "@types/node" "*" + "@types/responselike" "^1.0.0" + +"@types/connect@*": + version "3.4.38" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.38.tgz#5ba7f3bc4fbbdeaff8dded952e5ff2cc53f8d858" + integrity sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug== + dependencies: + "@types/node" "*" + +"@types/crypto-js@^4.1.1": + version "4.1.1" + resolved "https://registry.npmjs.org/@types/crypto-js/-/crypto-js-4.1.1.tgz" + integrity sha512-BG7fQKZ689HIoc5h+6D2Dgq1fABRa0RbBWKBd9SP/MVRVXROflpm5fhwyATX5duFmbStzyzyycPB8qUYKDH3NA== + +"@types/d3-array@*": + version "3.2.1" + resolved "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz" + integrity sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg== + +"@types/d3-axis@*": + version "3.0.6" + resolved "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.6.tgz" + integrity sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw== + dependencies: + "@types/d3-selection" "*" + +"@types/d3-brush@*": + version "3.0.6" + resolved "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.6.tgz" + integrity sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A== + dependencies: + "@types/d3-selection" "*" + +"@types/d3-chord@*": + version "3.0.6" + resolved "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.6.tgz" + integrity sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg== + +"@types/d3-color@*": + version "3.1.3" + resolved "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz" + integrity sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A== + +"@types/d3-contour@*": + version "3.0.6" + resolved "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.6.tgz" + integrity sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg== + dependencies: + "@types/d3-array" "*" + "@types/geojson" "*" + +"@types/d3-delaunay@*": + version "6.0.4" + resolved "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz" + integrity sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw== + +"@types/d3-dispatch@*": + version "3.0.6" + resolved "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.6.tgz" + integrity sha512-4fvZhzMeeuBJYZXRXrRIQnvUYfyXwYmLsdiN7XXmVNQKKw1cM8a5WdID0g1hVFZDqT9ZqZEY5pD44p24VS7iZQ== + +"@types/d3-drag@*", "@types/d3-drag@^3.0.1": + version "3.0.7" + resolved "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz" + integrity sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ== + dependencies: + "@types/d3-selection" "*" + +"@types/d3-dsv@*": + version "3.0.7" + resolved "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.7.tgz" + integrity sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g== + +"@types/d3-ease@*": + version "3.0.2" + resolved "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz" + integrity sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA== + +"@types/d3-fetch@*": + version "3.0.7" + resolved "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.7.tgz" + integrity sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA== + dependencies: + "@types/d3-dsv" "*" + +"@types/d3-force@*": + version "3.0.9" + resolved "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.9.tgz" + integrity sha512-IKtvyFdb4Q0LWna6ymywQsEYjK/94SGhPrMfEr1TIc5OBeziTi+1jcCvttts8e0UWZIxpasjnQk9MNk/3iS+kA== + +"@types/d3-format@*": + version "3.0.4" + resolved "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz" + integrity sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g== + +"@types/d3-geo@*": + version "3.1.0" + resolved "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.1.0.tgz" + integrity sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ== + dependencies: + "@types/geojson" "*" + +"@types/d3-hierarchy@*": + version "3.1.7" + resolved "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz" + integrity sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg== + +"@types/d3-interpolate@*": + version "3.0.4" + resolved "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz" + integrity sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA== + dependencies: + "@types/d3-color" "*" + +"@types/d3-path@*": + version "3.1.0" + resolved "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.0.tgz" + integrity sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ== + +"@types/d3-polygon@*": + version "3.0.2" + resolved "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.2.tgz" + integrity sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA== + +"@types/d3-quadtree@*": + version "3.0.6" + resolved "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz" + integrity sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg== + +"@types/d3-random@*": + version "3.0.3" + resolved "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.3.tgz" + integrity sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ== + +"@types/d3-scale-chromatic@*", "@types/d3-scale-chromatic@^3.0.0": + version "3.0.0" + resolved "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz" + integrity sha512-dsoJGEIShosKVRBZB0Vo3C8nqSDqVGujJU6tPznsBJxNJNwMF8utmS83nvCBKQYPpjCzaaHcrf66iTRpZosLPw== + +"@types/d3-scale@*", "@types/d3-scale@^4.0.3": + version "4.0.4" + resolved "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.4.tgz" + integrity sha512-eq1ZeTj0yr72L8MQk6N6heP603ubnywSDRfNpi5enouR112HzGLS6RIvExCzZTraFF4HdzNpJMwA/zGiMoHUUw== + dependencies: + "@types/d3-time" "*" + +"@types/d3-selection@*", "@types/d3-selection@^3.0.3": + version "3.0.10" + resolved "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.10.tgz" + integrity sha512-cuHoUgS/V3hLdjJOLTT691+G2QoqAjCVLmr4kJXR4ha56w1Zdu8UUQ5TxLRqudgNjwXeQxKMq4j+lyf9sWuslg== + +"@types/d3-shape@*": + version "3.1.6" + resolved "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.6.tgz" + integrity sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA== + dependencies: + "@types/d3-path" "*" + +"@types/d3-time-format@*": + version "4.0.3" + resolved "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.3.tgz" + integrity sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg== + +"@types/d3-time@*": + version "3.0.0" + resolved "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.0.tgz" + integrity sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg== + +"@types/d3-timer@*": + version "3.0.2" + resolved "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz" + integrity sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw== + +"@types/d3-transition@*": + version "3.0.8" + resolved "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.8.tgz" + integrity sha512-ew63aJfQ/ms7QQ4X7pk5NxQ9fZH/z+i24ZfJ6tJSfqxJMrYLiK01EAs2/Rtw/JreGUsS3pLPNV644qXFGnoZNQ== + dependencies: + "@types/d3-selection" "*" + +"@types/d3-zoom@*", "@types/d3-zoom@^3.0.1": + version "3.0.8" + resolved "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz" + integrity sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw== + dependencies: + "@types/d3-interpolate" "*" + "@types/d3-selection" "*" + +"@types/d3@^7.4.0": + version "7.4.3" + resolved "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz" + integrity sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww== + dependencies: + "@types/d3-array" "*" + "@types/d3-axis" "*" + "@types/d3-brush" "*" + "@types/d3-chord" "*" + "@types/d3-color" "*" + "@types/d3-contour" "*" + "@types/d3-delaunay" "*" + "@types/d3-dispatch" "*" + "@types/d3-drag" "*" + "@types/d3-dsv" "*" + "@types/d3-ease" "*" + "@types/d3-fetch" "*" + "@types/d3-force" "*" + "@types/d3-format" "*" + "@types/d3-geo" "*" + "@types/d3-hierarchy" "*" + "@types/d3-interpolate" "*" + "@types/d3-path" "*" + "@types/d3-polygon" "*" + "@types/d3-quadtree" "*" + "@types/d3-random" "*" + "@types/d3-scale" "*" + "@types/d3-scale-chromatic" "*" + "@types/d3-selection" "*" + "@types/d3-shape" "*" + "@types/d3-time" "*" + "@types/d3-time-format" "*" + "@types/d3-timer" "*" + "@types/d3-transition" "*" + "@types/d3-zoom" "*" + +"@types/dagre@^0.7.52": + version "0.7.52" + resolved "https://registry.npmjs.org/@types/dagre/-/dagre-0.7.52.tgz" + integrity sha512-XKJdy+OClLk3hketHi9Qg6gTfe1F3y+UFnHxKA2rn9Dw+oXa4Gb378Ztz9HlMgZKSxpPmn4BNVh9wgkpvrK1uw== + +"@types/debug@^4.0.0": + version "4.1.8" + resolved "https://registry.npmjs.org/@types/debug/-/debug-4.1.8.tgz" + integrity sha512-/vPO1EPOs306Cvhwv7KfVfYvOJqA/S/AXjaHQiJboCZzcNDb+TIJFN9/2C9DZ//ijSKWioNyUxD792QmDJ+HKQ== + dependencies: + "@types/ms" "*" + +"@types/doctrine@^0.0.9": + version "0.0.9" + resolved "https://registry.yarnpkg.com/@types/doctrine/-/doctrine-0.0.9.tgz#d86a5f452a15e3e3113b99e39616a9baa0f9863f" + integrity sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA== + +"@types/escodegen@^0.0.6": + version "0.0.6" + resolved "https://registry.yarnpkg.com/@types/escodegen/-/escodegen-0.0.6.tgz#5230a9ce796e042cda6f086dbf19f22ea330659c" + integrity sha512-AjwI4MvWx3HAOaZqYsjKWyEObT9lcVV0Y0V8nXo6cXzN8ZiMxVhf6F3d/UNvXVGKrEzL/Dluc5p+y9GkzlTWig== + +"@types/estree-jsx@^1.0.0": + version "1.0.0" + resolved "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.0.tgz" + integrity sha512-3qvGd0z8F2ENTGr/GG1yViqfiKmRfrXVx5sJyHGFu3z7m5g5utCQtGp/g29JnjflhtQJBv1WDQukHiT58xPcYQ== + dependencies: + "@types/estree" "*" + +"@types/estree@*", "@types/estree@^1.0.0": + version "1.0.5" + resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz" + integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== + +"@types/estree@^0.0.51": + version "0.0.51" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" + integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== + +"@types/estree@^1.0.5": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50" + integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw== + +"@types/express-serve-static-core@^4.17.33": + version "4.19.6" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz#e01324c2a024ff367d92c66f48553ced0ab50267" + integrity sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + "@types/send" "*" + +"@types/express@^4.17.21": + version "4.17.21" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.21.tgz#c26d4a151e60efe0084b23dc3369ebc631ed192d" + integrity sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.33" + "@types/qs" "*" + "@types/serve-static" "*" + +"@types/geojson@*": + version "7946.0.14" + resolved "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.14.tgz" + integrity sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg== + +"@types/graceful-fs@^4.1.3": + version "4.1.9" + resolved "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz#2a06bc0f68a20ab37b3e36aa238be6abdf49e8b4" + integrity sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ== + dependencies: + "@types/node" "*" + +"@types/hast@^2.0.0": + version "2.3.4" + resolved "https://registry.npmjs.org/@types/hast/-/hast-2.3.4.tgz" + integrity sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g== + dependencies: + "@types/unist" "*" + +"@types/hast@^3.0.0": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/hast/-/hast-3.0.4.tgz#1d6b39993b82cea6ad783945b0508c25903e15aa" + integrity sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ== + dependencies: + "@types/unist" "*" + +"@types/html-minifier-terser@^6.0.0": + version "6.1.0" + resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#4fc33a00c1d0c16987b1a20cf92d20614c55ac35" + integrity sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg== + +"@types/http-cache-semantics@*": + version "4.0.4" + resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz#b979ebad3919799c979b17c72621c0bc0a31c6c4" + integrity sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA== + +"@types/http-errors@*": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.4.tgz#7eb47726c391b7345a6ec35ad7f4de469cf5ba4f" + integrity sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA== + +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": + version "2.0.6" + resolved "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz#7739c232a1fee9b4d3ce8985f314c0c6d33549d7" + integrity sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w== + +"@types/istanbul-lib-report@*": + version "3.0.3" + resolved "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz#53047614ae72e19fc0401d872de3ae2b4ce350bf" + integrity sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA== + dependencies: + "@types/istanbul-lib-coverage" "*" + +"@types/istanbul-reports@^3.0.0": + version "3.0.4" + resolved "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz#0f03e3d2f670fbdac586e34b433783070cc16f54" + integrity sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ== + dependencies: + "@types/istanbul-lib-report" "*" + +"@types/jest@^29.5.12": + version "29.5.12" + resolved "https://registry.npmjs.org/@types/jest/-/jest-29.5.12.tgz#7f7dc6eb4cf246d2474ed78744b05d06ce025544" + integrity sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw== + dependencies: + expect "^29.0.0" + pretty-format "^29.0.0" + +"@types/js-cookie@^2.x.x": + version "2.2.7" + resolved "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-2.2.7.tgz" + integrity sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA== + +"@types/js-cookie@^3.0.3": + version "3.0.3" + resolved "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-3.0.3.tgz" + integrity sha512-Xe7IImK09HP1sv2M/aI+48a20VX+TdRJucfq4vfRVy6nWN8PYPOEnlMRSgxJAgYQIXJVL8dZ4/ilAM7dWNaOww== + +"@types/jsdom@^20.0.0": + version "20.0.1" + resolved "https://registry.npmjs.org/@types/jsdom/-/jsdom-20.0.1.tgz#07c14bc19bd2f918c1929541cdaacae894744808" + integrity sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ== + dependencies: + "@types/node" "*" + "@types/tough-cookie" "*" + parse5 "^7.0.0" + +"@types/json-schema@^7.0.8": + version "7.0.15" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== + +"@types/json-schema@^7.0.9": + version "7.0.12" + resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz" + integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA== + +"@types/json5@^0.0.29": + version "0.0.29" + resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz" + integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== + +"@types/katex@^0.14.0": + version "0.14.0" + resolved "https://registry.npmjs.org/@types/katex/-/katex-0.14.0.tgz" + integrity sha512-+2FW2CcT0K3P+JMR8YG846bmDwplKUTsWgT2ENwdQ1UdVfRk3GQrh6Mi4sTopy30gI8Uau5CEqHTDZ6YvWIUPA== + +"@types/katex@^0.16.0": + version "0.16.0" + resolved "https://registry.npmjs.org/@types/katex/-/katex-0.16.0.tgz" + integrity sha512-hz+S3nV6Mym5xPbT9fnO8dDhBFQguMYpY0Ipxv06JMi1ORgnEM4M1ymWDUhUNer3ElLmT583opRo4RzxKmh9jw== + +"@types/keyv@^3.1.4": + version "3.1.4" + resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.4.tgz#3ccdb1c6751b0c7e52300bcdacd5bcbf8faa75b6" + integrity sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg== + dependencies: + "@types/node" "*" + +"@types/lodash-es@^4.17.7": + version "4.17.7" + resolved "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.7.tgz" + integrity sha512-z0ptr6UI10VlU6l5MYhGwS4mC8DZyYer2mCoyysZtSF7p26zOX8UpbrV0YpNYLGS8K4PUFIyEr62IMFFjveSiQ== + dependencies: + "@types/lodash" "*" + +"@types/lodash@*": + version "4.14.195" + resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.195.tgz" + integrity sha512-Hwx9EUgdwf2GLarOjQp5ZH8ZmblzcbTBC2wtQWNKARBSxM9ezRIAUpeDTgoQRAFB0+8CNWXVA9+MaSOzOF3nPg== + +"@types/lodash@^4.14.167": + version "4.17.10" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.10.tgz#64f3edf656af2fe59e7278b73d3e62404144a6e6" + integrity sha512-YpS0zzoduEhuOWjAotS6A5AVCva7X4lVlYLF0FYHAY9sdraBfnatttHItlWeZdGhuEkf+OzMNg2ZYAx8t+52uQ== + +"@types/mdast@^3.0.0": + version "3.0.11" + resolved "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.11.tgz" + integrity sha512-Y/uImid8aAwrEA24/1tcRZwpxX3pIFTSilcNDKSPn+Y2iDywSEachzRuvgAYYLR3wpGXAsMbv5lvKLDZLeYPAw== + dependencies: + "@types/unist" "*" + +"@types/mdast@^4.0.0": + version "4.0.4" + resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-4.0.4.tgz#7ccf72edd2f1aa7dd3437e180c64373585804dd6" + integrity sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA== + dependencies: + "@types/unist" "*" + +"@types/mdx@^2.0.0": + version "2.0.5" + resolved "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.5.tgz" + integrity sha512-76CqzuD6Q7LC+AtbPqrvD9AqsN0k8bsYo2bM2J8pmNldP1aIPAbzUQ7QbobyXL4eLr1wK5x8FZFe8eF/ubRuBg== + +"@types/mime@^1": + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690" + integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w== + +"@types/ms@*": + version "0.7.31" + resolved "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz" + integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== + +"@types/negotiator@^0.6.1": + version "0.6.1" + resolved "https://registry.npmjs.org/@types/negotiator/-/negotiator-0.6.1.tgz" + integrity sha512-c4mvXFByghezQ/eVGN5HvH/jI63vm3B7FiE81BUzDAWmuiohRecCO6ddU60dfq29oKUMiQujsoB2h0JQC7JHKA== + +"@types/node@*", "@types/node@18.15.0": + version "18.15.0" + resolved "https://registry.npmjs.org/@types/node/-/node-18.15.0.tgz" + integrity sha512-z6nr0TTEOBGkzLGmbypWOGnpSpSIBorEhC4L+4HeQ2iezKCi4f77kyslRwvHeNitymGQ+oFyIWGP96l/DPSV9w== + +"@types/node@^22.0.0": + version "22.7.6" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.7.6.tgz#3ec3e2b071e136cd11093c19128405e1d1f92f33" + integrity sha512-/d7Rnj0/ExXDMcioS78/kf1lMzYk4BZV8MZGTBKzTGZ6/406ukkbYlIsZmMPhcR5KlkunDHQLrtAVmSq7r+mSw== + dependencies: + undici-types "~6.19.2" + +"@types/normalize-package-data@^2.4.0": + version "2.4.1" + resolved "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz" + integrity sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw== + +"@types/papaparse@^5.3.1": + version "5.3.7" + resolved "https://registry.npmjs.org/@types/papaparse/-/papaparse-5.3.7.tgz" + integrity sha512-f2HKmlnPdCvS0WI33WtCs5GD7X1cxzzS/aduaxSu3I7TbhWlENjSPs6z5TaB9K0J+BH1jbmqTaM+ja5puis4wg== + dependencies: + "@types/node" "*" + +"@types/parse-json@^4.0.0": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.2.tgz#5950e50960793055845e956c427fc2b0d70c5239" + integrity sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw== + +"@types/prop-types@*", "@types/prop-types@^15.0.0": + version "15.7.5" + resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz" + integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== + +"@types/qs@*": + version "6.9.16" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.16.tgz#52bba125a07c0482d26747d5d4947a64daf8f794" + integrity sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A== + +"@types/qs@^6.9.7": + version "6.9.7" + resolved "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz" + integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== + +"@types/range-parser@*": + version "1.2.7" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.7.tgz#50ae4353eaaddc04044279812f52c8c65857dbcb" + integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ== + +"@types/react-dom@~18.2.0": + version "18.2.25" + resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.25.tgz" + integrity sha512-o/V48vf4MQh7juIKZU2QGDfli6p1+OOi5oXx36Hffpc9adsHeXjVp8rHuPkjd8VT8sOJ2Zp05HR7CdpGTIUFUA== + dependencies: + "@types/react" "*" + +"@types/react-slider@^1.3.1": + version "1.3.1" + resolved "https://registry.npmjs.org/@types/react-slider/-/react-slider-1.3.1.tgz" + integrity sha512-4X2yK7RyCIy643YCFL+bc6XNmcnBtt8n88uuyihvcn5G7Lut23eNQU3q3KmwF7MWIfKfsW5NxCjw0SeDZRtgaA== + dependencies: + "@types/react" "*" + +"@types/react-syntax-highlighter@^15.5.6": + version "15.5.7" + resolved "https://registry.npmjs.org/@types/react-syntax-highlighter/-/react-syntax-highlighter-15.5.7.tgz" + integrity sha512-bo5fEO5toQeyCp0zVHBeggclqf5SQ/Z5blfFmjwO5dkMVGPgmiwZsJh9nu/Bo5L7IHTuGWrja6LxJVE2uB5ZrQ== + dependencies: + "@types/react" "*" + +"@types/react-window-infinite-loader@^1.0.6": + version "1.0.6" + resolved "https://registry.npmjs.org/@types/react-window-infinite-loader/-/react-window-infinite-loader-1.0.6.tgz" + integrity sha512-V8g8sBDLVeJJAfEENJS7VXZK+DRJ+jzPNtk8jpj2G+obhf+iqGNUDGwNWCbBhLiD+KpHhf3kWQlKBRi0tAeU4Q== + dependencies: + "@types/react" "*" + "@types/react-window" "*" + +"@types/react-window@*", "@types/react-window@^1.8.5": + version "1.8.5" + resolved "https://registry.npmjs.org/@types/react-window/-/react-window-1.8.5.tgz" + integrity sha512-V9q3CvhC9Jk9bWBOysPGaWy/Z0lxYcTXLtLipkt2cnRj1JOSFNF7wqGpkScSXMgBwC+fnVRg/7shwgddBG5ICw== + dependencies: + "@types/react" "*" + +"@types/react@*", "@types/react@>=16", "@types/react@^16.8.0 || ^17.0.0 || ^18.0.0", "@types/react@~18.2.0": + version "18.2.79" + resolved "https://registry.npmjs.org/@types/react/-/react-18.2.79.tgz" + integrity sha512-RwGAGXPl9kSXwdNTafkOEuFrTBD5SA2B3iEB96xi8+xu5ddUa/cpvyVCSNn+asgLCTHkb5ZxN8gbuibYJi4s1w== + dependencies: + "@types/prop-types" "*" + csstype "^3.0.2" + +"@types/recordrtc@^5.6.11": + version "5.6.11" + resolved "https://registry.npmjs.org/@types/recordrtc/-/recordrtc-5.6.11.tgz" + integrity sha512-X4XD5nltz0cjmyzsPNegQReOPF+C5ARTfSPAPhqnKV7SsfRta/M4FBJ5AtSInCaEveL71FLLSVQE9mg8Uuo++w== + +"@types/resolve@^1.20.2": + version "1.20.6" + resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.20.6.tgz#e6e60dad29c2c8c206c026e6dd8d6d1bdda850b8" + integrity sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ== + +"@types/responselike@^1.0.0": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.3.tgz#cc29706f0a397cfe6df89debfe4bf5cea159db50" + integrity sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw== + dependencies: + "@types/node" "*" + +"@types/semver@^7.3.12": + version "7.5.0" + resolved "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz" + integrity sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw== + +"@types/semver@^7.3.4": + version "7.5.8" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.8.tgz#8268a8c57a3e4abd25c165ecd36237db7948a55e" + integrity sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ== + +"@types/send@*": + version "0.17.4" + resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.4.tgz#6619cd24e7270793702e4e6a4b958a9010cfc57a" + integrity sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA== + dependencies: + "@types/mime" "^1" + "@types/node" "*" + +"@types/serve-static@*": + version "1.15.7" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.7.tgz#22174bbd74fb97fe303109738e9b5c2f3064f714" + integrity sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw== + dependencies: + "@types/http-errors" "*" + "@types/node" "*" + "@types/send" "*" + +"@types/sortablejs@^1.15.1": + version "1.15.1" + resolved "https://registry.npmjs.org/@types/sortablejs/-/sortablejs-1.15.1.tgz" + integrity sha512-g/JwBNToh6oCTAwNS8UGVmjO7NLDKsejVhvE4x1eWiPTC3uCuNsa/TD4ssvX3du+MLiM+SHPNDuijp8y76JzLQ== + +"@types/stack-utils@^2.0.0": + version "2.0.3" + resolved "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8" + integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw== + +"@types/tough-cookie@*": + version "4.0.5" + resolved "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz#cb6e2a691b70cb177c6e3ae9c1d2e8b2ea8cd304" + integrity sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA== + +"@types/unist@*", "@types/unist@^2.0.0", "@types/unist@^2.0.2": + version "2.0.6" + resolved "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz" + integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ== + +"@types/unist@^3.0.0": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@types/unist/-/unist-3.0.2.tgz#6dd61e43ef60b34086287f83683a5c1b2dc53d20" + integrity sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ== + +"@types/uuid@^9.0.1", "@types/uuid@^9.0.8": + version "9.0.8" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.8.tgz#7545ba4fc3c003d6c756f651f3bf163d8f0f29ba" + integrity sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA== + +"@types/yargs-parser@*": + version "21.0.3" + resolved "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15" + integrity sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ== + +"@types/yargs@^17.0.8": + version "17.0.32" + resolved "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz#030774723a2f7faafebf645f4e5a48371dca6229" + integrity sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog== + dependencies: + "@types/yargs-parser" "*" + +"@typescript-eslint/eslint-plugin@^5.53.0": + version "5.59.9" + resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.9.tgz" + integrity sha512-4uQIBq1ffXd2YvF7MAvehWKW3zVv/w+mSfRAu+8cKbfj3nwzyqJLNcZJpQ/WZ1HLbJDiowwmQ6NO+63nCA+fqA== + dependencies: + "@eslint-community/regexpp" "^4.4.0" + "@typescript-eslint/scope-manager" "5.59.9" + "@typescript-eslint/type-utils" "5.59.9" + "@typescript-eslint/utils" "5.59.9" + debug "^4.3.4" + grapheme-splitter "^1.0.4" + ignore "^5.2.0" + natural-compare-lite "^1.4.0" + semver "^7.3.7" + tsutils "^3.21.0" + +"@typescript-eslint/parser@^5.4.2 || ^6.0.0", "@typescript-eslint/parser@^5.53.0": + version "5.59.9" + resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.9.tgz" + integrity sha512-FsPkRvBtcLQ/eVK1ivDiNYBjn3TGJdXy2fhXX+rc7czWl4ARwnpArwbihSOHI2Peg9WbtGHrbThfBUkZZGTtvQ== + dependencies: + "@typescript-eslint/scope-manager" "5.59.9" + "@typescript-eslint/types" "5.59.9" + "@typescript-eslint/typescript-estree" "5.59.9" + debug "^4.3.4" + +"@typescript-eslint/scope-manager@5.59.9": + version "5.59.9" + resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.9.tgz" + integrity sha512-8RA+E+w78z1+2dzvK/tGZ2cpGigBZ58VMEHDZtpE1v+LLjzrYGc8mMaTONSxKyEkz3IuXFM0IqYiGHlCsmlZxQ== + dependencies: + "@typescript-eslint/types" "5.59.9" + "@typescript-eslint/visitor-keys" "5.59.9" + +"@typescript-eslint/scope-manager@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz#d9457ccc6a0b8d6b37d0eb252a23022478c5460c" + integrity sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w== + dependencies: + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/visitor-keys" "5.62.0" + +"@typescript-eslint/type-utils@5.59.9": + version "5.59.9" + resolved "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.9.tgz" + integrity sha512-ksEsT0/mEHg9e3qZu98AlSrONAQtrSTljL3ow9CGej8eRo7pe+yaC/mvTjptp23Xo/xIf2mLZKC6KPv4Sji26Q== + dependencies: + "@typescript-eslint/typescript-estree" "5.59.9" + "@typescript-eslint/utils" "5.59.9" + debug "^4.3.4" + tsutils "^3.21.0" + +"@typescript-eslint/types@5.59.9": + version "5.59.9" + resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.9.tgz" + integrity sha512-uW8H5NRgTVneSVTfiCVffBb8AbwWSKg7qcA4Ot3JI3MPCJGsB4Db4BhvAODIIYE5mNj7Q+VJkK7JxmRhk2Lyjw== + +"@typescript-eslint/types@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f" + integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ== + +"@typescript-eslint/typescript-estree@5.59.9": + version "5.59.9" + resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.9.tgz" + integrity sha512-pmM0/VQ7kUhd1QyIxgS+aRvMgw+ZljB3eDb+jYyp6d2bC0mQWLzUDF+DLwCTkQ3tlNyVsvZRXjFyV0LkU/aXjA== + dependencies: + "@typescript-eslint/types" "5.59.9" + "@typescript-eslint/visitor-keys" "5.59.9" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + semver "^7.3.7" + tsutils "^3.21.0" + +"@typescript-eslint/typescript-estree@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz#7d17794b77fabcac615d6a48fb143330d962eb9b" + integrity sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA== + dependencies: + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/visitor-keys" "5.62.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + semver "^7.3.7" + tsutils "^3.21.0" + +"@typescript-eslint/utils@5.59.9", "@typescript-eslint/utils@^5.10.0", "@typescript-eslint/utils@^5.53.0": + version "5.59.9" + resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.9.tgz" + integrity sha512-1PuMYsju/38I5Ggblaeb98TOoUvjhRvLpLa1DoTOFaLWqaXl/1iQ1eGurTXgBY58NUdtfTXKP5xBq7q9NDaLKg== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@types/json-schema" "^7.0.9" + "@types/semver" "^7.3.12" + "@typescript-eslint/scope-manager" "5.59.9" + "@typescript-eslint/types" "5.59.9" + "@typescript-eslint/typescript-estree" "5.59.9" + eslint-scope "^5.1.1" + semver "^7.3.7" + +"@typescript-eslint/utils@^5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.62.0.tgz#141e809c71636e4a75daa39faed2fb5f4b10df86" + integrity sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@types/json-schema" "^7.0.9" + "@types/semver" "^7.3.12" + "@typescript-eslint/scope-manager" "5.62.0" + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/typescript-estree" "5.62.0" + eslint-scope "^5.1.1" + semver "^7.3.7" + +"@typescript-eslint/visitor-keys@5.59.9": + version "5.59.9" + resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.9.tgz" + integrity sha512-bT7s0td97KMaLwpEBckbzj/YohnvXtqbe2XgqNvTl6RJVakY5mvENOTPvw5u66nljfZxthESpDozs86U+oLY8Q== + dependencies: + "@typescript-eslint/types" "5.59.9" + eslint-visitor-keys "^3.3.0" + +"@typescript-eslint/visitor-keys@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz#2174011917ce582875954ffe2f6912d5931e353e" + integrity sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw== + dependencies: + "@typescript-eslint/types" "5.62.0" + eslint-visitor-keys "^3.3.0" + +"@ungap/structured-clone@^1.0.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" + integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== + +"@vitest/expect@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-2.0.5.tgz#f3745a6a2c18acbea4d39f5935e913f40d26fa86" + integrity sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA== + dependencies: + "@vitest/spy" "2.0.5" + "@vitest/utils" "2.0.5" + chai "^5.1.1" + tinyrainbow "^1.2.0" + +"@vitest/pretty-format@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@vitest/pretty-format/-/pretty-format-2.0.5.tgz#91d2e6d3a7235c742e1a6cc50e7786e2f2979b1e" + integrity sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ== + dependencies: + tinyrainbow "^1.2.0" + +"@vitest/pretty-format@2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@vitest/pretty-format/-/pretty-format-2.1.3.tgz#48b9b03de75507d1d493df7beb48dc39a1946a3e" + integrity sha512-XH1XdtoLZCpqV59KRbPrIhFCOO0hErxrQCMcvnQete3Vibb9UeIOX02uFPfVn3Z9ZXsq78etlfyhnkmIZSzIwQ== + dependencies: + tinyrainbow "^1.2.0" + +"@vitest/spy@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-2.0.5.tgz#590fc07df84a78b8e9dd976ec2090920084a2b9f" + integrity sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA== + dependencies: + tinyspy "^3.0.0" + +"@vitest/utils@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-2.0.5.tgz#6f8307a4b6bc6ceb9270007f73c67c915944e926" + integrity sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ== + dependencies: + "@vitest/pretty-format" "2.0.5" + estree-walker "^3.0.3" + loupe "^3.1.1" + tinyrainbow "^1.2.0" + +"@vitest/utils@^2.0.5": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-2.1.3.tgz#e52aa5745384091b151cbdf79bb5a3ad2bea88d2" + integrity sha512-xpiVfDSg1RrYT0tX6czgerkpcKFmFOF/gCr30+Mve5V2kewCy4Prn1/NDMSRwaSmT7PRaOF83wu+bEtsY1wrvA== + dependencies: + "@vitest/pretty-format" "2.1.3" + loupe "^3.1.1" + tinyrainbow "^1.2.0" + +"@vue/compiler-core@3.4.25": + version "3.4.25" + resolved "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.25.tgz" + integrity sha512-Y2pLLopaElgWnMNolgG8w3C5nNUVev80L7hdQ5iIKPtMJvhVpG0zhnBG/g3UajJmZdvW0fktyZTotEHD1Srhbg== + dependencies: + "@babel/parser" "^7.24.4" + "@vue/shared" "3.4.25" + entities "^4.5.0" + estree-walker "^2.0.2" + source-map-js "^1.2.0" + +"@vue/compiler-dom@^3.2.47": + version "3.4.25" + resolved "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.25.tgz" + integrity sha512-Ugz5DusW57+HjllAugLci19NsDK+VyjGvmbB2TXaTcSlQxwL++2PETHx/+Qv6qFwNLzSt7HKepPe4DcTE3pBWg== + dependencies: + "@vue/compiler-core" "3.4.25" + "@vue/shared" "3.4.25" + +"@vue/shared@3.4.25": + version "3.4.25" + resolved "https://registry.npmjs.org/@vue/shared/-/shared-3.4.25.tgz" + integrity sha512-k0yappJ77g2+KNrIaF0FFnzwLvUBLUYr8VOwz+/6vLsmItFp51AcxLL7Ey3iPd7BIRyWPOcqUjMnm7OkahXllA== + +"@webassemblyjs/ast@1.12.1", "@webassemblyjs/ast@^1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.12.1.tgz#bb16a0e8b1914f979f45864c23819cc3e3f0d4bb" + integrity sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg== + dependencies: + "@webassemblyjs/helper-numbers" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + +"@webassemblyjs/floating-point-hex-parser@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz#dacbcb95aff135c8260f77fa3b4c5fea600a6431" + integrity sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw== + +"@webassemblyjs/helper-api-error@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz#6132f68c4acd59dcd141c44b18cbebbd9f2fa768" + integrity sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q== + +"@webassemblyjs/helper-buffer@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz#6df20d272ea5439bf20ab3492b7fb70e9bfcb3f6" + integrity sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw== + +"@webassemblyjs/helper-numbers@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz#cbce5e7e0c1bd32cf4905ae444ef64cea919f1b5" + integrity sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g== + dependencies: + "@webassemblyjs/floating-point-hex-parser" "1.11.6" + "@webassemblyjs/helper-api-error" "1.11.6" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/helper-wasm-bytecode@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz#bb2ebdb3b83aa26d9baad4c46d4315283acd51e9" + integrity sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA== + +"@webassemblyjs/helper-wasm-section@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz#3da623233ae1a60409b509a52ade9bc22a37f7bf" + integrity sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g== + dependencies: + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-buffer" "1.12.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/wasm-gen" "1.12.1" + +"@webassemblyjs/ieee754@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz#bb665c91d0b14fffceb0e38298c329af043c6e3a" + integrity sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.6.tgz#70e60e5e82f9ac81118bc25381a0b283893240d7" + integrity sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.6.tgz#90f8bc34c561595fe156603be7253cdbcd0fab5a" + integrity sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA== + +"@webassemblyjs/wasm-edit@^1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz#9f9f3ff52a14c980939be0ef9d5df9ebc678ae3b" + integrity sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g== + dependencies: + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-buffer" "1.12.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/helper-wasm-section" "1.12.1" + "@webassemblyjs/wasm-gen" "1.12.1" + "@webassemblyjs/wasm-opt" "1.12.1" + "@webassemblyjs/wasm-parser" "1.12.1" + "@webassemblyjs/wast-printer" "1.12.1" + +"@webassemblyjs/wasm-gen@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz#a6520601da1b5700448273666a71ad0a45d78547" + integrity sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w== + dependencies: + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/ieee754" "1.11.6" + "@webassemblyjs/leb128" "1.11.6" + "@webassemblyjs/utf8" "1.11.6" + +"@webassemblyjs/wasm-opt@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz#9e6e81475dfcfb62dab574ac2dda38226c232bc5" + integrity sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg== + dependencies: + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-buffer" "1.12.1" + "@webassemblyjs/wasm-gen" "1.12.1" + "@webassemblyjs/wasm-parser" "1.12.1" + +"@webassemblyjs/wasm-parser@1.12.1", "@webassemblyjs/wasm-parser@^1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz#c47acb90e6f083391e3fa61d113650eea1e95937" + integrity sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ== + dependencies: + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-api-error" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/ieee754" "1.11.6" + "@webassemblyjs/leb128" "1.11.6" + "@webassemblyjs/utf8" "1.11.6" + +"@webassemblyjs/wast-printer@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz#bcecf661d7d1abdaf989d8341a4833e33e2b31ac" + integrity sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA== + dependencies: + "@webassemblyjs/ast" "1.12.1" + "@xtuc/long" "4.2.2" + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +abab@^2.0.6: + version "2.0.6" + resolved "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" + integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== + +abort-controller@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" + integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== + dependencies: + event-target-shim "^5.0.0" + +accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + +acorn-globals@^7.0.0: + version "7.0.1" + resolved "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz#0dbf05c44fa7c94332914c02066d5beff62c40c3" + integrity sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q== + dependencies: + acorn "^8.1.0" + acorn-walk "^8.0.2" + +acorn-import-attributes@^1.9.5: + version "1.9.5" + resolved "https://registry.yarnpkg.com/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz#7eb1557b1ba05ef18b5ed0ec67591bfab04688ef" + integrity sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ== + +acorn-jsx@^5.0.0, acorn-jsx@^5.3.1, acorn-jsx@^5.3.2: + version "5.3.2" + resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== + +acorn-walk@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" + integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== + +acorn-walk@^8.0.2, acorn-walk@^8.1.1: + version "8.3.3" + resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz#9caeac29eefaa0c41e3d4c65137de4d6f34df43e" + integrity sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw== + dependencies: + acorn "^8.11.0" + +acorn@^7.4.1: + version "7.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" + integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== + +acorn@^8.0.0, acorn@^8.5.0, acorn@^8.8.0: + version "8.8.2" + resolved "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz" + integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== + +acorn@^8.1.0, acorn@^8.11.0, acorn@^8.4.1, acorn@^8.8.1: + version "8.12.1" + resolved "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz#71616bdccbe25e27a54439e0046e89ca76df2248" + integrity sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg== + +acorn@^8.12.1, acorn@^8.7.1, acorn@^8.8.2: + version "8.13.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.13.0.tgz#2a30d670818ad16ddd6a35d3842dacec9e5d7ca3" + integrity sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w== + +adjust-sourcemap-loader@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz#fc4a0fd080f7d10471f30a7320f25560ade28c99" + integrity sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A== + dependencies: + loader-utils "^2.0.0" + regex-parser "^2.2.11" + +agent-base@6: + version "6.0.2" + resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + +aggregate-error@^3.0.0: + version "3.1.0" + resolved "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + +ahooks-v3-count@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/ahooks-v3-count/-/ahooks-v3-count-1.0.0.tgz" + integrity sha512-V7uUvAwnimu6eh/PED4mCDjE7tokeZQLKlxg9lCTMPhN+NjsSbtdacByVlR1oluXQzD3MOw55wylDmQo4+S9ZQ== + +ahooks@^3.7.5: + version "3.7.7" + resolved "https://registry.npmjs.org/ahooks/-/ahooks-3.7.7.tgz" + integrity sha512-5e5WlPq81Y84UnTLOKIQeq2cJw4aa7yj8fR2Nb/oMmXPrWMjIMCbPS1o+fpxSfCaNA3AzOnnMc8AehWRZltkJQ== + dependencies: + "@babel/runtime" "^7.21.0" + "@types/js-cookie" "^2.x.x" + ahooks-v3-count "^1.0.0" + dayjs "^1.9.1" + intersection-observer "^0.12.0" + js-cookie "^2.x.x" + lodash "^4.17.21" + resize-observer-polyfill "^1.5.1" + screenfull "^5.0.0" + tslib "^2.4.1" + +ajv-formats@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" + integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== + dependencies: + ajv "^8.0.0" + +ajv-keywords@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== + +ajv-keywords@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" + integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== + dependencies: + fast-deep-equal "^3.1.3" + +ajv@^6.10.0, ajv@^6.12.4, ajv@^6.12.5: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ajv@^8.0.0, ajv@^8.9.0: + version "8.17.1" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.17.1.tgz#37d9a5c776af6bc92d7f4f9510eba4c0a60d11a6" + integrity sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g== + dependencies: + fast-deep-equal "^3.1.3" + fast-uri "^3.0.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + +ansi-escapes@^4.2.1, ansi-escapes@^4.3.0: + version "4.3.2" + resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" + +ansi-html-community@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" + integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== + +ansi-html@^0.0.9: + version "0.0.9" + resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.9.tgz#6512d02342ae2cc68131952644a129cb734cd3f0" + integrity sha512-ozbS3LuenHVxNRh/wdnN16QapUHzauqSomAl1jwwJRRsGwFwtj644lIhxfWu0Fy0acCij2+AEgHvjscq3dlVXg== + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +ansi-styles@^5.0.0: + version "5.2.0" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" + integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== + +ansi-styles@^6.0.0, ansi-styles@^6.1.0: + version "6.2.1" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== + +any-promise@^1.0.0: + version "1.3.0" + resolved "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz" + integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== + +anymatch@^3.0.3, anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + +arg@^5.0.2: + version "5.0.2" + resolved "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz" + integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg== + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +aria-query@5.3.0, aria-query@^5.0.0: + version "5.3.0" + resolved "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz#650c569e41ad90b51b3d7df5e5eed1c7549c103e" + integrity sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A== + dependencies: + dequal "^2.0.3" + +aria-query@^5.1.3: + version "5.1.3" + resolved "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz" + integrity sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ== + dependencies: + deep-equal "^2.0.5" + +array-buffer-byte-length@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz" + integrity sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A== + dependencies: + call-bind "^1.0.2" + is-array-buffer "^3.0.1" + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== + +array-includes@^3.1.5, array-includes@^3.1.6, array-includes@^3.1.7: + version "3.1.7" + resolved "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz" + integrity sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + get-intrinsic "^1.2.1" + is-string "^1.0.7" + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +array.prototype.findlastindex@^1.2.3: + version "1.2.3" + resolved "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz" + integrity sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + es-shim-unscopables "^1.0.0" + get-intrinsic "^1.2.1" + +array.prototype.flat@^1.3.2: + version "1.3.2" + resolved "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz" + integrity sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + es-shim-unscopables "^1.0.0" + +array.prototype.flatmap@^1.3.1, array.prototype.flatmap@^1.3.2: + version "1.3.2" + resolved "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz" + integrity sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + es-shim-unscopables "^1.0.0" + +array.prototype.tosorted@^1.1.1: + version "1.1.2" + resolved "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.2.tgz" + integrity sha512-HuQCHOlk1Weat5jzStICBCd83NxiIMwqDg/dHEsoefabn/hJRj5pVdWcPUSpRrwhwxZOsQassMpgN/xRYFBMIg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + es-shim-unscopables "^1.0.0" + get-intrinsic "^1.2.1" + +arraybuffer.prototype.slice@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz" + integrity sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw== + dependencies: + array-buffer-byte-length "^1.0.0" + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + get-intrinsic "^1.2.1" + is-array-buffer "^3.0.2" + is-shared-array-buffer "^1.0.2" + +asn1.js@^4.10.1: + version "4.10.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" + integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +assert@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/assert/-/assert-2.1.0.tgz#6d92a238d05dc02e7427c881fb8be81c8448b2dd" + integrity sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw== + dependencies: + call-bind "^1.0.2" + is-nan "^1.3.2" + object-is "^1.1.5" + object.assign "^4.1.4" + util "^0.12.5" + +assertion-error@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-2.0.1.tgz#f641a196b335690b1070bf00b6e7593fec190bf7" + integrity sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA== + +ast-types-flow@^0.0.7: + version "0.0.7" + resolved "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz" + integrity sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag== + +ast-types@^0.16.1: + version "0.16.1" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.16.1.tgz#7a9da1617c9081bc121faafe91711b4c8bb81da2" + integrity sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg== + dependencies: + tslib "^2.0.1" + +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz" + integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== + +astring@^1.8.0: + version "1.8.6" + resolved "https://registry.npmjs.org/astring/-/astring-1.8.6.tgz" + integrity sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg== + +async@^2.6.4: + version "2.6.4" + resolved "https://registry.npmjs.org/async/-/async-2.6.4.tgz" + integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA== + dependencies: + lodash "^4.17.14" + +asynciterator.prototype@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz" + integrity sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg== + dependencies: + has-symbols "^1.0.3" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + +autoprefixer@^10.4.14: + version "10.4.14" + resolved "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz" + integrity sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ== + dependencies: + browserslist "^4.21.5" + caniuse-lite "^1.0.30001464" + fraction.js "^4.2.0" + normalize-range "^0.1.2" + picocolors "^1.0.0" + postcss-value-parser "^4.2.0" + +available-typed-arrays@^1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz" + integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== + +available-typed-arrays@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz#a5cc375d6a03c2efc87a553f3e0b1522def14846" + integrity sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ== + dependencies: + possible-typed-array-names "^1.0.0" + +axe-core@^4.6.2: + version "4.7.2" + resolved "https://registry.npmjs.org/axe-core/-/axe-core-4.7.2.tgz" + integrity sha512-zIURGIS1E1Q4pcrMjp+nnEh+16G56eG/MUllJH8yEvw7asDo7Ac9uhC9KIH5jzpITueEZolfYglnCGIuSBz39g== + +axobject-query@^3.1.1: + version "3.1.1" + resolved "https://registry.npmjs.org/axobject-query/-/axobject-query-3.1.1.tgz" + integrity sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg== + dependencies: + deep-equal "^2.0.5" + +babel-jest@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz#f4369919225b684c56085998ac63dbd05be020d5" + integrity sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg== + dependencies: + "@jest/transform" "^29.7.0" + "@types/babel__core" "^7.1.14" + babel-plugin-istanbul "^6.1.1" + babel-preset-jest "^29.6.3" + chalk "^4.0.0" + graceful-fs "^4.2.9" + slash "^3.0.0" + +babel-loader@^9.1.3: + version "9.2.1" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-9.2.1.tgz#04c7835db16c246dd19ba0914418f3937797587b" + integrity sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA== + dependencies: + find-cache-dir "^4.0.0" + schema-utils "^4.0.0" + +babel-plugin-istanbul@^6.1.1: + version "6.1.1" + resolved "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" + integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@istanbuljs/load-nyc-config" "^1.0.0" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-instrument "^5.0.4" + test-exclude "^6.0.0" + +babel-plugin-jest-hoist@^29.6.3: + version "29.6.3" + resolved "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz#aadbe943464182a8922c3c927c3067ff40d24626" + integrity sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg== + dependencies: + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" + "@types/babel__core" "^7.1.14" + "@types/babel__traverse" "^7.0.6" + +babel-plugin-polyfill-corejs2@^0.4.10: + version "0.4.11" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz#30320dfe3ffe1a336c15afdcdafd6fd615b25e33" + integrity sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q== + dependencies: + "@babel/compat-data" "^7.22.6" + "@babel/helper-define-polyfill-provider" "^0.6.2" + semver "^6.3.1" + +babel-plugin-polyfill-corejs3@^0.10.6: + version "0.10.6" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz#2deda57caef50f59c525aeb4964d3b2f867710c7" + integrity sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.6.2" + core-js-compat "^3.38.0" + +babel-plugin-polyfill-regenerator@^0.6.1: + version "0.6.2" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz#addc47e240edd1da1058ebda03021f382bba785e" + integrity sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.6.2" + +babel-preset-current-node-syntax@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" + integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== + dependencies: + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-bigint" "^7.8.3" + "@babel/plugin-syntax-class-properties" "^7.8.3" + "@babel/plugin-syntax-import-meta" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.8.3" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-top-level-await" "^7.8.3" + +babel-preset-jest@^29.6.3: + version "29.6.3" + resolved "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz#fa05fa510e7d493896d7b0dd2033601c840f171c" + integrity sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA== + dependencies: + babel-plugin-jest-hoist "^29.6.3" + babel-preset-current-node-syntax "^1.0.0" + +bail@^2.0.0: + version "2.0.2" + resolved "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz" + integrity sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +better-opn@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/better-opn/-/better-opn-3.0.2.tgz#f96f35deaaf8f34144a4102651babcf00d1d8817" + integrity sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ== + dependencies: + open "^8.0.4" + +big-integer@^1.6.44: + version "1.6.51" + resolved "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz" + integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg== + +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +bing-translate-api@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/bing-translate-api/-/bing-translate-api-4.0.2.tgz#52807a128e883bf074b4174c5e674ffca60685e7" + integrity sha512-JJ8XUehnxzOhHU91oy86xEtp8OOMjVEjCZJX042fKxoO19NNvxJ5omeCcxQNFoPbDqVpBJwqiGVquL0oPdQm1Q== + dependencies: + got "^11.8.6" + +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9: + version "4.12.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" + integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== + +bn.js@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" + integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== + +body-parser@1.20.3: + version "1.20.3" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.3.tgz#1953431221c6fb5cd63c4b36d53fab0928e548c6" + integrity sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g== + dependencies: + bytes "3.1.2" + content-type "~1.0.5" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.13.0" + raw-body "2.5.2" + type-is "~1.6.18" + unpipe "1.0.0" + +boolbase@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz" + integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== + +bplist-parser@^0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz" + integrity sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw== + dependencies: + big-integer "^1.6.44" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + +braces@^3.0.3, braces@~3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" + integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== + dependencies: + fill-range "^7.1.1" + +brorand@^1.0.1, brorand@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== + +browser-assert@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/browser-assert/-/browser-assert-1.2.1.tgz#9aaa5a2a8c74685c2ae05bfe46efd606f068c200" + integrity sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ== + +browserify-aes@^1.0.4, browserify-aes@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +browserify-cipher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +browserify-rsa@^4.0.0, browserify-rsa@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.1.tgz#06e530907fe2949dc21fc3c2e2302e10b1437238" + integrity sha512-YBjSAiTqM04ZVei6sXighu679a3SqWORA3qZTEqZImnlkDIFtKc6pNutpjyZ8RJTjQtuYfeetkxM11GwoYXMIQ== + dependencies: + bn.js "^5.2.1" + randombytes "^2.1.0" + safe-buffer "^5.2.1" + +browserify-sign@^4.0.0: + version "4.2.3" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.3.tgz#7afe4c01ec7ee59a89a558a4b75bd85ae62d4208" + integrity sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw== + dependencies: + bn.js "^5.2.1" + browserify-rsa "^4.1.0" + create-hash "^1.2.0" + create-hmac "^1.1.7" + elliptic "^6.5.5" + hash-base "~3.0" + inherits "^2.0.4" + parse-asn1 "^5.1.7" + readable-stream "^2.3.8" + safe-buffer "^5.2.1" + +browserify-zlib@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" + integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== + dependencies: + pako "~1.0.5" + +browserslist@^4.21.10, browserslist@^4.23.3, browserslist@^4.24.0: + version "4.24.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.24.0.tgz#a1325fe4bc80b64fda169629fc01b3d6cecd38d4" + integrity sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A== + dependencies: + caniuse-lite "^1.0.30001663" + electron-to-chromium "^1.5.28" + node-releases "^2.0.18" + update-browserslist-db "^1.1.0" + +browserslist@^4.21.5: + version "4.23.0" + resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz" + integrity sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ== + dependencies: + caniuse-lite "^1.0.30001587" + electron-to-chromium "^1.4.668" + node-releases "^2.0.14" + update-browserslist-db "^1.0.13" + +browserslist@^4.23.1: + version "4.23.2" + resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz#244fe803641f1c19c28c48c4b6ec9736eb3d32ed" + integrity sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA== + dependencies: + caniuse-lite "^1.0.30001640" + electron-to-chromium "^1.4.820" + node-releases "^2.0.14" + update-browserslist-db "^1.1.0" + +bser@2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" + integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== + dependencies: + node-int64 "^0.4.0" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ== + +buffer@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.2.1" + +builtin-modules@^3.3.0: + version "3.3.0" + resolved "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz" + integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw== + +builtin-status-codes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + integrity sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ== + +builtins@^5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz" + integrity sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ== + dependencies: + semver "^7.0.0" + +bundle-name@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz" + integrity sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw== + dependencies: + run-applescript "^5.0.0" + +busboy@1.6.0: + version "1.6.0" + resolved "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz" + integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA== + dependencies: + streamsearch "^1.1.0" + +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + +cacheable-lookup@^5.0.3: + version "5.0.4" + resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005" + integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA== + +cacheable-request@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.4.tgz#7a33ebf08613178b403635be7b899d3e69bbe817" + integrity sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg== + dependencies: + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^4.0.0" + lowercase-keys "^2.0.0" + normalize-url "^6.0.1" + responselike "^2.0.0" + +call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.4, call-bind@^1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz" + integrity sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ== + dependencies: + function-bind "^1.1.2" + get-intrinsic "^1.2.1" + set-function-length "^1.1.1" + +call-bind@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" + integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + set-function-length "^1.2.1" + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camel-case@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.2.tgz#9728072a954f805228225a6deea6b38461e1bd5a" + integrity sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw== + dependencies: + pascal-case "^3.1.2" + tslib "^2.0.3" + +camelcase-css@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz" + integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== + +camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +camelcase@^6.2.0: + version "6.3.0" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +caniuse-lite@^1.0.30001464, caniuse-lite@^1.0.30001579, caniuse-lite@^1.0.30001587: + version "1.0.30001620" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001620.tgz" + integrity sha512-WJvYsOjd1/BYUY6SNGUosK9DUidBPDTnOARHp3fSmFO1ekdxaY6nKRttEVrfMmYi80ctS0kz1wiWmm14fVc3ew== + +caniuse-lite@^1.0.30001640: + version "1.0.30001642" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001642.tgz#6aa6610eb24067c246d30c57f055a9d0a7f8d05f" + integrity sha512-3XQ0DoRgLijXJErLSl+bLnJ+Et4KqV1PY6JJBGAFlsNsz31zeAIncyeZfLCabHK/jtSh+671RM9YMldxjUPZtA== + +caniuse-lite@^1.0.30001663: + version "1.0.30001669" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001669.tgz#fda8f1d29a8bfdc42de0c170d7f34a9cf19ed7a3" + integrity sha512-DlWzFDJqstqtIVx1zeSpIMLjunf5SmwOw0N2Ck/QSQdS8PLS4+9HrLaYei4w8BIAL7IB/UEDu889d8vhCTPA0w== + +case-sensitive-paths-webpack-plugin@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz#db64066c6422eed2e08cc14b986ca43796dbc6d4" + integrity sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw== + +ccount@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz" + integrity sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg== + +chai@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/chai/-/chai-5.1.1.tgz#f035d9792a22b481ead1c65908d14bb62ec1c82c" + integrity sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA== + dependencies: + assertion-error "^2.0.1" + check-error "^2.1.1" + deep-eql "^5.0.1" + loupe "^3.1.0" + pathval "^2.0.0" + +chalk@4.1.1, chalk@^4.0.0, chalk@^4.1.1: + version "4.1.1" + resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz" + integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chalk@5.2.0: + version "5.2.0" + resolved "https://registry.npmjs.org/chalk/-/chalk-5.2.0.tgz" + integrity sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA== + +chalk@^2.0.0, chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" + integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chalk@^4.1.0, chalk@^4.1.2: + version "4.1.2" + resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +char-regex@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" + integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== + +character-entities-html4@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz" + integrity sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA== + +character-entities-legacy@^1.0.0: + version "1.1.4" + resolved "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz" + integrity sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA== + +character-entities-legacy@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz" + integrity sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ== + +character-entities@^1.0.0: + version "1.2.4" + resolved "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz" + integrity sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw== + +character-entities@^2.0.0: + version "2.0.2" + resolved "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz" + integrity sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ== + +character-reference-invalid@^1.0.0: + version "1.1.4" + resolved "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz" + integrity sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg== + +character-reference-invalid@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz" + integrity sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw== + +check-error@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/check-error/-/check-error-2.1.1.tgz#87eb876ae71ee388fa0471fe423f494be1d96ccc" + integrity sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw== + +"chokidar@>=3.0.0 <4.0.0", chokidar@^3.5.3: + version "3.5.3" + resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +chromatic@^11.4.0: + version "11.12.5" + resolved "https://registry.yarnpkg.com/chromatic/-/chromatic-11.12.5.tgz#befbc9cbf62722183a8ac73813b3a7fb07d0b62f" + integrity sha512-5z+BXQy3TMyXIzCdCDO9Psc8aMs9kIrCFHhMgYbwA6dTXxAL0oUjHZbICn5h4Ay/fM9cZQPaCH9T7a3myPA8Sw== + +chrome-trace-event@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz#05bffd7ff928465093314708c93bdfa9bd1f0f5b" + integrity sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ== + +ci-info@^3.2.0: + version "3.9.0" + resolved "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" + integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== + +ci-info@^3.6.1: + version "3.8.0" + resolved "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz" + integrity sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw== + +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +cjs-module-lexer@^1.0.0: + version "1.3.1" + resolved "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz#c485341ae8fd999ca4ee5af2d7a1c9ae01e0099c" + integrity sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q== + +cjs-module-lexer@^1.2.3: + version "1.4.1" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.4.1.tgz#707413784dbb3a72aa11c2f2b042a0bef4004170" + integrity sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA== + +class-variance-authority@^0.7.0: + version "0.7.0" + resolved "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.0.tgz" + integrity sha512-jFI8IQw4hczaL4ALINxqLEXQbWcNjoSkloa4IaufXCJr6QawJyw7tuRysRsrE8w2p/4gGaxKIt/hX3qz/IbD1A== + dependencies: + clsx "2.0.0" + +classcat@^5.0.3, classcat@^5.0.4: + version "5.0.5" + resolved "https://registry.npmjs.org/classcat/-/classcat-5.0.5.tgz" + integrity sha512-JhZUT7JFcQy/EzW605k/ktHtncoo9vnyW/2GspNYwFlN1C/WmjuV/xtS04e9SOkL2sTdw0VAZ2UGCcQ9lR6p6w== + +classnames@2.3.1: + version "2.3.1" + resolved "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz" + integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA== + +classnames@^2.2.1, classnames@^2.3.2: + version "2.3.2" + resolved "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz" + integrity sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw== + +clean-css@^5.2.2: + version "5.3.3" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.3.3.tgz#b330653cd3bd6b75009cc25c714cae7b93351ccd" + integrity sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg== + dependencies: + source-map "~0.6.0" + +clean-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz" + integrity sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw== + dependencies: + escape-string-regexp "^1.0.5" + +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + +cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== + dependencies: + restore-cursor "^3.1.0" + +cli-truncate@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz" + integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg== + dependencies: + slice-ansi "^3.0.0" + string-width "^4.2.0" + +cli-truncate@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz" + integrity sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA== + dependencies: + slice-ansi "^5.0.0" + string-width "^5.0.0" + +client-only@0.0.1, client-only@^0.0.1: + version "0.0.1" + resolved "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz" + integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA== + +cliui@^8.0.1: + version "8.0.1" + resolved "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" + integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.1" + wrap-ansi "^7.0.0" + +clone-response@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.3.tgz#af2032aa47816399cf5f0a1d0db902f517abb8c3" + integrity sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA== + dependencies: + mimic-response "^1.0.0" + +clsx@2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz" + integrity sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q== + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.npmjs.org/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== + +code-inspector-core@0.13.0: + version "0.13.0" + resolved "https://registry.npmjs.org/code-inspector-core/-/code-inspector-core-0.13.0.tgz" + integrity sha512-oYPNLdJjn3SY50YtF3IuxZOKLBNwzXSRPOqiXVnZFceMz9Ar6ugP3+zj7HszouxrsLFb2dVtlv//5wr4+cq62A== + dependencies: + "@vue/compiler-dom" "^3.2.47" + chalk "^4.1.1" + portfinder "^1.0.28" + +code-inspector-plugin@^0.13.0: + version "0.13.0" + resolved "https://registry.npmjs.org/code-inspector-plugin/-/code-inspector-plugin-0.13.0.tgz" + integrity sha512-v4mq5hhHkyMmutembTzREVsFeZ/+KsCwfx20+0gTqm1Il/M1T4d2BCv9mZ4ivie3GvvDMt/pVz1iBBVP3SuzJA== + dependencies: + chalk "4.1.1" + code-inspector-core "0.13.0" + vite-code-inspector-plugin "0.13.0" + webpack-code-inspector-plugin "0.13.0" + +collect-v8-coverage@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz#c0b29bcd33bcd0779a1344c2136051e6afd3d9e9" + integrity sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q== + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + +color-name@^1.0.0, color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +color-string@^1.9.0: + version "1.9.1" + resolved "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz" + integrity sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg== + dependencies: + color-name "^1.0.0" + simple-swizzle "^0.2.2" + +color@^4.2.3: + version "4.2.3" + resolved "https://registry.npmjs.org/color/-/color-4.2.3.tgz" + integrity sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A== + dependencies: + color-convert "^2.0.1" + color-string "^1.9.0" + +colorette@^2.0.10, colorette@^2.0.19: + version "2.0.20" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" + integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== + +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +comma-separated-tokens@^1.0.0: + version "1.0.8" + resolved "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz" + integrity sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw== + +comma-separated-tokens@^2.0.0: + version "2.0.3" + resolved "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz" + integrity sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg== + +commander@7: + version "7.2.0" + resolved "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz" + integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== + +commander@^10.0.0: + version "10.0.1" + resolved "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz" + integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== + +commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@^4.0.0: + version "4.1.1" + resolved "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz" + integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== + +commander@^8.3.0: + version "8.3.0" + resolved "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz" + integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== + +common-path-prefix@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/common-path-prefix/-/common-path-prefix-3.0.0.tgz#7d007a7e07c58c4b4d5f433131a19141b29f11e0" + integrity sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w== + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +console-browserify@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" + integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== + +constants-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + integrity sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ== + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-type@~1.0.4, content-type@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== + +convert-source-map@^1.7.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" + integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== + +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + +cookie@0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.1.tgz#2f73c42142d5d5cf71310a74fc4ae61670e5dbc9" + integrity sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w== + +copy-to-clipboard@^3.3.3: + version "3.3.3" + resolved "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz" + integrity sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA== + dependencies: + toggle-selection "^1.0.6" + +core-js-compat@^3.38.0, core-js-compat@^3.38.1: + version "3.38.1" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.38.1.tgz#2bc7a298746ca5a7bcb9c164bcb120f2ebc09a09" + integrity sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw== + dependencies: + browserslist "^4.23.3" + +core-js-pure@^3.23.3: + version "3.38.1" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.38.1.tgz#e8534062a54b7221344884ba9b52474be495ada3" + integrity sha512-BY8Etc1FZqdw1glX0XNOq2FDwfrg/VGqoZOZCdaL+UmdaqDwQwYXkMJT4t6In+zfEfOJDcM9T0KdbBeJg8KKCQ== + +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + +cose-base@^1.0.0: + version "1.0.3" + resolved "https://registry.npmjs.org/cose-base/-/cose-base-1.0.3.tgz" + integrity sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg== + dependencies: + layout-base "^1.0.0" + +cose-base@^2.2.0: + version "2.2.0" + resolved "https://registry.npmjs.org/cose-base/-/cose-base-2.2.0.tgz" + integrity sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g== + dependencies: + layout-base "^2.0.0" + +cosmiconfig@^7.0.1: + version "7.1.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz#1443b9afa596b670082ea46cbd8f6a62b84635f6" + integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA== + dependencies: + "@types/parse-json" "^4.0.0" + import-fresh "^3.2.1" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.10.0" + +cosmiconfig@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-9.0.0.tgz#34c3fc58287b915f3ae905ab6dc3de258b55ad9d" + integrity sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg== + dependencies: + env-paths "^2.2.1" + import-fresh "^3.3.0" + js-yaml "^4.1.0" + parse-json "^5.2.0" + +create-ecdh@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" + integrity sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A== + dependencies: + bn.js "^4.1.0" + elliptic "^6.5.3" + +create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +create-jest@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz#a355c5b3cb1e1af02ba177fe7afd7feee49a5320" + integrity sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q== + dependencies: + "@jest/types" "^29.6.3" + chalk "^4.0.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + jest-config "^29.7.0" + jest-util "^29.7.0" + prompts "^2.0.1" + +create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + +cross-env@^7.0.3: + version "7.0.3" + resolved "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz" + integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw== + dependencies: + cross-spawn "^7.0.1" + +cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +crypto-browserify@^3.12.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + randomfill "^1.0.3" + +crypto-js@^4.2.0: + version "4.2.0" + resolved "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz" + integrity sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q== + +css-loader@^6.7.1, css-loader@^6.7.3: + version "6.11.0" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.11.0.tgz#33bae3bf6363d0a7c2cf9031c96c744ff54d85ba" + integrity sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g== + dependencies: + icss-utils "^5.1.0" + postcss "^8.4.33" + postcss-modules-extract-imports "^3.1.0" + postcss-modules-local-by-default "^4.0.5" + postcss-modules-scope "^3.2.0" + postcss-modules-values "^4.0.0" + postcss-value-parser "^4.2.0" + semver "^7.5.4" + +css-select@^4.1.3: + version "4.3.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.3.0.tgz#db7129b2846662fd8628cfc496abb2b59e41529b" + integrity sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ== + dependencies: + boolbase "^1.0.0" + css-what "^6.0.1" + domhandler "^4.3.1" + domutils "^2.8.0" + nth-check "^2.0.1" + +css-what@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" + integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== + +css.escape@^1.5.1: + version "1.5.1" + resolved "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb" + integrity sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg== + +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + +cssom@^0.5.0: + version "0.5.0" + resolved "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz#d254fa92cd8b6fbd83811b9fbaed34663cc17c36" + integrity sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw== + +cssom@~0.3.6: + version "0.3.8" + resolved "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" + integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== + +cssstyle@^2.3.0: + version "2.3.0" + resolved "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" + integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== + dependencies: + cssom "~0.3.6" + +csstype@^3.0.2: + version "3.1.2" + resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz" + integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== + +cytoscape-cose-bilkent@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz" + integrity sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ== + dependencies: + cose-base "^1.0.0" + +cytoscape-fcose@^2.1.0: + version "2.2.0" + resolved "https://registry.npmjs.org/cytoscape-fcose/-/cytoscape-fcose-2.2.0.tgz" + integrity sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ== + dependencies: + cose-base "^2.2.0" + +cytoscape@^3.23.0: + version "3.26.0" + resolved "https://registry.npmjs.org/cytoscape/-/cytoscape-3.26.0.tgz" + integrity sha512-IV+crL+KBcrCnVVUCZW+zRRRFUZQcrtdOPXki+o4CFUWLdAEYvuZLcBSJC9EBK++suamERKzeY7roq2hdovV3w== + dependencies: + heap "^0.2.6" + lodash "^4.17.21" + +"d3-array@1 - 2": + version "2.12.1" + resolved "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz" + integrity sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ== + dependencies: + internmap "^1.0.0" + +"d3-array@2 - 3", "d3-array@2.10.0 - 3", "d3-array@2.5.0 - 3", d3-array@3, d3-array@^3.2.0: + version "3.2.4" + resolved "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz" + integrity sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg== + dependencies: + internmap "1 - 2" + +d3-axis@3: + version "3.0.0" + resolved "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz" + integrity sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw== + +d3-brush@3: + version "3.0.0" + resolved "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz" + integrity sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ== + dependencies: + d3-dispatch "1 - 3" + d3-drag "2 - 3" + d3-interpolate "1 - 3" + d3-selection "3" + d3-transition "3" + +d3-chord@3: + version "3.0.1" + resolved "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz" + integrity sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g== + dependencies: + d3-path "1 - 3" + +"d3-color@1 - 3", d3-color@3: + version "3.1.0" + resolved "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz" + integrity sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA== + +d3-contour@4: + version "4.0.2" + resolved "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz" + integrity sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA== + dependencies: + d3-array "^3.2.0" + +d3-delaunay@6: + version "6.0.4" + resolved "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz" + integrity sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A== + dependencies: + delaunator "5" + +"d3-dispatch@1 - 3", d3-dispatch@3: + version "3.0.1" + resolved "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz" + integrity sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg== + +"d3-drag@2 - 3", d3-drag@3, d3-drag@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz" + integrity sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg== + dependencies: + d3-dispatch "1 - 3" + d3-selection "3" + +"d3-dsv@1 - 3", d3-dsv@3: + version "3.0.1" + resolved "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz" + integrity sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q== + dependencies: + commander "7" + iconv-lite "0.6" + rw "1" + +"d3-ease@1 - 3", d3-ease@3: + version "3.0.1" + resolved "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz" + integrity sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w== + +d3-fetch@3: + version "3.0.1" + resolved "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz" + integrity sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw== + dependencies: + d3-dsv "1 - 3" + +d3-force@3: + version "3.0.0" + resolved "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz" + integrity sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg== + dependencies: + d3-dispatch "1 - 3" + d3-quadtree "1 - 3" + d3-timer "1 - 3" + +"d3-format@1 - 3", d3-format@3: + version "3.1.0" + resolved "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz" + integrity sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA== + +d3-geo@3: + version "3.1.0" + resolved "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.0.tgz" + integrity sha512-JEo5HxXDdDYXCaWdwLRt79y7giK8SbhZJbFWXqbRTolCHFI5jRqteLzCsq51NKbUoX0PjBVSohxrx+NoOUujYA== + dependencies: + d3-array "2.5.0 - 3" + +d3-hierarchy@3: + version "3.1.2" + resolved "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz" + integrity sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA== + +"d3-interpolate@1 - 3", "d3-interpolate@1.2.0 - 3", d3-interpolate@3: + version "3.0.1" + resolved "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz" + integrity sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g== + dependencies: + d3-color "1 - 3" + +d3-path@1: + version "1.0.9" + resolved "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz" + integrity sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg== + +"d3-path@1 - 3", d3-path@3, d3-path@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz" + integrity sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ== + +d3-polygon@3: + version "3.0.1" + resolved "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz" + integrity sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg== + +"d3-quadtree@1 - 3", d3-quadtree@3: + version "3.0.1" + resolved "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz" + integrity sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw== + +d3-random@3: + version "3.0.1" + resolved "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz" + integrity sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ== + +d3-sankey@^0.12.3: + version "0.12.3" + resolved "https://registry.npmjs.org/d3-sankey/-/d3-sankey-0.12.3.tgz" + integrity sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ== + dependencies: + d3-array "1 - 2" + d3-shape "^1.2.0" + +d3-scale-chromatic@3: + version "3.0.0" + resolved "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz" + integrity sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g== + dependencies: + d3-color "1 - 3" + d3-interpolate "1 - 3" + +d3-scale@4: + version "4.0.2" + resolved "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz" + integrity sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ== + dependencies: + d3-array "2.10.0 - 3" + d3-format "1 - 3" + d3-interpolate "1.2.0 - 3" + d3-time "2.1.1 - 3" + d3-time-format "2 - 4" + +"d3-selection@2 - 3", d3-selection@3, d3-selection@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz" + integrity sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ== + +d3-shape@3: + version "3.2.0" + resolved "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz" + integrity sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA== + dependencies: + d3-path "^3.1.0" + +d3-shape@^1.2.0: + version "1.3.7" + resolved "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz" + integrity sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw== + dependencies: + d3-path "1" + +"d3-time-format@2 - 4", d3-time-format@4: + version "4.1.0" + resolved "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz" + integrity sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg== + dependencies: + d3-time "1 - 3" + +"d3-time@1 - 3", "d3-time@2.1.1 - 3", d3-time@3: + version "3.1.0" + resolved "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz" + integrity sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q== + dependencies: + d3-array "2 - 3" + +"d3-timer@1 - 3", d3-timer@3: + version "3.0.1" + resolved "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz" + integrity sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA== + +"d3-transition@2 - 3", d3-transition@3: + version "3.0.1" + resolved "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz" + integrity sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w== + dependencies: + d3-color "1 - 3" + d3-dispatch "1 - 3" + d3-ease "1 - 3" + d3-interpolate "1 - 3" + d3-timer "1 - 3" + +d3-zoom@3, d3-zoom@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz" + integrity sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw== + dependencies: + d3-dispatch "1 - 3" + d3-drag "2 - 3" + d3-interpolate "1 - 3" + d3-selection "2 - 3" + d3-transition "2 - 3" + +d3@^7.4.0, d3@^7.8.2: + version "7.8.5" + resolved "https://registry.npmjs.org/d3/-/d3-7.8.5.tgz" + integrity sha512-JgoahDG51ncUfJu6wX/1vWQEqOflgXyl4MaHqlcSruTez7yhaRKR9i8VjjcQGeS2en/jnFivXuaIMnseMMt0XA== + dependencies: + d3-array "3" + d3-axis "3" + d3-brush "3" + d3-chord "3" + d3-color "3" + d3-contour "4" + d3-delaunay "6" + d3-dispatch "3" + d3-drag "3" + d3-dsv "3" + d3-ease "3" + d3-fetch "3" + d3-force "3" + d3-format "3" + d3-geo "3" + d3-hierarchy "3" + d3-interpolate "3" + d3-path "3" + d3-polygon "3" + d3-quadtree "3" + d3-random "3" + d3-scale "4" + d3-scale-chromatic "3" + d3-selection "3" + d3-shape "3" + d3-time "3" + d3-time-format "4" + d3-timer "3" + d3-transition "3" + d3-zoom "3" + +dagre-d3-es@7.0.10: + version "7.0.10" + resolved "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.10.tgz" + integrity sha512-qTCQmEhcynucuaZgY5/+ti3X/rnszKZhEQH/ZdWdtP1tA/y3VoHJzcVrO9pjjJCNpigfscAtoUB5ONcd2wNn0A== + dependencies: + d3 "^7.8.2" + lodash-es "^4.17.21" + +damerau-levenshtein@^1.0.8: + version "1.0.8" + resolved "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz" + integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== + +data-urls@^3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz#9cf24a477ae22bcef5cd5f6f0bfbc1d2d3be9143" + integrity sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ== + dependencies: + abab "^2.0.6" + whatwg-mimetype "^3.0.0" + whatwg-url "^11.0.0" + +dayjs@^1.11.7, dayjs@^1.9.1: + version "1.11.8" + resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.8.tgz" + integrity sha512-LcgxzFoWMEPO7ggRv1Y2N31hUf2R0Vj7fuy/m+Bg1K8rr+KAs1AEy4y9jd5DXe8pbHgX+srkHNS7TH6Q6ZhYeQ== + +debug@2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@4, debug@^4.1.0, debug@^4.3.1: + version "4.3.5" + resolved "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz#e83444eceb9fedd4a1da56d671ae2446a01a6e1e" + integrity sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg== + dependencies: + ms "2.1.2" + +debug@^3.2.7: + version "3.2.7" + resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +debug@^4.0.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: + version "4.3.4" + resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +decimal.js@^10.4.2: + version "10.4.3" + resolved "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23" + integrity sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA== + +decode-named-character-reference@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz" + integrity sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg== + dependencies: + character-entities "^2.0.0" + +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + +dedent@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" + integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== + +dedent@^1.0.0: + version "1.5.3" + resolved "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz#99aee19eb9bae55a67327717b6e848d0bf777e5a" + integrity sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ== + +deep-eql@^5.0.1: + version "5.0.2" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-5.0.2.tgz#4b756d8d770a9257300825d52a2c2cff99c3a341" + integrity sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q== + +deep-equal@^2.0.5: + version "2.2.1" + resolved "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.1.tgz" + integrity sha512-lKdkdV6EOGoVn65XaOsPdH4rMxTZOnmFyuIkMjM1i5HHCbfjC97dawgTAy0deYNfuqUqW+Q5VrVaQYtUpSd6yQ== + dependencies: + array-buffer-byte-length "^1.0.0" + call-bind "^1.0.2" + es-get-iterator "^1.1.3" + get-intrinsic "^1.2.0" + is-arguments "^1.1.1" + is-array-buffer "^3.0.2" + is-date-object "^1.0.5" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.2" + isarray "^2.0.5" + object-is "^1.1.5" + object-keys "^1.1.1" + object.assign "^4.1.4" + regexp.prototype.flags "^1.5.0" + side-channel "^1.0.4" + which-boxed-primitive "^1.0.2" + which-collection "^1.0.1" + which-typed-array "^1.1.9" + +deep-is@^0.1.3: + version "0.1.4" + resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + +deepmerge@^4.2.2: + version "4.3.1" + resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" + integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== + +default-browser-id@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/default-browser-id/-/default-browser-id-3.0.0.tgz" + integrity sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA== + dependencies: + bplist-parser "^0.2.0" + untildify "^4.0.0" + +default-browser@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/default-browser/-/default-browser-4.0.0.tgz" + integrity sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA== + dependencies: + bundle-name "^3.0.0" + default-browser-id "^3.0.0" + execa "^7.1.1" + titleize "^3.0.0" + +defer-to-connect@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" + integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== + +define-data-property@^1.0.1, define-data-property@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz" + integrity sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ== + dependencies: + get-intrinsic "^1.2.1" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + +define-data-property@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" + integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + gopd "^1.0.1" + +define-lazy-prop@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" + integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== + +define-lazy-prop@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz" + integrity sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg== + +define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0, define-properties@^1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz" + integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== + dependencies: + define-data-property "^1.0.1" + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" + +delaunator@5: + version "5.0.0" + resolved "https://registry.npmjs.org/delaunator/-/delaunator-5.0.0.tgz" + integrity sha512-AyLvtyJdbv/U1GkiS6gUUzclRoAY4Gs75qkMygJJhU75LW4DNuSF2RMzpxs9jw9Oz1BobHjTdkG3zdP55VxAqw== + dependencies: + robust-predicates "^3.0.0" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + +depd@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +dequal@^2.0.0, dequal@^2.0.2, dequal@^2.0.3: + version "2.0.3" + resolved "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz" + integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== + +des.js@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.1.0.tgz#1d37f5766f3bbff4ee9638e871a8768c173b81da" + integrity sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg== + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + +detect-libc@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz" + integrity sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw== + +detect-libc@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.3.tgz#f0cd503b40f9939b894697d19ad50895e30cf700" + integrity sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw== + +detect-newline@^3.0.0: + version "3.1.0" + resolved "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" + integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== + +devlop@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/devlop/-/devlop-1.1.0.tgz#4db7c2ca4dc6e0e834c30be70c94bbc976dc7018" + integrity sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA== + dependencies: + dequal "^2.0.0" + +didyoumean@^1.2.2: + version "1.2.2" + resolved "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz" + integrity sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw== + +diff-sequences@^29.6.3: + version "29.6.3" + resolved "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921" + integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q== + +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + +diff@^5.0.0: + version "5.1.0" + resolved "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz" + integrity sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw== + +diffie-hellman@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +dlv@^1.1.3: + version "1.1.3" + resolved "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz" + integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA== + +doctrine@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz" + integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== + dependencies: + esutils "^2.0.2" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +dom-accessibility-api@^0.5.9: + version "0.5.16" + resolved "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz#5a7429e6066eb3664d911e33fb0e45de8eb08453" + integrity sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg== + +dom-accessibility-api@^0.6.3: + version "0.6.3" + resolved "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz#993e925cc1d73f2c662e7d75dd5a5445259a8fd8" + integrity sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w== + +dom-converter@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768" + integrity sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA== + dependencies: + utila "~0.4" + +dom-serializer@^1.0.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.4.1.tgz#de5d41b1aea290215dc45a6dae8adcf1d32e2d30" + integrity sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.2.0" + entities "^2.0.0" + +dom-serializer@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz" + integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.2" + entities "^4.2.0" + +domain-browser@^4.22.0: + version "4.23.0" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-4.23.0.tgz#427ebb91efcb070f05cffdfb8a4e9a6c25f8c94b" + integrity sha512-ArzcM/II1wCCujdCNyQjXrAFwS4mrLh4C7DZWlaI8mdh7h3BfKdNd3bKXITfl2PT9FtfQqaGvhi1vPRQPimjGA== + +domelementtype@^2.0.1, domelementtype@^2.2.0, domelementtype@^2.3.0: + version "2.3.0" + resolved "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz" + integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== + +domexception@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz#4ad1be56ccadc86fc76d033353999a8037d03673" + integrity sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw== + dependencies: + webidl-conversions "^7.0.0" + +domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.1.tgz#8d792033416f59d68bc03a5aa7b018c1ca89279c" + integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ== + dependencies: + domelementtype "^2.2.0" + +domhandler@^5.0.2, domhandler@^5.0.3: + version "5.0.3" + resolved "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz" + integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== + dependencies: + domelementtype "^2.3.0" + +dompurify@^3.0.5: + version "3.1.7" + resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.1.7.tgz#711a8c96479fb6ced93453732c160c3c72418a6a" + integrity sha512-VaTstWtsneJY8xzy7DekmYWEOZcmzIe3Qb3zPd4STve1OBTa+e+WmS1ITQec1fZYXI3HCsOZZiSMpG6oxoWMWQ== + +domutils@^2.5.2, domutils@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" + integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== + dependencies: + dom-serializer "^1.0.1" + domelementtype "^2.2.0" + domhandler "^4.2.0" + +domutils@^3.0.1: + version "3.1.0" + resolved "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz" + integrity sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA== + dependencies: + dom-serializer "^2.0.0" + domelementtype "^2.3.0" + domhandler "^5.0.3" + +dot-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" + integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w== + dependencies: + no-case "^3.0.4" + tslib "^2.0.3" + +echarts-for-react@^3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/echarts-for-react/-/echarts-for-react-3.0.2.tgz" + integrity sha512-DRwIiTzx8JfwPOVgGttDytBqdp5VzCSyMRIxubgU/g2n9y3VLUmF2FK7Icmg/sNVkv4+rktmrLN9w22U2yy3fA== + dependencies: + fast-deep-equal "^3.1.3" + size-sensor "^1.0.1" + +echarts@^5.4.1: + version "5.4.2" + resolved "https://registry.npmjs.org/echarts/-/echarts-5.4.2.tgz" + integrity sha512-2W3vw3oI2tWJdyAz+b8DuWS0nfXtSDqlDmqgin/lfzbkB01cuMEN66KWBlmur3YMp5nEDEEt5s23pllnAzB4EA== + dependencies: + tslib "2.3.0" + zrender "5.4.3" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + +electron-to-chromium@^1.4.668: + version "1.4.775" + resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.775.tgz" + integrity sha512-JpOfl1aNAiZ88wFzjPczTLwYIoPIsij8S9/XQH9lqMpiJOf23kxea68B8wje4f68t4rOIq4Bh+vP4I65njiJBw== + +electron-to-chromium@^1.4.820: + version "1.4.829" + resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.829.tgz#3034a865b5eac9064c9db8b38ba99b60a446bb73" + integrity sha512-5qp1N2POAfW0u1qGAxXEtz6P7bO1m6gpZr5hdf5ve6lxpLM7MpiM4jIPz7xcrNlClQMafbyUDDWjlIQZ1Mw0Rw== + +electron-to-chromium@^1.5.28: + version "1.5.40" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.40.tgz#5f6aec13751123c5c3185999ebe3e7bcaf828c2b" + integrity sha512-LYm78o6if4zTasnYclgQzxEcgMoIcybWOhkATWepN95uwVVWV0/IW10v+2sIeHE+bIYWipLneTftVyQm45UY7g== + +elkjs@^0.8.2: + version "0.8.2" + resolved "https://registry.npmjs.org/elkjs/-/elkjs-0.8.2.tgz" + integrity sha512-L6uRgvZTH+4OF5NE/MBbzQx/WYpru1xCBE9respNj6qznEewGUIfhzmm7horWWxbNO2M0WckQypGctR8lH79xQ== + +elliptic@^6.5.3, elliptic@^6.5.5: + version "6.5.7" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.7.tgz#8ec4da2cb2939926a1b9a73619d768207e647c8b" + integrity sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q== + dependencies: + bn.js "^4.11.9" + brorand "^1.1.0" + hash.js "^1.0.0" + hmac-drbg "^1.0.1" + inherits "^2.0.4" + minimalistic-assert "^1.0.1" + minimalistic-crypto-utils "^1.0.1" + +emittery@^0.13.1: + version "0.13.1" + resolved "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad" + integrity sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ== + +emoji-mart@^5.5.2: + version "5.5.2" + resolved "https://registry.npmjs.org/emoji-mart/-/emoji-mart-5.5.2.tgz" + integrity sha512-Sqc/nso4cjxhOwWJsp9xkVm8OF5c+mJLZJFoFfzRuKO+yWiN7K8c96xmtughYb0d/fZ8UC6cLIQ/p4BR6Pv3/A== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + +emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== + +encodeurl@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58" + integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== + +end-of-stream@^1.1.0: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +endent@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/endent/-/endent-2.1.0.tgz#5aaba698fb569e5e18e69e1ff7a28ff35373cd88" + integrity sha512-r8VyPX7XL8U01Xgnb1CjZ3XV+z90cXIJ9JPE/R9SEC9vpw2P6CfsRPJmp20DppC5N7ZAMCmjYkJIa744Iyg96w== + dependencies: + dedent "^0.7.0" + fast-json-parse "^1.0.3" + objectorarray "^1.0.5" + +enhanced-resolve@^5.12.0: + version "5.16.1" + resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.1.tgz" + integrity sha512-4U5pNsuDl0EhuZpq46M5xPslstkviJuhrdobaRDBk2Jy2KO37FDAJl4lb2KlNabxT0m4MTK2UHNrsAcphE8nyw== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + +enhanced-resolve@^5.17.1, enhanced-resolve@^5.7.0: + version "5.17.1" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz#67bfbbcc2f81d511be77d686a90267ef7f898a15" + integrity sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + +entities@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" + integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== + +entities@^4.2.0, entities@^4.4.0, entities@^4.5.0: + version "4.5.0" + resolved "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz" + integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== + +env-paths@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" + integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +error-stack-parser@^2.0.6: + version "2.1.4" + resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.1.4.tgz#229cb01cdbfa84440bfa91876285b94680188286" + integrity sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ== + dependencies: + stackframe "^1.3.4" + +es-abstract@^1.20.4, es-abstract@^1.22.1: + version "1.22.3" + resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz" + integrity sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA== + dependencies: + array-buffer-byte-length "^1.0.0" + arraybuffer.prototype.slice "^1.0.2" + available-typed-arrays "^1.0.5" + call-bind "^1.0.5" + es-set-tostringtag "^2.0.1" + es-to-primitive "^1.2.1" + function.prototype.name "^1.1.6" + get-intrinsic "^1.2.2" + get-symbol-description "^1.0.0" + globalthis "^1.0.3" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + internal-slot "^1.0.5" + is-array-buffer "^3.0.2" + is-callable "^1.2.7" + is-negative-zero "^2.0.2" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.2" + is-string "^1.0.7" + is-typed-array "^1.1.12" + is-weakref "^1.0.2" + object-inspect "^1.13.1" + object-keys "^1.1.1" + object.assign "^4.1.4" + regexp.prototype.flags "^1.5.1" + safe-array-concat "^1.0.1" + safe-regex-test "^1.0.0" + string.prototype.trim "^1.2.8" + string.prototype.trimend "^1.0.7" + string.prototype.trimstart "^1.0.7" + typed-array-buffer "^1.0.0" + typed-array-byte-length "^1.0.0" + typed-array-byte-offset "^1.0.0" + typed-array-length "^1.0.4" + unbox-primitive "^1.0.2" + which-typed-array "^1.1.13" + +es-define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" + integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== + dependencies: + get-intrinsic "^1.2.4" + +es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== + +es-get-iterator@^1.1.3: + version "1.1.3" + resolved "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz" + integrity sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.3" + has-symbols "^1.0.3" + is-arguments "^1.1.1" + is-map "^2.0.2" + is-set "^2.0.2" + is-string "^1.0.7" + isarray "^2.0.5" + stop-iteration-iterator "^1.0.0" + +es-iterator-helpers@^1.0.12: + version "1.0.15" + resolved "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.15.tgz" + integrity sha512-GhoY8uYqd6iwUl2kgjTm4CZAf6oo5mHK7BPqx3rKgx893YSsy0LGHV6gfqqQvZt/8xM8xeOnfXBCfqclMKkJ5g== + dependencies: + asynciterator.prototype "^1.0.0" + call-bind "^1.0.2" + define-properties "^1.2.1" + es-abstract "^1.22.1" + es-set-tostringtag "^2.0.1" + function-bind "^1.1.1" + get-intrinsic "^1.2.1" + globalthis "^1.0.3" + has-property-descriptors "^1.0.0" + has-proto "^1.0.1" + has-symbols "^1.0.3" + internal-slot "^1.0.5" + iterator.prototype "^1.1.2" + safe-array-concat "^1.0.1" + +es-module-lexer@^1.2.1, es-module-lexer@^1.5.0: + version "1.5.4" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.5.4.tgz#a8efec3a3da991e60efa6b633a7cad6ab8d26b78" + integrity sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw== + +es-set-tostringtag@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz" + integrity sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg== + dependencies: + get-intrinsic "^1.1.3" + has "^1.0.3" + has-tostringtag "^1.0.0" + +es-shim-unscopables@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz" + integrity sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w== + dependencies: + has "^1.0.3" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +esbuild-register@^3.5.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/esbuild-register/-/esbuild-register-3.6.0.tgz#cf270cfa677baebbc0010ac024b823cbf723a36d" + integrity sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg== + dependencies: + debug "^4.3.4" + +"esbuild@^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0": + version "0.23.1" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.23.1.tgz#40fdc3f9265ec0beae6f59824ade1bd3d3d2dab8" + integrity sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg== + optionalDependencies: + "@esbuild/aix-ppc64" "0.23.1" + "@esbuild/android-arm" "0.23.1" + "@esbuild/android-arm64" "0.23.1" + "@esbuild/android-x64" "0.23.1" + "@esbuild/darwin-arm64" "0.23.1" + "@esbuild/darwin-x64" "0.23.1" + "@esbuild/freebsd-arm64" "0.23.1" + "@esbuild/freebsd-x64" "0.23.1" + "@esbuild/linux-arm" "0.23.1" + "@esbuild/linux-arm64" "0.23.1" + "@esbuild/linux-ia32" "0.23.1" + "@esbuild/linux-loong64" "0.23.1" + "@esbuild/linux-mips64el" "0.23.1" + "@esbuild/linux-ppc64" "0.23.1" + "@esbuild/linux-riscv64" "0.23.1" + "@esbuild/linux-s390x" "0.23.1" + "@esbuild/linux-x64" "0.23.1" + "@esbuild/netbsd-x64" "0.23.1" + "@esbuild/openbsd-arm64" "0.23.1" + "@esbuild/openbsd-x64" "0.23.1" + "@esbuild/sunos-x64" "0.23.1" + "@esbuild/win32-arm64" "0.23.1" + "@esbuild/win32-ia32" "0.23.1" + "@esbuild/win32-x64" "0.23.1" + +escalade@^3.1.1, escalade@^3.1.2: + version "3.1.2" + resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz" + integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA== + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +escape-string-regexp@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz" + integrity sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw== + +escodegen@^2.0.0, escodegen@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.1.0.tgz#ba93bbb7a43986d29d6041f99f5262da773e2e17" + integrity sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w== + dependencies: + esprima "^4.0.1" + estraverse "^5.2.0" + esutils "^2.0.2" + optionalDependencies: + source-map "~0.6.1" + +eslint-config-next@^14.0.4: + version "14.1.0" + resolved "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-14.1.0.tgz" + integrity sha512-SBX2ed7DoRFXC6CQSLc/SbLY9Ut6HxNB2wPTcoIWjUMd7aF7O/SIE7111L8FdZ9TXsNV4pulUDnfthpyPtbFUg== + dependencies: + "@next/eslint-plugin-next" "14.1.0" + "@rushstack/eslint-patch" "^1.3.3" + "@typescript-eslint/parser" "^5.4.2 || ^6.0.0" + eslint-import-resolver-node "^0.3.6" + eslint-import-resolver-typescript "^3.5.2" + eslint-plugin-import "^2.28.1" + eslint-plugin-jsx-a11y "^6.7.1" + eslint-plugin-react "^7.33.2" + eslint-plugin-react-hooks "^4.5.0 || 5.0.0-canary-7118f5dd7-20230705" + +eslint-import-resolver-node@^0.3.6, eslint-import-resolver-node@^0.3.9: + version "0.3.9" + resolved "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz" + integrity sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g== + dependencies: + debug "^3.2.7" + is-core-module "^2.13.0" + resolve "^1.22.4" + +eslint-import-resolver-typescript@^3.5.2: + version "3.5.5" + resolved "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.5.5.tgz" + integrity sha512-TdJqPHs2lW5J9Zpe17DZNQuDnox4xo2o+0tE7Pggain9Rbc19ik8kFtXdxZ250FVx2kF4vlt2RSf4qlUpG7bhw== + dependencies: + debug "^4.3.4" + enhanced-resolve "^5.12.0" + eslint-module-utils "^2.7.4" + get-tsconfig "^4.5.0" + globby "^13.1.3" + is-core-module "^2.11.0" + is-glob "^4.0.3" + synckit "^0.8.5" + +eslint-module-utils@^2.7.4, eslint-module-utils@^2.8.0: + version "2.8.0" + resolved "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz" + integrity sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw== + dependencies: + debug "^3.2.7" + +eslint-plugin-antfu@0.36.0: + version "0.36.0" + resolved "https://registry.npmjs.org/eslint-plugin-antfu/-/eslint-plugin-antfu-0.36.0.tgz" + integrity sha512-qLYtjZC2y6d1fvVtG4nvVGoBUDEuUwQsS4E1RwjoEZyONZAkHYDPfeoeULDlPS0IqumSW8uGR6zGSAXi5rrVMg== + dependencies: + "@typescript-eslint/utils" "^5.53.0" + +eslint-plugin-es@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-4.1.0.tgz" + integrity sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ== + dependencies: + eslint-utils "^2.0.0" + regexpp "^3.0.0" + +eslint-plugin-eslint-comments@^3.2.0: + version "3.2.0" + resolved "https://registry.npmjs.org/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.2.0.tgz" + integrity sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ== + dependencies: + escape-string-regexp "^1.0.5" + ignore "^5.0.5" + +eslint-plugin-html@^7.1.0: + version "7.1.0" + resolved "https://registry.npmjs.org/eslint-plugin-html/-/eslint-plugin-html-7.1.0.tgz" + integrity sha512-fNLRraV/e6j8e3XYOC9xgND4j+U7b1Rq+OygMlLcMg+wI/IpVbF+ubQa3R78EjKB9njT6TQOlcK5rFKBVVtdfg== + dependencies: + htmlparser2 "^8.0.1" + +eslint-plugin-import@^2.27.5, eslint-plugin-import@^2.28.1: + version "2.29.1" + resolved "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz" + integrity sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw== + dependencies: + array-includes "^3.1.7" + array.prototype.findlastindex "^1.2.3" + array.prototype.flat "^1.3.2" + array.prototype.flatmap "^1.3.2" + debug "^3.2.7" + doctrine "^2.1.0" + eslint-import-resolver-node "^0.3.9" + eslint-module-utils "^2.8.0" + hasown "^2.0.0" + is-core-module "^2.13.1" + is-glob "^4.0.3" + minimatch "^3.1.2" + object.fromentries "^2.0.7" + object.groupby "^1.0.1" + object.values "^1.1.7" + semver "^6.3.1" + tsconfig-paths "^3.15.0" + +eslint-plugin-jest@^27.2.1: + version "27.2.1" + resolved "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.2.1.tgz" + integrity sha512-l067Uxx7ZT8cO9NJuf+eJHvt6bqJyz2Z29wykyEdz/OtmcELQl2MQGQLX8J94O1cSJWAwUSEvCjwjA7KEK3Hmg== + dependencies: + "@typescript-eslint/utils" "^5.10.0" + +eslint-plugin-jsonc@^2.6.0: + version "2.8.0" + resolved "https://registry.npmjs.org/eslint-plugin-jsonc/-/eslint-plugin-jsonc-2.8.0.tgz" + integrity sha512-K4VsnztnNwpm+V49CcCu5laq8VjclJpuhfI9LFkOrOyK+BKdQHMzkWo43B4X4rYaVrChm4U9kw/tTU5RHh5Wtg== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + jsonc-eslint-parser "^2.0.4" + natural-compare "^1.4.0" + +eslint-plugin-jsx-a11y@^6.7.1: + version "6.7.1" + resolved "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.7.1.tgz" + integrity sha512-63Bog4iIethyo8smBklORknVjB0T2dwB8Mr/hIC+fBS0uyHdYYpzM/Ed+YC8VxTjlXHEWFOdmgwcDn1U2L9VCA== + dependencies: + "@babel/runtime" "^7.20.7" + aria-query "^5.1.3" + array-includes "^3.1.6" + array.prototype.flatmap "^1.3.1" + ast-types-flow "^0.0.7" + axe-core "^4.6.2" + axobject-query "^3.1.1" + damerau-levenshtein "^1.0.8" + emoji-regex "^9.2.2" + has "^1.0.3" + jsx-ast-utils "^3.3.3" + language-tags "=1.0.5" + minimatch "^3.1.2" + object.entries "^1.1.6" + object.fromentries "^2.0.6" + semver "^6.3.0" + +eslint-plugin-markdown@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/eslint-plugin-markdown/-/eslint-plugin-markdown-3.0.0.tgz" + integrity sha512-hRs5RUJGbeHDLfS7ELanT0e29Ocyssf/7kBM+p7KluY5AwngGkDf8Oyu4658/NZSGTTq05FZeWbkxXtbVyHPwg== + dependencies: + mdast-util-from-markdown "^0.8.5" + +eslint-plugin-n@^15.6.1: + version "15.7.0" + resolved "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-15.7.0.tgz" + integrity sha512-jDex9s7D/Qial8AGVIHq4W7NswpUD5DPDL2RH8Lzd9EloWUuvUkHfv4FRLMipH5q2UtyurorBkPeNi1wVWNh3Q== + dependencies: + builtins "^5.0.1" + eslint-plugin-es "^4.1.0" + eslint-utils "^3.0.0" + ignore "^5.1.1" + is-core-module "^2.11.0" + minimatch "^3.1.2" + resolve "^1.22.1" + semver "^7.3.8" + +eslint-plugin-no-only-tests@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/eslint-plugin-no-only-tests/-/eslint-plugin-no-only-tests-3.1.0.tgz" + integrity sha512-Lf4YW/bL6Un1R6A76pRZyE1dl1vr31G/ev8UzIc/geCgFWyrKil8hVjYqWVKGB/UIGmb6Slzs9T0wNezdSVegw== + +eslint-plugin-promise@^6.1.1: + version "6.1.1" + resolved "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz" + integrity sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig== + +"eslint-plugin-react-hooks@^4.5.0 || 5.0.0-canary-7118f5dd7-20230705": + version "5.0.0-canary-7118f5dd7-20230705" + resolved "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.0.0-canary-7118f5dd7-20230705.tgz" + integrity sha512-AZYbMo/NW9chdL7vk6HQzQhT+PvTAEVqWk9ziruUoW2kAOcN5qNyelv70e0F1VNQAbvutOC9oc+xfWycI9FxDw== + +eslint-plugin-react@^7.33.2: + version "7.33.2" + resolved "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz" + integrity sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw== + dependencies: + array-includes "^3.1.6" + array.prototype.flatmap "^1.3.1" + array.prototype.tosorted "^1.1.1" + doctrine "^2.1.0" + es-iterator-helpers "^1.0.12" + estraverse "^5.3.0" + jsx-ast-utils "^2.4.1 || ^3.0.0" + minimatch "^3.1.2" + object.entries "^1.1.6" + object.fromentries "^2.0.6" + object.hasown "^1.1.2" + object.values "^1.1.6" + prop-types "^15.8.1" + resolve "^2.0.0-next.4" + semver "^6.3.1" + string.prototype.matchall "^4.0.8" + +eslint-plugin-storybook@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-storybook/-/eslint-plugin-storybook-0.9.0.tgz#8f985899b957748d5780f8e6eb5d37c705976bc8" + integrity sha512-qOT/2vQBo0VqrG/BhZv8IdSsKQiyzJw+2Wqq+WFCiblI/PfxLSrGkF/buiXF+HumwfsCyBdaC94UhqhmYFmAvA== + dependencies: + "@storybook/csf" "^0.0.1" + "@typescript-eslint/utils" "^5.62.0" + requireindex "^1.2.0" + ts-dedent "^2.2.0" + +eslint-plugin-unicorn@^45.0.2: + version "45.0.2" + resolved "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-45.0.2.tgz" + integrity sha512-Y0WUDXRyGDMcKLiwgL3zSMpHrXI00xmdyixEGIg90gHnj0PcHY4moNv3Ppje/kDivdAy5vUeUr7z211ImPv2gw== + dependencies: + "@babel/helper-validator-identifier" "^7.19.1" + "@eslint-community/eslint-utils" "^4.1.2" + ci-info "^3.6.1" + clean-regexp "^1.0.0" + esquery "^1.4.0" + indent-string "^4.0.0" + is-builtin-module "^3.2.0" + jsesc "^3.0.2" + lodash "^4.17.21" + pluralize "^8.0.0" + read-pkg-up "^7.0.1" + regexp-tree "^0.1.24" + regjsparser "^0.9.1" + safe-regex "^2.1.1" + semver "^7.3.8" + strip-indent "^3.0.0" + +eslint-plugin-unused-imports@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-2.0.0.tgz" + integrity sha512-3APeS/tQlTrFa167ThtP0Zm0vctjr4M44HMpeg1P4bK6wItarumq0Ma82xorMKdFsWpphQBlRPzw/pxiVELX1A== + dependencies: + eslint-rule-composer "^0.3.0" + +eslint-plugin-vue@^9.9.0: + version "9.14.1" + resolved "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.14.1.tgz" + integrity sha512-LQazDB1qkNEKejLe/b5a9VfEbtbczcOaui5lQ4Qw0tbRBbQYREyxxOV5BQgNDTqGPs9pxqiEpbMi9ywuIaF7vw== + dependencies: + "@eslint-community/eslint-utils" "^4.3.0" + natural-compare "^1.4.0" + nth-check "^2.0.1" + postcss-selector-parser "^6.0.9" + semver "^7.3.5" + vue-eslint-parser "^9.3.0" + xml-name-validator "^4.0.0" + +eslint-plugin-yml@^1.5.0: + version "1.7.0" + resolved "https://registry.npmjs.org/eslint-plugin-yml/-/eslint-plugin-yml-1.7.0.tgz" + integrity sha512-qq61FQJk+qIgWl0R06bec7UQQEIBrUH22jS+MroTbFUKu+3/iVlGRpZd8mjpOAm/+H/WEDFwy4x/+kKgVGbsWw== + dependencies: + debug "^4.3.2" + lodash "^4.17.21" + natural-compare "^1.4.0" + yaml-eslint-parser "^1.2.1" + +eslint-rule-composer@^0.3.0: + version "0.3.0" + resolved "https://registry.npmjs.org/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz" + integrity sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg== + +eslint-scope@5.1.1, eslint-scope@^5.1.1: + version "5.1.1" + resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +eslint-scope@^7.1.1: + version "7.2.0" + resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz" + integrity sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + +eslint-utils@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz" + integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== + dependencies: + eslint-visitor-keys "^1.1.0" + +eslint-utils@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz" + integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== + dependencies: + eslint-visitor-keys "^2.0.0" + +eslint-visitor-keys@^1.1.0: + version "1.3.0" + resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz" + integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== + +eslint-visitor-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz" + integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== + +eslint-visitor-keys@^3.0.0, eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1: + version "3.4.1" + resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz" + integrity sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA== + +eslint@^8.36.0: + version "8.36.0" + resolved "https://registry.npmjs.org/eslint/-/eslint-8.36.0.tgz" + integrity sha512-Y956lmS7vDqomxlaaQAHVmeb4tNMp2FWIvU/RnU5BD3IKMD/MJPr76xdyr68P8tV1iNMvN2mRK0yy3c+UjL+bw== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.4.0" + "@eslint/eslintrc" "^2.0.1" + "@eslint/js" "8.36.0" + "@humanwhocodes/config-array" "^0.11.8" + "@humanwhocodes/module-importer" "^1.0.1" + "@nodelib/fs.walk" "^1.2.8" + ajv "^6.10.0" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.3.2" + doctrine "^3.0.0" + escape-string-regexp "^4.0.0" + eslint-scope "^7.1.1" + eslint-visitor-keys "^3.3.0" + espree "^9.5.0" + esquery "^1.4.2" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + find-up "^5.0.0" + glob-parent "^6.0.2" + globals "^13.19.0" + grapheme-splitter "^1.0.4" + ignore "^5.2.0" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + is-path-inside "^3.0.3" + js-sdsl "^4.1.4" + js-yaml "^4.1.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.1.2" + natural-compare "^1.4.0" + optionator "^0.9.1" + strip-ansi "^6.0.1" + strip-json-comments "^3.1.0" + text-table "^0.2.0" + +espree@^9.0.0, espree@^9.3.1, espree@^9.5.0, espree@^9.5.2: + version "9.5.2" + resolved "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz" + integrity sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw== + dependencies: + acorn "^8.8.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.4.1" + +esprima@^4.0.0, esprima@^4.0.1, esprima@~4.0.0: + version "4.0.1" + resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esquery@^1.4.0, esquery@^1.4.2: + version "1.5.0" + resolved "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz" + integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0: + version "5.3.0" + resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +estree-util-attach-comments@^2.0.0: + version "2.1.1" + resolved "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-2.1.1.tgz" + integrity sha512-+5Ba/xGGS6mnwFbXIuQiDPTbuTxuMCooq3arVv7gPZtYpjp+VXH/NkHAP35OOefPhNG/UGqU3vt/LTABwcHX0w== + dependencies: + "@types/estree" "^1.0.0" + +estree-util-build-jsx@^2.0.0: + version "2.2.2" + resolved "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-2.2.2.tgz" + integrity sha512-m56vOXcOBuaF+Igpb9OPAy7f9w9OIkb5yhjsZuaPm7HoGi4oTOQi0h2+yZ+AtKklYFZ+rPC4n0wYCJCEU1ONqg== + dependencies: + "@types/estree-jsx" "^1.0.0" + estree-util-is-identifier-name "^2.0.0" + estree-walker "^3.0.0" + +estree-util-is-identifier-name@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-2.1.0.tgz" + integrity sha512-bEN9VHRyXAUOjkKVQVvArFym08BTWB0aJPppZZr0UNyAqWsLaVfAqP7hbaTJjzHifmB5ebnR8Wm7r7yGN/HonQ== + +estree-util-to-js@^1.1.0: + version "1.2.0" + resolved "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-1.2.0.tgz" + integrity sha512-IzU74r1PK5IMMGZXUVZbmiu4A1uhiPgW5hm1GjcOfr4ZzHaMPpLNJjR7HjXiIOzi25nZDrgFTobHTkV5Q6ITjA== + dependencies: + "@types/estree-jsx" "^1.0.0" + astring "^1.8.0" + source-map "^0.7.0" + +estree-util-visit@^1.0.0: + version "1.2.1" + resolved "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-1.2.1.tgz" + integrity sha512-xbgqcrkIVbIG+lI/gzbvd9SGTJL4zqJKBFttUl5pP27KhAjtMKbX/mQXJ7qgyXpMgVy/zvpm0xoQQaGL8OloOw== + dependencies: + "@types/estree-jsx" "^1.0.0" + "@types/unist" "^2.0.0" + +estree-walker@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz" + integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== + +estree-walker@^3.0.0, estree-walker@^3.0.3: + version "3.0.3" + resolved "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz" + integrity sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g== + dependencies: + "@types/estree" "^1.0.0" + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + +event-target-shim@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" + integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== + +events@^3.2.0, events@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + +evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +execa@^7.0.0, execa@^7.1.1: + version "7.1.1" + resolved "https://registry.npmjs.org/execa/-/execa-7.1.1.tgz" + integrity sha512-wH0eMf/UXckdUYnO21+HDztteVv05rq2GXksxT4fCGeHkBhw1DROXh40wcjMcRqDOWE7iPJ4n3M7e2+YFP+76Q== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.1" + human-signals "^4.3.0" + is-stream "^3.0.0" + merge-stream "^2.0.0" + npm-run-path "^5.1.0" + onetime "^6.0.0" + signal-exit "^3.0.7" + strip-final-newline "^3.0.0" + +exit@^0.1.2: + version "0.1.2" + resolved "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== + +expect@^29.0.0, expect@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz#578874590dcb3214514084c08115d8aee61e11bc" + integrity sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw== + dependencies: + "@jest/expect-utils" "^29.7.0" + jest-get-type "^29.6.3" + jest-matcher-utils "^29.7.0" + jest-message-util "^29.7.0" + jest-util "^29.7.0" + +express@^4.19.2: + version "4.21.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.21.1.tgz#9dae5dda832f16b4eec941a4e44aa89ec481b281" + integrity sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.3" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.7.1" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~2.0.0" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.3.1" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.3" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.10" + proxy-addr "~2.0.7" + qs "6.13.0" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.19.0" + serve-static "1.16.2" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +extend@^3.0.0: + version "3.0.2" + resolved "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-glob@^3.2.11, fast-glob@^3.2.12: + version "3.3.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-glob@^3.2.9, fast-glob@^3.3.0: + version "3.3.1" + resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz" + integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-json-parse@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/fast-json-parse/-/fast-json-parse-1.0.3.tgz#43e5c61ee4efa9265633046b770fb682a7577c4d" + integrity sha512-FRWsaZRWEJ1ESVNbDWmsAlqDk96gPQezzLghafp5J4GUKjbCz3OkAHuZs5TuPEtkbVQERysLp9xv6c24fBm8Aw== + +fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@^2.0.6: + version "2.0.6" + resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" + integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== + +fast-uri@^3.0.1: + version "3.0.3" + resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.0.3.tgz#892a1c91802d5d7860de728f18608a0573142241" + integrity sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw== + +fastq@^1.6.0: + version "1.15.0" + resolved "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz" + integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== + dependencies: + reusify "^1.0.4" + +fault@^1.0.0: + version "1.0.4" + resolved "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz" + integrity sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA== + dependencies: + format "^0.2.0" + +fb-watchman@^2.0.0: + version "2.0.2" + resolved "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz#e9524ee6b5c77e9e5001af0f85f3adbb8623255c" + integrity sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA== + dependencies: + bser "2.1.1" + +file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== + dependencies: + flat-cache "^3.0.4" + +filesize@^10.0.12: + version "10.1.6" + resolved "https://registry.yarnpkg.com/filesize/-/filesize-10.1.6.tgz#31194da825ac58689c0bce3948f33ce83aabd361" + integrity sha512-sJslQKU2uM33qH5nqewAwVB2QgR6w1aMNsYUp3aN5rMRyXEwJGmZvaWzeJFNTOXWlHQyBFCWrdj3fV/fsTOX8w== + +fill-range@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" + integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== + dependencies: + to-regex-range "^5.0.1" + +filter-obj@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/filter-obj/-/filter-obj-2.0.2.tgz#fff662368e505d69826abb113f0f6a98f56e9d5f" + integrity sha512-lO3ttPjHZRfjMcxWKb1j1eDhTFsu4meeR3lnMcnBFhk6RuLhvEiuALu2TlfL310ph4lCYYwgF/ElIjdP739tdg== + +finalhandler@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.3.1.tgz#0c575f1d1d324ddd1da35ad7ece3df7d19088019" + integrity sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ== + dependencies: + debug "2.6.9" + encodeurl "~2.0.0" + escape-html "~1.0.3" + on-finished "2.4.1" + parseurl "~1.3.3" + statuses "2.0.1" + unpipe "~1.0.0" + +find-cache-dir@^3.3.1: + version "3.3.2" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" + integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== + dependencies: + commondir "^1.0.1" + make-dir "^3.0.2" + pkg-dir "^4.1.0" + +find-cache-dir@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-4.0.0.tgz#a30ee0448f81a3990708f6453633c733e2f6eec2" + integrity sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg== + dependencies: + common-path-prefix "^3.0.0" + pkg-dir "^7.0.0" + +find-up@^4.0.0, find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +find-up@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-6.3.0.tgz#2abab3d3280b2dc7ac10199ef324c4e002c8c790" + integrity sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw== + dependencies: + locate-path "^7.1.0" + path-exists "^5.0.0" + +flat-cache@^3.0.4: + version "3.0.4" + resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz" + integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + dependencies: + flatted "^3.1.0" + rimraf "^3.0.2" + +flatted@^3.1.0: + version "3.2.7" + resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz" + integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== + +for-each@^0.3.3: + version "0.3.3" + resolved "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" + +foreground-child@^3.1.0: + version "3.1.1" + resolved "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz" + integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== + dependencies: + cross-spawn "^7.0.0" + signal-exit "^4.0.1" + +fork-ts-checker-webpack-plugin@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-8.0.0.tgz#dae45dfe7298aa5d553e2580096ced79b6179504" + integrity sha512-mX3qW3idpueT2klaQXBzrIM/pHw+T0B/V9KHEvNrqijTq9NFnMZU6oreVxDYcf33P8a5cW+67PjodNHthGnNVg== + dependencies: + "@babel/code-frame" "^7.16.7" + chalk "^4.1.2" + chokidar "^3.5.3" + cosmiconfig "^7.0.1" + deepmerge "^4.2.2" + fs-extra "^10.0.0" + memfs "^3.4.1" + minimatch "^3.0.4" + node-abort-controller "^3.0.1" + schema-utils "^3.1.1" + semver "^7.3.5" + tapable "^2.2.1" + +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +format@^0.2.0: + version "0.2.2" + resolved "https://registry.npmjs.org/format/-/format-0.2.2.tgz" + integrity sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww== + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fraction.js@^4.2.0: + version "4.2.0" + resolved "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz" + integrity sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA== + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== + +fs-extra@^10.0.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" + integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs-extra@^11.1.0: + version "11.2.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.2.0.tgz#e70e17dfad64232287d01929399e0ea7c86b0e5b" + integrity sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs-monkey@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.6.tgz#8ead082953e88d992cf3ff844faa907b26756da2" + integrity sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@^2.3.2, fsevents@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +function-bind@^1.1.1, function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + +function.prototype.name@^1.1.5, function.prototype.name@^1.1.6: + version "1.1.6" + resolved "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz" + integrity sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + functions-have-names "^1.2.3" + +functions-have-names@^1.2.3: + version "1.2.3" + resolved "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz" + integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== + +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2: + version "1.2.2" + resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz" + integrity sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA== + dependencies: + function-bind "^1.1.2" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + +get-intrinsic@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" + integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== + dependencies: + es-errors "^1.3.0" + function-bind "^1.1.2" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + +get-package-type@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" + integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== + +get-stream@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + +get-stream@^6.0.0, get-stream@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +get-symbol-description@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz" + integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + +get-tsconfig@^4.5.0: + version "4.6.0" + resolved "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.6.0.tgz" + integrity sha512-lgbo68hHTQnFddybKbbs/RDRJnJT5YyGy2kQzVwbq+g67X73i+5MVTval34QxGkOe9X5Ujf1UYpCaphLyltjEg== + dependencies: + resolve-pkg-maps "^1.0.0" + +github-slugger@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/github-slugger/-/github-slugger-2.0.0.tgz#52cf2f9279a21eb6c59dd385b410f0c0adda8f1a" + integrity sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw== + +glob-parent@^5.1.2, glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-parent@^6.0.2: + version "6.0.2" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + +glob-to-regexp@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" + integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== + +glob@10.3.10: + version "10.3.10" + resolved "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz" + integrity sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g== + dependencies: + foreground-child "^3.1.0" + jackspeak "^2.3.5" + minimatch "^9.0.1" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + path-scurry "^1.10.1" + +glob@7.1.6: + version "7.1.6" + resolved "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.1.3, glob@^7.1.4: + version "7.2.3" + resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +globals@^13.19.0: + version "13.20.0" + resolved "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz" + integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== + dependencies: + type-fest "^0.20.2" + +globalthis@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz" + integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== + dependencies: + define-properties "^1.1.3" + +globby@^11.1.0: + version "11.1.0" + resolved "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^3.0.0" + +globby@^13.1.3: + version "13.1.4" + resolved "https://registry.npmjs.org/globby/-/globby-13.1.4.tgz" + integrity sha512-iui/IiiW+QrJ1X1hKH5qwlMQyv34wJAYwH1vrf8b9kBA4sNiif3gKsMHa+BrdnOpEudWjpotfa7LrTzB1ERS/g== + dependencies: + dir-glob "^3.0.1" + fast-glob "^3.2.11" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^4.0.0" + +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + +got@^11.8.6: + version "11.8.6" + resolved "https://registry.yarnpkg.com/got/-/got-11.8.6.tgz#276e827ead8772eddbcfc97170590b841823233a" + integrity sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g== + dependencies: + "@sindresorhus/is" "^4.0.0" + "@szmarczak/http-timer" "^4.0.5" + "@types/cacheable-request" "^6.0.1" + "@types/responselike" "^1.0.0" + cacheable-lookup "^5.0.3" + cacheable-request "^7.0.2" + decompress-response "^6.0.0" + http2-wrapper "^1.0.0-beta.5.2" + lowercase-keys "^2.0.0" + p-cancelable "^2.0.0" + responselike "^2.0.0" + +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.11, graceful-fs@^4.2.4, graceful-fs@^4.2.9: + version "4.2.11" + resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + +grapheme-splitter@^1.0.4: + version "1.0.4" + resolved "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz" + integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== + +has-bigints@^1.0.1, has-bigints@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz" + integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-property-descriptors@^1.0.0, has-property-descriptors@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz" + integrity sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg== + dependencies: + get-intrinsic "^1.2.2" + +has-property-descriptors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" + integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== + dependencies: + es-define-property "^1.0.0" + +has-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz" + integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== + +has-symbols@^1.0.2, has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + +has-tostringtag@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc" + integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw== + dependencies: + has-symbols "^1.0.3" + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +hash-base@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" + integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== + dependencies: + inherits "^2.0.4" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" + +hash-base@~3.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" + integrity sha512-EeeoJKjTyt868liAlVmcv2ZsUfGHlE3Q+BICOXcZiwN3osr5Q/zFGYmTJpoIzuaSTAwndFy+GqhEwlU4L3j4Ow== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +hasown@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz" + integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA== + dependencies: + function-bind "^1.1.2" + +hast-util-from-dom@^4.0.0: + version "4.2.0" + resolved "https://registry.npmjs.org/hast-util-from-dom/-/hast-util-from-dom-4.2.0.tgz" + integrity sha512-t1RJW/OpJbCAJQeKi3Qrj1cAOLA0+av/iPFori112+0X7R3wng+jxLA+kXec8K4szqPRGI8vPxbbpEYvvpwaeQ== + dependencies: + hastscript "^7.0.0" + web-namespaces "^2.0.0" + +hast-util-from-html-isomorphic@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/hast-util-from-html-isomorphic/-/hast-util-from-html-isomorphic-1.0.0.tgz" + integrity sha512-Yu480AKeOEN/+l5LA674a+7BmIvtDj24GvOt7MtQWuhzUwlaaRWdEPXAh3Qm5vhuthpAipFb2vTetKXWOjmTvw== + dependencies: + "@types/hast" "^2.0.0" + hast-util-from-dom "^4.0.0" + hast-util-from-html "^1.0.0" + unist-util-remove-position "^4.0.0" + +hast-util-from-html@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-1.0.2.tgz" + integrity sha512-LhrTA2gfCbLOGJq2u/asp4kwuG0y6NhWTXiPKP+n0qNukKy7hc10whqqCFfyvIA1Q5U5d0sp9HhNim9gglEH4A== + dependencies: + "@types/hast" "^2.0.0" + hast-util-from-parse5 "^7.0.0" + parse5 "^7.0.0" + vfile "^5.0.0" + vfile-message "^3.0.0" + +hast-util-from-parse5@^7.0.0: + version "7.1.2" + resolved "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-7.1.2.tgz" + integrity sha512-Nz7FfPBuljzsN3tCQ4kCBKqdNhQE2l0Tn+X1ubgKBPRoiDIu1mL08Cfw4k7q71+Duyaw7DXDN+VTAp4Vh3oCOw== + dependencies: + "@types/hast" "^2.0.0" + "@types/unist" "^2.0.0" + hastscript "^7.0.0" + property-information "^6.0.0" + vfile "^5.0.0" + vfile-location "^4.0.0" + web-namespaces "^2.0.0" + +hast-util-from-parse5@^8.0.0: + version "8.0.1" + resolved "https://registry.yarnpkg.com/hast-util-from-parse5/-/hast-util-from-parse5-8.0.1.tgz#654a5676a41211e14ee80d1b1758c399a0327651" + integrity sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ== + dependencies: + "@types/hast" "^3.0.0" + "@types/unist" "^3.0.0" + devlop "^1.0.0" + hastscript "^8.0.0" + property-information "^6.0.0" + vfile "^6.0.0" + vfile-location "^5.0.0" + web-namespaces "^2.0.0" + +hast-util-heading-rank@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/hast-util-heading-rank/-/hast-util-heading-rank-3.0.0.tgz#2d5c6f2807a7af5c45f74e623498dd6054d2aba8" + integrity sha512-EJKb8oMUXVHcWZTDepnr+WNbfnXKFNf9duMesmr4S8SXTJBJ9M4Yok08pu9vxdJwdlGRhVumk9mEhkEvKGifwA== + dependencies: + "@types/hast" "^3.0.0" + +hast-util-is-element@^2.0.0: + version "2.1.3" + resolved "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-2.1.3.tgz" + integrity sha512-O1bKah6mhgEq2WtVMk+Ta5K7pPMqsBBlmzysLdcwKVrqzZQ0CHqUPiIVspNhAG1rvxpvJjtGee17XfauZYKqVA== + dependencies: + "@types/hast" "^2.0.0" + "@types/unist" "^2.0.0" + +hast-util-is-element@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz#6e31a6532c217e5b533848c7e52c9d9369ca0932" + integrity sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g== + dependencies: + "@types/hast" "^3.0.0" + +hast-util-parse-selector@^2.0.0: + version "2.2.5" + resolved "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz" + integrity sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ== + +hast-util-parse-selector@^3.0.0: + version "3.1.1" + resolved "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-3.1.1.tgz" + integrity sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA== + dependencies: + "@types/hast" "^2.0.0" + +hast-util-parse-selector@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz#352879fa86e25616036037dd8931fb5f34cb4a27" + integrity sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A== + dependencies: + "@types/hast" "^3.0.0" + +hast-util-raw@^9.0.0: + version "9.0.4" + resolved "https://registry.yarnpkg.com/hast-util-raw/-/hast-util-raw-9.0.4.tgz#2da03e37c46eb1a6f1391f02f9b84ae65818f7ed" + integrity sha512-LHE65TD2YiNsHD3YuXcKPHXPLuYh/gjp12mOfU8jxSrm1f/yJpsb0F/KKljS6U9LJoP0Ux+tCe8iJ2AsPzTdgA== + dependencies: + "@types/hast" "^3.0.0" + "@types/unist" "^3.0.0" + "@ungap/structured-clone" "^1.0.0" + hast-util-from-parse5 "^8.0.0" + hast-util-to-parse5 "^8.0.0" + html-void-elements "^3.0.0" + mdast-util-to-hast "^13.0.0" + parse5 "^7.0.0" + unist-util-position "^5.0.0" + unist-util-visit "^5.0.0" + vfile "^6.0.0" + web-namespaces "^2.0.0" + zwitch "^2.0.0" + +hast-util-to-estree@^2.0.0: + version "2.3.3" + resolved "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-2.3.3.tgz" + integrity sha512-ihhPIUPxN0v0w6M5+IiAZZrn0LH2uZomeWwhn7uP7avZC6TE7lIiEh2yBMPr5+zi1aUCXq6VoYRgs2Bw9xmycQ== + dependencies: + "@types/estree" "^1.0.0" + "@types/estree-jsx" "^1.0.0" + "@types/hast" "^2.0.0" + "@types/unist" "^2.0.0" + comma-separated-tokens "^2.0.0" + estree-util-attach-comments "^2.0.0" + estree-util-is-identifier-name "^2.0.0" + hast-util-whitespace "^2.0.0" + mdast-util-mdx-expression "^1.0.0" + mdast-util-mdxjs-esm "^1.0.0" + property-information "^6.0.0" + space-separated-tokens "^2.0.0" + style-to-object "^0.4.1" + unist-util-position "^4.0.0" + zwitch "^2.0.0" + +hast-util-to-parse5@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/hast-util-to-parse5/-/hast-util-to-parse5-8.0.0.tgz#477cd42d278d4f036bc2ea58586130f6f39ee6ed" + integrity sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw== + dependencies: + "@types/hast" "^3.0.0" + comma-separated-tokens "^2.0.0" + devlop "^1.0.0" + property-information "^6.0.0" + space-separated-tokens "^2.0.0" + web-namespaces "^2.0.0" + zwitch "^2.0.0" + +hast-util-to-string@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/hast-util-to-string/-/hast-util-to-string-3.0.1.tgz#a4f15e682849326dd211c97129c94b0c3e76527c" + integrity sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A== + dependencies: + "@types/hast" "^3.0.0" + +hast-util-to-text@^3.1.0: + version "3.1.2" + resolved "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-3.1.2.tgz" + integrity sha512-tcllLfp23dJJ+ju5wCCZHVpzsQQ43+moJbqVX3jNWPB7z/KFC4FyZD6R7y94cHL6MQ33YtMZL8Z0aIXXI4XFTw== + dependencies: + "@types/hast" "^2.0.0" + "@types/unist" "^2.0.0" + hast-util-is-element "^2.0.0" + unist-util-find-after "^4.0.0" + +hast-util-whitespace@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.1.tgz" + integrity sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng== + +hastscript@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz" + integrity sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w== + dependencies: + "@types/hast" "^2.0.0" + comma-separated-tokens "^1.0.0" + hast-util-parse-selector "^2.0.0" + property-information "^5.0.0" + space-separated-tokens "^1.0.0" + +hastscript@^7.0.0: + version "7.2.0" + resolved "https://registry.npmjs.org/hastscript/-/hastscript-7.2.0.tgz" + integrity sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw== + dependencies: + "@types/hast" "^2.0.0" + comma-separated-tokens "^2.0.0" + hast-util-parse-selector "^3.0.0" + property-information "^6.0.0" + space-separated-tokens "^2.0.0" + +hastscript@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-8.0.0.tgz#4ef795ec8dee867101b9f23cc830d4baf4fd781a" + integrity sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw== + dependencies: + "@types/hast" "^3.0.0" + comma-separated-tokens "^2.0.0" + hast-util-parse-selector "^4.0.0" + property-information "^6.0.0" + space-separated-tokens "^2.0.0" + +he@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +heap@^0.2.6: + version "0.2.7" + resolved "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz" + integrity sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg== + +highlight.js@^10.4.1, highlight.js@~10.7.0: + version "10.7.3" + resolved "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz" + integrity sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A== + +hmac-drbg@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg== + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +hoist-non-react-statics@^3.3.2: + version "3.3.2" + resolved "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz" + integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== + dependencies: + react-is "^16.7.0" + +hosted-git-info@^2.1.4: + version "2.8.9" + resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz" + integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== + +html-encoding-sniffer@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz#2cb1a8cf0db52414776e5b2a7a04d5dd98158de9" + integrity sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA== + dependencies: + whatwg-encoding "^2.0.0" + +html-entities@^2.1.0: + version "2.5.2" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.5.2.tgz#201a3cf95d3a15be7099521620d19dfb4f65359f" + integrity sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA== + +html-escaper@^2.0.0: + version "2.0.2" + resolved "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" + integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== + +html-minifier-terser@^6.0.2: + version "6.1.0" + resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#bfc818934cc07918f6b3669f5774ecdfd48f32ab" + integrity sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw== + dependencies: + camel-case "^4.1.2" + clean-css "^5.2.2" + commander "^8.3.0" + he "^1.2.0" + param-case "^3.0.4" + relateurl "^0.2.7" + terser "^5.10.0" + +html-parse-stringify@^3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz" + integrity sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg== + dependencies: + void-elements "3.1.0" + +html-tags@^3.1.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.3.1.tgz#a04026a18c882e4bba8a01a3d39cfe465d40b5ce" + integrity sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ== + +html-void-elements@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-3.0.0.tgz#fc9dbd84af9e747249034d4d62602def6517f1d7" + integrity sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg== + +html-webpack-plugin@^5.5.0: + version "5.6.0" + resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.6.0.tgz#50a8fa6709245608cb00e811eacecb8e0d7b7ea0" + integrity sha512-iwaY4wzbe48AfKLZ/Cc8k0L+FKG6oSNRaZ8x5A/T/IVDGyXcbHncM9TdDa93wn0FsSm82FhTKW7f3vS61thXAw== + dependencies: + "@types/html-minifier-terser" "^6.0.0" + html-minifier-terser "^6.0.2" + lodash "^4.17.21" + pretty-error "^4.0.0" + tapable "^2.0.0" + +htmlparser2@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7" + integrity sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.0.0" + domutils "^2.5.2" + entities "^2.0.0" + +htmlparser2@^8.0.1: + version "8.0.2" + resolved "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz" + integrity sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.3" + domutils "^3.0.1" + entities "^4.4.0" + +http-cache-semantics@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" + integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== + +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + +http-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" + integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w== + dependencies: + "@tootallnate/once" "2" + agent-base "6" + debug "4" + +http2-wrapper@^1.0.0-beta.5.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d" + integrity sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg== + dependencies: + quick-lru "^5.1.1" + resolve-alpn "^1.0.0" + +https-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" + integrity sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg== + +https-proxy-agent@^5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" + integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== + dependencies: + agent-base "6" + debug "4" + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +human-signals@^4.3.0: + version "4.3.1" + resolved "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz" + integrity sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ== + +husky@^8.0.3: + version "8.0.3" + resolved "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz" + integrity sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg== + +i18next-resources-to-backend@^1.1.3: + version "1.1.4" + resolved "https://registry.npmjs.org/i18next-resources-to-backend/-/i18next-resources-to-backend-1.1.4.tgz" + integrity sha512-hMyr9AOmIea17AOaVe1srNxK/l3mbk81P7Uf3fdcjlw3ehZy3UNTd0OP3EEi6yu4J02kf9jzhCcjokz6AFlEOg== + dependencies: + "@babel/runtime" "^7.21.5" + +i18next@^22.4.13: + version "22.5.1" + resolved "https://registry.npmjs.org/i18next/-/i18next-22.5.1.tgz" + integrity sha512-8TGPgM3pAD+VRsMtUMNknRz3kzqwp/gPALrWMsDnmC1mKqJwpWyooQRLMcbTwq8z8YwSmuj+ZYvc+xCuEpkssA== + dependencies: + "@babel/runtime" "^7.20.6" + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +iconv-lite@0.6, iconv-lite@0.6.3: + version "0.6.3" + resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + +icss-utils@^5.0.0, icss-utils@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" + integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== + +ieee754@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + +ignore@^5.0.5, ignore@^5.1.1, ignore@^5.2.0: + version "5.2.4" + resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz" + integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== + +image-size@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/image-size/-/image-size-1.1.1.tgz#ddd67d4dc340e52ac29ce5f546a09f4e29e840ac" + integrity sha512-541xKlUw6jr/6gGuk92F+mYM5zaFAc5ahphvkqvNe2bQ6gVBkd6bfrmVJ2t4KDAfikAYZyIqTnktX3i6/aQDrQ== + dependencies: + queue "6.0.2" + +immer@^9.0.19: + version "9.0.21" + resolved "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz" + integrity sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA== + +immutable@^4.0.0: + version "4.3.0" + resolved "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz" + integrity sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg== + +import-fresh@^3.0.0, import-fresh@^3.2.1, import-fresh@^3.3.0: + version "3.3.0" + resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +import-local@^3.0.2: + version "3.1.0" + resolved "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" + integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3, inherits@~2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inline-style-parser@0.1.1: + version "0.1.1" + resolved "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz" + integrity sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q== + +internal-slot@^1.0.4, internal-slot@^1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz" + integrity sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ== + dependencies: + get-intrinsic "^1.2.0" + has "^1.0.3" + side-channel "^1.0.4" + +"internmap@1 - 2": + version "2.0.3" + resolved "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz" + integrity sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg== + +internmap@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz" + integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw== + +intersection-observer@^0.12.0: + version "0.12.2" + resolved "https://registry.npmjs.org/intersection-observer/-/intersection-observer-0.12.2.tgz" + integrity sha512-7m1vEcPCxXYI8HqnL8CKI6siDyD+eIWSwgB3DZA+ZTogxk9I4CDnj4wilt9x/+/QbHI4YG5YZNmC6458/e9Ktg== + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +is-absolute-url@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-4.0.1.tgz#16e4d487d4fded05cfe0685e53ec86804a5e94dc" + integrity sha512-/51/TKE88Lmm7Gc4/8btclNXWS+g50wXhYJq8HWIBAGUBnoAdRu1aXeh364t/O7wXDAcTJDP8PNuNKWUDWie+A== + +is-alphabetical@^1.0.0: + version "1.0.4" + resolved "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz" + integrity sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg== + +is-alphabetical@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz" + integrity sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ== + +is-alphanumerical@^1.0.0: + version "1.0.4" + resolved "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz" + integrity sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A== + dependencies: + is-alphabetical "^1.0.0" + is-decimal "^1.0.0" + +is-alphanumerical@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz" + integrity sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw== + dependencies: + is-alphabetical "^2.0.0" + is-decimal "^2.0.0" + +is-arguments@^1.0.4, is-arguments@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" + integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz" + integrity sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.0" + is-typed-array "^1.1.10" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + +is-arrayish@^0.3.1: + version "0.3.2" + resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz" + integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== + +is-async-function@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz" + integrity sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA== + dependencies: + has-tostringtag "^1.0.0" + +is-bigint@^1.0.1: + version "1.0.4" + resolved "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz" + integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== + dependencies: + has-bigints "^1.0.1" + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-boolean-object@^1.1.0: + version "1.1.2" + resolved "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz" + integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-buffer@^2.0.0: + version "2.0.5" + resolved "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz" + integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== + +is-builtin-module@^3.2.0: + version "3.2.1" + resolved "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz" + integrity sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A== + dependencies: + builtin-modules "^3.3.0" + +is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: + version "1.2.7" + resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz" + integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== + +is-core-module@^2.11.0, is-core-module@^2.13.0, is-core-module@^2.13.1: + version "2.13.1" + resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz" + integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== + dependencies: + hasown "^2.0.0" + +is-date-object@^1.0.1, is-date-object@^1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz" + integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== + dependencies: + has-tostringtag "^1.0.0" + +is-decimal@^1.0.0: + version "1.0.4" + resolved "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz" + integrity sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw== + +is-decimal@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz" + integrity sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A== + +is-docker@^2.0.0, is-docker@^2.1.1: + version "2.2.1" + resolved "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + +is-docker@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz" + integrity sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ== + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-finalizationregistry@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz" + integrity sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw== + dependencies: + call-bind "^1.0.2" + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-fullwidth-code-point@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz" + integrity sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ== + +is-generator-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" + integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== + +is-generator-function@^1.0.10, is-generator-function@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" + integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== + dependencies: + has-tostringtag "^1.0.0" + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-hexadecimal@^1.0.0: + version "1.0.4" + resolved "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz" + integrity sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw== + +is-hexadecimal@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz" + integrity sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg== + +is-inside-container@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz" + integrity sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA== + dependencies: + is-docker "^3.0.0" + +is-map@^2.0.1, is-map@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz" + integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== + +is-nan@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/is-nan/-/is-nan-1.3.2.tgz#043a54adea31748b55b6cd4e09aadafa69bd9e1d" + integrity sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + +is-negative-zero@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz" + integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== + +is-number-object@^1.0.4: + version "1.0.7" + resolved "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz" + integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== + dependencies: + has-tostringtag "^1.0.0" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-path-inside@^3.0.3: + version "3.0.3" + resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + +is-plain-obj@^4.0.0: + version "4.1.0" + resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz" + integrity sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg== + +is-plain-object@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" + integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== + +is-potential-custom-element-name@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" + integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== + +is-reference@^3.0.0: + version "3.0.1" + resolved "https://registry.npmjs.org/is-reference/-/is-reference-3.0.1.tgz" + integrity sha512-baJJdQLiYaJdvFbJqXrcGv3WU3QCzBlUcI5QhbesIm6/xPsvmO+2CDoi/GMOFBQEQm+PXkwOPrp9KK5ozZsp2w== + dependencies: + "@types/estree" "*" + +is-regex@^1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-set@^2.0.1, is-set@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz" + integrity sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g== + +is-shared-array-buffer@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz" + integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== + dependencies: + call-bind "^1.0.2" + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +is-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz" + integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== + +is-string@^1.0.5, is-string@^1.0.7: + version "1.0.7" + resolved "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz" + integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== + dependencies: + has-tostringtag "^1.0.0" + +is-symbol@^1.0.2, is-symbol@^1.0.3: + version "1.0.4" + resolved "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz" + integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== + dependencies: + has-symbols "^1.0.2" + +is-typed-array@^1.1.10, is-typed-array@^1.1.12, is-typed-array@^1.1.9: + version "1.1.12" + resolved "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz" + integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== + dependencies: + which-typed-array "^1.1.11" + +is-typed-array@^1.1.3: + version "1.1.13" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.13.tgz#d6c5ca56df62334959322d7d7dd1cca50debe229" + integrity sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw== + dependencies: + which-typed-array "^1.1.14" + +is-weakmap@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz" + integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA== + +is-weakref@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz" + integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== + dependencies: + call-bind "^1.0.2" + +is-weakset@^2.0.1: + version "2.0.2" + resolved "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz" + integrity sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + +is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + +isarray@^2.0.5: + version "2.0.5" + resolved "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: + version "3.2.2" + resolved "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz#2d166c4b0644d43a39f04bf6c2edd1e585f31756" + integrity sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg== + +istanbul-lib-instrument@^5.0.4: + version "5.2.1" + resolved "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d" + integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== + dependencies: + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.2.0" + semver "^6.3.0" + +istanbul-lib-instrument@^6.0.0: + version "6.0.3" + resolved "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz#fa15401df6c15874bcb2105f773325d78c666765" + integrity sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q== + dependencies: + "@babel/core" "^7.23.9" + "@babel/parser" "^7.23.9" + "@istanbuljs/schema" "^0.1.3" + istanbul-lib-coverage "^3.2.0" + semver "^7.5.4" + +istanbul-lib-report@^3.0.0: + version "3.0.1" + resolved "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz#908305bac9a5bd175ac6a74489eafd0fc2445a7d" + integrity sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw== + dependencies: + istanbul-lib-coverage "^3.0.0" + make-dir "^4.0.0" + supports-color "^7.1.0" + +istanbul-lib-source-maps@^4.0.0: + version "4.0.1" + resolved "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" + integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== + dependencies: + debug "^4.1.1" + istanbul-lib-coverage "^3.0.0" + source-map "^0.6.1" + +istanbul-reports@^3.1.3: + version "3.1.7" + resolved "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz#daed12b9e1dca518e15c056e1e537e741280fa0b" + integrity sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g== + dependencies: + html-escaper "^2.0.0" + istanbul-lib-report "^3.0.0" + +iterator.prototype@^1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz" + integrity sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w== + dependencies: + define-properties "^1.2.1" + get-intrinsic "^1.2.1" + has-symbols "^1.0.3" + reflect.getprototypeof "^1.0.4" + set-function-name "^2.0.1" + +jackspeak@^2.3.5: + version "2.3.6" + resolved "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz" + integrity sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ== + dependencies: + "@isaacs/cliui" "^8.0.2" + optionalDependencies: + "@pkgjs/parseargs" "^0.11.0" + +jest-changed-files@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz#1c06d07e77c78e1585d020424dedc10d6e17ac3a" + integrity sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w== + dependencies: + execa "^5.0.0" + jest-util "^29.7.0" + p-limit "^3.1.0" + +jest-circus@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz#b6817a45fcc835d8b16d5962d0c026473ee3668a" + integrity sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw== + dependencies: + "@jest/environment" "^29.7.0" + "@jest/expect" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + dedent "^1.0.0" + is-generator-fn "^2.0.0" + jest-each "^29.7.0" + jest-matcher-utils "^29.7.0" + jest-message-util "^29.7.0" + jest-runtime "^29.7.0" + jest-snapshot "^29.7.0" + jest-util "^29.7.0" + p-limit "^3.1.0" + pretty-format "^29.7.0" + pure-rand "^6.0.0" + slash "^3.0.0" + stack-utils "^2.0.3" + +jest-cli@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz#5592c940798e0cae677eec169264f2d839a37995" + integrity sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg== + dependencies: + "@jest/core" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/types" "^29.6.3" + chalk "^4.0.0" + create-jest "^29.7.0" + exit "^0.1.2" + import-local "^3.0.2" + jest-config "^29.7.0" + jest-util "^29.7.0" + jest-validate "^29.7.0" + yargs "^17.3.1" + +jest-config@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz#bcbda8806dbcc01b1e316a46bb74085a84b0245f" + integrity sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ== + dependencies: + "@babel/core" "^7.11.6" + "@jest/test-sequencer" "^29.7.0" + "@jest/types" "^29.6.3" + babel-jest "^29.7.0" + chalk "^4.0.0" + ci-info "^3.2.0" + deepmerge "^4.2.2" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-circus "^29.7.0" + jest-environment-node "^29.7.0" + jest-get-type "^29.6.3" + jest-regex-util "^29.6.3" + jest-resolve "^29.7.0" + jest-runner "^29.7.0" + jest-util "^29.7.0" + jest-validate "^29.7.0" + micromatch "^4.0.4" + parse-json "^5.2.0" + pretty-format "^29.7.0" + slash "^3.0.0" + strip-json-comments "^3.1.1" + +jest-diff@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz#017934a66ebb7ecf6f205e84699be10afd70458a" + integrity sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw== + dependencies: + chalk "^4.0.0" + diff-sequences "^29.6.3" + jest-get-type "^29.6.3" + pretty-format "^29.7.0" + +jest-docblock@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz#8fddb6adc3cdc955c93e2a87f61cfd350d5d119a" + integrity sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g== + dependencies: + detect-newline "^3.0.0" + +jest-each@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz#162a9b3f2328bdd991beaabffbb74745e56577d1" + integrity sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ== + dependencies: + "@jest/types" "^29.6.3" + chalk "^4.0.0" + jest-get-type "^29.6.3" + jest-util "^29.7.0" + pretty-format "^29.7.0" + +jest-environment-jsdom@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-29.7.0.tgz#d206fa3551933c3fd519e5dfdb58a0f5139a837f" + integrity sha512-k9iQbsf9OyOfdzWH8HDmrRT0gSIcX+FLNW7IQq94tFX0gynPwqDTW0Ho6iMVNjGz/nb+l/vW3dWM2bbLLpkbXA== + dependencies: + "@jest/environment" "^29.7.0" + "@jest/fake-timers" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/jsdom" "^20.0.0" + "@types/node" "*" + jest-mock "^29.7.0" + jest-util "^29.7.0" + jsdom "^20.0.0" + +jest-environment-node@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz#0b93e111dda8ec120bc8300e6d1fb9576e164376" + integrity sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw== + dependencies: + "@jest/environment" "^29.7.0" + "@jest/fake-timers" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + jest-mock "^29.7.0" + jest-util "^29.7.0" + +jest-get-type@^29.6.3: + version "29.6.3" + resolved "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz#36f499fdcea197c1045a127319c0481723908fd1" + integrity sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw== + +jest-haste-map@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz#3c2396524482f5a0506376e6c858c3bbcc17b104" + integrity sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA== + dependencies: + "@jest/types" "^29.6.3" + "@types/graceful-fs" "^4.1.3" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.9" + jest-regex-util "^29.6.3" + jest-util "^29.7.0" + jest-worker "^29.7.0" + micromatch "^4.0.4" + walker "^1.0.8" + optionalDependencies: + fsevents "^2.3.2" + +jest-leak-detector@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz#5b7ec0dadfdfec0ca383dc9aa016d36b5ea4c728" + integrity sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw== + dependencies: + jest-get-type "^29.6.3" + pretty-format "^29.7.0" + +jest-matcher-utils@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz#ae8fec79ff249fd592ce80e3ee474e83a6c44f12" + integrity sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g== + dependencies: + chalk "^4.0.0" + jest-diff "^29.7.0" + jest-get-type "^29.6.3" + pretty-format "^29.7.0" + +jest-message-util@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz#8bc392e204e95dfe7564abbe72a404e28e51f7f3" + integrity sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^29.6.3" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^29.7.0" + slash "^3.0.0" + stack-utils "^2.0.3" + +jest-mock@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz#4e836cf60e99c6fcfabe9f99d017f3fdd50a6347" + integrity sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw== + dependencies: + "@jest/types" "^29.6.3" + "@types/node" "*" + jest-util "^29.7.0" + +jest-pnp-resolver@^1.2.2: + version "1.2.3" + resolved "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz#930b1546164d4ad5937d5540e711d4d38d4cad2e" + integrity sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w== + +jest-regex-util@^29.6.3: + version "29.6.3" + resolved "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz#4a556d9c776af68e1c5f48194f4d0327d24e8a52" + integrity sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg== + +jest-resolve-dependencies@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz#1b04f2c095f37fc776ff40803dc92921b1e88428" + integrity sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA== + dependencies: + jest-regex-util "^29.6.3" + jest-snapshot "^29.7.0" + +jest-resolve@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz#64d6a8992dd26f635ab0c01e5eef4399c6bcbc30" + integrity sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA== + dependencies: + chalk "^4.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^29.7.0" + jest-pnp-resolver "^1.2.2" + jest-util "^29.7.0" + jest-validate "^29.7.0" + resolve "^1.20.0" + resolve.exports "^2.0.0" + slash "^3.0.0" + +jest-runner@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz#809af072d408a53dcfd2e849a4c976d3132f718e" + integrity sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ== + dependencies: + "@jest/console" "^29.7.0" + "@jest/environment" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + emittery "^0.13.1" + graceful-fs "^4.2.9" + jest-docblock "^29.7.0" + jest-environment-node "^29.7.0" + jest-haste-map "^29.7.0" + jest-leak-detector "^29.7.0" + jest-message-util "^29.7.0" + jest-resolve "^29.7.0" + jest-runtime "^29.7.0" + jest-util "^29.7.0" + jest-watcher "^29.7.0" + jest-worker "^29.7.0" + p-limit "^3.1.0" + source-map-support "0.5.13" + +jest-runtime@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz#efecb3141cf7d3767a3a0cc8f7c9990587d3d817" + integrity sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ== + dependencies: + "@jest/environment" "^29.7.0" + "@jest/fake-timers" "^29.7.0" + "@jest/globals" "^29.7.0" + "@jest/source-map" "^29.6.3" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + cjs-module-lexer "^1.0.0" + collect-v8-coverage "^1.0.0" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-haste-map "^29.7.0" + jest-message-util "^29.7.0" + jest-mock "^29.7.0" + jest-regex-util "^29.6.3" + jest-resolve "^29.7.0" + jest-snapshot "^29.7.0" + jest-util "^29.7.0" + slash "^3.0.0" + strip-bom "^4.0.0" + +jest-snapshot@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz#c2c574c3f51865da1bb329036778a69bf88a6be5" + integrity sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw== + dependencies: + "@babel/core" "^7.11.6" + "@babel/generator" "^7.7.2" + "@babel/plugin-syntax-jsx" "^7.7.2" + "@babel/plugin-syntax-typescript" "^7.7.2" + "@babel/types" "^7.3.3" + "@jest/expect-utils" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" + babel-preset-current-node-syntax "^1.0.0" + chalk "^4.0.0" + expect "^29.7.0" + graceful-fs "^4.2.9" + jest-diff "^29.7.0" + jest-get-type "^29.6.3" + jest-matcher-utils "^29.7.0" + jest-message-util "^29.7.0" + jest-util "^29.7.0" + natural-compare "^1.4.0" + pretty-format "^29.7.0" + semver "^7.5.3" + +jest-util@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz#23c2b62bfb22be82b44de98055802ff3710fc0bc" + integrity sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA== + dependencies: + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + +jest-validate@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz#7bf705511c64da591d46b15fce41400d52147d9c" + integrity sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw== + dependencies: + "@jest/types" "^29.6.3" + camelcase "^6.2.0" + chalk "^4.0.0" + jest-get-type "^29.6.3" + leven "^3.1.0" + pretty-format "^29.7.0" + +jest-watcher@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz#7810d30d619c3a62093223ce6bb359ca1b28a2f2" + integrity sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g== + dependencies: + "@jest/test-result" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + emittery "^0.13.1" + jest-util "^29.7.0" + string-length "^4.0.1" + +jest-worker@^27.4.5: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" + integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +jest-worker@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz#acad073acbbaeb7262bd5389e1bcf43e10058d4a" + integrity sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw== + dependencies: + "@types/node" "*" + jest-util "^29.7.0" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +jest@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz#994676fc24177f088f1c5e3737f5697204ff2613" + integrity sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw== + dependencies: + "@jest/core" "^29.7.0" + "@jest/types" "^29.6.3" + import-local "^3.0.2" + jest-cli "^29.7.0" + +jiti@^1.20.0, jiti@^1.21.0: + version "1.21.6" + resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.6.tgz#6c7f7398dd4b3142767f9a168af2f317a428d268" + integrity sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w== + +js-audio-recorder@^1.0.7: + version "1.0.7" + resolved "https://registry.npmjs.org/js-audio-recorder/-/js-audio-recorder-1.0.7.tgz" + integrity sha512-JiDODCElVHGrFyjGYwYyNi7zCbKk9va9C77w+zCPMmi4C6ix7zsX2h3ddHugmo4dOTOTCym9++b/wVW9nC0IaA== + +js-cookie@^2.x.x: + version "2.2.1" + resolved "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz" + integrity sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ== + +js-cookie@^3.0.1: + version "3.0.5" + resolved "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz" + integrity sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw== + +js-sdsl@^4.1.4: + version "4.4.0" + resolved "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz" + integrity sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg== + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.13.1: + version "3.14.1" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +jsdoc-type-pratt-parser@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.1.0.tgz#ff6b4a3f339c34a6c188cbf50a16087858d22113" + integrity sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg== + +jsdom@^20.0.0: + version "20.0.3" + resolved "https://registry.npmjs.org/jsdom/-/jsdom-20.0.3.tgz#886a41ba1d4726f67a8858028c99489fed6ad4db" + integrity sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ== + dependencies: + abab "^2.0.6" + acorn "^8.8.1" + acorn-globals "^7.0.0" + cssom "^0.5.0" + cssstyle "^2.3.0" + data-urls "^3.0.2" + decimal.js "^10.4.2" + domexception "^4.0.0" + escodegen "^2.0.0" + form-data "^4.0.0" + html-encoding-sniffer "^3.0.0" + http-proxy-agent "^5.0.0" + https-proxy-agent "^5.0.1" + is-potential-custom-element-name "^1.0.1" + nwsapi "^2.2.2" + parse5 "^7.1.1" + saxes "^6.0.0" + symbol-tree "^3.2.4" + tough-cookie "^4.1.2" + w3c-xmlserializer "^4.0.0" + webidl-conversions "^7.0.0" + whatwg-encoding "^2.0.0" + whatwg-mimetype "^3.0.0" + whatwg-url "^11.0.0" + ws "^8.11.0" + xml-name-validator "^4.0.0" + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +jsesc@^3.0.2, jsesc@~3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz" + integrity sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g== + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz" + integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== + +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + +json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1: + version "2.3.1" + resolved "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" + integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== + +json5@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz" + integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== + dependencies: + minimist "^1.2.0" + +json5@^2.1.2, json5@^2.2.2, json5@^2.2.3: + version "2.2.3" + resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + +jsonc-eslint-parser@^2.0.4, jsonc-eslint-parser@^2.1.0: + version "2.3.0" + resolved "https://registry.npmjs.org/jsonc-eslint-parser/-/jsonc-eslint-parser-2.3.0.tgz" + integrity sha512-9xZPKVYp9DxnM3sd1yAsh/d59iIaswDkai8oTxbursfKYbg/ibjX0IzFt35+VZ8iEW453TVTXztnRvYUQlAfUQ== + dependencies: + acorn "^8.5.0" + eslint-visitor-keys "^3.0.0" + espree "^9.0.0" + semver "^7.3.5" + +jsonfile@^6.0.1, jsonfile@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + +"jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.3: + version "3.3.3" + resolved "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz" + integrity sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw== + dependencies: + array-includes "^3.1.5" + object.assign "^4.1.3" + +jwt-decode@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/jwt-decode/-/jwt-decode-4.0.0.tgz#2270352425fd413785b2faf11f6e755c5151bd4b" + integrity sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA== + +katex@^0.16.0, katex@^0.16.10: + version "0.16.10" + resolved "https://registry.npmjs.org/katex/-/katex-0.16.10.tgz" + integrity sha512-ZiqaC04tp2O5utMsl2TEZTXxa6WSC4yo0fv5ML++D3QZv/vx2Mct0mTlRx3O+uUkjfuAgOkzsCmq5MiUEsDDdA== + dependencies: + commander "^8.3.0" + +keyv@^4.0.0: + version "4.5.4" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" + integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== + dependencies: + json-buffer "3.0.1" + +khroma@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/khroma/-/khroma-2.0.0.tgz" + integrity sha512-2J8rDNlQWbtiNYThZRvmMv5yt44ZakX+Tz5ZIp/mN1pt4snn+m030Va5Z4v8xA0cQFDXBwO/8i42xL4QPsVk3g== + +kleur@^3.0.3: + version "3.0.3" + resolved "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" + integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== + +kleur@^4.0.3: + version "4.1.5" + resolved "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz" + integrity sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ== + +lamejs@^1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/lamejs/-/lamejs-1.2.1.tgz" + integrity sha512-s7bxvjvYthw6oPLCm5pFxvA84wUROODB8jEO2+CE1adhKgrIvVOlmMgY8zyugxGrvRaDHNJanOiS21/emty6dQ== + dependencies: + use-strict "1.0.1" + +language-subtag-registry@~0.3.2: + version "0.3.22" + resolved "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz" + integrity sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w== + +language-tags@=1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz" + integrity sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ== + dependencies: + language-subtag-registry "~0.3.2" + +layout-base@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/layout-base/-/layout-base-1.0.2.tgz" + integrity sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg== + +layout-base@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/layout-base/-/layout-base-2.0.1.tgz" + integrity sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg== + +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" + integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== + +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + +lexical@0.16.0, lexical@^0.16.0: + version "0.16.0" + resolved "https://registry.npmjs.org/lexical/-/lexical-0.16.0.tgz" + integrity sha512-Skn45Qhriazq4fpAtwnAB11U//GKc4vjzx54xsV3TkDLDvWpbL4Z9TNRwRoN3g7w8AkWnqjeOSODKkrjgfRSrg== + +lilconfig@2.1.0, lilconfig@^2.0.5, lilconfig@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz" + integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ== + +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + +lint-staged@^13.2.2: + version "13.2.2" + resolved "https://registry.npmjs.org/lint-staged/-/lint-staged-13.2.2.tgz" + integrity sha512-71gSwXKy649VrSU09s10uAT0rWCcY3aewhMaHyl2N84oBk4Xs9HgxvUp3AYu+bNsK4NrOYYxvSgg7FyGJ+jGcA== + dependencies: + chalk "5.2.0" + cli-truncate "^3.1.0" + commander "^10.0.0" + debug "^4.3.4" + execa "^7.0.0" + lilconfig "2.1.0" + listr2 "^5.0.7" + micromatch "^4.0.5" + normalize-path "^3.0.0" + object-inspect "^1.12.3" + pidtree "^0.6.0" + string-argv "^0.3.1" + yaml "^2.2.2" + +listr2@^5.0.7: + version "5.0.8" + resolved "https://registry.npmjs.org/listr2/-/listr2-5.0.8.tgz" + integrity sha512-mC73LitKHj9w6v30nLNGPetZIlfpUniNSsxxrbaPcWOjDb92SHPzJPi/t+v1YC/lxKz/AJ9egOjww0qUuFxBpA== + dependencies: + cli-truncate "^2.1.0" + colorette "^2.0.19" + log-update "^4.0.0" + p-map "^4.0.0" + rfdc "^1.3.0" + rxjs "^7.8.0" + through "^2.3.8" + wrap-ansi "^7.0.0" + +loader-runner@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" + integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== + +loader-utils@^2.0.0, loader-utils@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c" + integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^2.1.2" + +loader-utils@^3.2.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-3.3.1.tgz#735b9a19fd63648ca7adbd31c2327dfe281304e5" + integrity sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg== + +local-pkg@^0.4.3: + version "0.4.3" + resolved "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.3.tgz" + integrity sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g== + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +locate-path@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-7.2.0.tgz#69cb1779bd90b35ab1e771e1f2f89a202c2a8a8a" + integrity sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA== + dependencies: + p-locate "^6.0.0" + +lodash-es@^4.17.21: + version "4.17.21" + resolved "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz" + integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw== + +lodash.castarray@^4.4.0: + version "4.4.0" + resolved "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz" + integrity sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q== + +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== + +lodash.isplainobject@^4.0.6: + version "4.0.6" + resolved "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz" + integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA== + +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.20, lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +log-update@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz" + integrity sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg== + dependencies: + ansi-escapes "^4.3.0" + cli-cursor "^3.1.0" + slice-ansi "^4.0.0" + wrap-ansi "^6.2.0" + +longest-streak@^3.0.0: + version "3.1.0" + resolved "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz" + integrity sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g== + +loose-envify@^1.1.0, loose-envify@^1.4.0: + version "1.4.0" + resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +loupe@^3.1.0, loupe@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/loupe/-/loupe-3.1.2.tgz#c86e0696804a02218f2206124c45d8b15291a240" + integrity sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg== + +lower-case@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" + integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg== + dependencies: + tslib "^2.0.3" + +lowercase-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" + integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== + +lowlight@^1.17.0: + version "1.20.0" + resolved "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz" + integrity sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw== + dependencies: + fault "^1.0.0" + highlight.js "~10.7.0" + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +"lru-cache@^9.1.1 || ^10.0.0": + version "10.2.0" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz" + integrity sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q== + +lz-string@^1.5.0: + version "1.5.0" + resolved "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz#c1ab50f77887b712621201ba9fd4e3a6ed099941" + integrity sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ== + +magic-string@^0.30.5: + version "0.30.12" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.12.tgz#9eb11c9d072b9bcb4940a5b2c2e1a217e4ee1a60" + integrity sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw== + dependencies: + "@jridgewell/sourcemap-codec" "^1.5.0" + +magicast@^0.3.4: + version "0.3.5" + resolved "https://registry.yarnpkg.com/magicast/-/magicast-0.3.5.tgz#8301c3c7d66704a0771eb1bad74274f0ec036739" + integrity sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ== + dependencies: + "@babel/parser" "^7.25.4" + "@babel/types" "^7.25.4" + source-map-js "^1.2.0" + +make-dir@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + +make-dir@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz#c3c2307a771277cd9638305f915c29ae741b614e" + integrity sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw== + dependencies: + semver "^7.5.3" + +make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + +makeerror@1.0.12: + version "1.0.12" + resolved "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" + integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== + dependencies: + tmpl "1.0.5" + +map-or-similar@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/map-or-similar/-/map-or-similar-1.5.0.tgz#6de2653174adfb5d9edc33c69d3e92a1b76faf08" + integrity sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg== + +markdown-extensions@^1.0.0: + version "1.1.1" + resolved "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-1.1.1.tgz" + integrity sha512-WWC0ZuMzCyDHYCasEGs4IPvLyTGftYwh6wIEOULOF0HXcqZlhwRzrK0w2VUlxWA98xnvb/jszw4ZSkJ6ADpM6Q== + +markdown-table@^3.0.0: + version "3.0.3" + resolved "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz" + integrity sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw== + +markdown-to-jsx@^7.4.5: + version "7.5.0" + resolved "https://registry.yarnpkg.com/markdown-to-jsx/-/markdown-to-jsx-7.5.0.tgz#42ece0c71e842560a7d8bd9f81e7a34515c72150" + integrity sha512-RrBNcMHiFPcz/iqIj0n3wclzHXjwS7mzjBNWecKKVhNTIxQepIix6Il/wZCn2Cg5Y1ow2Qi84+eJrryFRWBEWw== + +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +mdast-util-definitions@^5.0.0: + version "5.1.2" + resolved "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-5.1.2.tgz" + integrity sha512-8SVPMuHqlPME/z3gqVwWY4zVXn8lqKv/pAhC57FuJ40ImXyBpmO5ukh98zB2v7Blql2FiHjHv9LVztSIqjY+MA== + dependencies: + "@types/mdast" "^3.0.0" + "@types/unist" "^2.0.0" + unist-util-visit "^4.0.0" + +mdast-util-find-and-replace@^2.0.0: + version "2.2.2" + resolved "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-2.2.2.tgz" + integrity sha512-MTtdFRz/eMDHXzeK6W3dO7mXUlF82Gom4y0oOgvHhh/HXZAGvIQDUvQ0SuUx+j2tv44b8xTHOm8K/9OoRFnXKw== + dependencies: + "@types/mdast" "^3.0.0" + escape-string-regexp "^5.0.0" + unist-util-is "^5.0.0" + unist-util-visit-parents "^5.0.0" + +mdast-util-from-markdown@^0.8.5: + version "0.8.5" + resolved "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz" + integrity sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ== + dependencies: + "@types/mdast" "^3.0.0" + mdast-util-to-string "^2.0.0" + micromark "~2.11.0" + parse-entities "^2.0.0" + unist-util-stringify-position "^2.0.0" + +mdast-util-from-markdown@^1.0.0, mdast-util-from-markdown@^1.1.0, mdast-util-from-markdown@^1.3.0: + version "1.3.1" + resolved "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz" + integrity sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww== + dependencies: + "@types/mdast" "^3.0.0" + "@types/unist" "^2.0.0" + decode-named-character-reference "^1.0.0" + mdast-util-to-string "^3.1.0" + micromark "^3.0.0" + micromark-util-decode-numeric-character-reference "^1.0.0" + micromark-util-decode-string "^1.0.0" + micromark-util-normalize-identifier "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + unist-util-stringify-position "^3.0.0" + uvu "^0.5.0" + +mdast-util-gfm-autolink-literal@^1.0.0: + version "1.0.3" + resolved "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-1.0.3.tgz" + integrity sha512-My8KJ57FYEy2W2LyNom4n3E7hKTuQk/0SES0u16tjA9Z3oFkF4RrC/hPAPgjlSpezsOvI8ObcXcElo92wn5IGA== + dependencies: + "@types/mdast" "^3.0.0" + ccount "^2.0.0" + mdast-util-find-and-replace "^2.0.0" + micromark-util-character "^1.0.0" + +mdast-util-gfm-footnote@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-1.0.2.tgz" + integrity sha512-56D19KOGbE00uKVj3sgIykpwKL179QsVFwx/DCW0u/0+URsryacI4MAdNJl0dh+u2PSsD9FtxPFbHCzJ78qJFQ== + dependencies: + "@types/mdast" "^3.0.0" + mdast-util-to-markdown "^1.3.0" + micromark-util-normalize-identifier "^1.0.0" + +mdast-util-gfm-strikethrough@^1.0.0: + version "1.0.3" + resolved "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-1.0.3.tgz" + integrity sha512-DAPhYzTYrRcXdMjUtUjKvW9z/FNAMTdU0ORyMcbmkwYNbKocDpdk+PX1L1dQgOID/+vVs1uBQ7ElrBQfZ0cuiQ== + dependencies: + "@types/mdast" "^3.0.0" + mdast-util-to-markdown "^1.3.0" + +mdast-util-gfm-table@^1.0.0: + version "1.0.7" + resolved "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-1.0.7.tgz" + integrity sha512-jjcpmNnQvrmN5Vx7y7lEc2iIOEytYv7rTvu+MeyAsSHTASGCCRA79Igg2uKssgOs1i1po8s3plW0sTu1wkkLGg== + dependencies: + "@types/mdast" "^3.0.0" + markdown-table "^3.0.0" + mdast-util-from-markdown "^1.0.0" + mdast-util-to-markdown "^1.3.0" + +mdast-util-gfm-task-list-item@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-1.0.2.tgz" + integrity sha512-PFTA1gzfp1B1UaiJVyhJZA1rm0+Tzn690frc/L8vNX1Jop4STZgOE6bxUhnzdVSB+vm2GU1tIsuQcA9bxTQpMQ== + dependencies: + "@types/mdast" "^3.0.0" + mdast-util-to-markdown "^1.3.0" + +mdast-util-gfm@^2.0.0: + version "2.0.2" + resolved "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-2.0.2.tgz" + integrity sha512-qvZ608nBppZ4icQlhQQIAdc6S3Ffj9RGmzwUKUWuEICFnd1LVkN3EktF7ZHAgfcEdvZB5owU9tQgt99e2TlLjg== + dependencies: + mdast-util-from-markdown "^1.0.0" + mdast-util-gfm-autolink-literal "^1.0.0" + mdast-util-gfm-footnote "^1.0.0" + mdast-util-gfm-strikethrough "^1.0.0" + mdast-util-gfm-table "^1.0.0" + mdast-util-gfm-task-list-item "^1.0.0" + mdast-util-to-markdown "^1.0.0" + +mdast-util-math@^2.0.0: + version "2.0.2" + resolved "https://registry.npmjs.org/mdast-util-math/-/mdast-util-math-2.0.2.tgz" + integrity sha512-8gmkKVp9v6+Tgjtq6SYx9kGPpTf6FVYRa53/DLh479aldR9AyP48qeVOgNZ5X7QUK7nOy4yw7vg6mbiGcs9jWQ== + dependencies: + "@types/mdast" "^3.0.0" + longest-streak "^3.0.0" + mdast-util-to-markdown "^1.3.0" + +mdast-util-mdx-expression@^1.0.0: + version "1.3.2" + resolved "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-1.3.2.tgz" + integrity sha512-xIPmR5ReJDu/DHH1OoIT1HkuybIfRGYRywC+gJtI7qHjCJp/M9jrmBEJW22O8lskDWm562BX2W8TiAwRTb0rKA== + dependencies: + "@types/estree-jsx" "^1.0.0" + "@types/hast" "^2.0.0" + "@types/mdast" "^3.0.0" + mdast-util-from-markdown "^1.0.0" + mdast-util-to-markdown "^1.0.0" + +mdast-util-mdx-jsx@^2.0.0: + version "2.1.4" + resolved "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-2.1.4.tgz" + integrity sha512-DtMn9CmVhVzZx3f+optVDF8yFgQVt7FghCRNdlIaS3X5Bnym3hZwPbg/XW86vdpKjlc1PVj26SpnLGeJBXD3JA== + dependencies: + "@types/estree-jsx" "^1.0.0" + "@types/hast" "^2.0.0" + "@types/mdast" "^3.0.0" + "@types/unist" "^2.0.0" + ccount "^2.0.0" + mdast-util-from-markdown "^1.1.0" + mdast-util-to-markdown "^1.3.0" + parse-entities "^4.0.0" + stringify-entities "^4.0.0" + unist-util-remove-position "^4.0.0" + unist-util-stringify-position "^3.0.0" + vfile-message "^3.0.0" + +mdast-util-mdx@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-2.0.1.tgz" + integrity sha512-38w5y+r8nyKlGvNjSEqWrhG0w5PmnRA+wnBvm+ulYCct7nsGYhFVb0lljS9bQav4psDAS1eGkP2LMVcZBi/aqw== + dependencies: + mdast-util-from-markdown "^1.0.0" + mdast-util-mdx-expression "^1.0.0" + mdast-util-mdx-jsx "^2.0.0" + mdast-util-mdxjs-esm "^1.0.0" + mdast-util-to-markdown "^1.0.0" + +mdast-util-mdxjs-esm@^1.0.0: + version "1.3.1" + resolved "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-1.3.1.tgz" + integrity sha512-SXqglS0HrEvSdUEfoXFtcg7DRl7S2cwOXc7jkuusG472Mmjag34DUDeOJUZtl+BVnyeO1frIgVpHlNRWc2gk/w== + dependencies: + "@types/estree-jsx" "^1.0.0" + "@types/hast" "^2.0.0" + "@types/mdast" "^3.0.0" + mdast-util-from-markdown "^1.0.0" + mdast-util-to-markdown "^1.0.0" + +mdast-util-newline-to-break@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/mdast-util-newline-to-break/-/mdast-util-newline-to-break-1.0.0.tgz" + integrity sha512-491LcYv3gbGhhCrLoeALncQmega2xPh+m3gbsIhVsOX4sw85+ShLFPvPyibxc1Swx/6GtzxgVodq+cGa/47ULg== + dependencies: + "@types/mdast" "^3.0.0" + mdast-util-find-and-replace "^2.0.0" + +mdast-util-phrasing@^3.0.0: + version "3.0.1" + resolved "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-3.0.1.tgz" + integrity sha512-WmI1gTXUBJo4/ZmSk79Wcb2HcjPJBzM1nlI/OUWA8yk2X9ik3ffNbBGsU+09BFmXaL1IBb9fiuvq6/KMiNycSg== + dependencies: + "@types/mdast" "^3.0.0" + unist-util-is "^5.0.0" + +mdast-util-to-hast@^12.1.0: + version "12.3.0" + resolved "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-12.3.0.tgz" + integrity sha512-pits93r8PhnIoU4Vy9bjW39M2jJ6/tdHyja9rrot9uujkN7UTU9SDnE6WNJz/IGyQk3XHX6yNNtrBH6cQzm8Hw== + dependencies: + "@types/hast" "^2.0.0" + "@types/mdast" "^3.0.0" + mdast-util-definitions "^5.0.0" + micromark-util-sanitize-uri "^1.1.0" + trim-lines "^3.0.0" + unist-util-generated "^2.0.0" + unist-util-position "^4.0.0" + unist-util-visit "^4.0.0" + +mdast-util-to-hast@^13.0.0: + version "13.2.0" + resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz#5ca58e5b921cc0a3ded1bc02eed79a4fe4fe41f4" + integrity sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA== + dependencies: + "@types/hast" "^3.0.0" + "@types/mdast" "^4.0.0" + "@ungap/structured-clone" "^1.0.0" + devlop "^1.0.0" + micromark-util-sanitize-uri "^2.0.0" + trim-lines "^3.0.0" + unist-util-position "^5.0.0" + unist-util-visit "^5.0.0" + vfile "^6.0.0" + +mdast-util-to-markdown@^1.0.0, mdast-util-to-markdown@^1.3.0: + version "1.5.0" + resolved "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.5.0.tgz" + integrity sha512-bbv7TPv/WC49thZPg3jXuqzuvI45IL2EVAr/KxF0BSdHsU0ceFHOmwQn6evxAh1GaoK/6GQ1wp4R4oW2+LFL/A== + dependencies: + "@types/mdast" "^3.0.0" + "@types/unist" "^2.0.0" + longest-streak "^3.0.0" + mdast-util-phrasing "^3.0.0" + mdast-util-to-string "^3.0.0" + micromark-util-decode-string "^1.0.0" + unist-util-visit "^4.0.0" + zwitch "^2.0.0" + +mdast-util-to-string@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz" + integrity sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w== + +mdast-util-to-string@^3.0.0, mdast-util-to-string@^3.1.0: + version "3.2.0" + resolved "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz" + integrity sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg== + dependencies: + "@types/mdast" "^3.0.0" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + +memfs@^3.4.1, memfs@^3.4.12: + version "3.6.0" + resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.6.0.tgz#d7a2110f86f79dd950a8b6df6d57bc984aa185f6" + integrity sha512-EGowvkkgbMcIChjMTMkESFDbZeSh8xZ7kNSF0hAiAN4Jh6jgHCRS0Ga/+C8y6Au+oqpezRHCfPsmJ2+DwAgiwQ== + dependencies: + fs-monkey "^1.0.4" + +"memoize-one@>=3.1.1 <6": + version "5.2.1" + resolved "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz" + integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q== + +memoizerific@^1.11.3: + version "1.11.3" + resolved "https://registry.yarnpkg.com/memoizerific/-/memoizerific-1.11.3.tgz#7c87a4646444c32d75438570905f2dbd1b1a805a" + integrity sha512-/EuHYwAPdLtXwAwSZkh/Gutery6pD2KYd44oQLhAvQp/50mpyduZh8Q7PYHXTCJ+wuXxt7oij2LXyIJOOYFPog== + dependencies: + map-or-similar "^1.5.0" + +merge-descriptors@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.3.tgz#d80319a65f3c7935351e5cfdac8f9318504dbed5" + integrity sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ== + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +mermaid@10.4.0: + version "10.4.0" + resolved "https://registry.npmjs.org/mermaid/-/mermaid-10.4.0.tgz" + integrity sha512-4QCQLp79lvz7UZxow5HUX7uWTPJOaQBVExduo91tliXC7v78i6kssZOPHxLL+Xs30KU72cpPn3g3imw/xm/gaw== + dependencies: + "@braintree/sanitize-url" "^6.0.1" + "@types/d3-scale" "^4.0.3" + "@types/d3-scale-chromatic" "^3.0.0" + cytoscape "^3.23.0" + cytoscape-cose-bilkent "^4.1.0" + cytoscape-fcose "^2.1.0" + d3 "^7.4.0" + d3-sankey "^0.12.3" + dagre-d3-es "7.0.10" + dayjs "^1.11.7" + dompurify "^3.0.5" + elkjs "^0.8.2" + khroma "^2.0.0" + lodash-es "^4.17.21" + mdast-util-from-markdown "^1.3.0" + non-layered-tidy-tree-layout "^2.0.2" + stylis "^4.1.3" + ts-dedent "^2.2.0" + uuid "^9.0.0" + web-worker "^1.2.0" + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== + +micromark-core-commonmark@^1.0.0, micromark-core-commonmark@^1.0.1: + version "1.1.0" + resolved "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz" + integrity sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw== + dependencies: + decode-named-character-reference "^1.0.0" + micromark-factory-destination "^1.0.0" + micromark-factory-label "^1.0.0" + micromark-factory-space "^1.0.0" + micromark-factory-title "^1.0.0" + micromark-factory-whitespace "^1.0.0" + micromark-util-character "^1.0.0" + micromark-util-chunked "^1.0.0" + micromark-util-classify-character "^1.0.0" + micromark-util-html-tag-name "^1.0.0" + micromark-util-normalize-identifier "^1.0.0" + micromark-util-resolve-all "^1.0.0" + micromark-util-subtokenize "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.1" + uvu "^0.5.0" + +micromark-extension-gfm-autolink-literal@^1.0.0: + version "1.0.5" + resolved "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-1.0.5.tgz" + integrity sha512-z3wJSLrDf8kRDOh2qBtoTRD53vJ+CWIyo7uyZuxf/JAbNJjiHsOpG1y5wxk8drtv3ETAHutCu6N3thkOOgueWg== + dependencies: + micromark-util-character "^1.0.0" + micromark-util-sanitize-uri "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + +micromark-extension-gfm-footnote@^1.0.0: + version "1.1.2" + resolved "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-1.1.2.tgz" + integrity sha512-Yxn7z7SxgyGWRNa4wzf8AhYYWNrwl5q1Z8ii+CSTTIqVkmGZF1CElX2JI8g5yGoM3GAman9/PVCUFUSJ0kB/8Q== + dependencies: + micromark-core-commonmark "^1.0.0" + micromark-factory-space "^1.0.0" + micromark-util-character "^1.0.0" + micromark-util-normalize-identifier "^1.0.0" + micromark-util-sanitize-uri "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + uvu "^0.5.0" + +micromark-extension-gfm-strikethrough@^1.0.0: + version "1.0.7" + resolved "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-1.0.7.tgz" + integrity sha512-sX0FawVE1o3abGk3vRjOH50L5TTLr3b5XMqnP9YDRb34M0v5OoZhG+OHFz1OffZ9dlwgpTBKaT4XW/AsUVnSDw== + dependencies: + micromark-util-chunked "^1.0.0" + micromark-util-classify-character "^1.0.0" + micromark-util-resolve-all "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + uvu "^0.5.0" + +micromark-extension-gfm-table@^1.0.0: + version "1.0.7" + resolved "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-1.0.7.tgz" + integrity sha512-3ZORTHtcSnMQEKtAOsBQ9/oHp9096pI/UvdPtN7ehKvrmZZ2+bbWhi0ln+I9drmwXMt5boocn6OlwQzNXeVeqw== + dependencies: + micromark-factory-space "^1.0.0" + micromark-util-character "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + uvu "^0.5.0" + +micromark-extension-gfm-tagfilter@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-1.0.2.tgz" + integrity sha512-5XWB9GbAUSHTn8VPU8/1DBXMuKYT5uOgEjJb8gN3mW0PNW5OPHpSdojoqf+iq1xo7vWzw/P8bAHY0n6ijpXF7g== + dependencies: + micromark-util-types "^1.0.0" + +micromark-extension-gfm-task-list-item@^1.0.0: + version "1.0.5" + resolved "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-1.0.5.tgz" + integrity sha512-RMFXl2uQ0pNQy6Lun2YBYT9g9INXtWJULgbt01D/x8/6yJ2qpKyzdZD3pi6UIkzF++Da49xAelVKUeUMqd5eIQ== + dependencies: + micromark-factory-space "^1.0.0" + micromark-util-character "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + uvu "^0.5.0" + +micromark-extension-gfm@^2.0.0: + version "2.0.3" + resolved "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-2.0.3.tgz" + integrity sha512-vb9OoHqrhCmbRidQv/2+Bc6pkP0FrtlhurxZofvOEy5o8RtuuvTq+RQ1Vw5ZDNrVraQZu3HixESqbG+0iKk/MQ== + dependencies: + micromark-extension-gfm-autolink-literal "^1.0.0" + micromark-extension-gfm-footnote "^1.0.0" + micromark-extension-gfm-strikethrough "^1.0.0" + micromark-extension-gfm-table "^1.0.0" + micromark-extension-gfm-tagfilter "^1.0.0" + micromark-extension-gfm-task-list-item "^1.0.0" + micromark-util-combine-extensions "^1.0.0" + micromark-util-types "^1.0.0" + +micromark-extension-math@^2.0.0: + version "2.1.2" + resolved "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-2.1.2.tgz" + integrity sha512-es0CcOV89VNS9wFmyn+wyFTKweXGW4CEvdaAca6SWRWPyYCbBisnjaHLjWO4Nszuiud84jCpkHsqAJoa768Pvg== + dependencies: + "@types/katex" "^0.16.0" + katex "^0.16.0" + micromark-factory-space "^1.0.0" + micromark-util-character "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + uvu "^0.5.0" + +micromark-extension-mdx-expression@^1.0.0: + version "1.0.8" + resolved "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-1.0.8.tgz" + integrity sha512-zZpeQtc5wfWKdzDsHRBY003H2Smg+PUi2REhqgIhdzAa5xonhP03FcXxqFSerFiNUr5AWmHpaNPQTBVOS4lrXw== + dependencies: + "@types/estree" "^1.0.0" + micromark-factory-mdx-expression "^1.0.0" + micromark-factory-space "^1.0.0" + micromark-util-character "^1.0.0" + micromark-util-events-to-acorn "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + uvu "^0.5.0" + +micromark-extension-mdx-jsx@^1.0.0: + version "1.0.5" + resolved "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-1.0.5.tgz" + integrity sha512-gPH+9ZdmDflbu19Xkb8+gheqEDqkSpdCEubQyxuz/Hn8DOXiXvrXeikOoBA71+e8Pfi0/UYmU3wW3H58kr7akA== + dependencies: + "@types/acorn" "^4.0.0" + "@types/estree" "^1.0.0" + estree-util-is-identifier-name "^2.0.0" + micromark-factory-mdx-expression "^1.0.0" + micromark-factory-space "^1.0.0" + micromark-util-character "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + uvu "^0.5.0" + vfile-message "^3.0.0" + +micromark-extension-mdx-md@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-1.0.1.tgz" + integrity sha512-7MSuj2S7xjOQXAjjkbjBsHkMtb+mDGVW6uI2dBL9snOBCbZmoNgDAeZ0nSn9j3T42UE/g2xVNMn18PJxZvkBEA== + dependencies: + micromark-util-types "^1.0.0" + +micromark-extension-mdxjs-esm@^1.0.0: + version "1.0.5" + resolved "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-1.0.5.tgz" + integrity sha512-xNRBw4aoURcyz/S69B19WnZAkWJMxHMT5hE36GtDAyhoyn/8TuAeqjFJQlwk+MKQsUD7b3l7kFX+vlfVWgcX1w== + dependencies: + "@types/estree" "^1.0.0" + micromark-core-commonmark "^1.0.0" + micromark-util-character "^1.0.0" + micromark-util-events-to-acorn "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + unist-util-position-from-estree "^1.1.0" + uvu "^0.5.0" + vfile-message "^3.0.0" + +micromark-extension-mdxjs@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-1.0.1.tgz" + integrity sha512-7YA7hF6i5eKOfFUzZ+0z6avRG52GpWR8DL+kN47y3f2KhxbBZMhmxe7auOeaTBrW2DenbbZTf1ea9tA2hDpC2Q== + dependencies: + acorn "^8.0.0" + acorn-jsx "^5.0.0" + micromark-extension-mdx-expression "^1.0.0" + micromark-extension-mdx-jsx "^1.0.0" + micromark-extension-mdx-md "^1.0.0" + micromark-extension-mdxjs-esm "^1.0.0" + micromark-util-combine-extensions "^1.0.0" + micromark-util-types "^1.0.0" + +micromark-factory-destination@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz" + integrity sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg== + dependencies: + micromark-util-character "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + +micromark-factory-label@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz" + integrity sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w== + dependencies: + micromark-util-character "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + uvu "^0.5.0" + +micromark-factory-mdx-expression@^1.0.0: + version "1.0.9" + resolved "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-1.0.9.tgz" + integrity sha512-jGIWzSmNfdnkJq05c7b0+Wv0Kfz3NJ3N4cBjnbO4zjXIlxJr+f8lk+5ZmwFvqdAbUy2q6B5rCY//g0QAAaXDWA== + dependencies: + "@types/estree" "^1.0.0" + micromark-util-character "^1.0.0" + micromark-util-events-to-acorn "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + unist-util-position-from-estree "^1.0.0" + uvu "^0.5.0" + vfile-message "^3.0.0" + +micromark-factory-space@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz" + integrity sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ== + dependencies: + micromark-util-character "^1.0.0" + micromark-util-types "^1.0.0" + +micromark-factory-title@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz" + integrity sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ== + dependencies: + micromark-factory-space "^1.0.0" + micromark-util-character "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + +micromark-factory-whitespace@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz" + integrity sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ== + dependencies: + micromark-factory-space "^1.0.0" + micromark-util-character "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + +micromark-util-character@^1.0.0: + version "1.2.0" + resolved "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz" + integrity sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg== + dependencies: + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + +micromark-util-character@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/micromark-util-character/-/micromark-util-character-2.1.0.tgz#31320ace16b4644316f6bf057531689c71e2aee1" + integrity sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ== + dependencies: + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-util-chunked@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz" + integrity sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ== + dependencies: + micromark-util-symbol "^1.0.0" + +micromark-util-classify-character@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz" + integrity sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw== + dependencies: + micromark-util-character "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + +micromark-util-combine-extensions@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz" + integrity sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA== + dependencies: + micromark-util-chunked "^1.0.0" + micromark-util-types "^1.0.0" + +micromark-util-decode-numeric-character-reference@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz" + integrity sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw== + dependencies: + micromark-util-symbol "^1.0.0" + +micromark-util-decode-string@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz" + integrity sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ== + dependencies: + decode-named-character-reference "^1.0.0" + micromark-util-character "^1.0.0" + micromark-util-decode-numeric-character-reference "^1.0.0" + micromark-util-symbol "^1.0.0" + +micromark-util-encode@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz" + integrity sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw== + +micromark-util-encode@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz#0921ac7953dc3f1fd281e3d1932decfdb9382ab1" + integrity sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA== + +micromark-util-events-to-acorn@^1.0.0: + version "1.2.3" + resolved "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-1.2.3.tgz" + integrity sha512-ij4X7Wuc4fED6UoLWkmo0xJQhsktfNh1J0m8g4PbIMPlx+ek/4YdW5mvbye8z/aZvAPUoxgXHrwVlXAPKMRp1w== + dependencies: + "@types/acorn" "^4.0.0" + "@types/estree" "^1.0.0" + "@types/unist" "^2.0.0" + estree-util-visit "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + uvu "^0.5.0" + vfile-message "^3.0.0" + +micromark-util-html-tag-name@^1.0.0: + version "1.2.0" + resolved "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz" + integrity sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q== + +micromark-util-normalize-identifier@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz" + integrity sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q== + dependencies: + micromark-util-symbol "^1.0.0" + +micromark-util-resolve-all@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz" + integrity sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA== + dependencies: + micromark-util-types "^1.0.0" + +micromark-util-sanitize-uri@^1.0.0, micromark-util-sanitize-uri@^1.1.0: + version "1.2.0" + resolved "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz" + integrity sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A== + dependencies: + micromark-util-character "^1.0.0" + micromark-util-encode "^1.0.0" + micromark-util-symbol "^1.0.0" + +micromark-util-sanitize-uri@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz#ec8fbf0258e9e6d8f13d9e4770f9be64342673de" + integrity sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw== + dependencies: + micromark-util-character "^2.0.0" + micromark-util-encode "^2.0.0" + micromark-util-symbol "^2.0.0" + +micromark-util-subtokenize@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz" + integrity sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A== + dependencies: + micromark-util-chunked "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + uvu "^0.5.0" + +micromark-util-symbol@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz" + integrity sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag== + +micromark-util-symbol@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz#12225c8f95edf8b17254e47080ce0862d5db8044" + integrity sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw== + +micromark-util-types@^1.0.0, micromark-util-types@^1.0.1: + version "1.1.0" + resolved "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz" + integrity sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg== + +micromark-util-types@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/micromark-util-types/-/micromark-util-types-2.0.0.tgz#63b4b7ffeb35d3ecf50d1ca20e68fc7caa36d95e" + integrity sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w== + +micromark@^3.0.0: + version "3.2.0" + resolved "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz" + integrity sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA== + dependencies: + "@types/debug" "^4.0.0" + debug "^4.0.0" + decode-named-character-reference "^1.0.0" + micromark-core-commonmark "^1.0.1" + micromark-factory-space "^1.0.0" + micromark-util-character "^1.0.0" + micromark-util-chunked "^1.0.0" + micromark-util-combine-extensions "^1.0.0" + micromark-util-decode-numeric-character-reference "^1.0.0" + micromark-util-encode "^1.0.0" + micromark-util-normalize-identifier "^1.0.0" + micromark-util-resolve-all "^1.0.0" + micromark-util-sanitize-uri "^1.0.0" + micromark-util-subtokenize "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.1" + uvu "^0.5.0" + +micromark@~2.11.0: + version "2.11.4" + resolved "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz" + integrity sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA== + dependencies: + debug "^4.0.0" + parse-entities "^2.0.0" + +micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5: + version "4.0.8" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" + integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== + dependencies: + braces "^3.0.3" + picomatch "^2.3.1" + +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.12, mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +mimic-fn@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz" + integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== + +mimic-response@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + +min-indent@^1.0.0, min-indent@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz" + integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== + +minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimatch@^9.0.1: + version "9.0.3" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz" + integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== + dependencies: + brace-expansion "^2.0.1" + +minimist@^1.2.0, minimist@^1.2.6: + version "1.2.8" + resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0": + version "7.0.4" + resolved "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz" + integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== + +mkdirp@^0.5.6: + version "0.5.6" + resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== + dependencies: + minimist "^1.2.6" + +mri@^1.1.0: + version "1.2.0" + resolved "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz" + integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA== + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + +ms@2.1.2, ms@^2.1.1: + version "2.1.2" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +mz@^2.7.0: + version "2.7.0" + resolved "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz" + integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== + dependencies: + any-promise "^1.0.0" + object-assign "^4.0.1" + thenify-all "^1.0.0" + +nanoid@^3.3.6: + version "3.3.6" + resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz" + integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== + +nanoid@^3.3.7: + version "3.3.7" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" + integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== + +natural-compare-lite@^1.4.0: + version "1.4.0" + resolved "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz" + integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== + +negotiator@0.6.3, negotiator@^0.6.3: + version "0.6.3" + resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +neo-async@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + +next@^14.1.1: + version "14.2.4" + resolved "https://registry.npmjs.org/next/-/next-14.2.4.tgz" + integrity sha512-R8/V7vugY+822rsQGQCjoLhMuC9oFj9SOi4Cl4b2wjDrseD0LRZ10W7R6Czo4w9ZznVSshKjuIomsRjvm9EKJQ== + dependencies: + "@next/env" "14.2.4" + "@swc/helpers" "0.5.5" + busboy "1.6.0" + caniuse-lite "^1.0.30001579" + graceful-fs "^4.2.11" + postcss "8.4.31" + styled-jsx "5.1.1" + optionalDependencies: + "@next/swc-darwin-arm64" "14.2.4" + "@next/swc-darwin-x64" "14.2.4" + "@next/swc-linux-arm64-gnu" "14.2.4" + "@next/swc-linux-arm64-musl" "14.2.4" + "@next/swc-linux-x64-gnu" "14.2.4" + "@next/swc-linux-x64-musl" "14.2.4" + "@next/swc-win32-arm64-msvc" "14.2.4" + "@next/swc-win32-ia32-msvc" "14.2.4" + "@next/swc-win32-x64-msvc" "14.2.4" + +no-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" + integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg== + dependencies: + lower-case "^2.0.2" + tslib "^2.0.3" + +node-abort-controller@^3.0.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/node-abort-controller/-/node-abort-controller-3.1.1.tgz#a94377e964a9a37ac3976d848cb5c765833b8548" + integrity sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ== + +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== + +node-polyfill-webpack-plugin@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/node-polyfill-webpack-plugin/-/node-polyfill-webpack-plugin-2.0.1.tgz#141d86f177103a8517c71d99b7c6a46edbb1bb58" + integrity sha512-ZUMiCnZkP1LF0Th2caY6J/eKKoA0TefpoVa68m/LQU1I/mE8rGt4fNYGgNuCcK+aG8P8P43nbeJ2RqJMOL/Y1A== + dependencies: + assert "^2.0.0" + browserify-zlib "^0.2.0" + buffer "^6.0.3" + console-browserify "^1.2.0" + constants-browserify "^1.0.0" + crypto-browserify "^3.12.0" + domain-browser "^4.22.0" + events "^3.3.0" + filter-obj "^2.0.2" + https-browserify "^1.0.0" + os-browserify "^0.3.0" + path-browserify "^1.0.1" + process "^0.11.10" + punycode "^2.1.1" + querystring-es3 "^0.2.1" + readable-stream "^4.0.0" + stream-browserify "^3.0.0" + stream-http "^3.2.0" + string_decoder "^1.3.0" + timers-browserify "^2.0.12" + tty-browserify "^0.0.1" + type-fest "^2.14.0" + url "^0.11.0" + util "^0.12.4" + vm-browserify "^1.1.2" + +node-releases@^2.0.14: + version "2.0.14" + resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz" + integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw== + +node-releases@^2.0.18: + version "2.0.18" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.18.tgz#f010e8d35e2fe8d6b2944f03f70213ecedc4ca3f" + integrity sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g== + +non-layered-tidy-tree-layout@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/non-layered-tidy-tree-layout/-/non-layered-tidy-tree-layout-2.0.2.tgz" + integrity sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw== + +normalize-package-data@^2.5.0: + version "2.5.0" + resolved "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +normalize-range@^0.1.2: + version "0.1.2" + resolved "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz" + integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== + +normalize-url@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" + integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== + +normalize-wheel@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/normalize-wheel/-/normalize-wheel-1.0.1.tgz#aec886affdb045070d856447df62ecf86146ec45" + integrity sha512-1OnlAPZ3zgrk8B91HyRj+eVv+kS5u+Z0SCsak6Xil/kmgEia50ga7zfkumayonZrImffAxPU/5WcyGhzetHNPA== + +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +npm-run-path@^5.1.0: + version "5.1.0" + resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz" + integrity sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q== + dependencies: + path-key "^4.0.0" + +nth-check@^2.0.1: + version "2.1.1" + resolved "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz" + integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== + dependencies: + boolbase "^1.0.0" + +nwsapi@^2.2.2: + version "2.2.12" + resolved "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.12.tgz#fb6af5c0ec35b27b4581eb3bbad34ec9e5c696f8" + integrity sha512-qXDmcVlZV4XRtKFzddidpfVP4oMSGhga+xdMc25mv8kaLUHtgzCDhUxkrN8exkGdTlLNaXj7CV3GtON7zuGZ+w== + +object-assign@^4.0.1, object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + +object-hash@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz" + integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== + +object-inspect@^1.12.3, object-inspect@^1.13.1, object-inspect@^1.9.0: + version "1.13.1" + resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz" + integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== + +object-is@^1.1.5: + version "1.1.5" + resolved "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz" + integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + +object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object.assign@^4.1.3, object.assign@^4.1.4: + version "4.1.4" + resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz" + integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + has-symbols "^1.0.3" + object-keys "^1.1.1" + +object.entries@^1.1.6: + version "1.1.6" + resolved "https://registry.npmjs.org/object.entries/-/object.entries-1.1.6.tgz" + integrity sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.4" + +object.fromentries@^2.0.6, object.fromentries@^2.0.7: + version "2.0.7" + resolved "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz" + integrity sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + +object.groupby@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.1.tgz" + integrity sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + get-intrinsic "^1.2.1" + +object.hasown@^1.1.2: + version "1.1.3" + resolved "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.3.tgz" + integrity sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA== + dependencies: + define-properties "^1.2.0" + es-abstract "^1.22.1" + +object.values@^1.1.6, object.values@^1.1.7: + version "1.1.7" + resolved "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz" + integrity sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + +objectorarray@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/objectorarray/-/objectorarray-1.0.5.tgz#2c05248bbefabd8f43ad13b41085951aac5e68a5" + integrity sha512-eJJDYkhJFFbBBAxeh8xW+weHlkI28n2ZdQV/J/DNfWfSKlGEf2xcfAbZTv3riEXHAhL9SVOTs2pRmXiSTf78xg== + +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +onetime@^5.1.0, onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +onetime@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz" + integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ== + dependencies: + mimic-fn "^4.0.0" + +open@^8.0.4: + version "8.4.2" + resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" + integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== + dependencies: + define-lazy-prop "^2.0.0" + is-docker "^2.1.1" + is-wsl "^2.2.0" + +open@^9.1.0: + version "9.1.0" + resolved "https://registry.npmjs.org/open/-/open-9.1.0.tgz" + integrity sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg== + dependencies: + default-browser "^4.0.0" + define-lazy-prop "^3.0.0" + is-inside-container "^1.0.0" + is-wsl "^2.2.0" + +optionator@^0.9.1: + version "0.9.1" + resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz" + integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== + dependencies: + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + word-wrap "^1.2.3" + +os-browserify@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" + integrity sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A== + +p-cancelable@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf" + integrity sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg== + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-limit@^3.0.2, p-limit@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-limit@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-4.0.0.tgz#914af6544ed32bfa54670b061cafcbd04984b644" + integrity sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ== + dependencies: + yocto-queue "^1.0.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +p-locate@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-6.0.0.tgz#3da9a49d4934b901089dca3302fa65dc5a05c04f" + integrity sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw== + dependencies: + p-limit "^4.0.0" + +p-map@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz" + integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== + dependencies: + aggregate-error "^3.0.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +pako@~1.0.5: + version "1.0.11" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== + +papaparse@^5.3.1: + version "5.4.1" + resolved "https://registry.npmjs.org/papaparse/-/papaparse-5.4.1.tgz" + integrity sha512-HipMsgJkZu8br23pW15uvo6sib6wne/4woLZPlFf3rpDyMe9ywEXUsuD7+6K9PRkJlVT51j/sCOYDKGGS3ZJrw== + +param-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5" + integrity sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A== + dependencies: + dot-case "^3.0.4" + tslib "^2.0.3" + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +parse-asn1@^5.0.0, parse-asn1@^5.1.7: + version "5.1.7" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.7.tgz#73cdaaa822125f9647165625eb45f8a051d2df06" + integrity sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg== + dependencies: + asn1.js "^4.10.1" + browserify-aes "^1.2.0" + evp_bytestokey "^1.0.3" + hash-base "~3.0" + pbkdf2 "^3.1.2" + safe-buffer "^5.2.1" + +parse-entities@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz" + integrity sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ== + dependencies: + character-entities "^1.0.0" + character-entities-legacy "^1.0.0" + character-reference-invalid "^1.0.0" + is-alphanumerical "^1.0.0" + is-decimal "^1.0.0" + is-hexadecimal "^1.0.0" + +parse-entities@^4.0.0: + version "4.0.1" + resolved "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.1.tgz" + integrity sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w== + dependencies: + "@types/unist" "^2.0.0" + character-entities "^2.0.0" + character-entities-legacy "^3.0.0" + character-reference-invalid "^2.0.0" + decode-named-character-reference "^1.0.0" + is-alphanumerical "^2.0.0" + is-decimal "^2.0.0" + is-hexadecimal "^2.0.0" + +parse-json@^5.0.0, parse-json@^5.2.0: + version "5.2.0" + resolved "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + +parse5@^7.0.0, parse5@^7.1.1: + version "7.1.2" + resolved "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz" + integrity sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw== + dependencies: + entities "^4.4.0" + +parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +pascal-case@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.2.tgz#b48e0ef2b98e205e7c1dae747d0b1508237660eb" + integrity sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g== + dependencies: + no-case "^3.0.4" + tslib "^2.0.3" + +path-browserify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" + integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-exists@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-5.0.0.tgz#a6aad9489200b21fab31e49cf09277e5116fb9e7" + integrity sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-key@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz" + integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-scurry@^1.10.1: + version "1.10.1" + resolved "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz" + integrity sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ== + dependencies: + lru-cache "^9.1.1 || ^10.0.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + +path-to-regexp@0.1.10: + version "0.1.10" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.10.tgz#67e9108c5c0551b9e5326064387de4763c4d5f8b" + integrity sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w== + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +pathval@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pathval/-/pathval-2.0.0.tgz#7e2550b422601d4f6b8e26f1301bc8f15a741a25" + integrity sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA== + +pbkdf2@^3.0.3, pbkdf2@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" + integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +periscopic@^3.0.0: + version "3.1.0" + resolved "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz" + integrity sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw== + dependencies: + "@types/estree" "^1.0.0" + estree-walker "^3.0.0" + is-reference "^3.0.0" + +picocolors@^1.0.0, picocolors@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz" + integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew== + +picocolors@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" + integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pidtree@^0.6.0: + version "0.6.0" + resolved "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz" + integrity sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g== + +pify@^2.3.0: + version "2.3.0" + resolved "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz" + integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== + +pinyin-pro@^3.23.0: + version "3.23.0" + resolved "https://registry.npmjs.org/pinyin-pro/-/pinyin-pro-3.23.0.tgz" + integrity sha512-YDwKw31PPxsr1RQzDMmHuv4Z3exaTHrVQNdVgolyhoIrsRuM3QhsoAtzYPXIaVxb5MyWCSIiEbkwvXMfy1imNA== + +pirates@^4.0.1: + version "4.0.5" + resolved "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz" + integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== + +pirates@^4.0.4: + version "4.0.6" + resolved "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" + integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== + +pkg-dir@^4.1.0, pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +pkg-dir@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-7.0.0.tgz#8f0c08d6df4476756c5ff29b3282d0bab7517d11" + integrity sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA== + dependencies: + find-up "^6.3.0" + +pluralize@^8.0.0: + version "8.0.0" + resolved "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz" + integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA== + +pnp-webpack-plugin@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.7.0.tgz#65741384f6d8056f36e2255a8d67ffc20866f5c9" + integrity sha512-2Rb3vm+EXble/sMXNSu6eoBx8e79gKqhNq9F5ZWW6ERNCTE/Q0wQNne5541tE5vKjfM8hpNCYL+LGc1YTfI0dg== + dependencies: + ts-pnp "^1.1.6" + +polished@^4.2.2: + version "4.3.1" + resolved "https://registry.yarnpkg.com/polished/-/polished-4.3.1.tgz#5a00ae32715609f83d89f6f31d0f0261c6170548" + integrity sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA== + dependencies: + "@babel/runtime" "^7.17.8" + +portfinder@^1.0.28: + version "1.0.32" + resolved "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz" + integrity sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg== + dependencies: + async "^2.6.4" + debug "^3.2.7" + mkdirp "^0.5.6" + +possible-typed-array-names@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz#89bb63c6fada2c3e90adc4a647beeeb39cc7bf8f" + integrity sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q== + +postcss-import@^15.1.0: + version "15.1.0" + resolved "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz" + integrity sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew== + dependencies: + postcss-value-parser "^4.0.0" + read-cache "^1.0.0" + resolve "^1.1.7" + +postcss-js@^4.0.1: + version "4.0.1" + resolved "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz" + integrity sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw== + dependencies: + camelcase-css "^2.0.1" + +postcss-load-config@^4.0.1: + version "4.0.1" + resolved "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.1.tgz" + integrity sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA== + dependencies: + lilconfig "^2.0.5" + yaml "^2.1.1" + +postcss-loader@^8.1.1: + version "8.1.1" + resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-8.1.1.tgz#2822589e7522927344954acb55bbf26e8b195dfe" + integrity sha512-0IeqyAsG6tYiDRCYKQJLAmgQr47DX6N7sFSWvQxt6AcupX8DIdmykuk/o/tx0Lze3ErGHJEp5OSRxrelC6+NdQ== + dependencies: + cosmiconfig "^9.0.0" + jiti "^1.20.0" + semver "^7.5.4" + +postcss-modules-extract-imports@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz#b4497cb85a9c0c4b5aabeb759bb25e8d89f15002" + integrity sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q== + +postcss-modules-local-by-default@^4.0.5: + version "4.0.5" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz#f1b9bd757a8edf4d8556e8d0f4f894260e3df78f" + integrity sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw== + dependencies: + icss-utils "^5.0.0" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.1.0" + +postcss-modules-scope@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz#a43d28289a169ce2c15c00c4e64c0858e43457d5" + integrity sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ== + dependencies: + postcss-selector-parser "^6.0.4" + +postcss-modules-values@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" + integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ== + dependencies: + icss-utils "^5.0.0" + +postcss-nested@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz" + integrity sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ== + dependencies: + postcss-selector-parser "^6.0.11" + +postcss-selector-parser@6.0.10, postcss-selector-parser@^6.0.9: + version "6.0.10" + resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz" + integrity sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + +postcss-selector-parser@^6.0.11: + version "6.0.13" + resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz" + integrity sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + +postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: + version "6.1.2" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz#27ecb41fb0e3b6ba7a1ec84fff347f734c7929de" + integrity sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + +postcss-value-parser@^4.0.0, postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: + version "4.2.0" + resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz" + integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== + +postcss@8.4.31, postcss@^8.4.23, postcss@^8.4.31: + version "8.4.31" + resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz" + integrity sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ== + dependencies: + nanoid "^3.3.6" + picocolors "^1.0.0" + source-map-js "^1.0.2" + +postcss@^8.2.14, postcss@^8.4.33, postcss@^8.4.38: + version "8.4.47" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.47.tgz#5bf6c9a010f3e724c503bf03ef7947dcb0fea365" + integrity sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ== + dependencies: + nanoid "^3.3.7" + picocolors "^1.1.0" + source-map-js "^1.2.1" + +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + +pretty-error@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-4.0.0.tgz#90a703f46dd7234adb46d0f84823e9d1cb8f10d6" + integrity sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw== + dependencies: + lodash "^4.17.20" + renderkid "^3.0.0" + +pretty-format@^27.0.2: + version "27.5.1" + resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e" + integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ== + dependencies: + ansi-regex "^5.0.1" + ansi-styles "^5.0.0" + react-is "^17.0.1" + +pretty-format@^29.0.0, pretty-format@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812" + integrity sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ== + dependencies: + "@jest/schemas" "^29.6.3" + ansi-styles "^5.0.0" + react-is "^18.0.0" + +prismjs@^1.27.0: + version "1.29.0" + resolved "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz" + integrity sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q== + +prismjs@~1.27.0: + version "1.27.0" + resolved "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz" + integrity sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA== + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== + +prompts@^2.0.1: + version "2.4.2" + resolved "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" + integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== + dependencies: + kleur "^3.0.3" + sisteransi "^1.0.5" + +prop-types@^15.0.0, prop-types@^15.5.8, prop-types@^15.7.2, prop-types@^15.8.1: + version "15.8.1" + resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz" + integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.13.1" + +property-information@^5.0.0: + version "5.6.0" + resolved "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz" + integrity sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA== + dependencies: + xtend "^4.0.0" + +property-information@^6.0.0: + version "6.2.0" + resolved "https://registry.npmjs.org/property-information/-/property-information-6.2.0.tgz" + integrity sha512-kma4U7AFCTwpqq5twzC1YVIDXSqg6qQK6JN0smOw8fgRy1OkMi0CYSzFmsy6dnqSenamAtj0CyXMUJ1Mf6oROg== + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +psl@^1.1.33: + version "1.9.0" + resolved "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" + integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== + +public-encrypt@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + safe-buffer "^5.1.2" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ== + +punycode@^2.1.0: + version "2.3.0" + resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz" + integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== + +punycode@^2.1.1: + version "2.3.1" + resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" + integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== + +pure-rand@^6.0.0: + version "6.1.0" + resolved "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz#d173cf23258231976ccbdb05247c9787957604f2" + integrity sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA== + +qrcode.react@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/qrcode.react/-/qrcode.react-3.1.0.tgz" + integrity sha512-oyF+Urr3oAMUG/OiOuONL3HXM+53wvuH3mtIWQrYmsXoAq0DkvZp2RYUWFSMFtbdOpuS++9v+WAkzNVkMlNW6Q== + +qs@6.13.0, qs@^6.12.3: + version "6.13.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.13.0.tgz#6ca3bd58439f7e245655798997787b0d88a51906" + integrity sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg== + dependencies: + side-channel "^1.0.6" + +qs@^6.11.1: + version "6.11.2" + resolved "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz" + integrity sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA== + dependencies: + side-channel "^1.0.4" + +querystring-es3@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + integrity sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA== + +querystringify@^2.1.1: + version "2.2.0" + resolved "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" + integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +queue@6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/queue/-/queue-6.0.2.tgz#b91525283e2315c7553d2efa18d83e76432fed65" + integrity sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA== + dependencies: + inherits "~2.0.3" + +quick-lru@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" + integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== + +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +randomfill@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + +range-parser@^1.2.1, range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.5.2: + version "2.5.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" + integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +rc-input@~1.3.5: + version "1.3.6" + resolved "https://registry.npmjs.org/rc-input/-/rc-input-1.3.6.tgz" + integrity sha512-/HjTaKi8/Ts4zNbYaB5oWCquxFyFQO4Co1MnMgoCeGJlpe7k8Eir2HN0a0F9IHDmmo+GYiGgPpz7w/d/krzsJA== + dependencies: + "@babel/runtime" "^7.11.1" + classnames "^2.2.1" + rc-util "^5.18.1" + +rc-resize-observer@^1.0.0: + version "1.4.0" + resolved "https://registry.npmjs.org/rc-resize-observer/-/rc-resize-observer-1.4.0.tgz" + integrity sha512-PnMVyRid9JLxFavTjeDXEXo65HCRqbmLBw9xX9gfC4BZiSzbLXKzW3jPz+J0P71pLbD5tBMTT+mkstV5gD0c9Q== + dependencies: + "@babel/runtime" "^7.20.7" + classnames "^2.2.1" + rc-util "^5.38.0" + resize-observer-polyfill "^1.5.1" + +rc-textarea@^1.5.2: + version "1.5.2" + resolved "https://registry.npmjs.org/rc-textarea/-/rc-textarea-1.5.2.tgz" + integrity sha512-VVwKYtkp5whZVhP+llX8zM8TtI3dv+BDA0FUbmBMGLaW/tuBJ7Yh35yPabO63V+Bi68xv17eI4hy+/4p2G0gFg== + dependencies: + "@babel/runtime" "^7.10.1" + classnames "^2.2.1" + rc-input "~1.3.5" + rc-resize-observer "^1.0.0" + rc-util "^5.27.0" + +rc-util@^5.18.1, rc-util@^5.27.0, rc-util@^5.38.0: + version "5.38.1" + resolved "https://registry.npmjs.org/rc-util/-/rc-util-5.38.1.tgz" + integrity sha512-e4ZMs7q9XqwTuhIK7zBIVFltUtMSjphuPPQXHoHlzRzNdOwUxDejo0Zls5HYaJfRKNURcsS/ceKVULlhjBrxng== + dependencies: + "@babel/runtime" "^7.18.3" + react-is "^18.2.0" + +react-18-input-autosize@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/react-18-input-autosize/-/react-18-input-autosize-3.0.0.tgz" + integrity sha512-7tsUc9PJWg6Vsp8qYuzlKKBf7hbCoTBdNfjYZSprEPbxf3meuhjklg9QPBe9rIyoR3uDAzmG7NpoJ1+kP5ns+w== + dependencies: + prop-types "^15.5.8" + +react-colorful@^5.1.2: + version "5.6.1" + resolved "https://registry.yarnpkg.com/react-colorful/-/react-colorful-5.6.1.tgz#7dc2aed2d7c72fac89694e834d179e32f3da563b" + integrity sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw== + +react-confetti@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/react-confetti/-/react-confetti-6.1.0.tgz#03dc4340d955acd10b174dbf301f374a06e29ce6" + integrity sha512-7Ypx4vz0+g8ECVxr88W9zhcQpbeujJAVqL14ZnXJ3I23mOI9/oBVTQ3dkJhUmB0D6XOtCZEM6N0Gm9PMngkORw== + dependencies: + tween-functions "^1.2.0" + +react-docgen-typescript@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/react-docgen-typescript/-/react-docgen-typescript-2.2.2.tgz#4611055e569edc071204aadb20e1c93e1ab1659c" + integrity sha512-tvg2ZtOpOi6QDwsb3GZhOjDkkX0h8Z2gipvTg6OVMUyoYoURhEiRNePT8NZItTVCDh39JJHnLdfCOkzoLbFnTg== + +react-docgen@^7.0.0: + version "7.0.3" + resolved "https://registry.yarnpkg.com/react-docgen/-/react-docgen-7.0.3.tgz#f811b785f07b1f2023cb899b6bcf9d522b21b95d" + integrity sha512-i8aF1nyKInZnANZ4uZrH49qn1paRgBZ7wZiCNBMnenlPzEv0mRl+ShpTVEI6wZNl8sSc79xZkivtgLKQArcanQ== + dependencies: + "@babel/core" "^7.18.9" + "@babel/traverse" "^7.18.9" + "@babel/types" "^7.18.9" + "@types/babel__core" "^7.18.0" + "@types/babel__traverse" "^7.18.0" + "@types/doctrine" "^0.0.9" + "@types/resolve" "^1.20.2" + doctrine "^3.0.0" + resolve "^1.22.1" + strip-indent "^4.0.0" + +"react-dom@^16.8.0 || ^17.0.0 || ^18.0.0": + version "18.3.1" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.3.1.tgz#c2265d79511b57d479b3dd3fdfa51536494c5cb4" + integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw== + dependencies: + loose-envify "^1.1.0" + scheduler "^0.23.2" + +react-dom@~18.2.0: + version "18.2.0" + resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz" + integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== + dependencies: + loose-envify "^1.1.0" + scheduler "^0.23.0" + +react-easy-crop@^5.0.8: + version "5.0.8" + resolved "https://registry.yarnpkg.com/react-easy-crop/-/react-easy-crop-5.0.8.tgz#6cf5be061c0ec6dc0c6ee7413974c34e35bf7475" + integrity sha512-KjulxXhR5iM7+ATN2sGCum/IyDxGw7xT0dFoGcqUP+ysaPU5Ka7gnrDa2tUHFHUoMNyPrVZ05QA+uvMgC5ym/g== + dependencies: + normalize-wheel "^1.0.1" + tslib "^2.0.1" + +react-element-to-jsx-string@^15.0.0: + version "15.0.0" + resolved "https://registry.yarnpkg.com/react-element-to-jsx-string/-/react-element-to-jsx-string-15.0.0.tgz#1cafd5b6ad41946ffc8755e254da3fc752a01ac6" + integrity sha512-UDg4lXB6BzlobN60P8fHWVPX3Kyw8ORrTeBtClmIlGdkOOE+GYQSFvmEU5iLLpwp/6v42DINwNcwOhOLfQ//FQ== + dependencies: + "@base2/pretty-print-object" "1.0.1" + is-plain-object "5.0.0" + react-is "18.1.0" + +react-error-boundary@^3.1.4: + version "3.1.4" + resolved "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-3.1.4.tgz" + integrity sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA== + dependencies: + "@babel/runtime" "^7.12.5" + +react-error-boundary@^4.0.2: + version "4.0.9" + resolved "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-4.0.9.tgz" + integrity sha512-f6DcHVdTDZmc9ixmRmuLDZpkdghYR/HKZdUzMLHD58s4cR2C4R6y4ktYztCosM6pyeK4/C8IofwqxgID25W6kw== + dependencies: + "@babel/runtime" "^7.12.5" + +react-headless-pagination@^1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/react-headless-pagination/-/react-headless-pagination-1.1.4.tgz" + integrity sha512-Z5d55g3gM2BQMvHJUGm1jbbQ5Bgtq54kNlI5ca1NTwdVR8ZNunN0EdOtNKNobsFRKuZGkQ24VTIu6ulNq190Iw== + dependencies: + classnames "2.3.1" + +react-hook-form@^7.51.4: + version "7.51.4" + resolved "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.51.4.tgz" + integrity sha512-V14i8SEkh+V1gs6YtD0hdHYnoL4tp/HX/A45wWQN15CYr9bFRmmRdYStSO5L65lCCZRF+kYiSKhm9alqbcdiVA== + +react-i18next@^12.2.0: + version "12.3.1" + resolved "https://registry.npmjs.org/react-i18next/-/react-i18next-12.3.1.tgz" + integrity sha512-5v8E2XjZDFzK7K87eSwC7AJcAkcLt5xYZ4+yTPDAW1i7C93oOY1dnr4BaQM7un4Hm+GmghuiPvevWwlca5PwDA== + dependencies: + "@babel/runtime" "^7.20.6" + html-parse-stringify "^3.0.1" + +react-infinite-scroll-component@^6.1.0: + version "6.1.0" + resolved "https://registry.npmjs.org/react-infinite-scroll-component/-/react-infinite-scroll-component-6.1.0.tgz" + integrity sha512-SQu5nCqy8DxQWpnUVLx7V7b7LcA37aM7tvoWjTLZp1dk6EJibM5/4EJKzOnl07/BsM1Y40sKLuqjCwwH/xV0TQ== + dependencies: + throttle-debounce "^2.1.0" + +react-is@18.1.0: + version "18.1.0" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.1.0.tgz#61aaed3096d30eacf2a2127118b5b41387d32a67" + integrity sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg== + +react-is@^16.13.1, react-is@^16.7.0: + version "16.13.1" + resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + +react-is@^17.0.1: + version "17.0.2" + resolved "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" + integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== + +react-is@^18.0.0, react-is@^18.2.0: + version "18.2.0" + resolved "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz" + integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== + +react-markdown@^8.0.6: + version "8.0.7" + resolved "https://registry.npmjs.org/react-markdown/-/react-markdown-8.0.7.tgz" + integrity sha512-bvWbzG4MtOU62XqBx3Xx+zB2raaFFsq4mYiAzfjXJMEz2sixgeAfraA3tvzULF02ZdOMUOKTBFFaZJDDrq+BJQ== + dependencies: + "@types/hast" "^2.0.0" + "@types/prop-types" "^15.0.0" + "@types/unist" "^2.0.0" + comma-separated-tokens "^2.0.0" + hast-util-whitespace "^2.0.0" + prop-types "^15.0.0" + property-information "^6.0.0" + react-is "^18.0.0" + remark-parse "^10.0.0" + remark-rehype "^10.0.0" + space-separated-tokens "^2.0.0" + style-to-object "^0.4.0" + unified "^10.0.0" + unist-util-visit "^4.0.0" + vfile "^5.0.0" + +react-multi-email@^1.0.14: + version "1.0.16" + resolved "https://registry.npmjs.org/react-multi-email/-/react-multi-email-1.0.16.tgz" + integrity sha512-dgg4TY3P5FWz6c4ghgxH1bjZOgYL3S/HN+EUNe6dqHbLMVzeyud1ztDUlqvft4NX1sUxKx2IF2zDq1yAJQA5yQ== + +react-papaparse@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/react-papaparse/-/react-papaparse-4.1.0.tgz" + integrity sha512-sGJqK+OE2rVVQPxQUCCDW2prLIglv9kTdizhNe2awXvKo0gLShmhpRN3BwA+ujw5M2gSJ/KGNEwtgII0OsLgkg== + dependencies: + "@types/papaparse" "^5.3.1" + papaparse "^5.3.1" + +react-refresh@^0.14.0: + version "0.14.2" + resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.2.tgz#3833da01ce32da470f1f936b9d477da5c7028bf9" + integrity sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA== + +react-slider@^2.0.4: + version "2.0.5" + resolved "https://registry.npmjs.org/react-slider/-/react-slider-2.0.5.tgz" + integrity sha512-MU5gaK1yYCKnbDDN3CMiVcgkKZwMvdqK2xUEW7fFU37NAzRgS1FZbF9N7vP08E3XXNVhiuZnwVzUa3PYQAZIMg== + dependencies: + prop-types "^15.8.1" + +react-sortablejs@^6.1.4: + version "6.1.4" + resolved "https://registry.npmjs.org/react-sortablejs/-/react-sortablejs-6.1.4.tgz" + integrity sha512-fc7cBosfhnbh53Mbm6a45W+F735jwZ1UFIYSrIqcO/gRIFoDyZeMtgKlpV4DdyQfbCzdh5LoALLTDRxhMpTyXQ== + dependencies: + classnames "2.3.1" + tiny-invariant "1.2.0" + +react-syntax-highlighter@^15.5.0: + version "15.5.0" + resolved "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.5.0.tgz" + integrity sha512-+zq2myprEnQmH5yw6Gqc8lD55QHnpKaU8TOcFeC/Lg/MQSs8UknEA0JC4nTZGFAXC2J2Hyj/ijJ7NlabyPi2gg== + dependencies: + "@babel/runtime" "^7.3.1" + highlight.js "^10.4.1" + lowlight "^1.17.0" + prismjs "^1.27.0" + refractor "^3.6.0" + +react-tooltip@5.8.3: + version "5.8.3" + resolved "https://registry.npmjs.org/react-tooltip/-/react-tooltip-5.8.3.tgz" + integrity sha512-h7maAlm2Xeymc14gWKhhrzsENeB83N65EzZ+AcQIGrOpNE0yefVRJIHhNcWHEJ0FEtf7VZXxtsj5glVXKxEtvA== + dependencies: + "@floating-ui/dom" "1.1.1" + classnames "^2.3.2" + +react-window-infinite-loader@^1.0.9: + version "1.0.9" + resolved "https://registry.npmjs.org/react-window-infinite-loader/-/react-window-infinite-loader-1.0.9.tgz" + integrity sha512-5Hg89IdU4Vrp0RT8kZYKeTIxWZYhNkVXeI1HbKo01Vm/Z7qztDvXljwx16sMzsa9yapRJQW3ODZfMUw38SOWHw== + +react-window@^1.8.9: + version "1.8.9" + resolved "https://registry.npmjs.org/react-window/-/react-window-1.8.9.tgz" + integrity sha512-+Eqx/fj1Aa5WnhRfj9dJg4VYATGwIUP2ItwItiJ6zboKWA6EX3lYDAXfGF2hyNqplEprhbtjbipiADEcwQ823Q== + dependencies: + "@babel/runtime" "^7.0.0" + memoize-one ">=3.1.1 <6" + +"react@^16.8.0 || ^17.0.0 || ^18.0.0": + version "18.3.1" + resolved "https://registry.yarnpkg.com/react/-/react-18.3.1.tgz#49ab892009c53933625bd16b2533fc754cab2891" + integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== + dependencies: + loose-envify "^1.1.0" + +react@~18.2.0: + version "18.2.0" + resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz" + integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== + dependencies: + loose-envify "^1.1.0" + +reactflow@^11.11.3: + version "11.11.3" + resolved "https://registry.npmjs.org/reactflow/-/reactflow-11.11.3.tgz" + integrity sha512-wusd1Xpn1wgsSEv7UIa4NNraCwH9syBtubBy4xVNXg3b+CDKM+sFaF3hnMx0tr0et4km9urIDdNvwm34QiZong== + dependencies: + "@reactflow/background" "11.3.13" + "@reactflow/controls" "11.2.13" + "@reactflow/core" "11.11.3" + "@reactflow/minimap" "11.7.13" + "@reactflow/node-resizer" "2.2.13" + "@reactflow/node-toolbar" "1.3.13" + +read-cache@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz" + integrity sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA== + dependencies: + pify "^2.3.0" + +read-pkg-up@^7.0.1: + version "7.0.1" + resolved "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz" + integrity sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg== + dependencies: + find-up "^4.1.0" + read-pkg "^5.2.0" + type-fest "^0.8.1" + +read-pkg@^5.2.0: + version "5.2.0" + resolved "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz" + integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg== + dependencies: + "@types/normalize-package-data" "^2.4.0" + normalize-package-data "^2.5.0" + parse-json "^5.0.0" + type-fest "^0.6.0" + +readable-stream@^2.3.8: + version "2.3.8" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" + integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.5.0, readable-stream@^3.6.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readable-stream@^4.0.0: + version "4.5.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-4.5.2.tgz#9e7fc4c45099baeed934bff6eb97ba6cf2729e09" + integrity sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g== + dependencies: + abort-controller "^3.0.0" + buffer "^6.0.3" + events "^3.3.0" + process "^0.11.10" + string_decoder "^1.3.0" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +recast@^0.23.5: + version "0.23.9" + resolved "https://registry.yarnpkg.com/recast/-/recast-0.23.9.tgz#587c5d3a77c2cfcb0c18ccce6da4361528c2587b" + integrity sha512-Hx/BGIbwj+Des3+xy5uAtAbdCyqK9y9wbBcDFDYanLS9JnMqf7OeF87HQwUimE87OEc72mr6tkKUKMBBL+hF9Q== + dependencies: + ast-types "^0.16.1" + esprima "~4.0.0" + source-map "~0.6.1" + tiny-invariant "^1.3.3" + tslib "^2.0.1" + +recordrtc@^5.6.2: + version "5.6.2" + resolved "https://registry.npmjs.org/recordrtc/-/recordrtc-5.6.2.tgz" + integrity sha512-1QNKKNtl7+KcwD1lyOgP3ZlbiJ1d0HtXnypUy7yq49xEERxk31PHvE9RCciDrulPCY7WJ+oz0R9hpNxgsIurGQ== + +redent@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f" + integrity sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg== + dependencies: + indent-string "^4.0.0" + strip-indent "^3.0.0" + +reflect.getprototypeof@^1.0.4: + version "1.0.4" + resolved "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz" + integrity sha512-ECkTw8TmJwW60lOTR+ZkODISW6RQ8+2CL3COqtiJKLd6MmB45hN51HprHFziKLGkAuTGQhBb91V8cy+KHlaCjw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + get-intrinsic "^1.2.1" + globalthis "^1.0.3" + which-builtin-type "^1.1.3" + +refractor@^3.6.0: + version "3.6.0" + resolved "https://registry.npmjs.org/refractor/-/refractor-3.6.0.tgz" + integrity sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA== + dependencies: + hastscript "^6.0.0" + parse-entities "^2.0.0" + prismjs "~1.27.0" + +regenerate-unicode-properties@^10.2.0: + version "10.2.0" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz#626e39df8c372338ea9b8028d1f99dc3fd9c3db0" + integrity sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA== + dependencies: + regenerate "^1.4.2" + +regenerate@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" + integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== + +regenerator-runtime@^0.13.11: + version "0.13.11" + resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz" + integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== + +regenerator-runtime@^0.14.0: + version "0.14.1" + resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" + integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== + +regenerator-transform@^0.15.2: + version "0.15.2" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.2.tgz#5bbae58b522098ebdf09bca2f83838929001c7a4" + integrity sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg== + dependencies: + "@babel/runtime" "^7.8.4" + +regex-parser@^2.2.11: + version "2.3.0" + resolved "https://registry.yarnpkg.com/regex-parser/-/regex-parser-2.3.0.tgz#4bb61461b1a19b8b913f3960364bb57887f920ee" + integrity sha512-TVILVSz2jY5D47F4mA4MppkBrafEaiUWJO/TcZHEIuI13AqoZMkK1WMA4Om1YkYbTx+9Ki1/tSUXbceyr9saRg== + +regexp-tree@^0.1.24, regexp-tree@~0.1.1: + version "0.1.27" + resolved "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz" + integrity sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA== + +regexp.prototype.flags@^1.5.0, regexp.prototype.flags@^1.5.1: + version "1.5.1" + resolved "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz" + integrity sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + set-function-name "^2.0.0" + +regexpp@^3.0.0: + version "3.2.0" + resolved "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz" + integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== + +regexpu-core@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-6.1.1.tgz#b469b245594cb2d088ceebc6369dceb8c00becac" + integrity sha512-k67Nb9jvwJcJmVpw0jPttR1/zVfnKf8Km0IPatrU/zJ5XeG3+Slx0xLXs9HByJSzXzrlz5EDvN6yLNMDc2qdnw== + dependencies: + regenerate "^1.4.2" + regenerate-unicode-properties "^10.2.0" + regjsgen "^0.8.0" + regjsparser "^0.11.0" + unicode-match-property-ecmascript "^2.0.0" + unicode-match-property-value-ecmascript "^2.1.0" + +regjsgen@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.8.0.tgz#df23ff26e0c5b300a6470cad160a9d090c3a37ab" + integrity sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q== + +regjsparser@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.11.1.tgz#ae55c74f646db0c8fcb922d4da635e33da405149" + integrity sha512-1DHODs4B8p/mQHU9kr+jv8+wIC9mtG4eBHxWxIq5mhjE3D5oORhCc6deRKzTjs9DcfRFmj9BHSDguZklqCGFWQ== + dependencies: + jsesc "~3.0.2" + +regjsparser@^0.9.1: + version "0.9.1" + resolved "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz" + integrity sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ== + dependencies: + jsesc "~0.5.0" + +rehype-external-links@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/rehype-external-links/-/rehype-external-links-3.0.0.tgz#2b28b5cda1932f83f045b6f80a3e1b15f168c6f6" + integrity sha512-yp+e5N9V3C6bwBeAC4n796kc86M4gJCdlVhiMTxIrJG5UHDMh+PJANf9heqORJbt1nrCbDwIlAZKjANIaVBbvw== + dependencies: + "@types/hast" "^3.0.0" + "@ungap/structured-clone" "^1.0.0" + hast-util-is-element "^3.0.0" + is-absolute-url "^4.0.0" + space-separated-tokens "^2.0.0" + unist-util-visit "^5.0.0" + +rehype-katex@^6.0.2: + version "6.0.3" + resolved "https://registry.npmjs.org/rehype-katex/-/rehype-katex-6.0.3.tgz" + integrity sha512-ByZlRwRUcWegNbF70CVRm2h/7xy7jQ3R9LaY4VVSvjnoVWwWVhNL60DiZsBpC5tSzYQOCvDbzncIpIjPZWodZA== + dependencies: + "@types/hast" "^2.0.0" + "@types/katex" "^0.14.0" + hast-util-from-html-isomorphic "^1.0.0" + hast-util-to-text "^3.1.0" + katex "^0.16.0" + unist-util-visit "^4.0.0" + +rehype-raw@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/rehype-raw/-/rehype-raw-7.0.0.tgz#59d7348fd5dbef3807bbaa1d443efd2dd85ecee4" + integrity sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww== + dependencies: + "@types/hast" "^3.0.0" + hast-util-raw "^9.0.0" + vfile "^6.0.0" + +rehype-slug@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/rehype-slug/-/rehype-slug-6.0.0.tgz#1d21cf7fc8a83ef874d873c15e6adaee6344eaf1" + integrity sha512-lWyvf/jwu+oS5+hL5eClVd3hNdmwM1kAC0BUvEGD19pajQMIzcNUd/k9GsfQ+FfECvX+JE+e9/btsKH0EjJT6A== + dependencies: + "@types/hast" "^3.0.0" + github-slugger "^2.0.0" + hast-util-heading-rank "^3.0.0" + hast-util-to-string "^3.0.0" + unist-util-visit "^5.0.0" + +relateurl@^0.2.7: + version "0.2.7" + resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" + integrity sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog== + +remark-breaks@^3.0.2: + version "3.0.3" + resolved "https://registry.npmjs.org/remark-breaks/-/remark-breaks-3.0.3.tgz" + integrity sha512-C7VkvcUp1TPUc2eAYzsPdaUh8Xj4FSbQnYA5A9f80diApLZscTDeG7efiWP65W8hV2sEy3JuGVU0i6qr5D8Hug== + dependencies: + "@types/mdast" "^3.0.0" + mdast-util-newline-to-break "^1.0.0" + unified "^10.0.0" + +remark-gfm@^3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/remark-gfm/-/remark-gfm-3.0.1.tgz" + integrity sha512-lEFDoi2PICJyNrACFOfDD3JlLkuSbOa5Wd8EPt06HUdptv8Gn0bxYTdbU/XXQ3swAPkEaGxxPN9cbnMHvVu1Ig== + dependencies: + "@types/mdast" "^3.0.0" + mdast-util-gfm "^2.0.0" + micromark-extension-gfm "^2.0.0" + unified "^10.0.0" + +remark-math@^5.1.1: + version "5.1.1" + resolved "https://registry.npmjs.org/remark-math/-/remark-math-5.1.1.tgz" + integrity sha512-cE5T2R/xLVtfFI4cCePtiRn+e6jKMtFDR3P8V3qpv8wpKjwvHoBA4eJzvX+nVrnlNy0911bdGmuspCSwetfYHw== + dependencies: + "@types/mdast" "^3.0.0" + mdast-util-math "^2.0.0" + micromark-extension-math "^2.0.0" + unified "^10.0.0" + +remark-mdx@^2.0.0: + version "2.3.0" + resolved "https://registry.npmjs.org/remark-mdx/-/remark-mdx-2.3.0.tgz" + integrity sha512-g53hMkpM0I98MU266IzDFMrTD980gNF3BJnkyFcmN+dD873mQeD5rdMO3Y2X+x8umQfbSE0PcoEDl7ledSA+2g== + dependencies: + mdast-util-mdx "^2.0.0" + micromark-extension-mdxjs "^1.0.0" + +remark-parse@^10.0.0: + version "10.0.2" + resolved "https://registry.npmjs.org/remark-parse/-/remark-parse-10.0.2.tgz" + integrity sha512-3ydxgHa/ZQzG8LvC7jTXccARYDcRld3VfcgIIFs7bI6vbRSxJJmzgLEIIoYKyrfhaY+ujuWaf/PJiMZXoiCXgw== + dependencies: + "@types/mdast" "^3.0.0" + mdast-util-from-markdown "^1.0.0" + unified "^10.0.0" + +remark-rehype@^10.0.0: + version "10.1.0" + resolved "https://registry.npmjs.org/remark-rehype/-/remark-rehype-10.1.0.tgz" + integrity sha512-EFmR5zppdBp0WQeDVZ/b66CWJipB2q2VLNFMabzDSGR66Z2fQii83G5gTBbgGEnEEA0QRussvrFHxk1HWGJskw== + dependencies: + "@types/hast" "^2.0.0" + "@types/mdast" "^3.0.0" + mdast-util-to-hast "^12.1.0" + unified "^10.0.0" + +renderkid@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-3.0.0.tgz#5fd823e4d6951d37358ecc9a58b1f06836b6268a" + integrity sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg== + dependencies: + css-select "^4.1.3" + dom-converter "^0.2.0" + htmlparser2 "^6.1.0" + lodash "^4.17.21" + strip-ansi "^6.0.1" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + +requireindex@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/requireindex/-/requireindex-1.2.0.tgz#3463cdb22ee151902635aa6c9535d4de9c2ef1ef" + integrity sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww== + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== + +resize-observer-polyfill@^1.5.1: + version "1.5.1" + resolved "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz" + integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg== + +resolve-alpn@^1.0.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9" + integrity sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g== + +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve-pkg-maps@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz" + integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw== + +resolve-url-loader@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-5.0.0.tgz#ee3142fb1f1e0d9db9524d539cfa166e9314f795" + integrity sha512-uZtduh8/8srhBoMx//5bwqjQ+rfYOUq8zC9NrMUGtjBiGTtFJM42s58/36+hTqeqINcnYe08Nj3LkK9lW4N8Xg== + dependencies: + adjust-sourcemap-loader "^4.0.0" + convert-source-map "^1.7.0" + loader-utils "^2.0.0" + postcss "^8.2.14" + source-map "0.6.1" + +resolve.exports@^2.0.0: + version "2.0.2" + resolved "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz#f8c934b8e6a13f539e38b7098e2e36134f01e800" + integrity sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg== + +resolve@^1.1.7, resolve@^1.10.0, resolve@^1.14.2, resolve@^1.20.0, resolve@^1.22.1, resolve@^1.22.2, resolve@^1.22.4, resolve@^1.22.8: + version "1.22.8" + resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz" + integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +resolve@^2.0.0-next.4: + version "2.0.0-next.5" + resolved "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz" + integrity sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +responselike@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.1.tgz#9a0bc8fdc252f3fb1cca68b016591059ba1422bc" + integrity sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw== + dependencies: + lowercase-keys "^2.0.0" + +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rfdc@^1.3.0: + version "1.3.0" + resolved "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz" + integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +robust-predicates@^3.0.0: + version "3.0.2" + resolved "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz" + integrity sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg== + +run-applescript@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/run-applescript/-/run-applescript-5.0.0.tgz" + integrity sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg== + dependencies: + execa "^5.0.0" + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +rw@1: + version "1.3.3" + resolved "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz" + integrity sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ== + +rxjs@^7.8.0: + version "7.8.1" + resolved "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz" + integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== + dependencies: + tslib "^2.1.0" + +sade@^1.7.3: + version "1.8.1" + resolved "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz" + integrity sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A== + dependencies: + mri "^1.1.0" + +safe-array-concat@^1.0.1: + version "1.1.0" + resolved "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.0.tgz" + integrity sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg== + dependencies: + call-bind "^1.0.5" + get-intrinsic "^1.2.2" + has-symbols "^1.0.3" + isarray "^2.0.5" + +safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@^5.2.1, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-regex-test@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz" + integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.3" + is-regex "^1.1.4" + +safe-regex@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz" + integrity sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A== + dependencies: + regexp-tree "~0.1.1" + +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": + version "2.1.2" + resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sass-loader@^13.2.0: + version "13.3.3" + resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-13.3.3.tgz#60df5e858788cffb1a3215e5b92e9cba61e7e133" + integrity sha512-mt5YN2F1MOZr3d/wBRcZxeFgwgkH44wVc2zohO2YF6JiOMkiXe4BYRZpSu2sO1g71mo/j16txzUhsKZlqjVGzA== + dependencies: + neo-async "^2.6.2" + +sass@^1.61.0: + version "1.62.1" + resolved "https://registry.npmjs.org/sass/-/sass-1.62.1.tgz" + integrity sha512-NHpxIzN29MXvWiuswfc1W3I0N8SXBd8UR26WntmDlRYf0bSADnwnOjsyMZ3lMezSlArD33Vs3YFhp7dWvL770A== + dependencies: + chokidar ">=3.0.0 <4.0.0" + immutable "^4.0.0" + source-map-js ">=0.6.2 <2.0.0" + +saxes@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz#fe5b4a4768df4f14a201b1ba6a65c1f3d9988cc5" + integrity sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA== + dependencies: + xmlchars "^2.2.0" + +scheduler@^0.23.0: + version "0.23.0" + resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz" + integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw== + dependencies: + loose-envify "^1.1.0" + +scheduler@^0.23.2: + version "0.23.2" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.2.tgz#414ba64a3b282892e944cf2108ecc078d115cdc3" + integrity sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ== + dependencies: + loose-envify "^1.1.0" + +schema-utils@^3.1.1, schema-utils@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe" + integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +schema-utils@^4.0.0, schema-utils@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.2.0.tgz#70d7c93e153a273a805801882ebd3bff20d89c8b" + integrity sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw== + dependencies: + "@types/json-schema" "^7.0.9" + ajv "^8.9.0" + ajv-formats "^2.1.1" + ajv-keywords "^5.1.0" + +screenfull@^5.0.0: + version "5.2.0" + resolved "https://registry.npmjs.org/screenfull/-/screenfull-5.2.0.tgz" + integrity sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA== + +"semver@2 || 3 || 4 || 5": + version "5.7.2" + resolved "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== + +semver@^6.0.0, semver@^6.3.0, semver@^6.3.1: + version "6.3.1" + resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + +semver@^7.0.0, semver@^7.3.5, semver@^7.3.6, semver@^7.3.7, semver@^7.3.8, semver@^7.5.4: + version "7.6.0" + resolved "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz" + integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg== + dependencies: + lru-cache "^6.0.0" + +semver@^7.5.3, semver@^7.6.2, semver@^7.6.3: + version "7.6.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" + integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== + +send@0.19.0: + version "0.19.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.19.0.tgz#bbc5a388c8ea6c048967049dbeac0e4a3f09d7f8" + integrity sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + +serialize-javascript@^6.0.1: + version "6.0.2" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2" + integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g== + dependencies: + randombytes "^2.1.0" + +serve-static@1.16.2: + version "1.16.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.16.2.tgz#b6a5343da47f6bdd2673848bf45754941e803296" + integrity sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw== + dependencies: + encodeurl "~2.0.0" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.19.0" + +server-only@^0.0.1: + version "0.0.1" + resolved "https://registry.npmjs.org/server-only/-/server-only-0.0.1.tgz" + integrity sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA== + +set-function-length@^1.1.1: + version "1.2.0" + resolved "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.0.tgz" + integrity sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w== + dependencies: + define-data-property "^1.1.1" + function-bind "^1.1.2" + get-intrinsic "^1.2.2" + gopd "^1.0.1" + has-property-descriptors "^1.0.1" + +set-function-length@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" + integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== + dependencies: + define-data-property "^1.1.4" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + gopd "^1.0.1" + has-property-descriptors "^1.0.2" + +set-function-name@^2.0.0, set-function-name@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz" + integrity sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA== + dependencies: + define-data-property "^1.0.1" + functions-have-names "^1.2.3" + has-property-descriptors "^1.0.0" + +setimmediate@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +sharp@^0.33.2: + version "0.33.2" + resolved "https://registry.npmjs.org/sharp/-/sharp-0.33.2.tgz" + integrity sha512-WlYOPyyPDiiM07j/UO+E720ju6gtNtHjEGg5vovUk1Lgxyjm2LFO+37Nt/UI3MMh2l6hxTWQWi7qk3cXJTutcQ== + dependencies: + color "^4.2.3" + detect-libc "^2.0.2" + semver "^7.5.4" + optionalDependencies: + "@img/sharp-darwin-arm64" "0.33.2" + "@img/sharp-darwin-x64" "0.33.2" + "@img/sharp-libvips-darwin-arm64" "1.0.1" + "@img/sharp-libvips-darwin-x64" "1.0.1" + "@img/sharp-libvips-linux-arm" "1.0.1" + "@img/sharp-libvips-linux-arm64" "1.0.1" + "@img/sharp-libvips-linux-s390x" "1.0.1" + "@img/sharp-libvips-linux-x64" "1.0.1" + "@img/sharp-libvips-linuxmusl-arm64" "1.0.1" + "@img/sharp-libvips-linuxmusl-x64" "1.0.1" + "@img/sharp-linux-arm" "0.33.2" + "@img/sharp-linux-arm64" "0.33.2" + "@img/sharp-linux-s390x" "0.33.2" + "@img/sharp-linux-x64" "0.33.2" + "@img/sharp-linuxmusl-arm64" "0.33.2" + "@img/sharp-linuxmusl-x64" "0.33.2" + "@img/sharp-wasm32" "0.33.2" + "@img/sharp-win32-ia32" "0.33.2" + "@img/sharp-win32-x64" "0.33.2" + +sharp@^0.33.3: + version "0.33.5" + resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.33.5.tgz#13e0e4130cc309d6a9497596715240b2ec0c594e" + integrity sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw== + dependencies: + color "^4.2.3" + detect-libc "^2.0.3" + semver "^7.6.3" + optionalDependencies: + "@img/sharp-darwin-arm64" "0.33.5" + "@img/sharp-darwin-x64" "0.33.5" + "@img/sharp-libvips-darwin-arm64" "1.0.4" + "@img/sharp-libvips-darwin-x64" "1.0.4" + "@img/sharp-libvips-linux-arm" "1.0.5" + "@img/sharp-libvips-linux-arm64" "1.0.4" + "@img/sharp-libvips-linux-s390x" "1.0.4" + "@img/sharp-libvips-linux-x64" "1.0.4" + "@img/sharp-libvips-linuxmusl-arm64" "1.0.4" + "@img/sharp-libvips-linuxmusl-x64" "1.0.4" + "@img/sharp-linux-arm" "0.33.5" + "@img/sharp-linux-arm64" "0.33.5" + "@img/sharp-linux-s390x" "0.33.5" + "@img/sharp-linux-x64" "0.33.5" + "@img/sharp-linuxmusl-arm64" "0.33.5" + "@img/sharp-linuxmusl-x64" "0.33.5" + "@img/sharp-wasm32" "0.33.5" + "@img/sharp-win32-ia32" "0.33.5" + "@img/sharp-win32-x64" "0.33.5" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + +side-channel@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2" + integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA== + dependencies: + call-bind "^1.0.7" + es-errors "^1.3.0" + get-intrinsic "^1.2.4" + object-inspect "^1.13.1" + +signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: + version "3.0.7" + resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +signal-exit@^4.0.1: + version "4.1.0" + resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== + +simple-swizzle@^0.2.2: + version "0.2.2" + resolved "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz" + integrity sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg== + dependencies: + is-arrayish "^0.3.1" + +sisteransi@^1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" + integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== + +size-sensor@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/size-sensor/-/size-sensor-1.0.1.tgz" + integrity sha512-QTy7MnuugCFXIedXRpUSk9gUnyNiaxIdxGfUjr8xxXOqIB3QvBUYP9+b51oCg2C4dnhaeNk/h57TxjbvoJrJUA== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +slash@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz" + integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== + +slice-ansi@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz" + integrity sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + +slice-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz" + integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + +slice-ansi@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz" + integrity sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ== + dependencies: + ansi-styles "^6.0.0" + is-fullwidth-code-point "^4.0.0" + +sortablejs@^1.15.0: + version "1.15.0" + resolved "https://registry.npmjs.org/sortablejs/-/sortablejs-1.15.0.tgz" + integrity sha512-bv9qgVMjUMf89wAvM6AxVvS/4MX3sPeN0+agqShejLU5z5GX4C75ow1O2e5k4L6XItUyAK3gH6AxSbXrOM5e8w== + +"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.2, source-map-js@^1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz" + integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg== + +source-map-js@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" + integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== + +source-map-support@0.5.13: + version "0.5.13" + resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" + integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-support@~0.5.20: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@^0.7.0, source-map@^0.7.3: + version "0.7.4" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz" + integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== + +space-separated-tokens@^1.0.0: + version "1.1.5" + resolved "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz" + integrity sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA== + +space-separated-tokens@^2.0.0: + version "2.0.2" + resolved "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz" + integrity sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q== + +spdx-correct@^3.0.0: + version "3.2.0" + resolved "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz" + integrity sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.3.0" + resolved "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz" + integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== + +spdx-expression-parse@^3.0.0: + version "3.0.1" + resolved "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.13" + resolved "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz" + integrity sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w== + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== + +stack-utils@^2.0.3: + version "2.0.6" + resolved "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f" + integrity sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ== + dependencies: + escape-string-regexp "^2.0.0" + +stackframe@^1.3.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.3.4.tgz#b881a004c8c149a5e8efef37d51b16e412943310" + integrity sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw== + +state-local@^1.0.6: + version "1.0.7" + resolved "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz" + integrity sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w== + +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + +stop-iteration-iterator@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz" + integrity sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ== + dependencies: + internal-slot "^1.0.4" + +storybook@^8.3.5: + version "8.3.5" + resolved "https://registry.yarnpkg.com/storybook/-/storybook-8.3.5.tgz#aef0542c08e245b7ac22742c1e1633a125063b8e" + integrity sha512-hYQVtP2l+3kO8oKDn4fjXXQYxgTRsj/LaV6lUMJH0zt+OhVmDXKJLxmdUP4ieTm0T8wEbSYosFavgPcQZlxRfw== + dependencies: + "@storybook/core" "8.3.5" + +stream-browserify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-3.0.0.tgz#22b0a2850cdf6503e73085da1fc7b7d0c2122f2f" + integrity sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA== + dependencies: + inherits "~2.0.4" + readable-stream "^3.5.0" + +stream-http@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-3.2.0.tgz#1872dfcf24cb15752677e40e5c3f9cc1926028b5" + integrity sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A== + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.4" + readable-stream "^3.6.0" + xtend "^4.0.2" + +streamsearch@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz" + integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== + +string-argv@^0.3.1: + version "0.3.2" + resolved "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz" + integrity sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q== + +string-length@^4.0.1: + version "4.0.2" + resolved "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" + integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== + dependencies: + char-regex "^1.0.2" + strip-ansi "^6.0.0" + +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@4.2.3, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3, string-width@^5.0.0, string-width@^5.0.1, string-width@^5.1.2: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string.prototype.matchall@^4.0.8: + version "4.0.10" + resolved "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz" + integrity sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + get-intrinsic "^1.2.1" + has-symbols "^1.0.3" + internal-slot "^1.0.5" + regexp.prototype.flags "^1.5.0" + set-function-name "^2.0.0" + side-channel "^1.0.4" + +string.prototype.trim@^1.2.8: + version "1.2.8" + resolved "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz" + integrity sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + +string.prototype.trimend@^1.0.7: + version "1.0.7" + resolved "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz" + integrity sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + +string.prototype.trimstart@^1.0.7: + version "1.0.7" + resolved "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz" + integrity sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + +string_decoder@^1.1.1, string_decoder@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +stringify-entities@^4.0.0: + version "4.0.3" + resolved "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.3.tgz" + integrity sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g== + dependencies: + character-entities-html4 "^2.0.0" + character-entities-legacy "^3.0.0" + +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^7.0.1, strip-ansi@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== + dependencies: + ansi-regex "^6.0.1" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" + integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== + +strip-bom@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" + integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +strip-final-newline@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz" + integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw== + +strip-indent@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz" + integrity sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ== + dependencies: + min-indent "^1.0.0" + +strip-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-4.0.0.tgz#b41379433dd06f5eae805e21d631e07ee670d853" + integrity sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA== + dependencies: + min-indent "^1.0.1" + +strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +style-loader@^3.3.1: + version "3.3.4" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.4.tgz#f30f786c36db03a45cbd55b6a70d930c479090e7" + integrity sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w== + +style-to-object@^0.4.0, style-to-object@^0.4.1: + version "0.4.1" + resolved "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.1.tgz" + integrity sha512-HFpbb5gr2ypci7Qw+IOhnP2zOU7e77b+rzM+wTzXzfi1PrtBCX0E7Pk4wL4iTLnhzZ+JgEGAhX81ebTg/aYjQw== + dependencies: + inline-style-parser "0.1.1" + +styled-jsx@5.1.1: + version "5.1.1" + resolved "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz" + integrity sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw== + dependencies: + client-only "0.0.1" + +styled-jsx@^5.1.6: + version "5.1.6" + resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-5.1.6.tgz#83b90c077e6c6a80f7f5e8781d0f311b2fe41499" + integrity sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA== + dependencies: + client-only "0.0.1" + +stylis@^4.1.3: + version "4.3.0" + resolved "https://registry.npmjs.org/stylis/-/stylis-4.3.0.tgz" + integrity sha512-E87pIogpwUsUwXw7dNyU4QDjdgVMy52m+XEOPEKUn161cCzWjjhPSQhByfd1CcNvrOLnXQ6OnnZDwnJrz/Z4YQ== + +sucrase@^3.32.0: + version "3.32.0" + resolved "https://registry.npmjs.org/sucrase/-/sucrase-3.32.0.tgz" + integrity sha512-ydQOU34rpSyj2TGyz4D2p8rbktIOZ8QY9s+DGLvFU1i5pWJE8vkpruCjGCMHsdXwnD7JDcS+noSwM/a7zyNFDQ== + dependencies: + "@jridgewell/gen-mapping" "^0.3.2" + commander "^4.0.0" + glob "7.1.6" + lines-and-columns "^1.1.6" + mz "^2.7.0" + pirates "^4.0.1" + ts-interface-checker "^0.1.9" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +swr@^2.1.0: + version "2.1.5" + resolved "https://registry.npmjs.org/swr/-/swr-2.1.5.tgz" + integrity sha512-/OhfZMcEpuz77KavXST5q6XE9nrOBOVcBLWjMT+oAE/kQHyE3PASrevXCtQDZ8aamntOfFkbVJp7Il9tNBQWrw== + dependencies: + use-sync-external-store "^1.2.0" + +symbol-tree@^3.2.4: + version "3.2.4" + resolved "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" + integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== + +synckit@^0.8.5: + version "0.8.5" + resolved "https://registry.npmjs.org/synckit/-/synckit-0.8.5.tgz" + integrity sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q== + dependencies: + "@pkgr/utils" "^2.3.1" + tslib "^2.5.0" + +tabbable@^6.0.1: + version "6.2.0" + resolved "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz" + integrity sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew== + +tailwind-merge@^2.4.0: + version "2.4.0" + resolved "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.4.0.tgz#1345209dc1f484f15159c9180610130587703042" + integrity sha512-49AwoOQNKdqKPd9CViyH5wJoSKsCDjUlzL8DxuGp3P1FsGY36NJDAa18jLZcaHAUUuTj+JB8IAo8zWgBNvBF7A== + +tailwindcss@^3.4.4: + version "3.4.4" + resolved "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.4.tgz#351d932273e6abfa75ce7d226b5bf3a6cb257c05" + integrity sha512-ZoyXOdJjISB7/BcLTR6SEsLgKtDStYyYZVLsUtWChO4Ps20CBad7lfJKVDiejocV4ME1hLmyY0WJE3hSDcmQ2A== + dependencies: + "@alloc/quick-lru" "^5.2.0" + arg "^5.0.2" + chokidar "^3.5.3" + didyoumean "^1.2.2" + dlv "^1.1.3" + fast-glob "^3.3.0" + glob-parent "^6.0.2" + is-glob "^4.0.3" + jiti "^1.21.0" + lilconfig "^2.1.0" + micromatch "^4.0.5" + normalize-path "^3.0.0" + object-hash "^3.0.0" + picocolors "^1.0.0" + postcss "^8.4.23" + postcss-import "^15.1.0" + postcss-js "^4.0.1" + postcss-load-config "^4.0.1" + postcss-nested "^6.0.1" + postcss-selector-parser "^6.0.11" + resolve "^1.22.2" + sucrase "^3.32.0" + +tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0, tapable@^2.2.1: + version "2.2.1" + resolved "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz" + integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== + +telejson@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/telejson/-/telejson-7.2.0.tgz#3994f6c9a8f8d7f2dba9be2c7c5bbb447e876f32" + integrity sha512-1QTEcJkJEhc8OnStBx/ILRu5J2p0GjvWsBx56bmZRqnrkdBMUe+nX92jxV+p3dB4CP6PZCdJMQJwCggkNBMzkQ== + dependencies: + memoizerific "^1.11.3" + +terser-webpack-plugin@^5.3.1, terser-webpack-plugin@^5.3.10: + version "5.3.10" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz#904f4c9193c6fd2a03f693a2150c62a92f40d199" + integrity sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w== + dependencies: + "@jridgewell/trace-mapping" "^0.3.20" + jest-worker "^27.4.5" + schema-utils "^3.1.1" + serialize-javascript "^6.0.1" + terser "^5.26.0" + +terser@^5.10.0, terser@^5.26.0: + version "5.36.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.36.0.tgz#8b0dbed459ac40ff7b4c9fd5a3a2029de105180e" + integrity sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w== + dependencies: + "@jridgewell/source-map" "^0.3.3" + acorn "^8.8.2" + commander "^2.20.0" + source-map-support "~0.5.20" + +test-exclude@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" + integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== + dependencies: + "@istanbuljs/schema" "^0.1.2" + glob "^7.1.4" + minimatch "^3.0.4" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" + integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== + +thenify-all@^1.0.0: + version "1.6.0" + resolved "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz" + integrity sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA== + dependencies: + thenify ">= 3.1.0 < 4" + +"thenify@>= 3.1.0 < 4": + version "3.3.1" + resolved "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz" + integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== + dependencies: + any-promise "^1.0.0" + +throttle-debounce@^2.1.0: + version "2.3.0" + resolved "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-2.3.0.tgz" + integrity sha512-H7oLPV0P7+jgvrk+6mwwwBDmxTaxnu9HMXmloNLXwnNO0ZxZ31Orah2n8lU1eMPvsaowP2CX+USCgyovXfdOFQ== + +through@^2.3.8: + version "2.3.8" + resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz" + integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== + +timers-browserify@^2.0.12: + version "2.0.12" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.12.tgz#44a45c11fbf407f34f97bccd1577c652361b00ee" + integrity sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ== + dependencies: + setimmediate "^1.0.4" + +tiny-invariant@1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.2.0.tgz" + integrity sha512-1Uhn/aqw5C6RI4KejVeTg6mIS7IqxnLJ8Mv2tV5rTc0qWobay7pDUz6Wi392Cnc8ak1H0F2cjoRzb2/AW4+Fvg== + +tiny-invariant@^1.3.1, tiny-invariant@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.3.tgz#46680b7a873a0d5d10005995eb90a70d74d60127" + integrity sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg== + +tinyrainbow@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/tinyrainbow/-/tinyrainbow-1.2.0.tgz#5c57d2fc0fb3d1afd78465c33ca885d04f02abb5" + integrity sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ== + +tinyspy@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/tinyspy/-/tinyspy-3.0.2.tgz#86dd3cf3d737b15adcf17d7887c84a75201df20a" + integrity sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q== + +titleize@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz" + integrity sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ== + +tmpl@1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" + integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toggle-selection@^1.0.6: + version "1.0.6" + resolved "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz" + integrity sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ== + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +tough-cookie@^4.1.2: + version "4.1.4" + resolved "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz#945f1461b45b5a8c76821c33ea49c3ac192c1b36" + integrity sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag== + dependencies: + psl "^1.1.33" + punycode "^2.1.1" + universalify "^0.2.0" + url-parse "^1.5.3" + +tr46@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz#555c4e297a950617e8eeddef633c87d4d9d6cbf9" + integrity sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA== + dependencies: + punycode "^2.1.1" + +trim-lines@^3.0.0: + version "3.0.1" + resolved "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz" + integrity sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg== + +trough@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/trough/-/trough-2.1.0.tgz" + integrity sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g== + +ts-dedent@^2.0.0, ts-dedent@^2.2.0: + version "2.2.0" + resolved "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz" + integrity sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ== + +ts-interface-checker@^0.1.9: + version "0.1.13" + resolved "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz" + integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA== + +ts-node@^10.9.2: + version "10.9.2" + resolved "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz#70f021c9e185bccdca820e26dc413805c101c71f" + integrity sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ== + dependencies: + "@cspotcode/source-map-support" "^0.8.0" + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.2" + acorn "^8.4.1" + acorn-walk "^8.1.1" + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + v8-compile-cache-lib "^3.0.1" + yn "3.1.1" + +ts-pnp@^1.1.6: + version "1.2.0" + resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92" + integrity sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw== + +tsconfig-paths-webpack-plugin@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-4.1.0.tgz#3c6892c5e7319c146eee1e7302ed9e6f2be4f763" + integrity sha512-xWFISjviPydmtmgeUAuXp4N1fky+VCtfhOkDUFIv5ea7p4wuTomI4QTrXvFBX2S4jZsmyTSrStQl+E+4w+RzxA== + dependencies: + chalk "^4.1.0" + enhanced-resolve "^5.7.0" + tsconfig-paths "^4.1.2" + +tsconfig-paths@^3.15.0: + version "3.15.0" + resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz" + integrity sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg== + dependencies: + "@types/json5" "^0.0.29" + json5 "^1.0.2" + minimist "^1.2.6" + strip-bom "^3.0.0" + +tsconfig-paths@^4.0.0, tsconfig-paths@^4.1.2, tsconfig-paths@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz#ef78e19039133446d244beac0fd6a1632e2d107c" + integrity sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg== + dependencies: + json5 "^2.2.2" + minimist "^1.2.6" + strip-bom "^3.0.0" + +tslib@2.3.0: + version "2.3.0" + resolved "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz" + integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg== + +tslib@^1.8.1, tslib@^1.9.3: + version "1.14.1" + resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tslib@^2.0.0, tslib@^2.0.3: + version "2.8.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.0.tgz#d124c86c3c05a40a91e6fdea4021bd31d377971b" + integrity sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA== + +tslib@^2.0.1: + version "2.7.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.7.0.tgz#d9b40c5c40ab59e8738f297df3087bf1a2690c01" + integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA== + +tslib@^2.1.0, tslib@^2.4.0, tslib@^2.4.1, tslib@^2.5.0: + version "2.5.3" + resolved "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz" + integrity sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w== + +tsutils@^3.21.0: + version "3.21.0" + resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz" + integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== + dependencies: + tslib "^1.8.1" + +tty-browserify@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.1.tgz#3f05251ee17904dfd0677546670db9651682b811" + integrity sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw== + +tween-functions@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/tween-functions/-/tween-functions-1.2.0.tgz#1ae3a50e7c60bb3def774eac707acbca73bbc3ff" + integrity sha512-PZBtLYcCLtEcjL14Fzb1gSxPBeL7nWvGhO5ZFPGqziCcr8uvHp0NDmdjBchp6KHL+tExcg0m3NISmKxhU394dA== + +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + +type-detect@4.0.8: + version "4.0.8" + resolved "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + +type-fest@^0.6.0: + version "0.6.0" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz" + integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== + +type-fest@^0.8.1: + version "0.8.1" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz" + integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== + +type-fest@^2.14.0, type-fest@^2.19.0, type-fest@~2.19: + version "2.19.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b" + integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA== + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +typed-array-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz" + integrity sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.1" + is-typed-array "^1.1.10" + +typed-array-byte-length@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz" + integrity sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA== + dependencies: + call-bind "^1.0.2" + for-each "^0.3.3" + has-proto "^1.0.1" + is-typed-array "^1.1.10" + +typed-array-byte-offset@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz" + integrity sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + has-proto "^1.0.1" + is-typed-array "^1.1.10" + +typed-array-length@^1.0.4: + version "1.0.4" + resolved "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz" + integrity sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng== + dependencies: + call-bind "^1.0.2" + for-each "^0.3.3" + is-typed-array "^1.1.9" + +typescript@4.9.5: + version "4.9.5" + resolved "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz" + integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== + +uglify-js@^3.17.4: + version "3.17.4" + resolved "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz" + integrity sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g== + +unbox-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz" + integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== + dependencies: + call-bind "^1.0.2" + has-bigints "^1.0.2" + has-symbols "^1.0.3" + which-boxed-primitive "^1.0.2" + +undici-types@~6.19.2: + version "6.19.8" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" + integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== + +unicode-canonical-property-names-ecmascript@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz#cb3173fe47ca743e228216e4a3ddc4c84d628cc2" + integrity sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg== + +unicode-match-property-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3" + integrity sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q== + dependencies: + unicode-canonical-property-names-ecmascript "^2.0.0" + unicode-property-aliases-ecmascript "^2.0.0" + +unicode-match-property-value-ecmascript@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz#a0401aee72714598f739b68b104e4fe3a0cb3c71" + integrity sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg== + +unicode-property-aliases-ecmascript@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz#43d41e3be698bd493ef911077c9b131f827e8ccd" + integrity sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w== + +unified@^10.0.0: + version "10.1.2" + resolved "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz" + integrity sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q== + dependencies: + "@types/unist" "^2.0.0" + bail "^2.0.0" + extend "^3.0.0" + is-buffer "^2.0.0" + is-plain-obj "^4.0.0" + trough "^2.0.0" + vfile "^5.0.0" + +unist-util-find-after@^4.0.0: + version "4.0.1" + resolved "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-4.0.1.tgz" + integrity sha512-QO/PuPMm2ERxC6vFXEPtmAutOopy5PknD+Oq64gGwxKtk4xwo9Z97t9Av1obPmGU0IyTa6EKYUfTrK2QJS3Ozw== + dependencies: + "@types/unist" "^2.0.0" + unist-util-is "^5.0.0" + +unist-util-generated@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-2.0.1.tgz" + integrity sha512-qF72kLmPxAw0oN2fwpWIqbXAVyEqUzDHMsbtPvOudIlUzXYFIeQIuxXQCRCFh22B7cixvU0MG7m3MW8FTq/S+A== + +unist-util-is@^5.0.0: + version "5.2.1" + resolved "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz" + integrity sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw== + dependencies: + "@types/unist" "^2.0.0" + +unist-util-is@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-6.0.0.tgz#b775956486aff107a9ded971d996c173374be424" + integrity sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw== + dependencies: + "@types/unist" "^3.0.0" + +unist-util-position-from-estree@^1.0.0, unist-util-position-from-estree@^1.1.0: + version "1.1.2" + resolved "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-1.1.2.tgz" + integrity sha512-poZa0eXpS+/XpoQwGwl79UUdea4ol2ZuCYguVaJS4qzIOMDzbqz8a3erUCOmubSZkaOuGamb3tX790iwOIROww== + dependencies: + "@types/unist" "^2.0.0" + +unist-util-position@^4.0.0: + version "4.0.4" + resolved "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.4.tgz" + integrity sha512-kUBE91efOWfIVBo8xzh/uZQ7p9ffYRtUbMRZBNFYwf0RK8koUMx6dGUfwylLOKmaT2cs4wSW96QoYUSXAyEtpg== + dependencies: + "@types/unist" "^2.0.0" + +unist-util-position@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-5.0.0.tgz#678f20ab5ca1207a97d7ea8a388373c9cf896be4" + integrity sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA== + dependencies: + "@types/unist" "^3.0.0" + +unist-util-remove-position@^4.0.0: + version "4.0.2" + resolved "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-4.0.2.tgz" + integrity sha512-TkBb0HABNmxzAcfLf4qsIbFbaPDvMO6wa3b3j4VcEzFVaw1LBKwnW4/sRJ/atSLSzoIg41JWEdnE7N6DIhGDGQ== + dependencies: + "@types/unist" "^2.0.0" + unist-util-visit "^4.0.0" + +unist-util-stringify-position@^2.0.0: + version "2.0.3" + resolved "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz" + integrity sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g== + dependencies: + "@types/unist" "^2.0.2" + +unist-util-stringify-position@^3.0.0: + version "3.0.3" + resolved "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz" + integrity sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg== + dependencies: + "@types/unist" "^2.0.0" + +unist-util-stringify-position@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz#449c6e21a880e0855bf5aabadeb3a740314abac2" + integrity sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ== + dependencies: + "@types/unist" "^3.0.0" + +unist-util-visit-parents@^5.0.0, unist-util-visit-parents@^5.1.1: + version "5.1.3" + resolved "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz" + integrity sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg== + dependencies: + "@types/unist" "^2.0.0" + unist-util-is "^5.0.0" + +unist-util-visit-parents@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz#4d5f85755c3b8f0dc69e21eca5d6d82d22162815" + integrity sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw== + dependencies: + "@types/unist" "^3.0.0" + unist-util-is "^6.0.0" + +unist-util-visit@^4.0.0: + version "4.1.2" + resolved "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz" + integrity sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg== + dependencies: + "@types/unist" "^2.0.0" + unist-util-is "^5.0.0" + unist-util-visit-parents "^5.1.1" + +unist-util-visit@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-5.0.0.tgz#a7de1f31f72ffd3519ea71814cccf5fd6a9217d6" + integrity sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg== + dependencies: + "@types/unist" "^3.0.0" + unist-util-is "^6.0.0" + unist-util-visit-parents "^6.0.0" + +universalify@^0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0" + integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg== + +universalify@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" + integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== + +unplugin@^1.3.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/unplugin/-/unplugin-1.14.1.tgz#c76d6155a661e43e6a897bce6b767a1ecc344c1a" + integrity sha512-lBlHbfSFPToDYp9pjXlUEFVxYLaue9f9T1HC+4OHlmj+HnMDdz9oZY+erXfoCe/5V/7gKUSY2jpXPb9S7f0f/w== + dependencies: + acorn "^8.12.1" + webpack-virtual-modules "^0.6.2" + +untildify@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz" + integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== + +update-browserslist-db@^1.0.13: + version "1.0.16" + resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz" + integrity sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ== + dependencies: + escalade "^3.1.2" + picocolors "^1.0.1" + +update-browserslist-db@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz#7ca61c0d8650766090728046e416a8cde682859e" + integrity sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ== + dependencies: + escalade "^3.1.2" + picocolors "^1.0.1" + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +url-parse@^1.5.3: + version "1.5.10" + resolved "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1" + integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ== + dependencies: + querystringify "^2.1.1" + requires-port "^1.0.0" + +url@^0.11.0: + version "0.11.4" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.4.tgz#adca77b3562d56b72746e76b330b7f27b6721f3c" + integrity sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg== + dependencies: + punycode "^1.4.1" + qs "^6.12.3" + +use-context-selector@^1.4.1: + version "1.4.1" + resolved "https://registry.npmjs.org/use-context-selector/-/use-context-selector-1.4.1.tgz" + integrity sha512-Io2ArvcRO+6MWIhkdfMFt+WKQX+Vb++W8DS2l03z/Vw/rz3BclKpM0ynr4LYGyU85Eke+Yx5oIhTY++QR0ZDoA== + +use-strict@1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/use-strict/-/use-strict-1.0.1.tgz" + integrity sha512-IeiWvvEXfW5ltKVMkxq6FvNf2LojMKvB2OCeja6+ct24S1XOmQw2dGr2JyndwACWAGJva9B7yPHwAmeA9QCqAQ== + +use-sync-external-store@1.2.0, use-sync-external-store@^1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz" + integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== + +util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +util@^0.12.4, util@^0.12.5: + version "0.12.5" + resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc" + integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== + dependencies: + inherits "^2.0.3" + is-arguments "^1.0.4" + is-generator-function "^1.0.7" + is-typed-array "^1.1.3" + which-typed-array "^1.1.2" + +utila@~0.4: + version "0.4.0" + resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" + integrity sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA== + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== + +uuid@^9.0.0, uuid@^9.0.1: + version "9.0.1" + resolved "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz" + integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== + +uvu@^0.5.0: + version "0.5.6" + resolved "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz" + integrity sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA== + dependencies: + dequal "^2.0.0" + diff "^5.0.0" + kleur "^4.0.3" + sade "^1.7.3" + +v8-compile-cache-lib@^3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" + integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== + +v8-to-istanbul@^9.0.1: + version "9.3.0" + resolved "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz#b9572abfa62bd556c16d75fdebc1a411d5ff3175" + integrity sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA== + dependencies: + "@jridgewell/trace-mapping" "^0.3.12" + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^2.0.0" + +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== + +vfile-location@^4.0.0: + version "4.1.0" + resolved "https://registry.npmjs.org/vfile-location/-/vfile-location-4.1.0.tgz" + integrity sha512-YF23YMyASIIJXpktBa4vIGLJ5Gs88UB/XePgqPmTa7cDA+JeO3yclbpheQYCHjVHBn/yePzrXuygIL+xbvRYHw== + dependencies: + "@types/unist" "^2.0.0" + vfile "^5.0.0" + +vfile-location@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-5.0.3.tgz#cb9eacd20f2b6426d19451e0eafa3d0a846225c3" + integrity sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg== + dependencies: + "@types/unist" "^3.0.0" + vfile "^6.0.0" + +vfile-message@^3.0.0: + version "3.1.4" + resolved "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.4.tgz" + integrity sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw== + dependencies: + "@types/unist" "^2.0.0" + unist-util-stringify-position "^3.0.0" + +vfile-message@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-4.0.2.tgz#c883c9f677c72c166362fd635f21fc165a7d1181" + integrity sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw== + dependencies: + "@types/unist" "^3.0.0" + unist-util-stringify-position "^4.0.0" + +vfile@^5.0.0: + version "5.3.7" + resolved "https://registry.npmjs.org/vfile/-/vfile-5.3.7.tgz" + integrity sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g== + dependencies: + "@types/unist" "^2.0.0" + is-buffer "^2.0.0" + unist-util-stringify-position "^3.0.0" + vfile-message "^3.0.0" + +vfile@^6.0.0: + version "6.0.2" + resolved "https://registry.yarnpkg.com/vfile/-/vfile-6.0.2.tgz#ef49548ea3d270097a67011921411130ceae7deb" + integrity sha512-zND7NlS8rJYb/sPqkb13ZvbbUoExdbi4w3SfRrMq6R3FvnLQmmfpajJNITuuYm6AZ5uao9vy4BAos3EXBPf2rg== + dependencies: + "@types/unist" "^3.0.0" + unist-util-stringify-position "^4.0.0" + vfile-message "^4.0.0" + +vite-code-inspector-plugin@0.13.0: + version "0.13.0" + resolved "https://registry.npmjs.org/vite-code-inspector-plugin/-/vite-code-inspector-plugin-0.13.0.tgz" + integrity sha512-hvIn9G+IFzQHVVynWh2wGTBHo51CBJRqQBzYryeuuaL0BK0w8my2/tlpSAae5ofQxOBXBMhyXC2gWgYUJnNWrA== + dependencies: + code-inspector-core "0.13.0" + +vm-browserify@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" + integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== + +void-elements@3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz" + integrity sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w== + +vue-eslint-parser@^9.3.0: + version "9.3.0" + resolved "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.3.0.tgz" + integrity sha512-48IxT9d0+wArT1+3wNIy0tascRoywqSUe2E1YalIC1L8jsUGe5aJQItWfRok7DVFGz3UYvzEI7n5wiTXsCMAcQ== + dependencies: + debug "^4.3.4" + eslint-scope "^7.1.1" + eslint-visitor-keys "^3.3.0" + espree "^9.3.1" + esquery "^1.4.0" + lodash "^4.17.21" + semver "^7.3.6" + +w3c-xmlserializer@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz#aebdc84920d806222936e3cdce408e32488a3073" + integrity sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw== + dependencies: + xml-name-validator "^4.0.0" + +walker@^1.0.8: + version "1.0.8" + resolved "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" + integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== + dependencies: + makeerror "1.0.12" + +watchpack@^2.4.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.2.tgz#2feeaed67412e7c33184e5a79ca738fbd38564da" + integrity sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + +web-namespaces@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz" + integrity sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ== + +web-worker@^1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz" + integrity sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA== + +webidl-conversions@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a" + integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g== + +webpack-code-inspector-plugin@0.13.0: + version "0.13.0" + resolved "https://registry.npmjs.org/webpack-code-inspector-plugin/-/webpack-code-inspector-plugin-0.13.0.tgz" + integrity sha512-T3ZZ84NX0cVmwff5zyYhB9OuroZYsyaQpSgFicgiuYAWCsQePYApM/R3bHdvcECkBXO50hAVtr9SjWRTu1+Ntg== + dependencies: + code-inspector-core "0.13.0" + +webpack-dev-middleware@^6.1.2: + version "6.1.3" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-6.1.3.tgz#79f4103f8c898564c9e96c3a9c2422de50f249bc" + integrity sha512-A4ChP0Qj8oGociTs6UdlRUGANIGrCDL3y+pmQMc+dSsraXHCatFpmMey4mYELA+juqwUqwQsUgJJISXl1KWmiw== + dependencies: + colorette "^2.0.10" + memfs "^3.4.12" + mime-types "^2.1.31" + range-parser "^1.2.1" + schema-utils "^4.0.0" + +webpack-hot-middleware@^2.25.1: + version "2.26.1" + resolved "https://registry.yarnpkg.com/webpack-hot-middleware/-/webpack-hot-middleware-2.26.1.tgz#87214f1e3f9f3acab9271fef9e6ed7b637d719c0" + integrity sha512-khZGfAeJx6I8K9zKohEWWYN6KDlVw2DHownoe+6Vtwj1LP9WFgegXnVMSkZ/dBEBtXFwrkkydsaPFlB7f8wU2A== + dependencies: + ansi-html-community "0.0.8" + html-entities "^2.1.0" + strip-ansi "^6.0.0" + +webpack-sources@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" + integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== + +webpack-virtual-modules@^0.6.0, webpack-virtual-modules@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz#057faa9065c8acf48f24cb57ac0e77739ab9a7e8" + integrity sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ== + +webpack@5: + version "5.95.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.95.0.tgz#8fd8c454fa60dad186fbe36c400a55848307b4c0" + integrity sha512-2t3XstrKULz41MNMBF+cJ97TyHdyQ8HCt//pqErqDvNjU9YQBnZxIHa11VXsi7F3mb5/aO2tuDxdeTPdU7xu9Q== + dependencies: + "@types/estree" "^1.0.5" + "@webassemblyjs/ast" "^1.12.1" + "@webassemblyjs/wasm-edit" "^1.12.1" + "@webassemblyjs/wasm-parser" "^1.12.1" + acorn "^8.7.1" + acorn-import-attributes "^1.9.5" + browserslist "^4.21.10" + chrome-trace-event "^1.0.2" + enhanced-resolve "^5.17.1" + es-module-lexer "^1.2.1" + eslint-scope "5.1.1" + events "^3.2.0" + glob-to-regexp "^0.4.1" + graceful-fs "^4.2.11" + json-parse-even-better-errors "^2.3.1" + loader-runner "^4.2.0" + mime-types "^2.1.27" + neo-async "^2.6.2" + schema-utils "^3.2.0" + tapable "^2.1.1" + terser-webpack-plugin "^5.3.10" + watchpack "^2.4.1" + webpack-sources "^3.2.3" + +whatwg-encoding@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz#e7635f597fd87020858626805a2729fa7698ac53" + integrity sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg== + dependencies: + iconv-lite "0.6.3" + +whatwg-mimetype@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz#5fa1a7623867ff1af6ca3dc72ad6b8a4208beba7" + integrity sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q== + +whatwg-url@^11.0.0: + version "11.0.0" + resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz#0a849eebb5faf2119b901bb76fd795c2848d4018" + integrity sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ== + dependencies: + tr46 "^3.0.0" + webidl-conversions "^7.0.0" + +which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + dependencies: + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" + +which-builtin-type@^1.1.3: + version "1.1.3" + resolved "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz" + integrity sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw== + dependencies: + function.prototype.name "^1.1.5" + has-tostringtag "^1.0.0" + is-async-function "^2.0.0" + is-date-object "^1.0.5" + is-finalizationregistry "^1.0.2" + is-generator-function "^1.0.10" + is-regex "^1.1.4" + is-weakref "^1.0.2" + isarray "^2.0.5" + which-boxed-primitive "^1.0.2" + which-collection "^1.0.1" + which-typed-array "^1.1.9" + +which-collection@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz" + integrity sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A== + dependencies: + is-map "^2.0.1" + is-set "^2.0.1" + is-weakmap "^2.0.1" + is-weakset "^2.0.1" + +which-typed-array@^1.1.11, which-typed-array@^1.1.13, which-typed-array@^1.1.9: + version "1.1.13" + resolved "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz" + integrity sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.4" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.0" + +which-typed-array@^1.1.14, which-typed-array@^1.1.2: + version "1.1.15" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.15.tgz#264859e9b11a649b388bfaaf4f767df1f779b38d" + integrity sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA== + dependencies: + available-typed-arrays "^1.0.7" + call-bind "^1.0.7" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.2" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +word-wrap@^1.2.3: + version "1.2.5" + resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz" + integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== + +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version "7.0.0" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^8.1.0: + version "8.1.0" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz" + integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== + dependencies: + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" + +wrappy@1: + version "1.0.2" + resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +write-file-atomic@^4.0.2: + version "4.0.2" + resolved "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd" + integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg== + dependencies: + imurmurhash "^0.1.4" + signal-exit "^3.0.7" + +ws@^8.11.0, ws@^8.2.3: + version "8.18.0" + resolved "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc" + integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw== + +xml-name-validator@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz" + integrity sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw== + +xmlchars@^2.2.0: + version "2.2.0" + resolved "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" + integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== + +xtend@^4.0.0, xtend@^4.0.2: + version "4.0.2" + resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yaml-eslint-parser@^1.1.0, yaml-eslint-parser@^1.2.1: + version "1.2.2" + resolved "https://registry.npmjs.org/yaml-eslint-parser/-/yaml-eslint-parser-1.2.2.tgz" + integrity sha512-pEwzfsKbTrB8G3xc/sN7aw1v6A6c/pKxLAkjclnAyo5g5qOh6eL9WGu0o3cSDQZKrTNk4KL4lQSwZW+nBkANEg== + dependencies: + eslint-visitor-keys "^3.0.0" + lodash "^4.17.21" + yaml "^2.0.0" + +yaml@^1.10.0: + version "1.10.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" + integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== + +yaml@^2.0.0, yaml@^2.1.1, yaml@^2.2.2: + version "2.3.1" + resolved "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz" + integrity sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ== + +yargs-parser@^21.1.1: + version "21.1.1" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" + integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== + +yargs@^17.3.1: + version "17.7.2" + resolved "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" + integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== + dependencies: + cliui "^8.0.1" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.1.1" + +yn@3.1.1: + version "3.1.1" + resolved "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + +yocto-queue@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.1.1.tgz#fef65ce3ac9f8a32ceac5a634f74e17e5b232110" + integrity sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g== + +zod@^3.23.6: + version "3.23.6" + resolved "https://registry.npmjs.org/zod/-/zod-3.23.6.tgz" + integrity sha512-RTHJlZhsRbuA8Hmp/iNL7jnfc4nZishjsanDAfEY1QpDQZCahUp3xDzl+zfweE9BklxMUcgBgS1b7Lvie/ZVwA== + +zrender@5.4.3: + version "5.4.3" + resolved "https://registry.npmjs.org/zrender/-/zrender-5.4.3.tgz" + integrity sha512-DRUM4ZLnoaT0PBVvGBDO9oWIDBKFdAVieNWxWwK0niYzJCMwGchRk21/hsE+RKkIveH3XHCyvXcJDkgLVvfizQ== + dependencies: + tslib "2.3.0" + +zundo@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/zundo/-/zundo-2.1.0.tgz" + integrity sha512-IMhYXDZWbyGu/p3rQb1d3orhCfAyi9hGkx6N579ZtO7mWrzvBdNyGEcxciv1jtIYPKBqLSAgzKqjLguau09f9g== + +zustand@^4.4.1, zustand@^4.5.2: + version "4.5.4" + resolved "https://registry.npmjs.org/zustand/-/zustand-4.5.4.tgz" + integrity sha512-/BPMyLKJPtFEvVL0E9E9BTUM63MNyhPGlvxk1XjrfWTUlV+BR8jufjsovHzrtR6YNcBEcL7cMHovL1n9xHawEg== + dependencies: + use-sync-external-store "1.2.0" + +zwitch@^2.0.0: + version "2.0.4" + resolved "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz" + integrity sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A== From 63b333cdb18fb9d58ce59081696e4d5c25aab958 Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Wed, 16 Oct 2024 15:37:32 +0800 Subject: [PATCH 095/346] modify plugin detail panel --- .../(commonLayout)/plugins/test/card/page.tsx | 6 -- .../plugins/plugin-detail-panel/index.tsx | 61 +++++-------------- .../plugins/plugin-page/plugins-panel.tsx | 10 +++ 3 files changed, 25 insertions(+), 52 deletions(-) diff --git a/web/app/(commonLayout)/plugins/test/card/page.tsx b/web/app/(commonLayout)/plugins/test/card/page.tsx index a2ec11e223..dd280aac38 100644 --- a/web/app/(commonLayout)/plugins/test/card/page.tsx +++ b/web/app/(commonLayout)/plugins/test/card/page.tsx @@ -4,12 +4,9 @@ import { customTool, extensionDallE, modelGPT4, toolNotion } from '@/app/compone import PluginItem from '@/app/components/plugins/plugin-item' import CardMoreInfo from '@/app/components/plugins/card/card-more-info' import ProviderCard from '@/app/components/plugins/provider-card' -import PluginDetailPanel from '@/app/components/plugins/plugin-detail-panel' -import { getLocaleOnServer } from '@/i18n/server' import Badge from '@/app/components/base/badge' const PluginList = async () => { - const locale = getLocaleOnServer() const pluginList = [toolNotion, extensionDallE, modelGPT4, customTool] return ( @@ -66,9 +63,6 @@ const PluginList = async () => { ))} </div> </div> - <PluginDetailPanel - locale={locale} - /> </div> ) } diff --git a/web/app/components/plugins/plugin-detail-panel/index.tsx b/web/app/components/plugins/plugin-detail-panel/index.tsx index 62163008c1..8508ee2546 100644 --- a/web/app/components/plugins/plugin-detail-panel/index.tsx +++ b/web/app/components/plugins/plugin-detail-panel/index.tsx @@ -1,8 +1,8 @@ 'use client' -import React, { useEffect, useMemo, useState } from 'react' +import React, { useMemo } from 'react' import type { FC } from 'react' +import { useContext } from 'use-context-selector' import { useTranslation } from 'react-i18next' -import { usePathname, useRouter, useSearchParams } from 'next/navigation' import { RiCloseLine, RiVerifiedBadgeLine } from '@remixicon/react' import type { Plugin } from '../types' // import { PluginType } from '../types' @@ -14,35 +14,26 @@ import OperationDropdown from './operation-dropdown' import EndpointList from './endpoint-list' import ActionList from './action-list' import ModelList from './model-list' -import type { Locale } from '@/i18n' -import { fetchPluginDetail } from '@/app/(commonLayout)/plugins/test/card/actions' +// import type { Locale } from '@/i18n' import { BoxSparkleFill } from '@/app/components/base/icons/src/vender/plugin' import Button from '@/app/components/base/button' import ActionButton from '@/app/components/base/action-button' import Drawer from '@/app/components/base/drawer' -import Loading from '@/app/components/base/loading' +// import Loading from '@/app/components/base/loading' +import I18n from '@/context/i18n' import cn from '@/utils/classnames' -import { - // extensionDallE, - // modelGPT4, - toolNotion, -} from '@/app/components/plugins/card/card-mock' type Props = { - locale: Locale // The component is used in both client and server side, so we can't get the locale from both side(getLocaleOnServer and useContext) + pluginDetail: Plugin | undefined + onHide: () => void } const PluginDetailPanel: FC<Props> = ({ - locale, + pluginDetail, + onHide, }) => { const { t } = useTranslation() - const searchParams = useSearchParams() - const org = searchParams.get('org') - const name = searchParams.get('name') - const router = useRouter() - const pathname = usePathname() - const [loading, setLoading] = useState(true) - const [pluginDetail, setPluginDetail] = useState<Plugin>() + const { locale } = useContext(I18n) const hasNewVersion = useMemo(() => { if (!pluginDetail) @@ -50,45 +41,23 @@ const PluginDetailPanel: FC<Props> = ({ return pluginDetail.latest_version !== pluginDetail.version }, [pluginDetail]) - const getPluginDetail = async (org: string, name: string) => { - console.log('organization: ', org) - console.log('plugin name: ', name) - setLoading(true) - const detail = await fetchPluginDetail(org, name) - setPluginDetail({ - ...detail, - ...toolNotion, - } as any) - setLoading(false) - } - - const handleClose = () => { - setPluginDetail(undefined) - router.replace(pathname) - } - const handleUpdate = () => {} - useEffect(() => { - if (org && name) - getPluginDetail(org, name) - }, [org, name]) - - if (!org || !name) + if (!pluginDetail) return null return ( <Drawer isOpen={!!pluginDetail} clickOutsideNotOpen={false} - onClose={handleClose} + onClose={onHide} footer={null} mask={false} positionCenter={false} panelClassname={cn('justify-start mt-[64px] mr-2 mb-2 !w-[420px] !max-w-[420px] !p-0 !bg-components-panel-bg rounded-2xl border-[0.5px] border-components-panel-border shadow-xl')} > - {loading && <Loading type='area' />} - {!loading && pluginDetail && ( + {/* {loading && <Loading type='area' />} */} + {pluginDetail && ( <> <div className={cn('shrink-0 p-4 pb-3 border-b border-divider-subtle bg-components-panel-bg')}> <div className="flex"> @@ -116,7 +85,7 @@ const PluginDetailPanel: FC<Props> = ({ </div> <div className='flex gap-1'> <OperationDropdown /> - <ActionButton onClick={handleClose}> + <ActionButton onClick={onHide}> <RiCloseLine className='w-4 h-4' /> </ActionButton> </div> diff --git a/web/app/components/plugins/plugin-page/plugins-panel.tsx b/web/app/components/plugins/plugin-page/plugins-panel.tsx index da36e6c424..4db88a705b 100644 --- a/web/app/components/plugins/plugin-page/plugins-panel.tsx +++ b/web/app/components/plugins/plugin-page/plugins-panel.tsx @@ -1,4 +1,12 @@ 'use client' +import { useState } from 'react' +import type { Plugin } from '../types' +import PluginDetailPanel from '@/app/components/plugins/plugin-detail-panel' +import { + // extensionDallE, + // modelGPT4, + toolNotion, +} from '@/app/components/plugins/card/card-mock' import type { FilterState } from './filter-management' import FilterManagement from './filter-management' @@ -9,6 +17,7 @@ const PluginsPanel = () => { // } + const [currentPluginDetail, setCurrentPluginDetail] = useState<Plugin | undefined>(toolNotion as any) return ( <> <div className='flex flex-col pt-1 pb-3 px-12 justify-center items-start gap-3 self-stretch'> @@ -22,6 +31,7 @@ const PluginsPanel = () => { <List /> </div> </div> + <PluginDetailPanel pluginDetail={currentPluginDetail} onHide={() => setCurrentPluginDetail(undefined)} /> </> ) } From 7c5c35600c8cb2455e1c0fcf8d03789bf0ef26af Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Wed, 16 Oct 2024 15:57:23 +0800 Subject: [PATCH 096/346] plugin detail type --- web/app/components/plugins/types.ts | 38 +++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts index a14f7825da..77963763f9 100644 --- a/web/app/components/plugins/types.ts +++ b/web/app/components/plugins/types.ts @@ -7,6 +7,44 @@ export enum PluginType { extension = 'extension', } +export enum PluginSource { + marketplace = 'marketplace', + github = 'github', + local = 'package', + debugging = 'remote', +} + +export type PluginDeclaration = { + version: string + author: string + icon: string + name: string + label: Record<Locale, string> + created_at: string + resource: any // useless in frontend + plugins: any // useless in frontend + tool: any // TODO + endpoint: any // TODO + model: any // TODO +} + +export type PluginDetail = { + id: string + created_at: string + updated_at: string + name: string + plugin_id: string + plugin_unique_identifier: string + declaration: PluginDeclaration + installation_id: string + tenant_id: string + endpoints_setups: number + endpoints_active: number + version: string + source: PluginSource + meta?: any +} + export type Plugin = { 'type': PluginType 'org': string From 10190a9aa5c2f978f1bf1cf9958912fb90aa4edc Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Wed, 16 Oct 2024 17:30:51 +0800 Subject: [PATCH 097/346] plugin detail header data binding --- .../plugins/plugin-detail-panel/index.tsx | 63 ++++++++++++++----- .../plugins/plugin-detail-panel/mock.ts | 36 +++++++++++ .../plugins/plugin-page/plugins-panel.tsx | 10 +-- web/app/components/plugins/types.ts | 28 ++++++++- web/i18n/en-US/plugin.ts | 6 ++ web/i18n/zh-Hans/plugin.ts | 6 ++ 6 files changed, 125 insertions(+), 24 deletions(-) create mode 100644 web/app/components/plugins/plugin-detail-panel/mock.ts diff --git a/web/app/components/plugins/plugin-detail-panel/index.tsx b/web/app/components/plugins/plugin-detail-panel/index.tsx index 8508ee2546..bd5bed93b7 100644 --- a/web/app/components/plugins/plugin-detail-panel/index.tsx +++ b/web/app/components/plugins/plugin-detail-panel/index.tsx @@ -3,19 +3,26 @@ import React, { useMemo } from 'react' import type { FC } from 'react' import { useContext } from 'use-context-selector' import { useTranslation } from 'react-i18next' -import { RiCloseLine, RiVerifiedBadgeLine } from '@remixicon/react' -import type { Plugin } from '../types' -// import { PluginType } from '../types' -import Badge from '../../base/badge' -import Description from '../card/base/description' +import { + RiBugLine, + RiCloseLine, + RiHardDrive3Line, + // RiVerifiedBadgeLine, +} from '@remixicon/react' +import type { PluginDetail } from '../types' +import { PluginSource } from '../types' +// import Description from '../card/base/description' import Icon from '../card/base/card-icon' import Title from '../card/base/title' +import OrgInfo from '../card/base/org-info' import OperationDropdown from './operation-dropdown' import EndpointList from './endpoint-list' import ActionList from './action-list' import ModelList from './model-list' -// import type { Locale } from '@/i18n' +import Badge from '@/app/components/base/badge' +import Tooltip from '@/app/components/base/tooltip' import { BoxSparkleFill } from '@/app/components/base/icons/src/vender/plugin' +import { Github } from '@/app/components/base/icons/src/public/common' import Button from '@/app/components/base/button' import ActionButton from '@/app/components/base/action-button' import Drawer from '@/app/components/base/drawer' @@ -24,7 +31,7 @@ import I18n from '@/context/i18n' import cn from '@/utils/classnames' type Props = { - pluginDetail: Plugin | undefined + pluginDetail: PluginDetail | undefined onHide: () => void } @@ -38,7 +45,8 @@ const PluginDetailPanel: FC<Props> = ({ const hasNewVersion = useMemo(() => { if (!pluginDetail) return false - return pluginDetail.latest_version !== pluginDetail.version + return false // TODO + // return pluginDetail.latest_version !== pluginDetail.version }, [pluginDetail]) const handleUpdate = () => {} @@ -61,11 +69,11 @@ const PluginDetailPanel: FC<Props> = ({ <> <div className={cn('shrink-0 p-4 pb-3 border-b border-divider-subtle bg-components-panel-bg')}> <div className="flex"> - <Icon src={pluginDetail.icon} /> + <Icon src={pluginDetail.declaration.icon} /> <div className="ml-3 w-0 grow"> <div className="flex items-center h-5"> - <Title title={pluginDetail.label[locale]} /> - <RiVerifiedBadgeLine className="shrink-0 ml-0.5 w-4 h-4 text-text-accent" /> + <Title title={pluginDetail.declaration.label[locale]} /> + {/* <RiVerifiedBadgeLine className="shrink-0 ml-0.5 w-4 h-4 text-text-accent" /> */} <Badge className='mx-1' text={pluginDetail.version} @@ -77,9 +85,33 @@ const PluginDetailPanel: FC<Props> = ({ </div> <div className='mb-1 flex justify-between items-center h-4'> <div className='flex items-center'> - <div className='text-text-tertiary system-xs-regular'>{pluginDetail.org}</div> - <div className='ml-1 text-text-quaternary system-xs-regular'>·</div> - <BoxSparkleFill className='w-3.5 h-3.5 text-text-tertiary' /> + <OrgInfo + className="mt-0.5" + packageNameClassName='w-auto' + orgName={pluginDetail.declaration.author} + packageName={pluginDetail.declaration.name} + /> + <div className='ml-1 mr-0.5 text-text-quaternary system-xs-regular'>·</div> + {pluginDetail.source === PluginSource.marketplace && ( + <Tooltip popupContent={t('plugin.detailPanel.categoryTip.marketplace')} > + <BoxSparkleFill className='w-3.5 h-3.5 text-text-tertiary hover:text-text-accent' /> + </Tooltip> + )} + {pluginDetail.source === PluginSource.github && ( + <Tooltip popupContent={t('plugin.detailPanel.categoryTip.github')} > + <Github className='w-3.5 h-3.5 text-text-secondary hover:text-text-primary' /> + </Tooltip> + )} + {pluginDetail.source === PluginSource.local && ( + <Tooltip popupContent={t('plugin.detailPanel.categoryTip.local')} > + <RiHardDrive3Line className='w-3.5 h-3.5 text-text-tertiary' /> + </Tooltip> + )} + {pluginDetail.source === PluginSource.debugging && ( + <Tooltip popupContent={t('plugin.detailPanel.categoryTip.debugging')} > + <RiBugLine className='w-3.5 h-3.5 text-text-tertiary hover:text-text-warning' /> + </Tooltip> + )} </div> </div> </div> @@ -90,7 +122,8 @@ const PluginDetailPanel: FC<Props> = ({ </ActionButton> </div> </div> - <Description className='mt-3' text={pluginDetail.brief[locale]} descriptionLineRows={2}></Description> + {/* category === extension TODO */} + {/* <Description className='mt-3' text={pluginDetail.declaration.brief[locale]} descriptionLineRows={2}></Description> */} </div> <div className='grow overflow-y-auto'> <ActionList /> diff --git a/web/app/components/plugins/plugin-detail-panel/mock.ts b/web/app/components/plugins/plugin-detail-panel/mock.ts new file mode 100644 index 0000000000..985e16a7b5 --- /dev/null +++ b/web/app/components/plugins/plugin-detail-panel/mock.ts @@ -0,0 +1,36 @@ +import { PluginSource, PluginType } from '../types' + +export const toolNotion = { + id: 'dlfajkgjdga-dfjalksjfglkds-dfjakld', + created_at: '2024-10-16 16:05:33', + updated_at: '2024-10-16 16:05:33', + name: 'notion page search', + plugin_id: 'Notion/notion-page-search', + plugin_unique_identifier: 'Notion/notion-page-search:1.2.0@fldsjflkdsajfldsakajfkls', + declaration: { + version: '1.2.0', + author: 'Notion', + name: 'notion page search', + category: PluginType.tool, + icon: 'https://via.placeholder.com/150', + label: { + 'en-US': 'Notion Page Search', + 'zh-Hans': 'Notion 页面搜索', + }, + brief: { + 'en-US': 'Description: Search Notion pages and open visited ones faster. No admin access required.More and more info...More and more info...More and more info...', + 'zh-Hans': '搜索 Notion 页面并更快地打开已访问的页面。无需管理员访问权限。More and more info...More and more info...More and more info...', + }, + created_at: '2024-10-16 16:05:33', + resource: {}, + plugins: {}, + tool: {}, // TODO + }, + installation_id: 'jflkdsjoewingljlsadjgoijg-dkfjldajglkajglask-dlfkajdg', + tenant_id: 'jflkdsjoewingljlsadjgoijg', + endpoints_setups: 2, + endpoints_active: 1, + version: '1.2.0', + source: PluginSource.marketplace, + meta: null, +} diff --git a/web/app/components/plugins/plugin-page/plugins-panel.tsx b/web/app/components/plugins/plugin-page/plugins-panel.tsx index 4db88a705b..7bd9620177 100644 --- a/web/app/components/plugins/plugin-page/plugins-panel.tsx +++ b/web/app/components/plugins/plugin-page/plugins-panel.tsx @@ -1,12 +1,8 @@ 'use client' import { useState } from 'react' -import type { Plugin } from '../types' +import type { PluginDetail } from '../types' import PluginDetailPanel from '@/app/components/plugins/plugin-detail-panel' -import { - // extensionDallE, - // modelGPT4, - toolNotion, -} from '@/app/components/plugins/card/card-mock' +import { toolNotion } from '@/app/components/plugins/plugin-detail-panel/mock' import type { FilterState } from './filter-management' import FilterManagement from './filter-management' @@ -17,7 +13,7 @@ const PluginsPanel = () => { // } - const [currentPluginDetail, setCurrentPluginDetail] = useState<Plugin | undefined>(toolNotion as any) + const [currentPluginDetail, setCurrentPluginDetail] = useState<PluginDetail | undefined>(toolNotion as any) return ( <> <div className='flex flex-col pt-1 pb-3 px-12 justify-center items-start gap-3 self-stretch'> diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts index 77963763f9..413a5172c9 100644 --- a/web/app/components/plugins/types.ts +++ b/web/app/components/plugins/types.ts @@ -14,17 +14,41 @@ export enum PluginSource { debugging = 'remote', } +export type PluginToolDeclaration = { + identity: { + author: string + name: string + description: Record<Locale, string> + icon: string + label: Record<Locale, string> + tags: string[] + } + credentials_schema: CredentialFormSchemaBase[] // TODO +} + +export type PluginEndpointDeclaration = { + settings: CredentialFormSchemaBase[] + endpoint: EndpointItem[] +} + +export type EndpointItem = { + path: string + method: string +} + export type PluginDeclaration = { version: string author: string icon: string name: string + category: PluginType label: Record<Locale, string> + brief: Record<Locale, string> created_at: string resource: any // useless in frontend plugins: any // useless in frontend - tool: any // TODO - endpoint: any // TODO + tool: PluginToolDeclaration + endpoint: PluginEndpointDeclaration model: any // TODO } diff --git a/web/i18n/en-US/plugin.ts b/web/i18n/en-US/plugin.ts index 9d94549d64..7decbcd9d4 100644 --- a/web/i18n/en-US/plugin.ts +++ b/web/i18n/en-US/plugin.ts @@ -3,6 +3,12 @@ const translation = { fromMarketplace: 'From Marketplace', endpointsEnabled: '{{num}} sets of endpoints enabled', detailPanel: { + categoryTip: { + marketplace: 'Installed from Marketplace', + github: 'Installed from Github', + local: 'Local Plugin', + debugging: 'Debugging Plugin', + }, operation: { install: 'Install', detail: 'Detail', diff --git a/web/i18n/zh-Hans/plugin.ts b/web/i18n/zh-Hans/plugin.ts index 30f6032261..118595971f 100644 --- a/web/i18n/zh-Hans/plugin.ts +++ b/web/i18n/zh-Hans/plugin.ts @@ -3,6 +3,12 @@ const translation = { fromMarketplace: '来自市场', endpointsEnabled: '{{num}} 组端点已启用', detailPanel: { + categoryTip: { + marketplace: '从 Marketplace 安装', + github: '从 Github 安装', + local: '本地插件', + debugging: '调试插件', + }, operation: { install: '安装', detail: '详情', From 307af29b65756cd115320e9fe6b24058cdad29cc Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Thu, 17 Oct 2024 08:49:29 +0800 Subject: [PATCH 098/346] add plugin description --- web/app/components/plugins/plugin-detail-panel/index.tsx | 5 ++--- web/app/components/plugins/plugin-detail-panel/mock.ts | 2 +- web/app/components/plugins/types.ts | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/web/app/components/plugins/plugin-detail-panel/index.tsx b/web/app/components/plugins/plugin-detail-panel/index.tsx index bd5bed93b7..5aba9e5cf5 100644 --- a/web/app/components/plugins/plugin-detail-panel/index.tsx +++ b/web/app/components/plugins/plugin-detail-panel/index.tsx @@ -11,7 +11,7 @@ import { } from '@remixicon/react' import type { PluginDetail } from '../types' import { PluginSource } from '../types' -// import Description from '../card/base/description' +import Description from '../card/base/description' import Icon from '../card/base/card-icon' import Title from '../card/base/title' import OrgInfo from '../card/base/org-info' @@ -122,8 +122,7 @@ const PluginDetailPanel: FC<Props> = ({ </ActionButton> </div> </div> - {/* category === extension TODO */} - {/* <Description className='mt-3' text={pluginDetail.declaration.brief[locale]} descriptionLineRows={2}></Description> */} + <Description className='mt-3' text={pluginDetail.declaration.description[locale]} descriptionLineRows={2}></Description> </div> <div className='grow overflow-y-auto'> <ActionList /> diff --git a/web/app/components/plugins/plugin-detail-panel/mock.ts b/web/app/components/plugins/plugin-detail-panel/mock.ts index 985e16a7b5..f41d749bc9 100644 --- a/web/app/components/plugins/plugin-detail-panel/mock.ts +++ b/web/app/components/plugins/plugin-detail-panel/mock.ts @@ -17,7 +17,7 @@ export const toolNotion = { 'en-US': 'Notion Page Search', 'zh-Hans': 'Notion 页面搜索', }, - brief: { + description: { 'en-US': 'Description: Search Notion pages and open visited ones faster. No admin access required.More and more info...More and more info...More and more info...', 'zh-Hans': '搜索 Notion 页面并更快地打开已访问的页面。无需管理员访问权限。More and more info...More and more info...More and more info...', }, diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts index 413a5172c9..c25d9fd1a8 100644 --- a/web/app/components/plugins/types.ts +++ b/web/app/components/plugins/types.ts @@ -43,7 +43,7 @@ export type PluginDeclaration = { name: string category: PluginType label: Record<Locale, string> - brief: Record<Locale, string> + description: Record<Locale, string> created_at: string resource: any // useless in frontend plugins: any // useless in frontend From 1ecea620527eae48a48ad8b79084393eb877b3b7 Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Thu, 17 Oct 2024 13:44:56 +0800 Subject: [PATCH 099/346] add verified tag --- web/app/components/plugins/plugin-detail-panel/index.tsx | 4 ++-- web/app/components/plugins/plugin-detail-panel/mock.ts | 1 + web/app/components/plugins/types.ts | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/web/app/components/plugins/plugin-detail-panel/index.tsx b/web/app/components/plugins/plugin-detail-panel/index.tsx index 5aba9e5cf5..aab5a93f66 100644 --- a/web/app/components/plugins/plugin-detail-panel/index.tsx +++ b/web/app/components/plugins/plugin-detail-panel/index.tsx @@ -7,7 +7,7 @@ import { RiBugLine, RiCloseLine, RiHardDrive3Line, - // RiVerifiedBadgeLine, + RiVerifiedBadgeLine, } from '@remixicon/react' import type { PluginDetail } from '../types' import { PluginSource } from '../types' @@ -73,7 +73,7 @@ const PluginDetailPanel: FC<Props> = ({ <div className="ml-3 w-0 grow"> <div className="flex items-center h-5"> <Title title={pluginDetail.declaration.label[locale]} /> - {/* <RiVerifiedBadgeLine className="shrink-0 ml-0.5 w-4 h-4 text-text-accent" /> */} + {pluginDetail.declaration.verified && <RiVerifiedBadgeLine className="shrink-0 ml-0.5 w-4 h-4 text-text-accent" />} <Badge className='mx-1' text={pluginDetail.version} diff --git a/web/app/components/plugins/plugin-detail-panel/mock.ts b/web/app/components/plugins/plugin-detail-panel/mock.ts index f41d749bc9..98e72086b5 100644 --- a/web/app/components/plugins/plugin-detail-panel/mock.ts +++ b/web/app/components/plugins/plugin-detail-panel/mock.ts @@ -25,6 +25,7 @@ export const toolNotion = { resource: {}, plugins: {}, tool: {}, // TODO + verified: true, }, installation_id: 'jflkdsjoewingljlsadjgoijg-dkfjldajglkajglask-dlfkajdg', tenant_id: 'jflkdsjoewingljlsadjgoijg', diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts index c25d9fd1a8..698b4e3532 100644 --- a/web/app/components/plugins/types.ts +++ b/web/app/components/plugins/types.ts @@ -47,6 +47,7 @@ export type PluginDeclaration = { created_at: string resource: any // useless in frontend plugins: any // useless in frontend + verified: boolean tool: PluginToolDeclaration endpoint: PluginEndpointDeclaration model: any // TODO From 5295c72ca1e01a55c6e6bd290da66cbb4bebd51b Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Fri, 18 Oct 2024 18:18:23 +0800 Subject: [PATCH 100/346] endpoints mock data --- .../plugins/plugin-detail-panel/mock.ts | 43 +++++++++++++++++++ web/app/components/plugins/types.ts | 17 +++++++- 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/web/app/components/plugins/plugin-detail-panel/mock.ts b/web/app/components/plugins/plugin-detail-panel/mock.ts index 98e72086b5..7c421ce942 100644 --- a/web/app/components/plugins/plugin-detail-panel/mock.ts +++ b/web/app/components/plugins/plugin-detail-panel/mock.ts @@ -35,3 +35,46 @@ export const toolNotion = { source: PluginSource.marketplace, meta: null, } + +export const toolNotionEndpoints = [ + { + id: 'dlfajkgjdga-dfjalksjfglkds-dfjakld', + created_at: '2024-10-16 16:05:33', + updated_at: '2024-10-16 16:05:33', + settings: { + 'api-key': '*******', + }, + tenant_id: 'jflkdsjoewingljlsadjgoijg', + plugin_id: 'Notion/notion-page-search', + expired_at: '2024-10-16 16:05:33', + declaration: { + settings: [ + { + type: 'secret-input', + name: 'api-key', + required: true, + default: null, + options: null, + label: { + 'en-US': 'API-key', + 'zh-Hans': 'API-key', + }, + help: null, + url: null, + placeholder: { + 'en-US': 'Please input your API key', + 'zh-Hans': '请输入你的 API key', + }, + }, + ], + endpoint: [ + { path: '/duck/<app_id>', method: 'GET' }, + { path: '/neko', method: 'GET' }, + ], + }, + name: 'default', + enabled: true, + url: 'http://localhost:5002/e/45rj9V4TRxAjL0I2wXRZgZdXjdHEKBh8', + hook_id: '45rj9V4TRxAjL0I2wXRZgZdXjdHEKBh8', + }, +] diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts index 698b4e3532..4b3b750497 100644 --- a/web/app/components/plugins/types.ts +++ b/web/app/components/plugins/types.ts @@ -28,7 +28,7 @@ export type PluginToolDeclaration = { export type PluginEndpointDeclaration = { settings: CredentialFormSchemaBase[] - endpoint: EndpointItem[] + endpoints: EndpointItem[] } export type EndpointItem = { @@ -36,6 +36,21 @@ export type EndpointItem = { method: string } +export type EndpointListItem = { + id: string + created_at: string + updated_at: string + settings: Record<string, any> + tenant_id: string + plugin_id: string + expired_at: string + declaration: PluginEndpointDeclaration + name: string + enabled: boolean + url: string + hook_id: string +} + export type PluginDeclaration = { version: string author: string From 64067e1f207e78ad369a299b257e2a057225c651 Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Sat, 19 Oct 2024 13:53:55 +0800 Subject: [PATCH 101/346] plugin detail header operations --- .../plugin-detail-panel/detail-header.tsx | 152 ++++++++++++++++++ .../plugins/plugin-detail-panel/index.tsx | 95 +---------- .../operation-dropdown.tsx | 13 +- 3 files changed, 170 insertions(+), 90 deletions(-) create mode 100644 web/app/components/plugins/plugin-detail-panel/detail-header.tsx diff --git a/web/app/components/plugins/plugin-detail-panel/detail-header.tsx b/web/app/components/plugins/plugin-detail-panel/detail-header.tsx new file mode 100644 index 0000000000..5ec0e4fbe2 --- /dev/null +++ b/web/app/components/plugins/plugin-detail-panel/detail-header.tsx @@ -0,0 +1,152 @@ +import React, { useMemo } from 'react' +import { useTranslation } from 'react-i18next' +import { useContext } from 'use-context-selector' +import { useBoolean } from 'ahooks' +import { + RiBugLine, + RiCloseLine, + RiHardDrive3Line, + RiVerifiedBadgeLine, +} from '@remixicon/react' +import type { PluginDetail } from '../types' +import { PluginSource } from '../types' +import Description from '../card/base/description' +import Icon from '../card/base/card-icon' +import Title from '../card/base/title' +import OrgInfo from '../card/base/org-info' +import OperationDropdown from './operation-dropdown' +import PluginInfo from '@/app/components/plugins/plugin-page/plugin-info' +import ActionButton from '@/app/components/base/action-button' +import Button from '@/app/components/base/button' +import Badge from '@/app/components/base/badge' +import Confirm from '@/app/components/base/confirm' +import Tooltip from '@/app/components/base/tooltip' +import { BoxSparkleFill } from '@/app/components/base/icons/src/vender/plugin' +import { Github } from '@/app/components/base/icons/src/public/common' +import I18n from '@/context/i18n' +import cn from '@/utils/classnames' + +const i18nPrefix = 'plugin.action' + +type Props = { + detail: PluginDetail + onHide: () => void + onDelete: () => void +} + +const DetailHeader = ({ + detail, + onHide, + onDelete, +}: Props) => { + const { t } = useTranslation() + const { locale } = useContext(I18n) + + const hasNewVersion = useMemo(() => { + if (!detail) + return false + return false + // return pluginDetail.latest_version !== pluginDetail.version + }, [detail]) + + const handleUpdate = () => {} + + const [isShowPluginInfo, { + setTrue: showPluginInfo, + setFalse: hidePluginInfo, + }] = useBoolean(false) + + const [isShowDeleteConfirm, { + setTrue: showDeleteConfirm, + setFalse: hideDeleteConfirm, + }] = useBoolean(false) + + const usedInApps = 3 + + return ( + <div className={cn('shrink-0 p-4 pb-3 border-b border-divider-subtle bg-components-panel-bg')}> + <div className="flex"> + <Icon src={detail.declaration.icon} /> + <div className="ml-3 w-0 grow"> + <div className="flex items-center h-5"> + <Title title={detail.declaration.label[locale]} /> + {detail.declaration.verified && <RiVerifiedBadgeLine className="shrink-0 ml-0.5 w-4 h-4 text-text-accent" />} + <Badge + className='mx-1' + text={detail.version} + hasRedCornerMark={hasNewVersion} + /> + {hasNewVersion && ( + <Button variant='secondary-accent' size='small' className='!h-5' onClick={handleUpdate}>{t('plugin.detailPanel.operation.update')}</Button> + )} + </div> + <div className='mb-1 flex justify-between items-center h-4'> + <div className='flex items-center'> + <OrgInfo + className="mt-0.5" + packageNameClassName='w-auto' + orgName={detail.declaration.author} + packageName={detail.declaration.name} + /> + <div className='ml-1 mr-0.5 text-text-quaternary system-xs-regular'>·</div> + {detail.source === PluginSource.marketplace && ( + <Tooltip popupContent={t('plugin.detailPanel.categoryTip.marketplace')} > + <BoxSparkleFill className='w-3.5 h-3.5 text-text-tertiary hover:text-text-accent' /> + </Tooltip> + )} + {detail.source === PluginSource.github && ( + <Tooltip popupContent={t('plugin.detailPanel.categoryTip.github')} > + <Github className='w-3.5 h-3.5 text-text-secondary hover:text-text-primary' /> + </Tooltip> + )} + {detail.source === PluginSource.local && ( + <Tooltip popupContent={t('plugin.detailPanel.categoryTip.local')} > + <RiHardDrive3Line className='w-3.5 h-3.5 text-text-tertiary' /> + </Tooltip> + )} + {detail.source === PluginSource.debugging && ( + <Tooltip popupContent={t('plugin.detailPanel.categoryTip.debugging')} > + <RiBugLine className='w-3.5 h-3.5 text-text-tertiary hover:text-text-warning' /> + </Tooltip> + )} + </div> + </div> + </div> + <div className='flex gap-1'> + <OperationDropdown + onInfo={showPluginInfo} + onRemove={showDeleteConfirm} + /> + <ActionButton onClick={onHide}> + <RiCloseLine className='w-4 h-4' /> + </ActionButton> + </div> + </div> + <Description className='mt-3' text={detail.declaration.description[locale]} descriptionLineRows={2}></Description> + {isShowPluginInfo && ( + <PluginInfo + repository={detail.meta?.repo} + release={detail.version} + packageName={detail.meta?.package} + onHide={hidePluginInfo} + /> + )} + {isShowDeleteConfirm && ( + <Confirm + isShow + title={t(`${i18nPrefix}.delete`)} + content={ + <div> + {t(`${i18nPrefix}.deleteContentLeft`)}<span className='system-md-semibold'>{detail.declaration.label[locale]}</span>{t(`${i18nPrefix}.deleteContentRight`)}<br /> + {usedInApps > 0 && t(`${i18nPrefix}.usedInApps`, { num: usedInApps })} + </div> + } + onCancel={hideDeleteConfirm} + onConfirm={onDelete} + /> + )} + </div> + ) +} + +export default DetailHeader diff --git a/web/app/components/plugins/plugin-detail-panel/index.tsx b/web/app/components/plugins/plugin-detail-panel/index.tsx index aab5a93f66..0fd9570137 100644 --- a/web/app/components/plugins/plugin-detail-panel/index.tsx +++ b/web/app/components/plugins/plugin-detail-panel/index.tsx @@ -1,33 +1,14 @@ 'use client' -import React, { useMemo } from 'react' +import React from 'react' import type { FC } from 'react' -import { useContext } from 'use-context-selector' import { useTranslation } from 'react-i18next' -import { - RiBugLine, - RiCloseLine, - RiHardDrive3Line, - RiVerifiedBadgeLine, -} from '@remixicon/react' import type { PluginDetail } from '../types' -import { PluginSource } from '../types' -import Description from '../card/base/description' -import Icon from '../card/base/card-icon' -import Title from '../card/base/title' -import OrgInfo from '../card/base/org-info' -import OperationDropdown from './operation-dropdown' +import DetailHeader from './detail-header' import EndpointList from './endpoint-list' import ActionList from './action-list' import ModelList from './model-list' -import Badge from '@/app/components/base/badge' -import Tooltip from '@/app/components/base/tooltip' -import { BoxSparkleFill } from '@/app/components/base/icons/src/vender/plugin' -import { Github } from '@/app/components/base/icons/src/public/common' -import Button from '@/app/components/base/button' -import ActionButton from '@/app/components/base/action-button' import Drawer from '@/app/components/base/drawer' // import Loading from '@/app/components/base/loading' -import I18n from '@/context/i18n' import cn from '@/utils/classnames' type Props = { @@ -40,16 +21,8 @@ const PluginDetailPanel: FC<Props> = ({ onHide, }) => { const { t } = useTranslation() - const { locale } = useContext(I18n) - const hasNewVersion = useMemo(() => { - if (!pluginDetail) - return false - return false // TODO - // return pluginDetail.latest_version !== pluginDetail.version - }, [pluginDetail]) - - const handleUpdate = () => {} + const handleDelete = () => {} if (!pluginDetail) return null @@ -67,63 +40,11 @@ const PluginDetailPanel: FC<Props> = ({ {/* {loading && <Loading type='area' />} */} {pluginDetail && ( <> - <div className={cn('shrink-0 p-4 pb-3 border-b border-divider-subtle bg-components-panel-bg')}> - <div className="flex"> - <Icon src={pluginDetail.declaration.icon} /> - <div className="ml-3 w-0 grow"> - <div className="flex items-center h-5"> - <Title title={pluginDetail.declaration.label[locale]} /> - {pluginDetail.declaration.verified && <RiVerifiedBadgeLine className="shrink-0 ml-0.5 w-4 h-4 text-text-accent" />} - <Badge - className='mx-1' - text={pluginDetail.version} - hasRedCornerMark={hasNewVersion} - /> - {hasNewVersion && ( - <Button variant='secondary-accent' size='small' className='!h-5' onClick={handleUpdate}>{t('plugin.detailPanel.operation.update')}</Button> - )} - </div> - <div className='mb-1 flex justify-between items-center h-4'> - <div className='flex items-center'> - <OrgInfo - className="mt-0.5" - packageNameClassName='w-auto' - orgName={pluginDetail.declaration.author} - packageName={pluginDetail.declaration.name} - /> - <div className='ml-1 mr-0.5 text-text-quaternary system-xs-regular'>·</div> - {pluginDetail.source === PluginSource.marketplace && ( - <Tooltip popupContent={t('plugin.detailPanel.categoryTip.marketplace')} > - <BoxSparkleFill className='w-3.5 h-3.5 text-text-tertiary hover:text-text-accent' /> - </Tooltip> - )} - {pluginDetail.source === PluginSource.github && ( - <Tooltip popupContent={t('plugin.detailPanel.categoryTip.github')} > - <Github className='w-3.5 h-3.5 text-text-secondary hover:text-text-primary' /> - </Tooltip> - )} - {pluginDetail.source === PluginSource.local && ( - <Tooltip popupContent={t('plugin.detailPanel.categoryTip.local')} > - <RiHardDrive3Line className='w-3.5 h-3.5 text-text-tertiary' /> - </Tooltip> - )} - {pluginDetail.source === PluginSource.debugging && ( - <Tooltip popupContent={t('plugin.detailPanel.categoryTip.debugging')} > - <RiBugLine className='w-3.5 h-3.5 text-text-tertiary hover:text-text-warning' /> - </Tooltip> - )} - </div> - </div> - </div> - <div className='flex gap-1'> - <OperationDropdown /> - <ActionButton onClick={onHide}> - <RiCloseLine className='w-4 h-4' /> - </ActionButton> - </div> - </div> - <Description className='mt-3' text={pluginDetail.declaration.description[locale]} descriptionLineRows={2}></Description> - </div> + <DetailHeader + detail={pluginDetail} + onHide={onHide} + onDelete={handleDelete} + /> <div className='grow overflow-y-auto'> <ActionList /> <EndpointList /> diff --git a/web/app/components/plugins/plugin-detail-panel/operation-dropdown.tsx b/web/app/components/plugins/plugin-detail-panel/operation-dropdown.tsx index c9be924a65..e8186d1958 100644 --- a/web/app/components/plugins/plugin-detail-panel/operation-dropdown.tsx +++ b/web/app/components/plugins/plugin-detail-panel/operation-dropdown.tsx @@ -13,9 +13,14 @@ import { import cn from '@/utils/classnames' type Props = { + onInfo: () => void + onRemove: () => void } -const OperationDropdown: FC<Props> = () => { +const OperationDropdown: FC<Props> = ({ + onInfo, + onRemove, +}) => { const { t } = useTranslation() const [open, doSetOpen] = useState(false) const openRef = useRef(open) @@ -45,14 +50,16 @@ const OperationDropdown: FC<Props> = () => { </PortalToFollowElemTrigger> <PortalToFollowElemContent className='z-50'> <div className='w-[160px] p-1 bg-components-panel-bg-blur rounded-xl border-[0.5px] border-components-panel-border shadow-lg'> - <div className='px-3 py-1.5 rounded-lg text-text-secondary system-md-regular cursor-pointer hover:bg-state-base-hover'>{t('plugin.detailPanel.operation.info')}</div> + <div onClick={onInfo} className='px-3 py-1.5 rounded-lg text-text-secondary system-md-regular cursor-pointer hover:bg-state-base-hover'>{t('plugin.detailPanel.operation.info')}</div> + {/* ##plugin TODO## check update */} <div className='px-3 py-1.5 rounded-lg text-text-secondary system-md-regular cursor-pointer hover:bg-state-base-hover'>{t('plugin.detailPanel.operation.checkUpdate')}</div> + {/* ##plugin TODO## router action */} <div className='flex items-center px-3 py-1.5 rounded-lg text-text-secondary system-md-regular cursor-pointer hover:bg-state-base-hover'> <div className='grow'>{t('plugin.detailPanel.operation.viewDetail')}</div> <RiArrowRightUpLine className='shrink-0 w-3.5 h-3.5 text-text-tertiary' /> </div> <div className='my-1 h-px bg-divider-subtle'></div> - <div className='px-3 py-1.5 rounded-lg text-text-secondary system-md-regular cursor-pointer hover:bg-state-base-hover'>{t('plugin.detailPanel.operation.remove')}</div> + <div onClick={onRemove} className='px-3 py-1.5 rounded-lg text-text-secondary system-md-regular cursor-pointer hover:bg-state-base-hover'>{t('plugin.detailPanel.operation.remove')}</div> </div> </PortalToFollowElemContent> </PortalToFollowElem> From 5e077e4ce893733b6efba9b49005c2bc5a744191 Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Sat, 19 Oct 2024 14:18:51 +0800 Subject: [PATCH 102/346] endpoints data binding --- .../plugin-detail-panel/endpoint-card.tsx | 60 +++++++++++++++ .../plugin-detail-panel/endpoint-list.tsx | 74 ++++--------------- .../plugins/plugin-detail-panel/index.tsx | 15 +++- .../plugins/plugin-detail-panel/mock.ts | 29 +++++++- .../plugins/plugin-page/plugins-panel.tsx | 17 +++-- web/app/components/plugins/types.ts | 2 +- 6 files changed, 126 insertions(+), 71 deletions(-) create mode 100644 web/app/components/plugins/plugin-detail-panel/endpoint-card.tsx diff --git a/web/app/components/plugins/plugin-detail-panel/endpoint-card.tsx b/web/app/components/plugins/plugin-detail-panel/endpoint-card.tsx new file mode 100644 index 0000000000..59f620a64e --- /dev/null +++ b/web/app/components/plugins/plugin-detail-panel/endpoint-card.tsx @@ -0,0 +1,60 @@ +import React from 'react' +import { useTranslation } from 'react-i18next' +import { RiLoginCircleLine } from '@remixicon/react' +import CopyBtn from '@/app/components/base/copy-btn' +import Indicator from '@/app/components/header/indicator' +import Switch from '@/app/components/base/switch' + +const EndpointCard = () => { + const { t } = useTranslation() + return ( + <div className='p-0.5 bg-background-section-burn rounded-xl'> + <div className='p-2.5 pl-3 bg-components-panel-on-panel-item-bg rounded-[10px] border-[0.5px] border-components-panel-border'> + <div className='mb-1 h-6 flex items-center gap-1 text-text-secondary system-md-semibold'> + <RiLoginCircleLine className='w-4 h-4' /> + <div>Endpoint for Unreal workspace</div> + </div> + <div className='h-6 flex items-center'> + <div className='shrink-0 w-24 text-text-tertiary system-xs-regular'>Start Callback</div> + <div className='group grow flex items-center text-text-secondary system-xs-regular truncate'> + <div className='truncate'>https://extension.dify.ai/a1b2c3d4/onStart</div> + <CopyBtn + className='hidden shrink-0 ml-2 group-hover:block' + value={'https://extension.dify.ai/a1b2c3d4/onStart'} + isPlain + /> + </div> + </div> + <div className='h-6 flex items-center'> + <div className='shrink-0 w-24 text-text-tertiary system-xs-regular'>Finish Callback</div> + <div className='group grow flex items-center text-text-secondary system-xs-regular truncate'> + <div className='truncate'>https://extension.dify.ai/a1b2c3d4/onFinish</div> + <CopyBtn + className='hidden shrink-0 ml-2 group-hover:block' + value={'https://extension.dify.ai/a1b2c3d4/onFinish'} + isPlain + /> + </div> + </div> + </div> + <div className='px-3 py-2 flex items-center justify-between'> + <div className='flex items-center gap-1 system-xs-semibold-uppercase text-util-colors-green-green-600'> + <Indicator color='green' /> + {t('plugin.detailPanel.serviceOk')} + </div> + {/* <div className='flex items-center gap-1 system-xs-semibold-uppercase text-text-tertiary'> + <Indicator color='gray' /> + {t('plugin.detailPanel.disabled')} + </div> */} + <Switch + className='ml-3' + defaultValue={true} + onChange={() => {}} + size='sm' + /> + </div> + </div> + ) +} + +export default EndpointCard diff --git a/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx b/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx index 4dfd4bbd55..5acf1c18ab 100644 --- a/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx +++ b/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx @@ -1,65 +1,19 @@ import React from 'react' import { useTranslation } from 'react-i18next' -import { RiAddLine, RiLoginCircleLine } from '@remixicon/react' +import { RiAddLine } from '@remixicon/react' +import EndpointCard from './endpoint-card' import ActionButton from '@/app/components/base/action-button' -import CopyBtn from '@/app/components/base/copy-btn' -import Indicator from '@/app/components/header/indicator' import Tooltip from '@/app/components/base/tooltip' -import Switch from '@/app/components/base/switch' -const EndpointCard = () => { - const { t } = useTranslation() - return ( - <div className='p-0.5 bg-background-section-burn rounded-xl'> - <div className='p-2.5 pl-3 bg-components-panel-on-panel-item-bg rounded-[10px] border-[0.5px] border-components-panel-border'> - <div className='mb-1 h-6 flex items-center gap-1 text-text-secondary system-md-semibold'> - <RiLoginCircleLine className='w-4 h-4' /> - <div>Endpoint for Unreal workspace</div> - </div> - <div className='h-6 flex items-center'> - <div className='shrink-0 w-24 text-text-tertiary system-xs-regular'>Start Callback</div> - <div className='group grow flex items-center text-text-secondary system-xs-regular truncate'> - <div className='truncate'>https://extension.dify.ai/a1b2c3d4/onStart</div> - <CopyBtn - className='hidden shrink-0 ml-2 group-hover:block' - value={'https://extension.dify.ai/a1b2c3d4/onStart'} - isPlain - /> - </div> - </div> - <div className='h-6 flex items-center'> - <div className='shrink-0 w-24 text-text-tertiary system-xs-regular'>Finish Callback</div> - <div className='group grow flex items-center text-text-secondary system-xs-regular truncate'> - <div className='truncate'>https://extension.dify.ai/a1b2c3d4/onFinish</div> - <CopyBtn - className='hidden shrink-0 ml-2 group-hover:block' - value={'https://extension.dify.ai/a1b2c3d4/onFinish'} - isPlain - /> - </div> - </div> - </div> - <div className='px-3 py-2 flex items-center justify-between'> - <div className='flex items-center gap-1 system-xs-semibold-uppercase text-util-colors-green-green-600'> - <Indicator color='green' /> - {t('plugin.detailPanel.serviceOk')} - </div> - {/* <div className='flex items-center gap-1 system-xs-semibold-uppercase text-text-tertiary'> - <Indicator color='gray' /> - {t('plugin.detailPanel.disabled')} - </div> */} - <Switch - className='ml-3' - defaultValue={true} - onChange={() => {}} - size='sm' - /> - </div> - </div> - ) +type Props = { + declaration: any + list: any[] } -const EndpointList = () => { +const EndpointList = ({ + declaration, + list, +}: Props) => { const { t } = useTranslation() return ( <div className='px-4 py-2 border-t border-divider-subtle'> @@ -80,11 +34,13 @@ const EndpointList = () => { <RiAddLine className='w-4 h-4' /> </ActionButton> </div> - <div className='mb-1 p-3 flex justify-center rounded-[10px] bg-background-section text-text-tertiary system-xs-regular'>{t('plugin.detailPanel.endpointsEmpty')}</div> + {list.length === 0 && ( + <div className='mb-1 p-3 flex justify-center rounded-[10px] bg-background-section text-text-tertiary system-xs-regular'>{t('plugin.detailPanel.endpointsEmpty')}</div> + )} <div className='flex flex-col gap-2'> - <EndpointCard /> - <EndpointCard /> - <EndpointCard /> + {list.map((item, index) => ( + <EndpointCard key={index} /> + ))} </div> </div> ) diff --git a/web/app/components/plugins/plugin-detail-panel/index.tsx b/web/app/components/plugins/plugin-detail-panel/index.tsx index 0fd9570137..17823dea23 100644 --- a/web/app/components/plugins/plugin-detail-panel/index.tsx +++ b/web/app/components/plugins/plugin-detail-panel/index.tsx @@ -2,7 +2,7 @@ import React from 'react' import type { FC } from 'react' import { useTranslation } from 'react-i18next' -import type { PluginDetail } from '../types' +import type { EndpointListItem, PluginDetail } from '../types' import DetailHeader from './detail-header' import EndpointList from './endpoint-list' import ActionList from './action-list' @@ -13,11 +13,13 @@ import cn from '@/utils/classnames' type Props = { pluginDetail: PluginDetail | undefined + endpointList: EndpointListItem[] onHide: () => void } const PluginDetailPanel: FC<Props> = ({ pluginDetail, + endpointList = [], onHide, }) => { const { t } = useTranslation() @@ -46,9 +48,14 @@ const PluginDetailPanel: FC<Props> = ({ onDelete={handleDelete} /> <div className='grow overflow-y-auto'> - <ActionList /> - <EndpointList /> - <ModelList /> + {!!pluginDetail.declaration.endpoint && ( + <EndpointList + list={endpointList} + declaration={pluginDetail.declaration.endpoint} + /> + )} + {!!pluginDetail.declaration.tool && <ActionList />} + {!!pluginDetail.declaration.model && <ModelList />} </div> </> )} diff --git a/web/app/components/plugins/plugin-detail-panel/mock.ts b/web/app/components/plugins/plugin-detail-panel/mock.ts index 7c421ce942..dd76c7bdbe 100644 --- a/web/app/components/plugins/plugin-detail-panel/mock.ts +++ b/web/app/components/plugins/plugin-detail-panel/mock.ts @@ -24,7 +24,32 @@ export const toolNotion = { created_at: '2024-10-16 16:05:33', resource: {}, plugins: {}, - tool: {}, // TODO + endpoint: { + settings: [ + { + type: 'secret-input', + name: 'api-key', + required: true, + default: null, + options: null, + label: { + 'en-US': 'API-key', + 'zh-Hans': 'API-key', + }, + help: null, + url: null, + placeholder: { + 'en-US': 'Please input your API key', + 'zh-Hans': '请输入你的 API key', + }, + }, + ], + endpoints: [ + { path: '/duck/<app_id>', method: 'GET' }, + { path: '/neko', method: 'GET' }, + ], + }, + tool: null, // TODO verified: true, }, installation_id: 'jflkdsjoewingljlsadjgoijg-dkfjldajglkajglask-dlfkajdg', @@ -67,7 +92,7 @@ export const toolNotionEndpoints = [ }, }, ], - endpoint: [ + endpoints: [ { path: '/duck/<app_id>', method: 'GET' }, { path: '/neko', method: 'GET' }, ], diff --git a/web/app/components/plugins/plugin-page/plugins-panel.tsx b/web/app/components/plugins/plugin-page/plugins-panel.tsx index 7bd9620177..7dd8a5e480 100644 --- a/web/app/components/plugins/plugin-page/plugins-panel.tsx +++ b/web/app/components/plugins/plugin-page/plugins-panel.tsx @@ -1,12 +1,11 @@ 'use client' import { useState } from 'react' -import type { PluginDetail } from '../types' -import PluginDetailPanel from '@/app/components/plugins/plugin-detail-panel' -import { toolNotion } from '@/app/components/plugins/plugin-detail-panel/mock' - +import type { EndpointListItem, PluginDetail } from '../types' import type { FilterState } from './filter-management' import FilterManagement from './filter-management' import List from './list' +import PluginDetailPanel from '@/app/components/plugins/plugin-detail-panel' +import { toolNotion, toolNotionEndpoints } from '@/app/components/plugins/plugin-detail-panel/mock' const PluginsPanel = () => { const handleFilterChange = (filters: FilterState) => { @@ -14,6 +13,7 @@ const PluginsPanel = () => { } const [currentPluginDetail, setCurrentPluginDetail] = useState<PluginDetail | undefined>(toolNotion as any) + const [currentPluginEndpoints, setCurrentEndpoints] = useState<EndpointListItem[]>(toolNotionEndpoints as any) return ( <> <div className='flex flex-col pt-1 pb-3 px-12 justify-center items-start gap-3 self-stretch'> @@ -27,7 +27,14 @@ const PluginsPanel = () => { <List /> </div> </div> - <PluginDetailPanel pluginDetail={currentPluginDetail} onHide={() => setCurrentPluginDetail(undefined)} /> + <PluginDetailPanel + pluginDetail={currentPluginDetail} + endpointList={currentPluginEndpoints} + onHide={() => { + setCurrentPluginDetail(undefined) + setCurrentEndpoints([]) + }} + /> </> ) } diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts index 4b3b750497..75a8e1e9a0 100644 --- a/web/app/components/plugins/types.ts +++ b/web/app/components/plugins/types.ts @@ -63,8 +63,8 @@ export type PluginDeclaration = { resource: any // useless in frontend plugins: any // useless in frontend verified: boolean - tool: PluginToolDeclaration endpoint: PluginEndpointDeclaration + tool: PluginToolDeclaration model: any // TODO } From 0279bd8c759442f88c893b6847f1837dba7c40fa Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Sat, 19 Oct 2024 14:46:17 +0800 Subject: [PATCH 103/346] endpoint card databing --- .../plugin-detail-panel/endpoint-card.tsx | 95 +++++++++++-------- .../plugin-detail-panel/endpoint-list.tsx | 16 ++-- .../plugins/plugin-detail-panel/index.tsx | 2 - 3 files changed, 65 insertions(+), 48 deletions(-) diff --git a/web/app/components/plugins/plugin-detail-panel/endpoint-card.tsx b/web/app/components/plugins/plugin-detail-panel/endpoint-card.tsx index 59f620a64e..55a5b9e781 100644 --- a/web/app/components/plugins/plugin-detail-panel/endpoint-card.tsx +++ b/web/app/components/plugins/plugin-detail-panel/endpoint-card.tsx @@ -1,55 +1,74 @@ -import React from 'react' +import React, { useState } from 'react' import { useTranslation } from 'react-i18next' -import { RiLoginCircleLine } from '@remixicon/react' +import { RiDeleteBinLine, RiEditLine, RiLoginCircleLine } from '@remixicon/react' +import type { EndpointListItem } from '../types' +import ActionButton from '@/app/components/base/action-button' import CopyBtn from '@/app/components/base/copy-btn' import Indicator from '@/app/components/header/indicator' import Switch from '@/app/components/base/switch' -const EndpointCard = () => { +type Props = { + data: EndpointListItem +} + +const EndpointCard = ({ + data, +}: Props) => { const { t } = useTranslation() + const [active, setActive] = useState(data.enabled) + + const handleSwitch = () => { + setActive(!active) + } + return ( <div className='p-0.5 bg-background-section-burn rounded-xl'> - <div className='p-2.5 pl-3 bg-components-panel-on-panel-item-bg rounded-[10px] border-[0.5px] border-components-panel-border'> - <div className='mb-1 h-6 flex items-center gap-1 text-text-secondary system-md-semibold'> - <RiLoginCircleLine className='w-4 h-4' /> - <div>Endpoint for Unreal workspace</div> - </div> - <div className='h-6 flex items-center'> - <div className='shrink-0 w-24 text-text-tertiary system-xs-regular'>Start Callback</div> - <div className='group grow flex items-center text-text-secondary system-xs-regular truncate'> - <div className='truncate'>https://extension.dify.ai/a1b2c3d4/onStart</div> - <CopyBtn - className='hidden shrink-0 ml-2 group-hover:block' - value={'https://extension.dify.ai/a1b2c3d4/onStart'} - isPlain - /> + <div className='group p-2.5 pl-3 bg-components-panel-on-panel-item-bg rounded-[10px] border-[0.5px] border-components-panel-border'> + <div className='flex items-center'> + <div className='grow mb-1 h-6 flex items-center gap-1 text-text-secondary system-md-semibold'> + <RiLoginCircleLine className='w-4 h-4' /> + <div>{data.name}</div> + </div> + <div className='hidden group-hover:flex items-center'> + <ActionButton> + <RiEditLine className='w-4 h-4' /> + </ActionButton> + <ActionButton className='hover:bg-state-destructive-hover text-text-tertiary hover:text-text-destructive'> + <RiDeleteBinLine className='w-4 h-4' /> + </ActionButton> </div> </div> - <div className='h-6 flex items-center'> - <div className='shrink-0 w-24 text-text-tertiary system-xs-regular'>Finish Callback</div> - <div className='group grow flex items-center text-text-secondary system-xs-regular truncate'> - <div className='truncate'>https://extension.dify.ai/a1b2c3d4/onFinish</div> - <CopyBtn - className='hidden shrink-0 ml-2 group-hover:block' - value={'https://extension.dify.ai/a1b2c3d4/onFinish'} - isPlain - /> + {data.declaration.endpoints.map((endpoint, index) => ( + <div key={index} className='h-6 flex items-center'> + <div className='shrink-0 w-12 text-text-tertiary system-xs-regular'>{endpoint.method}</div> + <div className='group/item grow flex items-center text-text-secondary system-xs-regular truncate'> + <div className='truncate'>{`${data.url}${endpoint.path}`}</div> + <CopyBtn + className='hidden shrink-0 ml-2 group-hover/item:block' + value={`${data.url}${endpoint.path}`} + isPlain + /> + </div> </div> - </div> + ))} </div> - <div className='px-3 py-2 flex items-center justify-between'> - <div className='flex items-center gap-1 system-xs-semibold-uppercase text-util-colors-green-green-600'> - <Indicator color='green' /> - {t('plugin.detailPanel.serviceOk')} - </div> - {/* <div className='flex items-center gap-1 system-xs-semibold-uppercase text-text-tertiary'> - <Indicator color='gray' /> - {t('plugin.detailPanel.disabled')} - </div> */} + <div className='p-2 pl-3 flex items-center justify-between'> + {active && ( + <div className='flex items-center gap-1 system-xs-semibold-uppercase text-util-colors-green-green-600'> + <Indicator color='green' /> + {t('plugin.detailPanel.serviceOk')} + </div> + )} + {!active && ( + <div className='flex items-center gap-1 system-xs-semibold-uppercase text-text-tertiary'> + <Indicator color='gray' /> + {t('plugin.detailPanel.disabled')} + </div> + )} <Switch className='ml-3' - defaultValue={true} - onChange={() => {}} + defaultValue={active} + onChange={handleSwitch} size='sm' /> </div> diff --git a/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx b/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx index 5acf1c18ab..2906d422fc 100644 --- a/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx +++ b/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx @@ -1,13 +1,14 @@ import React from 'react' import { useTranslation } from 'react-i18next' import { RiAddLine } from '@remixicon/react' +import type { EndpointListItem, PluginEndpointDeclaration } from '../types' import EndpointCard from './endpoint-card' import ActionButton from '@/app/components/base/action-button' import Tooltip from '@/app/components/base/tooltip' type Props = { - declaration: any - list: any[] + declaration: PluginEndpointDeclaration + list: EndpointListItem[] } const EndpointList = ({ @@ -22,11 +23,7 @@ const EndpointList = ({ {t('plugin.detailPanel.endpoints')} <Tooltip popupContent={ - <div className='w-[180px]'> - {t('appDebug.voice.voiceSettings.resolutionTooltip').split('\n').map(item => ( - <div key={item}>{item}</div> - ))} - </div> + <div className='w-[180px]'>TODO</div> } /> </div> @@ -39,7 +36,10 @@ const EndpointList = ({ )} <div className='flex flex-col gap-2'> {list.map((item, index) => ( - <EndpointCard key={index} /> + <EndpointCard + key={index} + data={item} + /> ))} </div> </div> diff --git a/web/app/components/plugins/plugin-detail-panel/index.tsx b/web/app/components/plugins/plugin-detail-panel/index.tsx index 17823dea23..3f60d19196 100644 --- a/web/app/components/plugins/plugin-detail-panel/index.tsx +++ b/web/app/components/plugins/plugin-detail-panel/index.tsx @@ -8,7 +8,6 @@ import EndpointList from './endpoint-list' import ActionList from './action-list' import ModelList from './model-list' import Drawer from '@/app/components/base/drawer' -// import Loading from '@/app/components/base/loading' import cn from '@/utils/classnames' type Props = { @@ -39,7 +38,6 @@ const PluginDetailPanel: FC<Props> = ({ positionCenter={false} panelClassname={cn('justify-start mt-[64px] mr-2 mb-2 !w-[420px] !max-w-[420px] !p-0 !bg-components-panel-bg rounded-2xl border-[0.5px] border-components-panel-border shadow-xl')} > - {/* {loading && <Loading type='area' />} */} {pluginDetail && ( <> <DetailHeader From b1771194ccdb4a3257193c6651342468224758a0 Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Sat, 19 Oct 2024 15:20:09 +0800 Subject: [PATCH 104/346] servise of endpoints --- web/app/components/plugins/types.ts | 27 ++++++++++++++++++++ web/service/plugins.ts | 39 +++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts index 75a8e1e9a0..574b407895 100644 --- a/web/app/components/plugins/types.ts +++ b/web/app/components/plugins/types.ts @@ -114,3 +114,30 @@ export type Permissions = { canManagement: PermissionType canDebugger: PermissionType } + +// endpoint +export type CreateEndpointRequest = { + plugin_unique_identifier: string + settings: Record<string, any> + name: string +} +export type EndpointOperationResponse = { + result: 'success' | 'error' +} +export type EndpointsRequest = { + limit: number + page: number + plugin_id: string +} +export type EndpointsResponse = { + endpoints: EndpointListItem[] + has_more: boolean + limit: number + total: number + page: number +} +export type UpdateEndpointRequest = { + endpoint_id: string + settings: Record<string, any> + name: string +} diff --git a/web/service/plugins.ts b/web/service/plugins.ts index e69de29bb2..c5eb55c5c9 100644 --- a/web/service/plugins.ts +++ b/web/service/plugins.ts @@ -0,0 +1,39 @@ +import type { Fetcher } from 'swr' +import { del, get, post } from './base' +import type { + CreateEndpointRequest, + EndpointOperationResponse, + EndpointsRequest, + EndpointsResponse, + UpdateEndpointRequest, +} from '@/app/components/plugins/types' + +export const createEndpoint: Fetcher<EndpointOperationResponse, { url: string; body: CreateEndpointRequest }> = ({ url, body }) => { + // url = /workspaces/current/endpoints/create + return post<EndpointOperationResponse>(url, { body }) +} + +export const fetchEndpointList: Fetcher<EndpointsResponse, { url: string; params?: EndpointsRequest }> = ({ url, params }) => { + // url = /workspaces/current/endpoints/list/plugin?plugin_id=xxx + return get<EndpointsResponse>(url, { params }) +} + +export const deleteEndpoint: Fetcher<EndpointOperationResponse, { url: string; endpointID: string }> = ({ url, endpointID }) => { + // url = /workspaces/current/endpoints/delete + return del<EndpointOperationResponse>(url, { body: { endpoint_id: endpointID } }) +} + +export const updateEndpoint: Fetcher<EndpointOperationResponse, { url: string; body: UpdateEndpointRequest }> = ({ url, body }) => { + // url = /workspaces/current/endpoints/update + return post<EndpointOperationResponse>(url, { body }) +} + +export const enableEndpoint: Fetcher<EndpointOperationResponse, { url: string; endpointID: string }> = ({ url, endpointID }) => { + // url = /workspaces/current/endpoints/enable + return post<EndpointOperationResponse>(url, { body: { endpoint_id: endpointID } }) +} + +export const disableEndpoint: Fetcher<EndpointOperationResponse, { url: string; endpointID: string }> = ({ url, endpointID }) => { + // url = /workspaces/current/endpoints/disable + return post<EndpointOperationResponse>(url, { body: { endpoint_id: endpointID } }) +} From 37f55098fe3d4a5cbb2fb26c3adf8de9572648a0 Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Sat, 19 Oct 2024 15:38:03 +0800 Subject: [PATCH 105/346] switch endpoint service state --- .../plugin-detail-panel/endpoint-card.tsx | 36 +++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/web/app/components/plugins/plugin-detail-panel/endpoint-card.tsx b/web/app/components/plugins/plugin-detail-panel/endpoint-card.tsx index 55a5b9e781..5e70ca1efa 100644 --- a/web/app/components/plugins/plugin-detail-panel/endpoint-card.tsx +++ b/web/app/components/plugins/plugin-detail-panel/endpoint-card.tsx @@ -6,6 +6,10 @@ import ActionButton from '@/app/components/base/action-button' import CopyBtn from '@/app/components/base/copy-btn' import Indicator from '@/app/components/header/indicator' import Switch from '@/app/components/base/switch' +import { + disableEndpoint, + enableEndpoint, +} from '@/service/plugins' type Props = { data: EndpointListItem @@ -16,9 +20,37 @@ const EndpointCard = ({ }: Props) => { const { t } = useTranslation() const [active, setActive] = useState(data.enabled) + const endpointID = data.id - const handleSwitch = () => { - setActive(!active) + const activeEndpoint = async () => { + try { + await enableEndpoint({ + url: '/workspaces/current/endpoints/enable', + endpointID, + }) + } + catch (error) { + console.error(error) + setActive(true) + } + } + const inactiveEndpoint = async () => { + try { + await disableEndpoint({ + url: '/workspaces/current/endpoints/disable', + endpointID, + }) + } + catch (error) { + console.error(error) + setActive(false) + } + } + const handleSwitch = (state: boolean) => { + if (state) + activeEndpoint() + else + inactiveEndpoint() } return ( From d2190e9c3ab85fb04d5ab0587d74c1dc3214bafb Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Sat, 19 Oct 2024 16:17:10 +0800 Subject: [PATCH 106/346] remove endpoint --- .../plugin-detail-panel/endpoint-card.tsx | 75 ++++++++++++++++-- .../plugin-detail-panel/endpoint-modal.tsx | 79 +++++++++++++++++++ web/i18n/en-US/plugin.ts | 4 + web/i18n/zh-Hans/plugin.ts | 6 +- 4 files changed, 155 insertions(+), 9 deletions(-) create mode 100644 web/app/components/plugins/plugin-detail-panel/endpoint-modal.tsx diff --git a/web/app/components/plugins/plugin-detail-panel/endpoint-card.tsx b/web/app/components/plugins/plugin-detail-panel/endpoint-card.tsx index 5e70ca1efa..72f89d8194 100644 --- a/web/app/components/plugins/plugin-detail-panel/endpoint-card.tsx +++ b/web/app/components/plugins/plugin-detail-panel/endpoint-card.tsx @@ -1,12 +1,16 @@ import React, { useState } from 'react' import { useTranslation } from 'react-i18next' +import { useBoolean } from 'ahooks' import { RiDeleteBinLine, RiEditLine, RiLoginCircleLine } from '@remixicon/react' import type { EndpointListItem } from '../types' +import EndpointModal from './endpoint-modal' import ActionButton from '@/app/components/base/action-button' import CopyBtn from '@/app/components/base/copy-btn' +import Confirm from '@/app/components/base/confirm' import Indicator from '@/app/components/header/indicator' import Switch from '@/app/components/base/switch' import { + deleteEndpoint, disableEndpoint, enableEndpoint, } from '@/service/plugins' @@ -22,6 +26,10 @@ const EndpointCard = ({ const [active, setActive] = useState(data.enabled) const endpointID = data.id + const [isShowDisableConfirm, { + setTrue: showDisableConfirm, + setFalse: hideDisableConfirm, + }] = useBoolean(false) const activeEndpoint = async () => { try { await enableEndpoint({ @@ -31,7 +39,7 @@ const EndpointCard = ({ } catch (error) { console.error(error) - setActive(true) + setActive(false) } } const inactiveEndpoint = async () => { @@ -43,16 +51,41 @@ const EndpointCard = ({ } catch (error) { console.error(error) - setActive(false) + setActive(true) } } const handleSwitch = (state: boolean) => { - if (state) + if (state) { + setActive(true) activeEndpoint() - else - inactiveEndpoint() + } + else { + setActive(false) + showDisableConfirm() + } } + const [isShowDeleteConfirm, { + setTrue: showDeleteConfirm, + setFalse: hideDeleteConfirm, + }] = useBoolean(false) + const handleDelete = async () => { + try { + await deleteEndpoint({ + url: '/workspaces/current/endpoints/delete', + endpointID, + }) + } + catch (error) { + console.error(error) + } + } + + const [isShowEndpointModal, { + setTrue: showEndpointModalConfirm, + setFalse: hideEndpointModalConfirm, + }] = useBoolean(false) + return ( <div className='p-0.5 bg-background-section-burn rounded-xl'> <div className='group p-2.5 pl-3 bg-components-panel-on-panel-item-bg rounded-[10px] border-[0.5px] border-components-panel-border'> @@ -62,10 +95,10 @@ const EndpointCard = ({ <div>{data.name}</div> </div> <div className='hidden group-hover:flex items-center'> - <ActionButton> + <ActionButton onClick={showEndpointModalConfirm}> <RiEditLine className='w-4 h-4' /> </ActionButton> - <ActionButton className='hover:bg-state-destructive-hover text-text-tertiary hover:text-text-destructive'> + <ActionButton onClick={showDeleteConfirm} className='hover:bg-state-destructive-hover text-text-tertiary hover:text-text-destructive'> <RiDeleteBinLine className='w-4 h-4' /> </ActionButton> </div> @@ -74,7 +107,7 @@ const EndpointCard = ({ <div key={index} className='h-6 flex items-center'> <div className='shrink-0 w-12 text-text-tertiary system-xs-regular'>{endpoint.method}</div> <div className='group/item grow flex items-center text-text-secondary system-xs-regular truncate'> - <div className='truncate'>{`${data.url}${endpoint.path}`}</div> + <div title={`${data.url}${endpoint.path}`} className='truncate'>{`${data.url}${endpoint.path}`}</div> <CopyBtn className='hidden shrink-0 ml-2 group-hover/item:block' value={`${data.url}${endpoint.path}`} @@ -104,6 +137,32 @@ const EndpointCard = ({ size='sm' /> </div> + {isShowDisableConfirm && ( + <Confirm + isShow + title={t('plugin.detailPanel.endpointDisableTip')} + content={<div>{t('plugin.detailPanel.endpointDisableContent', { name: data.name })}</div>} + onCancel={() => { + hideDisableConfirm() + setActive(true) + }} + onConfirm={inactiveEndpoint} + /> + )} + {isShowDeleteConfirm && ( + <Confirm + isShow + title={t('plugin.detailPanel.endpointDeleteTip')} + content={<div>{t('plugin.detailPanel.endpointDeleteContent', { name: data.name })}</div>} + onCancel={hideDeleteConfirm} + onConfirm={handleDelete} + /> + )} + {isShowEndpointModal && ( + <EndpointModal + onCancel={hideEndpointModalConfirm} + /> + )} </div> ) } diff --git a/web/app/components/plugins/plugin-detail-panel/endpoint-modal.tsx b/web/app/components/plugins/plugin-detail-panel/endpoint-modal.tsx new file mode 100644 index 0000000000..bc65596044 --- /dev/null +++ b/web/app/components/plugins/plugin-detail-panel/endpoint-modal.tsx @@ -0,0 +1,79 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import { useTranslation } from 'react-i18next' +import Drawer from '@/app/components/base/drawer' +import Button from '@/app/components/base/button' +// import Toast from '@/app/components/base/toast' +// import Form from '@/app/components/header/account-setting/model-provider-page/model-modal/Form' +// import { LinkExternal02 } from '@/app/components/base/icons/src/vender/line/general' +import { useLanguage } from '@/app/components/header/account-setting/model-provider-page/hooks' +import cn from '@/utils/classnames' + +type Props = { + onCancel: () => void + // onSaved: (value: Record<string, any>) => void + onRemove?: () => void +} + +const EndpointModal: FC<Props> = ({ + onCancel, + // onSaved, + onRemove = () => { }, +}) => { + const { t } = useTranslation() + const language = useLanguage() + + const handleSave = () => { + // for (const field of credentialSchema) { + // if (field.required && !tempCredential[field.name]) { + // Toast.notify({ type: 'error', message: t('common.errorMsg.fieldRequired', { field: field.label[language] || field.label.en_US }) }) + // return + // } + // } + // onSaved(tempCredential) + } + + return ( + <Drawer + isOpen + clickOutsideNotOpen={false} + onClose={onCancel} + footer={null} + mask + positionCenter={false} + panelClassname={cn('justify-start mt-[64px] mr-2 mb-2 !w-[420px] !max-w-[420px] !p-0 !bg-components-panel-bg rounded-2xl border-[0.5px] border-components-panel-border shadow-xl')} + > + <> + {/* <Form + value={tempCredential} + onChange={(v) => { + setTempCredential(v) + }} + formSchemas={credentialSchema} + isEditMode={true} + showOnVariableMap={{}} + validating={false} + inputClassName='!bg-gray-50' + fieldMoreInfo={item => item.url + ? (<a + href={item.url} + target='_blank' rel='noopener noreferrer' + className='inline-flex items-center text-xs text-primary-600' + > + {t('tools.howToGet')} + <LinkExternal02 className='ml-1 w-3 h-3' /> + </a>) + : null} + /> */} + <div className={cn('mt-2 flex justify-end')} > + < div className='flex space-x-2'> + <Button onClick={onCancel}>{t('common.operation.cancel')}</Button> + <Button variant='primary' onClick={handleSave}>{t('common.operation.save')}</Button> + </div> + </div> + </> + </Drawer> + ) +} +export default React.memo(EndpointModal) diff --git a/web/i18n/en-US/plugin.ts b/web/i18n/en-US/plugin.ts index 7decbcd9d4..3866263fb7 100644 --- a/web/i18n/en-US/plugin.ts +++ b/web/i18n/en-US/plugin.ts @@ -21,6 +21,10 @@ const translation = { actionNum: '{{num}} ACTIONS INCLUDED', endpoints: 'Endpoints', endpointsEmpty: 'Click the \'+\' button to add an endpoint', + endpointDisableTip: 'Disable Endpoint', + endpointDisableContent: 'Would you like to disable {{name}}? ', + endpointDeleteTip: 'Remove Endpoint', + endpointDeleteContent: 'Would you like to remove {{name}}? ', serviceOk: 'Service OK', disabled: 'Disabled', modelNum: '{{num}} MODELS INCLUDED', diff --git a/web/i18n/zh-Hans/plugin.ts b/web/i18n/zh-Hans/plugin.ts index 118595971f..26f913ce2f 100644 --- a/web/i18n/zh-Hans/plugin.ts +++ b/web/i18n/zh-Hans/plugin.ts @@ -20,7 +20,11 @@ const translation = { }, actionNum: '{{num}} ACTIONS 已包含', endpoints: 'Endpoints', - endpointsEmpty: '点击 \'+\' 按钮添加端点', + endpointsEmpty: '点击 \'+\' 按钮添加 Endpoint', + endpointDisableTip: '停用 Endpoint', + endpointDisableContent: '是否要停用 {{name}} 的 Endpoint ?', + endpointDeleteTip: '移除 Endpoint', + endpointDeleteContent: '是否要移除 {{name}} ?', serviceOk: '服务正常', disabled: '停用', modelNum: '{{num}} 模型已包含', From ebaf8766ef085827768b7b54e51b47ea2c395af2 Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Sat, 19 Oct 2024 17:23:26 +0800 Subject: [PATCH 107/346] endpoint form --- .../plugin-detail-panel/endpoint-card.tsx | 13 ++- .../plugin-detail-panel/endpoint-list.tsx | 26 +++++- .../plugin-detail-panel/endpoint-modal.tsx | 79 ++++++++++++------- .../plugins/plugin-detail-panel/index.tsx | 1 + .../plugins/plugin-detail-panel/mock.ts | 16 ++-- web/app/components/plugins/types.ts | 5 +- web/i18n/en-US/plugin.ts | 2 + web/i18n/zh-Hans/plugin.ts | 2 + 8 files changed, 101 insertions(+), 43 deletions(-) diff --git a/web/app/components/plugins/plugin-detail-panel/endpoint-card.tsx b/web/app/components/plugins/plugin-detail-panel/endpoint-card.tsx index 72f89d8194..066c6cc737 100644 --- a/web/app/components/plugins/plugin-detail-panel/endpoint-card.tsx +++ b/web/app/components/plugins/plugin-detail-panel/endpoint-card.tsx @@ -1,9 +1,10 @@ -import React, { useState } from 'react' +import React, { useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import { useBoolean } from 'ahooks' import { RiDeleteBinLine, RiEditLine, RiLoginCircleLine } from '@remixicon/react' import type { EndpointListItem } from '../types' import EndpointModal from './endpoint-modal' +import { addDefaultValue, toolCredentialToFormSchemas } from '@/app/components/tools/utils/to-form-schema' import ActionButton from '@/app/components/base/action-button' import CopyBtn from '@/app/components/base/copy-btn' import Confirm from '@/app/components/base/confirm' @@ -86,6 +87,13 @@ const EndpointCard = ({ setFalse: hideEndpointModalConfirm, }] = useBoolean(false) + const formSchemas = useMemo(() => { + return toolCredentialToFormSchemas(data.declaration.settings) + }, [data.declaration.settings]) + const formValue = useMemo(() => { + return addDefaultValue(data.settings, formSchemas) + }, [data.settings, formSchemas]) + return ( <div className='p-0.5 bg-background-section-burn rounded-xl'> <div className='group p-2.5 pl-3 bg-components-panel-on-panel-item-bg rounded-[10px] border-[0.5px] border-components-panel-border'> @@ -160,6 +168,9 @@ const EndpointCard = ({ )} {isShowEndpointModal && ( <EndpointModal + id={data.id} + formSchemas={formSchemas} + defaultValues={formValue} onCancel={hideEndpointModalConfirm} /> )} diff --git a/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx b/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx index 2906d422fc..a40f7345da 100644 --- a/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx +++ b/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx @@ -1,21 +1,36 @@ -import React from 'react' +import React, { useMemo } from 'react' import { useTranslation } from 'react-i18next' +import { useBoolean } from 'ahooks' import { RiAddLine } from '@remixicon/react' import type { EndpointListItem, PluginEndpointDeclaration } from '../types' +import EndpointModal from './endpoint-modal' import EndpointCard from './endpoint-card' +import { toolCredentialToFormSchemas } from '@/app/components/tools/utils/to-form-schema' import ActionButton from '@/app/components/base/action-button' import Tooltip from '@/app/components/base/tooltip' type Props = { + pluginUniqueID: string declaration: PluginEndpointDeclaration list: EndpointListItem[] } const EndpointList = ({ + pluginUniqueID, declaration, list, }: Props) => { const { t } = useTranslation() + + const [isShowEndpointModal, { + setTrue: showEndpointModal, + setFalse: hideEndpointModal, + }] = useBoolean(false) + + const formSchemas = useMemo(() => { + return toolCredentialToFormSchemas(declaration.settings) + }, [declaration.settings]) + return ( <div className='px-4 py-2 border-t border-divider-subtle'> <div className='mb-1 h-6 flex items-center justify-between text-text-secondary system-sm-semibold-uppercase'> @@ -27,7 +42,7 @@ const EndpointList = ({ } /> </div> - <ActionButton> + <ActionButton onClick={showEndpointModal}> <RiAddLine className='w-4 h-4' /> </ActionButton> </div> @@ -42,6 +57,13 @@ const EndpointList = ({ /> ))} </div> + {isShowEndpointModal && ( + <EndpointModal + id={pluginUniqueID} + formSchemas={formSchemas} + onCancel={hideEndpointModal} + /> + )} </div> ) } diff --git a/web/app/components/plugins/plugin-detail-panel/endpoint-modal.tsx b/web/app/components/plugins/plugin-detail-panel/endpoint-modal.tsx index bc65596044..aac18dbcbb 100644 --- a/web/app/components/plugins/plugin-detail-panel/endpoint-modal.tsx +++ b/web/app/components/plugins/plugin-detail-panel/endpoint-modal.tsx @@ -2,27 +2,33 @@ import type { FC } from 'react' import React from 'react' import { useTranslation } from 'react-i18next' -import Drawer from '@/app/components/base/drawer' +import { RiArrowRightUpLine, RiCloseLine } from '@remixicon/react' +import ActionButton from '@/app/components/base/action-button' import Button from '@/app/components/base/button' +import Drawer from '@/app/components/base/drawer' +import Form from '@/app/components/header/account-setting/model-provider-page/model-modal/Form' // import Toast from '@/app/components/base/toast' -// import Form from '@/app/components/header/account-setting/model-provider-page/model-modal/Form' -// import { LinkExternal02 } from '@/app/components/base/icons/src/vender/line/general' import { useLanguage } from '@/app/components/header/account-setting/model-provider-page/hooks' import cn from '@/utils/classnames' type Props = { + id: string + formSchemas: any + defaultValues?: any onCancel: () => void // onSaved: (value: Record<string, any>) => void - onRemove?: () => void } const EndpointModal: FC<Props> = ({ + id, + formSchemas, + defaultValues = {}, onCancel, // onSaved, - onRemove = () => { }, }) => { const { t } = useTranslation() const language = useLanguage() + const [tempCredential, setTempCredential] = React.useState<any>(defaultValues) const handleSave = () => { // for (const field of credentialSchema) { @@ -45,31 +51,44 @@ const EndpointModal: FC<Props> = ({ panelClassname={cn('justify-start mt-[64px] mr-2 mb-2 !w-[420px] !max-w-[420px] !p-0 !bg-components-panel-bg rounded-2xl border-[0.5px] border-components-panel-border shadow-xl')} > <> - {/* <Form - value={tempCredential} - onChange={(v) => { - setTempCredential(v) - }} - formSchemas={credentialSchema} - isEditMode={true} - showOnVariableMap={{}} - validating={false} - inputClassName='!bg-gray-50' - fieldMoreInfo={item => item.url - ? (<a - href={item.url} - target='_blank' rel='noopener noreferrer' - className='inline-flex items-center text-xs text-primary-600' - > - {t('tools.howToGet')} - <LinkExternal02 className='ml-1 w-3 h-3' /> - </a>) - : null} - /> */} - <div className={cn('mt-2 flex justify-end')} > - < div className='flex space-x-2'> - <Button onClick={onCancel}>{t('common.operation.cancel')}</Button> - <Button variant='primary' onClick={handleSave}>{t('common.operation.save')}</Button> + <div className='p-4 pb-2'> + <div className='flex items-center justify-between'> + <div className='text-text-primary system-xl-semibold'>{t('plugin.detailPanel.endpointModalTitle')}</div> + <ActionButton onClick={onCancel}> + <RiCloseLine className='w-4 h-4' /> + </ActionButton> + </div> + <div className='mt-0.5 text-text-tertiary system-xs-regular'>{t('plugin.detailPanel.endpointModalDesc')}</div> + </div> + <div className='grow overflow-y-auto'> + <div className='px-4 py-2'> + <Form + value={tempCredential} + onChange={(v) => { + setTempCredential(v) + }} + formSchemas={formSchemas} + isEditMode={true} + showOnVariableMap={{}} + validating={false} + inputClassName='!bg-gray-50' + fieldMoreInfo={item => item.url + ? (<a + href={item.url} + target='_blank' rel='noopener noreferrer' + className='inline-flex items-center body-xs-regular text-text-accent-secondary' + > + {t('tools.howToGet')} + <RiArrowRightUpLine className='ml-1 w-3 h-3' /> + </a>) + : null} + /> + </div> + <div className={cn('p-4 pt-0 flex justify-end')} > + <div className='flex gap-2'> + <Button onClick={onCancel}>{t('common.operation.cancel')}</Button> + <Button variant='primary' onClick={handleSave}>{t('common.operation.save')}</Button> + </div> </div> </div> </> diff --git a/web/app/components/plugins/plugin-detail-panel/index.tsx b/web/app/components/plugins/plugin-detail-panel/index.tsx index 3f60d19196..76ae8d7625 100644 --- a/web/app/components/plugins/plugin-detail-panel/index.tsx +++ b/web/app/components/plugins/plugin-detail-panel/index.tsx @@ -48,6 +48,7 @@ const PluginDetailPanel: FC<Props> = ({ <div className='grow overflow-y-auto'> {!!pluginDetail.declaration.endpoint && ( <EndpointList + pluginUniqueID={pluginDetail.plugin_unique_identifier} list={endpointList} declaration={pluginDetail.declaration.endpoint} /> diff --git a/web/app/components/plugins/plugin-detail-panel/mock.ts b/web/app/components/plugins/plugin-detail-panel/mock.ts index dd76c7bdbe..dffe753922 100644 --- a/web/app/components/plugins/plugin-detail-panel/mock.ts +++ b/web/app/components/plugins/plugin-detail-panel/mock.ts @@ -33,14 +33,14 @@ export const toolNotion = { default: null, options: null, label: { - 'en-US': 'API-key', - 'zh-Hans': 'API-key', + en_US: 'API-key', + zh_Hans: 'API-key', }, help: null, url: null, placeholder: { - 'en-US': 'Please input your API key', - 'zh-Hans': '请输入你的 API key', + en_US: 'Please input your API key', + zh_Hans: '请输入你的 API key', }, }, ], @@ -81,14 +81,14 @@ export const toolNotionEndpoints = [ default: null, options: null, label: { - 'en-US': 'API-key', - 'zh-Hans': 'API-key', + en_US: 'API-key', + zh_Hans: 'API-key', }, help: null, url: null, placeholder: { - 'en-US': 'Please input your API key', - 'zh-Hans': '请输入你的 API key', + en_US: 'Please input your API key', + zh_Hans: '请输入你的 API key', }, }, ], diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts index 574b407895..2becf1e43d 100644 --- a/web/app/components/plugins/types.ts +++ b/web/app/components/plugins/types.ts @@ -1,4 +1,5 @@ import type { CredentialFormSchemaBase } from '../header/account-setting/model-provider-page/declarations' +import type { ToolCredential } from '@/app/components/tools/types' import type { Locale } from '@/i18n' export enum PluginType { @@ -23,11 +24,11 @@ export type PluginToolDeclaration = { label: Record<Locale, string> tags: string[] } - credentials_schema: CredentialFormSchemaBase[] // TODO + credentials_schema: ToolCredential[] // TODO } export type PluginEndpointDeclaration = { - settings: CredentialFormSchemaBase[] + settings: ToolCredential[] endpoints: EndpointItem[] } diff --git a/web/i18n/en-US/plugin.ts b/web/i18n/en-US/plugin.ts index 3866263fb7..b2ce5654ad 100644 --- a/web/i18n/en-US/plugin.ts +++ b/web/i18n/en-US/plugin.ts @@ -25,6 +25,8 @@ const translation = { endpointDisableContent: 'Would you like to disable {{name}}? ', endpointDeleteTip: 'Remove Endpoint', endpointDeleteContent: 'Would you like to remove {{name}}? ', + endpointModalTitle: 'Setup endpoint', + endpointModalDesc: 'After configuring form, all members within the workspace can use this endpoint when orchestrating applications.', serviceOk: 'Service OK', disabled: 'Disabled', modelNum: '{{num}} MODELS INCLUDED', diff --git a/web/i18n/zh-Hans/plugin.ts b/web/i18n/zh-Hans/plugin.ts index 26f913ce2f..69f0aeb079 100644 --- a/web/i18n/zh-Hans/plugin.ts +++ b/web/i18n/zh-Hans/plugin.ts @@ -25,6 +25,8 @@ const translation = { endpointDisableContent: '是否要停用 {{name}} 的 Endpoint ?', endpointDeleteTip: '移除 Endpoint', endpointDeleteContent: '是否要移除 {{name}} ?', + endpointModalTitle: '设置 Endpoint', + endpointModalDesc: '配置表单后,工作区内的所有成员都可以在编排应用时使用此端点。', serviceOk: '服务正常', disabled: '停用', modelNum: '{{num}} 模型已包含', From 973cd126bbf9bd96d7fab94e2933bce5b9b6c262 Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Sat, 19 Oct 2024 17:37:23 +0800 Subject: [PATCH 108/346] create & update endpoint --- .../plugin-detail-panel/endpoint-card.tsx | 19 +++++++++++++++- .../plugin-detail-panel/endpoint-list.tsx | 21 +++++++++++++++++- .../plugin-detail-panel/endpoint-modal.tsx | 22 +++++++++---------- 3 files changed, 48 insertions(+), 14 deletions(-) diff --git a/web/app/components/plugins/plugin-detail-panel/endpoint-card.tsx b/web/app/components/plugins/plugin-detail-panel/endpoint-card.tsx index 066c6cc737..948cbdd225 100644 --- a/web/app/components/plugins/plugin-detail-panel/endpoint-card.tsx +++ b/web/app/components/plugins/plugin-detail-panel/endpoint-card.tsx @@ -14,6 +14,7 @@ import { deleteEndpoint, disableEndpoint, enableEndpoint, + updateEndpoint, } from '@/service/plugins' type Props = { @@ -94,6 +95,22 @@ const EndpointCard = ({ return addDefaultValue(data.settings, formSchemas) }, [data.settings, formSchemas]) + const handleUpdate = (state: any) => { + try { + updateEndpoint({ + url: '/workspaces/current/endpoints', + body: { + endpoint_id: data.id, + settings: state, + name: state.name, + }, + }) + } + catch (error) { + console.error(error) + } + } + return ( <div className='p-0.5 bg-background-section-burn rounded-xl'> <div className='group p-2.5 pl-3 bg-components-panel-on-panel-item-bg rounded-[10px] border-[0.5px] border-components-panel-border'> @@ -168,10 +185,10 @@ const EndpointCard = ({ )} {isShowEndpointModal && ( <EndpointModal - id={data.id} formSchemas={formSchemas} defaultValues={formValue} onCancel={hideEndpointModalConfirm} + onSaved={handleUpdate} /> )} </div> diff --git a/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx b/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx index a40f7345da..de87750ad4 100644 --- a/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx +++ b/web/app/components/plugins/plugin-detail-panel/endpoint-list.tsx @@ -8,6 +8,9 @@ import EndpointCard from './endpoint-card' import { toolCredentialToFormSchemas } from '@/app/components/tools/utils/to-form-schema' import ActionButton from '@/app/components/base/action-button' import Tooltip from '@/app/components/base/tooltip' +import { + createEndpoint, +} from '@/service/plugins' type Props = { pluginUniqueID: string @@ -31,6 +34,22 @@ const EndpointList = ({ return toolCredentialToFormSchemas(declaration.settings) }, [declaration.settings]) + const handleCreate = (state: any) => { + try { + createEndpoint({ + url: '/workspaces/current/endpoints', + body: { + plugin_unique_identifier: pluginUniqueID, + settings: state, + name: state.name, + }, + }) + } + catch (error) { + console.error(error) + } + } + return ( <div className='px-4 py-2 border-t border-divider-subtle'> <div className='mb-1 h-6 flex items-center justify-between text-text-secondary system-sm-semibold-uppercase'> @@ -59,9 +78,9 @@ const EndpointList = ({ </div> {isShowEndpointModal && ( <EndpointModal - id={pluginUniqueID} formSchemas={formSchemas} onCancel={hideEndpointModal} + onSaved={handleCreate} /> )} </div> diff --git a/web/app/components/plugins/plugin-detail-panel/endpoint-modal.tsx b/web/app/components/plugins/plugin-detail-panel/endpoint-modal.tsx index aac18dbcbb..c09de2bdb2 100644 --- a/web/app/components/plugins/plugin-detail-panel/endpoint-modal.tsx +++ b/web/app/components/plugins/plugin-detail-panel/endpoint-modal.tsx @@ -7,37 +7,35 @@ import ActionButton from '@/app/components/base/action-button' import Button from '@/app/components/base/button' import Drawer from '@/app/components/base/drawer' import Form from '@/app/components/header/account-setting/model-provider-page/model-modal/Form' -// import Toast from '@/app/components/base/toast' +import Toast from '@/app/components/base/toast' import { useLanguage } from '@/app/components/header/account-setting/model-provider-page/hooks' import cn from '@/utils/classnames' type Props = { - id: string formSchemas: any defaultValues?: any onCancel: () => void - // onSaved: (value: Record<string, any>) => void + onSaved: (value: Record<string, any>) => void } const EndpointModal: FC<Props> = ({ - id, formSchemas, defaultValues = {}, onCancel, - // onSaved, + onSaved, }) => { const { t } = useTranslation() const language = useLanguage() const [tempCredential, setTempCredential] = React.useState<any>(defaultValues) const handleSave = () => { - // for (const field of credentialSchema) { - // if (field.required && !tempCredential[field.name]) { - // Toast.notify({ type: 'error', message: t('common.errorMsg.fieldRequired', { field: field.label[language] || field.label.en_US }) }) - // return - // } - // } - // onSaved(tempCredential) + for (const field of formSchemas) { + if (field.required && !tempCredential[field.name]) { + Toast.notify({ type: 'error', message: t('common.errorMsg.fieldRequired', { field: field.label[language] || field.label.en_US }) }) + return + } + } + onSaved(tempCredential) } return ( From 5e3160e6f6d0d692cee9e89b45a36ef6a93df2ad Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Sat, 19 Oct 2024 18:23:32 +0800 Subject: [PATCH 109/346] fix title & description of tool provider --- web/app/components/plugins/card/index.tsx | 5 ++--- web/app/components/tools/provider-list.tsx | 13 +++++-------- web/i18n/en-US/tools.ts | 2 +- web/i18n/zh-Hans/tools.ts | 2 +- 4 files changed, 9 insertions(+), 13 deletions(-) diff --git a/web/app/components/plugins/card/index.tsx b/web/app/components/plugins/card/index.tsx index ef0c146512..049d92536b 100644 --- a/web/app/components/plugins/card/index.tsx +++ b/web/app/components/plugins/card/index.tsx @@ -1,6 +1,5 @@ 'use client' import React from 'react' -import { useContext } from 'use-context-selector' import { RiVerifiedBadgeLine } from '@remixicon/react' import type { Plugin } from '../types' import Icon from '../card/base/card-icon' @@ -10,7 +9,7 @@ import OrgInfo from './base/org-info' import Description from './base/description' import Placeholder from './base/placeholder' import cn from '@/utils/classnames' -import I18n from '@/context/i18n' +import { useGetLanguage } from '@/context/i18n' type Props = { className?: string @@ -35,7 +34,7 @@ const Card = ({ isLoading = false, loadingFileName, }: Props) => { - const { locale } = useContext(I18n) + const locale = useGetLanguage() const { type, name, org, label, brief, icon } = payload diff --git a/web/app/components/tools/provider-list.tsx b/web/app/components/tools/provider-list.tsx index 6f8fbc76bf..8f222bb637 100644 --- a/web/app/components/tools/provider-list.tsx +++ b/web/app/components/tools/provider-list.tsx @@ -9,10 +9,7 @@ import { useTabSearchParams } from '@/hooks/use-tab-searchparams' import TabSliderNew from '@/app/components/base/tab-slider-new' import LabelFilter from '@/app/components/tools/labels/filter' import SearchInput from '@/app/components/base/search-input' -import { DotsGrid } from '@/app/components/base/icons/src/vender/line/general' -import { Colors } from '@/app/components/base/icons/src/vender/line/others' -import { Route } from '@/app/components/base/icons/src/vender/line/mapsAndTravel' -import CustomCreateCard from '@/app/components/tools/provider/custom-create-card' +// import CustomCreateCard from '@/app/components/tools/provider/custom-create-card' import ProviderDetail from '@/app/components/tools/provider/detail' import Empty from '@/app/components/tools/add-tool-modal/empty' import { fetchCollectionList } from '@/service/tools' @@ -31,9 +28,9 @@ const ProviderList = () => { defaultTab: 'builtin', }) const options = [ - { value: 'builtin', text: t('tools.type.builtIn'), icon: <DotsGrid className='w-[14px] h-[14px] mr-1' /> }, - { value: 'api', text: t('tools.type.custom'), icon: <Colors className='w-[14px] h-[14px] mr-1' /> }, - { value: 'workflow', text: t('tools.type.workflow'), icon: <Route className='w-[14px] h-[14px] mr-1' /> }, + { value: 'builtin', text: t('tools.type.builtIn') }, + { value: 'api', text: t('tools.type.custom') }, + { value: 'workflow', text: t('tools.type.workflow') }, ] const [tagFilterValue, setTagFilterValue] = useState<string[]>([]) const handleTagsChange = (value: string[]) => { @@ -100,7 +97,7 @@ const ProviderList = () => { 'relative grid content-start grid-cols-1 gap-4 px-12 pt-2 pb-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 grow shrink-0', currentProvider && 'pr-6 sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-3', )}> - {activeTab === 'api' && <CustomCreateCard onRefreshData={getProviderList} />} + {/* {activeTab === 'api' && <CustomCreateCard onRefreshData={getProviderList} />} */} {filteredCollectionList.map(collection => ( <div key={collection.id} diff --git a/web/i18n/en-US/tools.ts b/web/i18n/en-US/tools.ts index e50086c3eb..64555e24ff 100644 --- a/web/i18n/en-US/tools.ts +++ b/web/i18n/en-US/tools.ts @@ -4,7 +4,7 @@ const translation = { customToolTip: 'Learn more about Dify custom tools', type: { all: 'All', - builtIn: 'Built-in', + builtIn: 'Tools', custom: 'Custom', workflow: 'Workflow', }, diff --git a/web/i18n/zh-Hans/tools.ts b/web/i18n/zh-Hans/tools.ts index 9064bbd263..4d42aa60fd 100644 --- a/web/i18n/zh-Hans/tools.ts +++ b/web/i18n/zh-Hans/tools.ts @@ -4,7 +4,7 @@ const translation = { customToolTip: '了解更多关于 Dify 自定义工具的信息', type: { all: '全部', - builtIn: '内置', + builtIn: '工具', custom: '自定义', workflow: '工作流', }, From 4651ab41952417232886853872bfe277d9f50406 Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Sat, 19 Oct 2024 18:32:36 +0800 Subject: [PATCH 110/346] new style of provider detail --- web/app/components/tools/provider-list.tsx | 19 +- web/app/components/tools/provider/detail.tsx | 319 ++++++++++--------- 2 files changed, 173 insertions(+), 165 deletions(-) diff --git a/web/app/components/tools/provider-list.tsx b/web/app/components/tools/provider-list.tsx index 8f222bb637..4ca28991cc 100644 --- a/web/app/components/tools/provider-list.tsx +++ b/web/app/components/tools/provider-list.tsx @@ -1,7 +1,6 @@ 'use client' import { useEffect, useMemo, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' -import { RiCloseLine } from '@remixicon/react' import type { Collection } from './types' import Marketplace from './marketplace' import cn from '@/utils/classnames' @@ -9,18 +8,15 @@ import { useTabSearchParams } from '@/hooks/use-tab-searchparams' import TabSliderNew from '@/app/components/base/tab-slider-new' import LabelFilter from '@/app/components/tools/labels/filter' import SearchInput from '@/app/components/base/search-input' -// import CustomCreateCard from '@/app/components/tools/provider/custom-create-card' import ProviderDetail from '@/app/components/tools/provider/detail' import Empty from '@/app/components/tools/add-tool-modal/empty' import { fetchCollectionList } from '@/service/tools' import Card from '@/app/components/plugins/card' -import { useGetLanguage } from '@/context/i18n' import CardMoreInfo from '@/app/components/plugins/card/card-more-info' import { useSelector as useAppContextSelector } from '@/context/app-context' const ProviderList = () => { const { t } = useTranslation() - const language = useGetLanguage() const containerRef = useRef<HTMLDivElement>(null) const { enable_marketplace } = useAppContextSelector(s => s.systemFeatures) @@ -97,7 +93,6 @@ const ProviderList = () => { 'relative grid content-start grid-cols-1 gap-4 px-12 pt-2 pb-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 grow shrink-0', currentProvider && 'pr-6 sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-3', )}> - {/* {activeTab === 'api' && <CustomCreateCard onRefreshData={getProviderList} />} */} {filteredCollectionList.map(collection => ( <div key={collection.id} @@ -131,13 +126,13 @@ const ProviderList = () => { ) } </div> - <div className={cn( - 'shrink-0 w-0 border-l-[0.5px] border-black/8 overflow-y-auto transition-all duration-200 ease-in-out', - currentProvider && 'w-[420px]', - )}> - {currentProvider && <ProviderDetail collection={currentProvider} onRefreshData={getProviderList} />} - </div> - <div className='absolute top-5 right-5 p-1 cursor-pointer' onClick={() => setCurrentProvider(undefined)}><RiCloseLine className='w-4 h-4' /></div> + {currentProvider && ( + <ProviderDetail + collection={currentProvider} + onHide={() => setCurrentProvider(undefined)} + onRefreshData={getProviderList} + /> + )} </div> ) } diff --git a/web/app/components/tools/provider/detail.tsx b/web/app/components/tools/provider/detail.tsx index 566fe4623a..35f333912a 100644 --- a/web/app/components/tools/provider/detail.tsx +++ b/web/app/components/tools/provider/detail.tsx @@ -17,6 +17,7 @@ import ConfigCredential from '@/app/components/tools/setting/build-in/config-cre import EditCustomToolModal from '@/app/components/tools/edit-custom-collection-modal' import WorkflowToolModal from '@/app/components/tools/workflow-tool' import Toast from '@/app/components/base/toast' +import Drawer from '@/app/components/base/drawer' import { deleteWorkflowTool, fetchBuiltInToolList, @@ -38,11 +39,13 @@ import { useAppContext } from '@/context/app-context' type Props = { collection: Collection + onHide: () => void onRefreshData: () => void } const ProviderDetail = ({ collection, + onHide, onRefreshData, }: Props) => { const { t } = useTranslation() @@ -213,164 +216,174 @@ const ProviderDetail = ({ }, [collection.name, collection.type, getCustomProvider, getProviderToolList, getWorkflowToolProvider]) return ( - <div className='px-6 py-3'> - <div className='flex items-center py-1 gap-2'> - <div className='relative shrink-0'> - {typeof collection.icon === 'string' && ( - <div className='w-8 h-8 bg-center bg-cover bg-no-repeat rounded-md' style={{ backgroundImage: `url(${collection.icon})` }} /> - )} - {typeof collection.icon !== 'string' && ( - <AppIcon - size='small' - icon={collection.icon.content} - background={collection.icon.background} - /> - )} - </div> - <div className='grow w-0 py-[1px]'> - <div className='flex items-center text-md leading-6 font-semibold text-gray-900'> - <div className='truncate' title={collection.label[language]}>{collection.label[language]}</div> - </div> - </div> - </div> - <div className='mt-2 min-h-[36px] text-gray-500 text-sm leading-[18px]'>{collection.description[language]}</div> - <div className='flex gap-1 border-b-[0.5px] border-black/5'> - {(collection.type === CollectionType.builtIn) && needAuth && ( - <Button - variant={isAuthed ? 'secondary' : 'primary'} - className={cn('shrink-0 my-3 w-full', isAuthed && 'bg-white')} - onClick={() => { - if (collection.type === CollectionType.builtIn || collection.type === CollectionType.model) - showSettingAuthModal() - }} - disabled={!isCurrentWorkspaceManager} - > - {isAuthed && <Indicator className='mr-2' color={'green'} />} - <div className={cn('text-white leading-[18px] text-[13px] font-medium', isAuthed && '!text-gray-700')}> - {isAuthed ? t('tools.auth.authorized') : t('tools.auth.unauthorized')} - </div> - </Button> - )} - {collection.type === CollectionType.custom && !isDetailLoading && ( - <Button - className={cn('shrink-0 my-3 w-full')} - onClick={() => setIsShowEditCustomCollectionModal(true)} - > - <Settings01 className='mr-1 w-4 h-4 text-gray-500' /> - <div className='leading-5 text-sm font-medium text-gray-700'>{t('tools.createTool.editAction')}</div> - </Button> - )} - {collection.type === CollectionType.workflow && !isDetailLoading && customCollection && ( - <> - <Button - variant='primary' - className={cn('shrink-0 my-3 w-[183px]')} - > - <a className='flex items-center text-white' href={`/app/${(customCollection as WorkflowToolProviderResponse).workflow_app_id}/workflow`} rel='noreferrer' target='_blank'> - <div className='leading-5 text-sm font-medium'>{t('tools.openInStudio')}</div> - <LinkExternal02 className='ml-1 w-4 h-4' /> - </a> - </Button> - <Button - className={cn('shrink-0 my-3 w-[183px]')} - onClick={() => setIsShowEditWorkflowToolModal(true)} - disabled={!isCurrentWorkspaceManager} - > - <div className='leading-5 text-sm font-medium text-gray-700'>{t('tools.createTool.editAction')}</div> - </Button> - </> - )} - </div> - {/* Tools */} - <div className='pt-3'> - {isDetailLoading && <div className='flex h-[200px]'><Loading type='app' /></div>} - {!isDetailLoading && ( - <div className='text-xs font-medium leading-6 text-gray-500'> - {collection.type === CollectionType.workflow && <span className=''>{t('tools.createTool.toolInput.title').toLocaleUpperCase()}</span>} - {collection.type !== CollectionType.workflow && <span className=''>{t('tools.includeToolNum', { num: toolList.length }).toLocaleUpperCase()}</span>} - {needAuth && (isBuiltIn || isModel) && !isAuthed && ( - <> - <span className='px-1'>·</span> - <span className='text-[#DC6803]'>{t('tools.auth.setup').toLocaleUpperCase()}</span> - </> + <Drawer + isOpen={!!collection} + clickOutsideNotOpen={false} + onClose={onHide} + footer={null} + mask={false} + positionCenter={false} + panelClassname={cn('justify-start mt-[64px] mr-2 mb-2 !w-[420px] !max-w-[420px] !p-0 !bg-components-panel-bg rounded-2xl border-[0.5px] border-components-panel-border shadow-xl')} + > + <div className='px-6 py-3'> + <div className='flex items-center py-1 gap-2'> + <div className='relative shrink-0'> + {typeof collection.icon === 'string' && ( + <div className='w-8 h-8 bg-center bg-cover bg-no-repeat rounded-md' style={{ backgroundImage: `url(${collection.icon})` }} /> + )} + {typeof collection.icon !== 'string' && ( + <AppIcon + size='small' + icon={collection.icon.content} + background={collection.icon.background} + /> )} </div> - )} - {!isDetailLoading && ( - <div className='mt-1'> - {collection.type !== CollectionType.workflow && toolList.map(tool => ( - <ToolItem - key={tool.name} - disabled={needAuth && (isBuiltIn || isModel) && !isAuthed} - collection={collection} - tool={tool} - isBuiltIn={isBuiltIn} - isModel={isModel} - /> - ))} - {collection.type === CollectionType.workflow && (customCollection as WorkflowToolProviderResponse)?.tool?.parameters.map(item => ( - <div key={item.name} className='mb-2 px-4 py-3 rounded-xl bg-gray-25 border-[0.5px] border-gray-200'> - <div className='flex items-center gap-2'> - <span className='font-medium text-sm text-gray-900'>{item.name}</span> - <span className='text-xs leading-[18px] text-gray-500'>{item.type}</span> - <span className='font-medium text-xs leading-[18px] text-[#ec4a0a]'>{item.required ? t('tools.createTool.toolInput.required') : ''}</span> - </div> - <div className='h-[18px] leading-[18px] text-gray-500 text-xs'>{item.llm_description}</div> - </div> - ))} + <div className='grow w-0 py-[1px]'> + <div className='flex items-center text-md leading-6 font-semibold text-gray-900'> + <div className='truncate' title={collection.label[language]}>{collection.label[language]}</div> + </div> </div> + </div> + <div className='mt-2 min-h-[36px] text-gray-500 text-sm leading-[18px]'>{collection.description[language]}</div> + <div className='flex gap-1 border-b-[0.5px] border-black/5'> + {(collection.type === CollectionType.builtIn) && needAuth && ( + <Button + variant={isAuthed ? 'secondary' : 'primary'} + className={cn('shrink-0 my-3 w-full', isAuthed && 'bg-white')} + onClick={() => { + if (collection.type === CollectionType.builtIn || collection.type === CollectionType.model) + showSettingAuthModal() + }} + disabled={!isCurrentWorkspaceManager} + > + {isAuthed && <Indicator className='mr-2' color={'green'} />} + <div className={cn('text-white leading-[18px] text-[13px] font-medium', isAuthed && '!text-gray-700')}> + {isAuthed ? t('tools.auth.authorized') : t('tools.auth.unauthorized')} + </div> + </Button> + )} + {collection.type === CollectionType.custom && !isDetailLoading && ( + <Button + className={cn('shrink-0 my-3 w-full')} + onClick={() => setIsShowEditCustomCollectionModal(true)} + > + <Settings01 className='mr-1 w-4 h-4 text-gray-500' /> + <div className='leading-5 text-sm font-medium text-gray-700'>{t('tools.createTool.editAction')}</div> + </Button> + )} + {collection.type === CollectionType.workflow && !isDetailLoading && customCollection && ( + <> + <Button + variant='primary' + className={cn('shrink-0 my-3 w-[183px]')} + > + <a className='flex items-center text-white' href={`/app/${(customCollection as WorkflowToolProviderResponse).workflow_app_id}/workflow`} rel='noreferrer' target='_blank'> + <div className='leading-5 text-sm font-medium'>{t('tools.openInStudio')}</div> + <LinkExternal02 className='ml-1 w-4 h-4' /> + </a> + </Button> + <Button + className={cn('shrink-0 my-3 w-[183px]')} + onClick={() => setIsShowEditWorkflowToolModal(true)} + disabled={!isCurrentWorkspaceManager} + > + <div className='leading-5 text-sm font-medium text-gray-700'>{t('tools.createTool.editAction')}</div> + </Button> + </> + )} + </div> + {/* Tools */} + <div className='pt-3'> + {isDetailLoading && <div className='flex h-[200px]'><Loading type='app' /></div>} + {!isDetailLoading && ( + <div className='text-xs font-medium leading-6 text-gray-500'> + {collection.type === CollectionType.workflow && <span className=''>{t('tools.createTool.toolInput.title').toLocaleUpperCase()}</span>} + {collection.type !== CollectionType.workflow && <span className=''>{t('tools.includeToolNum', { num: toolList.length }).toLocaleUpperCase()}</span>} + {needAuth && (isBuiltIn || isModel) && !isAuthed && ( + <> + <span className='px-1'>·</span> + <span className='text-[#DC6803]'>{t('tools.auth.setup').toLocaleUpperCase()}</span> + </> + )} + </div> + )} + {!isDetailLoading && ( + <div className='mt-1'> + {collection.type !== CollectionType.workflow && toolList.map(tool => ( + <ToolItem + key={tool.name} + disabled={needAuth && (isBuiltIn || isModel) && !isAuthed} + collection={collection} + tool={tool} + isBuiltIn={isBuiltIn} + isModel={isModel} + /> + ))} + {collection.type === CollectionType.workflow && (customCollection as WorkflowToolProviderResponse)?.tool?.parameters.map(item => ( + <div key={item.name} className='mb-2 px-4 py-3 rounded-xl bg-gray-25 border-[0.5px] border-gray-200'> + <div className='flex items-center gap-2'> + <span className='font-medium text-sm text-gray-900'>{item.name}</span> + <span className='text-xs leading-[18px] text-gray-500'>{item.type}</span> + <span className='font-medium text-xs leading-[18px] text-[#ec4a0a]'>{item.required ? t('tools.createTool.toolInput.required') : ''}</span> + </div> + <div className='h-[18px] leading-[18px] text-gray-500 text-xs'>{item.llm_description}</div> + </div> + ))} + </div> + )} + </div> + {showSettingAuth && ( + <ConfigCredential + collection={collection} + onCancel={() => setShowSettingAuth(false)} + onSaved={async (value) => { + await updateBuiltInToolCredential(collection.name, value) + Toast.notify({ + type: 'success', + message: t('common.api.actionSuccess'), + }) + await onRefreshData() + setShowSettingAuth(false) + }} + onRemove={async () => { + await removeBuiltInToolCredential(collection.name) + Toast.notify({ + type: 'success', + message: t('common.api.actionSuccess'), + }) + await onRefreshData() + setShowSettingAuth(false) + }} + /> + )} + {isShowEditCollectionToolModal && ( + <EditCustomToolModal + payload={customCollection} + onHide={() => setIsShowEditCustomCollectionModal(false)} + onEdit={doUpdateCustomToolCollection} + onRemove={onClickCustomToolDelete} + /> + )} + {isShowEditWorkflowToolModal && ( + <WorkflowToolModal + payload={customCollection} + onHide={() => setIsShowEditWorkflowToolModal(false)} + onRemove={onClickWorkflowToolDelete} + onSave={updateWorkflowToolProvider} + /> + )} + {showConfirmDelete && ( + <Confirm + title={t('tools.createTool.deleteToolConfirmTitle')} + content={t('tools.createTool.deleteToolConfirmContent')} + isShow={showConfirmDelete} + onConfirm={handleConfirmDelete} + onCancel={() => setShowConfirmDelete(false)} + /> )} </div> - {showSettingAuth && ( - <ConfigCredential - collection={collection} - onCancel={() => setShowSettingAuth(false)} - onSaved={async (value) => { - await updateBuiltInToolCredential(collection.name, value) - Toast.notify({ - type: 'success', - message: t('common.api.actionSuccess'), - }) - await onRefreshData() - setShowSettingAuth(false) - }} - onRemove={async () => { - await removeBuiltInToolCredential(collection.name) - Toast.notify({ - type: 'success', - message: t('common.api.actionSuccess'), - }) - await onRefreshData() - setShowSettingAuth(false) - }} - /> - )} - {isShowEditCollectionToolModal && ( - <EditCustomToolModal - payload={customCollection} - onHide={() => setIsShowEditCustomCollectionModal(false)} - onEdit={doUpdateCustomToolCollection} - onRemove={onClickCustomToolDelete} - /> - )} - {isShowEditWorkflowToolModal && ( - <WorkflowToolModal - payload={customCollection} - onHide={() => setIsShowEditWorkflowToolModal(false)} - onRemove={onClickWorkflowToolDelete} - onSave={updateWorkflowToolProvider} - /> - )} - {showConfirmDelete && ( - <Confirm - title={t('tools.createTool.deleteToolConfirmTitle')} - content={t('tools.createTool.deleteToolConfirmContent')} - isShow={showConfirmDelete} - onConfirm={handleConfirmDelete} - onCancel={() => setShowConfirmDelete(false)} - /> - )} - </div> + </Drawer> ) } export default ProviderDetail From 15dd79e822d9402772dd1e193aea94f1d64409bc Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Sat, 19 Oct 2024 20:52:46 +0800 Subject: [PATCH 111/346] provider detail data binding --- web/app/components/tools/provider-list.tsx | 1 - web/app/components/tools/provider/detail.tsx | 62 +++++++++++-------- .../components/tools/provider/tool-item.tsx | 6 +- web/i18n/en-US/tools.ts | 2 +- web/i18n/zh-Hans/tools.ts | 2 +- 5 files changed, 41 insertions(+), 32 deletions(-) diff --git a/web/app/components/tools/provider-list.tsx b/web/app/components/tools/provider-list.tsx index 4ca28991cc..3f2593020e 100644 --- a/web/app/components/tools/provider-list.tsx +++ b/web/app/components/tools/provider-list.tsx @@ -91,7 +91,6 @@ const ProviderList = () => { </div> <div className={cn( 'relative grid content-start grid-cols-1 gap-4 px-12 pt-2 pb-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 grow shrink-0', - currentProvider && 'pr-6 sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-3', )}> {filteredCollectionList.map(collection => ( <div diff --git a/web/app/components/tools/provider/detail.tsx b/web/app/components/tools/provider/detail.tsx index 35f333912a..fef3becb8c 100644 --- a/web/app/components/tools/provider/detail.tsx +++ b/web/app/components/tools/provider/detail.tsx @@ -2,6 +2,9 @@ import React, { useCallback, useEffect, useState } from 'react' import { useTranslation } from 'react-i18next' import { useContext } from 'use-context-selector' +import { + RiCloseLine, +} from '@remixicon/react' import { AuthHeaderPrefix, AuthType, CollectionType } from '../types' import type { Collection, CustomCollectionBackend, Tool, WorkflowToolProviderRequest, WorkflowToolProviderResponse } from '../types' import ToolItem from './tool-item' @@ -9,15 +12,20 @@ import cn from '@/utils/classnames' import I18n from '@/context/i18n' import { getLanguage } from '@/i18n/language' import Confirm from '@/app/components/base/confirm' -import AppIcon from '@/app/components/base/app-icon' import Button from '@/app/components/base/button' import Indicator from '@/app/components/header/indicator' import { LinkExternal02, Settings01 } from '@/app/components/base/icons/src/vender/line/general' +import Icon from '@/app/components/plugins/card/base/card-icon' +import Title from '@/app/components/plugins/card/base/title' +import OrgInfo from '@/app/components/plugins/card/base/org-info' +import Description from '@/app/components/plugins/card/base/description' import ConfigCredential from '@/app/components/tools/setting/build-in/config-credentials' import EditCustomToolModal from '@/app/components/tools/edit-custom-collection-modal' import WorkflowToolModal from '@/app/components/tools/workflow-tool' import Toast from '@/app/components/base/toast' import Drawer from '@/app/components/base/drawer' +import ActionButton from '@/app/components/base/action-button' + import { deleteWorkflowTool, fetchBuiltInToolList, @@ -225,27 +233,29 @@ const ProviderDetail = ({ positionCenter={false} panelClassname={cn('justify-start mt-[64px] mr-2 mb-2 !w-[420px] !max-w-[420px] !p-0 !bg-components-panel-bg rounded-2xl border-[0.5px] border-components-panel-border shadow-xl')} > - <div className='px-6 py-3'> - <div className='flex items-center py-1 gap-2'> - <div className='relative shrink-0'> - {typeof collection.icon === 'string' && ( - <div className='w-8 h-8 bg-center bg-cover bg-no-repeat rounded-md' style={{ backgroundImage: `url(${collection.icon})` }} /> - )} - {typeof collection.icon !== 'string' && ( - <AppIcon - size='small' - icon={collection.icon.content} - background={collection.icon.background} + <div className='p-4'> + <div className='flex'> + <Icon src={collection.icon} /> + <div className="ml-3 w-0 grow"> + <div className="flex items-center h-5"> + <Title title={collection.label[language]} /> + </div> + <div className='mb-1 flex justify-between items-center h-4'> + <OrgInfo + className="mt-0.5" + packageNameClassName='w-auto' + orgName={collection.author} + packageName={collection.name} /> - )} - </div> - <div className='grow w-0 py-[1px]'> - <div className='flex items-center text-md leading-6 font-semibold text-gray-900'> - <div className='truncate' title={collection.label[language]}>{collection.label[language]}</div> </div> </div> + <div className='flex gap-1'> + <ActionButton onClick={onHide}> + <RiCloseLine className='w-4 h-4' /> + </ActionButton> + </div> </div> - <div className='mt-2 min-h-[36px] text-gray-500 text-sm leading-[18px]'>{collection.description[language]}</div> + <Description className='mt-3' text={collection.description[language]} descriptionLineRows={2}></Description> <div className='flex gap-1 border-b-[0.5px] border-black/5'> {(collection.type === CollectionType.builtIn) && needAuth && ( <Button @@ -297,7 +307,7 @@ const ProviderDetail = ({ <div className='pt-3'> {isDetailLoading && <div className='flex h-[200px]'><Loading type='app' /></div>} {!isDetailLoading && ( - <div className='text-xs font-medium leading-6 text-gray-500'> + <div className='text-text-secondary system-sm-semibold-uppercase'> {collection.type === CollectionType.workflow && <span className=''>{t('tools.createTool.toolInput.title').toLocaleUpperCase()}</span>} {collection.type !== CollectionType.workflow && <span className=''>{t('tools.includeToolNum', { num: toolList.length }).toLocaleUpperCase()}</span>} {needAuth && (isBuiltIn || isModel) && !isAuthed && ( @@ -309,7 +319,7 @@ const ProviderDetail = ({ </div> )} {!isDetailLoading && ( - <div className='mt-1'> + <div className='mt-1 py-2'> {collection.type !== CollectionType.workflow && toolList.map(tool => ( <ToolItem key={tool.name} @@ -321,13 +331,13 @@ const ProviderDetail = ({ /> ))} {collection.type === CollectionType.workflow && (customCollection as WorkflowToolProviderResponse)?.tool?.parameters.map(item => ( - <div key={item.name} className='mb-2 px-4 py-3 rounded-xl bg-gray-25 border-[0.5px] border-gray-200'> - <div className='flex items-center gap-2'> - <span className='font-medium text-sm text-gray-900'>{item.name}</span> - <span className='text-xs leading-[18px] text-gray-500'>{item.type}</span> - <span className='font-medium text-xs leading-[18px] text-[#ec4a0a]'>{item.required ? t('tools.createTool.toolInput.required') : ''}</span> + <div key={item.name} className='mb-1 py-1'> + <div className='mb-1 flex items-center gap-2'> + <span className='text-text-secondary code-sm-semibold'>{item.name}</span> + <span className='text-text-tertiary system-xs-regular'>{item.type}</span> + <span className='text-text-warning-secondary system-xs-medium'>{item.required ? t('tools.createTool.toolInput.required') : ''}</span> </div> - <div className='h-[18px] leading-[18px] text-gray-500 text-xs'>{item.llm_description}</div> + <div className='text-text-tertiary system-xs-regular'>{item.llm_description}</div> </div> ))} </div> diff --git a/web/app/components/tools/provider/tool-item.tsx b/web/app/components/tools/provider/tool-item.tsx index 2133f9221a..537f43c1b6 100644 --- a/web/app/components/tools/provider/tool-item.tsx +++ b/web/app/components/tools/provider/tool-item.tsx @@ -29,11 +29,11 @@ const ToolItem = ({ return ( <> <div - className={cn('mb-2 px-4 py-3 rounded-xl bg-gray-25 border-[0.5px] border-gary-200 shadow-xs cursor-pointer', disabled && 'opacity-50 !cursor-not-allowed')} + className={cn('mb-2 px-4 py-3 bg-components-panel-item-bg rounded-xl border-[0.5px] border-components-panel-border-subtle shadow-xs cursor-pointer hover:bg-components-panel-on-panel-item-bg-hover', disabled && 'opacity-50 !cursor-not-allowed')} onClick={() => !disabled && setShowDetail(true)} > - <div className='text-gray-800 font-semibold text-sm leading-5'>{tool.label[language]}</div> - <div className='mt-0.5 text-xs leading-[18px] text-gray-500 line-clamp-2' title={tool.description[language]}>{tool.description[language]}</div> + <div className='pb-0.5 text-text-secondary system-md-semibold'>{tool.label[language]}</div> + <div className='text-text-tertiary system-xs-regular line-clamp-2' title={tool.description[language]}>{tool.description[language]}</div> </div> {showDetail && ( <SettingBuiltInTool diff --git a/web/i18n/en-US/tools.ts b/web/i18n/en-US/tools.ts index 64555e24ff..d3572eb317 100644 --- a/web/i18n/en-US/tools.ts +++ b/web/i18n/en-US/tools.ts @@ -21,7 +21,7 @@ const translation = { setupModalTitle: 'Set Up Authorization', setupModalTitleDescription: 'After configuring credentials, all members within the workspace can use this tool when orchestrating applications.', }, - includeToolNum: '{{num}} tools included', + includeToolNum: '{{num}} actions included', addTool: 'Add Tool', addToolModal: { type: 'type', diff --git a/web/i18n/zh-Hans/tools.ts b/web/i18n/zh-Hans/tools.ts index 4d42aa60fd..4c3b48b287 100644 --- a/web/i18n/zh-Hans/tools.ts +++ b/web/i18n/zh-Hans/tools.ts @@ -21,7 +21,7 @@ const translation = { setupModalTitle: '设置授权', setupModalTitleDescription: '配置凭据后,工作区中的所有成员都可以在编排应用程序时使用此工具。', }, - includeToolNum: '包含 {{num}} 个工具', + includeToolNum: '包含 {{num}} 个 action', addTool: '添加工具', addToolModal: { type: '类型', From 5aa7696cc3a94c348fd7509054ec64831ac41c73 Mon Sep 17 00:00:00 2001 From: JzoNg <jzongcode@gmail.com> Date: Sat, 19 Oct 2024 21:34:14 +0800 Subject: [PATCH 112/346] update style of action list --- .../agent-tools/setting-built-in-tool.tsx | 29 +++++++++---------- .../setting/build-in/config-credentials.tsx | 6 ++-- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/web/app/components/app/configuration/config/agent/agent-tools/setting-built-in-tool.tsx b/web/app/components/app/configuration/config/agent/agent-tools/setting-built-in-tool.tsx index 69e18e3136..254e248c05 100644 --- a/web/app/components/app/configuration/config/agent/agent-tools/setting-built-in-tool.tsx +++ b/web/app/components/app/configuration/config/agent/agent-tools/setting-built-in-tool.tsx @@ -106,23 +106,22 @@ const SettingBuiltInTool: FC<Props> = ({ </div> {infoSchemas.length > 0 && ( - <div className='mt-6'> - <div className='flex items-center mb-4 leading-[18px] text-xs font-semibold text-gray-500 uppercase'> - <div className='mr-3'>{t('tools.setBuiltInTools.parameters')}</div> - <div className='grow w-0 h-px bg-[#f3f4f6]'></div> + <div className='my-2'> + <div className='pt-3 text-text-secondary system-sm-semibold-uppercase'> + {t('tools.setBuiltInTools.parameters')} </div> - <div className='space-y-4'> + <div className='py-2 space-y-3'> {infoSchemas.map((item: any, index) => ( - <div key={index}> - <div className='flex items-center space-x-2 leading-[18px]'> - <div className='text-[13px] font-semibold text-gray-900'>{item.label[language]}</div> - <div className='text-xs font-medium text-gray-500'>{item.type === 'number-input' ? t('tools.setBuiltInTools.number') : t('tools.setBuiltInTools.string')}</div> + <div key={index} className='py-1'> + <div className='flex items-center gap-2'> + <div className='text-text-secondary code-sm-semibold'>{item.label[language]}</div> + <div className='text-text-tertiary system-xs-regular'>{item.type === 'number-input' ? t('tools.setBuiltInTools.number') : t('tools.setBuiltInTools.string')}</div> {item.required && ( - <div className='text-xs font-medium text-[#EC4A0A]'>{t('tools.setBuiltInTools.required')}</div> + <div className='text-text-warning-secondary system-xs-medium'>{t('tools.setBuiltInTools.required')}</div> )} </div> {item.human_description && ( - <div className='mt-1 leading-[18px] text-xs font-normal text-gray-600'> + <div className='mt-0.5 text-text-tertiary system-xs-regular'> {item.human_description?.[language]} </div> )} @@ -192,9 +191,9 @@ const SettingBuiltInTool: FC<Props> = ({ </>)} </div> )} - panelClassName='mt-[65px] !w-[405px]' - maxWidthClassName='!max-w-[405px]' - height='calc(100vh - 65px)' + panelClassName='mt-[64px] mb-2 !w-[420px]' + maxWidthClassName='!max-w-[420px]' + height='calc(100vh - 64px)' headerClassName='!border-b-black/5' body={ <div className='h-full pt-3'> @@ -203,7 +202,7 @@ const SettingBuiltInTool: FC<Props> = ({ <Loading type='app' /> </div> : (<div className='flex flex-col h-full'> - <div className='grow h-0 overflow-y-auto px-6'> + <div className='grow h-0 overflow-y-auto px-4'> {isInfoActive ? infoUI : settingUI} </div> {!readonly && !isInfoActive && ( diff --git a/web/app/components/tools/setting/build-in/config-credentials.tsx b/web/app/components/tools/setting/build-in/config-credentials.tsx index 23ef867feb..167cef27f1 100644 --- a/web/app/components/tools/setting/build-in/config-credentials.tsx +++ b/web/app/components/tools/setting/build-in/config-credentials.tsx @@ -61,9 +61,9 @@ const ConfigCredential: FC<Props> = ({ onHide={onCancel} title={t('tools.auth.setupModalTitle') as string} titleDescription={t('tools.auth.setupModalTitleDescription') as string} - panelClassName='mt-2 !w-[405px]' - maxWidthClassName='!max-w-[405px]' - height='calc(100vh - 16px)' + panelClassName='mt-[64px] mb-2 !w-[420px]' + maxWidthClassName='!max-w-[420px]' + height='calc(100vh - 64px)' contentClassName='!bg-gray-100' headerClassName='!border-b-black/5' body={ From 8f49572f8534fa861917c7836134d02bf1f1dc9f Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Mon, 21 Oct 2024 15:07:10 +0800 Subject: [PATCH 113/346] chore: from marketplace tilte ui --- .../block-selector/market-place-plugin/item.tsx | 2 +- .../block-selector/market-place-plugin/list.tsx | 15 ++++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/web/app/components/workflow/block-selector/market-place-plugin/item.tsx b/web/app/components/workflow/block-selector/market-place-plugin/item.tsx index 725535135c..8d3dff4cc6 100644 --- a/web/app/components/workflow/block-selector/market-place-plugin/item.tsx +++ b/web/app/components/workflow/block-selector/market-place-plugin/item.tsx @@ -26,7 +26,7 @@ const Item: FC<Props> = ({ const { locale } = useContext(I18n) return ( - <div className='group/plugin flex rounded-lg py-2 pr-1 pl-3 hover:bg-state-base-hover'> + <div className='group/plugin flex rounded-lg py-1 pr-1 pl-3 hover:bg-state-base-hover'> <div className='shrink-0 relative w-6 h-6 border-[0.5px] border-components-panel-border-subtle rounded-md bg-center bg-no-repeat bg-contain' style={{ backgroundImage: `url(${payload.icon})` }} diff --git a/web/app/components/workflow/block-selector/market-place-plugin/list.tsx b/web/app/components/workflow/block-selector/market-place-plugin/list.tsx index 906f31657c..baf506c7d4 100644 --- a/web/app/components/workflow/block-selector/market-place-plugin/list.tsx +++ b/web/app/components/workflow/block-selector/market-place-plugin/list.tsx @@ -5,6 +5,7 @@ import useStickyScroll, { ScrollPosition } from '../use-sticky-scroll' import Item from './item' import type { Plugin } from '@/app/components/plugins/types.ts' import cn from '@/utils/classnames' +// import { RiArrowRightUpLine } from '@remixicon/react' type Props = { wrapElemRef: React.RefObject<HTMLElement> @@ -26,11 +27,11 @@ const List = ({ const stickyClassName = useMemo(() => { switch (scrollPosition) { case ScrollPosition.aboveTheWrap: - return 'top-0 shadow-md bg-white' + return 'top-0 h-9 pt-3 pb-2 shadow-xs bg-components-panel-bg-blur' case ScrollPosition.showing: - return 'bottom-0' + return 'bottom-0 pt-3 pb-1' case ScrollPosition.belowTheWrap: - return 'bottom-0 border-t border-gray-500 bg-white text-blue-500' + return 'bottom-0 items-center rounded-b-xl border-t border-[0.5px] border-components-panel-border bg-components-panel-bg-blur text-blue-500 shadow-lg text-text-accent-light-mode-only cursor-pointer' } }, [scrollPosition]) @@ -41,8 +42,12 @@ const List = ({ return ( <> <div - className={cn('sticky z-10 pt-3 px-4 py-1 text-text-primary system-sm-medium', stickyClassName)}> - {t('plugin.fromMarketplace')} + className={cn('sticky z-10 flex h-8 px-4 py-1 text-text-primary system-sm-medium', stickyClassName)} + > + <span>{t('plugin.fromMarketplace')}</span> + {/* {scrollPosition === ScrollPosition.belowTheWrap && ( + <RiArrowRightUpLine className='ml-0.5 w-3 h-3' /> + )} */} </div> <div className='p-1 pb-[500px]' ref={nextToStickyELemRef}> {list.map((item, index) => ( From 8e9d7a229d063640a456fcf7011756b4ae2ee3f0 Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Mon, 21 Oct 2024 18:21:45 +0800 Subject: [PATCH 114/346] feat: scroll to view and fix action hidden --- .../workflow/block-selector/all-tools.tsx | 1 + .../block-selector/market-place-plugin/action.tsx | 14 +++++++++----- .../block-selector/market-place-plugin/item.tsx | 9 +++++++-- .../block-selector/market-place-plugin/list.tsx | 10 +++++++++- 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/web/app/components/workflow/block-selector/all-tools.tsx b/web/app/components/workflow/block-selector/all-tools.tsx index a9a316b272..67c30f4aea 100644 --- a/web/app/components/workflow/block-selector/all-tools.tsx +++ b/web/app/components/workflow/block-selector/all-tools.tsx @@ -89,6 +89,7 @@ const AllTools = ({ onSelect={onSelect} viewType={activeView} /> + {/* Plugins from marketplace */} <PluginList wrapElemRef={wrapElemRef} list={[toolNotion, extensionDallE, modelGPT4] as any} ref={pluginRef} /> </div> </div> diff --git a/web/app/components/workflow/block-selector/market-place-plugin/action.tsx b/web/app/components/workflow/block-selector/market-place-plugin/action.tsx index df606fdb41..d77ea248fe 100644 --- a/web/app/components/workflow/block-selector/market-place-plugin/action.tsx +++ b/web/app/components/workflow/block-selector/market-place-plugin/action.tsx @@ -1,6 +1,6 @@ 'use client' import type { FC } from 'react' -import React, { useCallback, useRef, useState } from 'react' +import React, { useCallback, useRef } from 'react' import { useTranslation } from 'react-i18next' import { RiMoreFill } from '@remixicon/react' import ActionButton from '@/app/components/base/action-button' @@ -13,16 +13,20 @@ import { import cn from '@/utils/classnames' type Props = { + open: boolean + onOpenChange: (v: boolean) => void } -const OperationDropdown: FC<Props> = () => { +const OperationDropdown: FC<Props> = ({ + open, + onOpenChange, +}) => { const { t } = useTranslation() - const [open, doSetOpen] = useState(false) const openRef = useRef(open) const setOpen = useCallback((v: boolean) => { - doSetOpen(v) + onOpenChange(v) openRef.current = v - }, [doSetOpen]) + }, [onOpenChange]) const handleTrigger = useCallback(() => { setOpen(!openRef.current) diff --git a/web/app/components/workflow/block-selector/market-place-plugin/item.tsx b/web/app/components/workflow/block-selector/market-place-plugin/item.tsx index 8d3dff4cc6..b5a73b9743 100644 --- a/web/app/components/workflow/block-selector/market-place-plugin/item.tsx +++ b/web/app/components/workflow/block-selector/market-place-plugin/item.tsx @@ -6,6 +6,7 @@ import { useTranslation } from 'react-i18next' import Action from './action' import type { Plugin } from '@/app/components/plugins/types.ts' import I18n from '@/context/i18n' +import cn from '@/utils/classnames' import { formatNumber } from '@/utils/format' @@ -23,6 +24,7 @@ const Item: FC<Props> = ({ payload, }) => { const { t } = useTranslation() + const [open, setOpen] = React.useState(false) const { locale } = useContext(I18n) return ( @@ -42,9 +44,12 @@ const Item: FC<Props> = ({ </div> </div> {/* Action */} - <div className='hidden group-hover/plugin:flex items-center space-x-1 h-4 text-components-button-secondary-accent-text system-xs-medium'> + <div className={cn(!open ? 'hidden' : 'flex', 'group-hover/plugin:flex items-center space-x-1 h-4 text-components-button-secondary-accent-text system-xs-medium')}> <div className='px-1.5'>{t('plugin.installAction')}</div> - <Action /> + <Action + open={open} + onOpenChange={setOpen} + /> </div> </div> diff --git a/web/app/components/workflow/block-selector/market-place-plugin/list.tsx b/web/app/components/workflow/block-selector/market-place-plugin/list.tsx index baf506c7d4..9861cf2a9e 100644 --- a/web/app/components/workflow/block-selector/market-place-plugin/list.tsx +++ b/web/app/components/workflow/block-selector/market-place-plugin/list.tsx @@ -39,17 +39,25 @@ const List = ({ handleScroll, })) + const scrollToView = () => { + if (scrollPosition !== ScrollPosition.belowTheWrap) + return + + nextToStickyELemRef.current?.scrollIntoView({ behavior: 'smooth', block: 'start' }) + } + return ( <> <div className={cn('sticky z-10 flex h-8 px-4 py-1 text-text-primary system-sm-medium', stickyClassName)} + onClick={scrollToView} > <span>{t('plugin.fromMarketplace')}</span> {/* {scrollPosition === ScrollPosition.belowTheWrap && ( <RiArrowRightUpLine className='ml-0.5 w-3 h-3' /> )} */} </div> - <div className='p-1 pb-[500px]' ref={nextToStickyELemRef}> + <div className='p-1' ref={nextToStickyELemRef}> {list.map((item, index) => ( <Item key={index} From f4f11135d30b3ad8b0efdd4972856d5164735d76 Mon Sep 17 00:00:00 2001 From: AkaraChen <akarachen@outlook.com> Date: Mon, 21 Oct 2024 13:16:56 +0800 Subject: [PATCH 115/346] build: using eslint flat config --- web/.eslintignore | 7 --- web/.eslintrc.json | 32 ----------- web/eslint.config.mjs | 55 +++++++++++++++++++ web/package.json | 2 + web/pnpm-lock.yaml | 125 +++++++++++++++++++++++------------------- 5 files changed, 126 insertions(+), 95 deletions(-) delete mode 100644 web/.eslintignore delete mode 100644 web/.eslintrc.json create mode 100644 web/eslint.config.mjs diff --git a/web/.eslintignore b/web/.eslintignore deleted file mode 100644 index 8a8bc38d80..0000000000 --- a/web/.eslintignore +++ /dev/null @@ -1,7 +0,0 @@ -/**/node_modules/* -node_modules/ - -dist/ -build/ -out/ -.next/ \ No newline at end of file diff --git a/web/.eslintrc.json b/web/.eslintrc.json deleted file mode 100644 index 41d99a9d19..0000000000 --- a/web/.eslintrc.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "root": true, - "extends": [ - "next", - "@antfu", - "plugin:storybook/recommended" - ], - "rules": { - "@typescript-eslint/consistent-type-definitions": [ - "error", - "type" - ], - "@typescript-eslint/no-var-requires": "off", - "no-console": "off", - "indent": "off", - "@typescript-eslint/indent": [ - "error", - 2, - { - "SwitchCase": 1, - "flatTernaryExpressions": false, - "ignoredNodes": [ - "PropertyDefinition[decorators]", - "TSUnionType", - "FunctionExpression[params]:has(Identifier[decorators])" - ] - } - ], - "react-hooks/exhaustive-deps": "warn", - "react/display-name": "warn" - } -} \ No newline at end of file diff --git a/web/eslint.config.mjs b/web/eslint.config.mjs new file mode 100644 index 0000000000..58109b43aa --- /dev/null +++ b/web/eslint.config.mjs @@ -0,0 +1,55 @@ +import path from 'node:path' +import { fileURLToPath } from 'node:url' +import js from '@eslint/js' +import { FlatCompat } from '@eslint/eslintrc' + +const __filename = fileURLToPath(import.meta.url) +const __dirname = path.dirname(__filename) +const compat = new FlatCompat({ + baseDirectory: __dirname, + recommendedConfig: js.configs.recommended, + allConfig: js.configs.all, +}) + +const ignores = [ + '**/node_modules/*', + '**/node_modules/', + '**/dist/', + '**/build/', + '**/out/', + '**/.next/', + // TODO: remove this + '**/*.json', + '**/*.md', +] + +const backup = { + rules: { + '@typescript-eslint/consistent-type-definitions': ['error', 'type'], + '@typescript-eslint/no-var-requires': 'off', + 'no-console': 'off', + 'indent': 'off', + + '@typescript-eslint/indent': ['error', 2, { + SwitchCase: 1, + flatTernaryExpressions: false, + + ignoredNodes: [ + 'PropertyDefinition[decorators]', + 'TSUnionType', + 'FunctionExpression[params]:has(Identifier[decorators])', + ], + }], + + 'react-hooks/exhaustive-deps': 'warn', + 'react/display-name': 'warn', + }, +} + +const config = [ + { ignores }, + ...compat.extends('next', '@antfu', 'plugin:storybook/recommended'), + backup, +] + +export default config diff --git a/web/package.json b/web/package.json index 03e714d05a..464543b551 100644 --- a/web/package.json +++ b/web/package.json @@ -110,6 +110,8 @@ "devDependencies": { "@antfu/eslint-config": "^0.36.0", "@chromatic-com/storybook": "^1.9.0", + "@eslint/eslintrc": "^3.1.0", + "@eslint/js": "^9.13.0", "@faker-js/faker": "^7.6.0", "@rgrove/parse-xml": "^4.1.0", "@storybook/addon-essentials": "^8.3.5", diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index d84b25948b..b69455526f 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -266,6 +266,12 @@ importers: '@chromatic-com/storybook': specifier: ^1.9.0 version: 1.9.0(react@18.2.0) + '@eslint/eslintrc': + specifier: ^3.1.0 + version: 3.1.0 + '@eslint/js': + specifier: ^9.13.0 + version: 9.13.0 '@faker-js/faker': specifier: ^7.6.0 version: 7.6.0 @@ -1268,10 +1274,18 @@ packages: resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@eslint/eslintrc@3.1.0': + resolution: {integrity: sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/js@8.57.1': resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@eslint/js@9.13.0': + resolution: {integrity: sha512-IFLyoY4d72Z5y/6o/BazFBezupzI/taV8sGumxTAVw3lXG9A6md1Dc34T9s1FoD/an9pJH8RHbAxsaEbBed9lA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@faker-js/faker@7.6.0': resolution: {integrity: sha512-XK6BTq1NDMo9Xqw/YkYyGjSsg44fbNwYRx7QK2CuoQgyy+f1rrTDHoExVM5PsyXCtfl2vs2vVJ0MN0yN6LppRw==} engines: {node: '>=14.0.0', npm: '>=6.0.0'} @@ -4249,12 +4263,20 @@ packages: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + eslint-visitor-keys@4.1.0: + resolution: {integrity: sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + eslint@8.57.1: resolution: {integrity: sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. hasBin: true + espree@10.2.0: + resolution: {integrity: sha512-upbkBJbckcCNBDBDXEbuhjbP68n+scUd3k/U2EkyM9nw+I/jPiL4cLF/Al06CF96wRltFda16sxDFrxsI1v0/g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + espree@9.6.1: resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -4549,6 +4571,10 @@ packages: resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} engines: {node: '>=8'} + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + globalthis@1.0.4: resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} engines: {node: '>= 0.4'} @@ -7794,7 +7820,7 @@ snapshots: '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 - '@antfu/eslint-config-basic@0.36.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5)': + '@antfu/eslint-config-basic@0.36.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5)': dependencies: eslint: 8.57.1 eslint-plugin-antfu: 0.36.0(eslint@8.57.1)(typescript@4.9.5) @@ -7807,7 +7833,7 @@ snapshots: eslint-plugin-no-only-tests: 3.3.0 eslint-plugin-promise: 6.6.0(eslint@8.57.1) eslint-plugin-unicorn: 45.0.2(eslint@8.57.1) - eslint-plugin-unused-imports: 2.0.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1) + eslint-plugin-unused-imports: 2.0.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1) eslint-plugin-yml: 1.14.0(eslint@8.57.1) jsonc-eslint-parser: 2.4.0 yaml-eslint-parser: 1.2.3 @@ -7821,11 +7847,11 @@ snapshots: '@antfu/eslint-config-ts@0.36.0(eslint@8.57.1)(jest@29.7.0(@types/node@18.15.0)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)))(typescript@4.9.5)': dependencies: - '@antfu/eslint-config-basic': 0.36.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) + '@antfu/eslint-config-basic': 0.36.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@4.9.5) eslint: 8.57.1 - eslint-plugin-jest: 27.9.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(jest@29.7.0(@types/node@18.15.0)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)))(typescript@4.9.5) + eslint-plugin-jest: 27.9.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(jest@29.7.0(@types/node@18.15.0)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)))(typescript@4.9.5) typescript: 4.9.5 transitivePeerDependencies: - eslint-import-resolver-typescript @@ -7833,9 +7859,9 @@ snapshots: - jest - supports-color - '@antfu/eslint-config-vue@0.36.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(jest@29.7.0(@types/node@18.15.0)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)))(typescript@4.9.5)': + '@antfu/eslint-config-vue@0.36.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(jest@29.7.0(@types/node@18.15.0)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)))(typescript@4.9.5)': dependencies: - '@antfu/eslint-config-basic': 0.36.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) + '@antfu/eslint-config-basic': 0.36.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) '@antfu/eslint-config-ts': 0.36.0(eslint@8.57.1)(jest@29.7.0(@types/node@18.15.0)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)))(typescript@4.9.5) eslint: 8.57.1 eslint-plugin-vue: 9.29.1(eslint@8.57.1) @@ -7851,7 +7877,7 @@ snapshots: '@antfu/eslint-config@0.36.0(eslint@8.57.1)(jest@29.7.0(@types/node@18.15.0)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)))(typescript@4.9.5)': dependencies: - '@antfu/eslint-config-vue': 0.36.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(jest@29.7.0(@types/node@18.15.0)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)))(typescript@4.9.5) + '@antfu/eslint-config-vue': 0.36.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(jest@29.7.0(@types/node@18.15.0)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)))(typescript@4.9.5) '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@4.9.5) eslint: 8.57.1 @@ -8818,8 +8844,24 @@ snapshots: transitivePeerDependencies: - supports-color + '@eslint/eslintrc@3.1.0': + dependencies: + ajv: 6.12.6 + debug: 4.3.7 + espree: 10.2.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + '@eslint/js@8.57.1': {} + '@eslint/js@9.13.0': {} + '@faker-js/faker@7.6.0': {} '@floating-ui/core@1.6.8': @@ -12309,8 +12351,8 @@ snapshots: '@typescript-eslint/parser': 8.10.0(eslint@8.57.1)(typescript@4.9.5) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1))(eslint@8.57.1) - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) + eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1) eslint-plugin-jsx-a11y: 6.10.0(eslint@8.57.1) eslint-plugin-react: 7.37.1(eslint@8.57.1) eslint-plugin-react-hooks: 5.0.0-canary-7118f5dd7-20230705(eslint@8.57.1) @@ -12329,43 +12371,33 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1))(eslint@8.57.1): + eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.3.7 enhanced-resolve: 5.17.1 eslint: 8.57.1 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1) fast-glob: 3.3.2 get-tsconfig: 4.8.1 is-bun-module: 1.2.1 is-glob: 4.0.3 optionalDependencies: - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1) transitivePeerDependencies: - '@typescript-eslint/parser' - eslint-import-resolver-node - eslint-import-resolver-webpack - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1): - dependencies: - debug: 3.2.7 - optionalDependencies: - '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@4.9.5) - eslint: 8.57.1 - eslint-import-resolver-node: 0.3.9 - transitivePeerDependencies: - - supports-color - - eslint-module-utils@2.12.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 8.10.0(eslint@8.57.1)(typescript@4.9.5) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1))(eslint@8.57.1) + eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1) transitivePeerDependencies: - supports-color @@ -12404,7 +12436,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint@8.57.1) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3 @@ -12422,36 +12454,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1): - dependencies: - '@rtsao/scc': 1.1.0 - array-includes: 3.1.8 - array.prototype.findlastindex: 1.2.5 - array.prototype.flat: 1.3.2 - array.prototype.flatmap: 1.3.2 - debug: 3.2.7 - doctrine: 2.1.0 - eslint: 8.57.1 - eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) - hasown: 2.0.2 - is-core-module: 2.15.1 - is-glob: 4.0.3 - minimatch: 3.1.2 - object.fromentries: 2.0.8 - object.groupby: 1.0.3 - object.values: 1.2.0 - semver: 6.3.1 - string.prototype.trimend: 1.0.8 - tsconfig-paths: 3.15.0 - optionalDependencies: - '@typescript-eslint/parser': 8.10.0(eslint@8.57.1)(typescript@4.9.5) - transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - supports-color - - eslint-plugin-jest@27.9.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(jest@29.7.0(@types/node@18.15.0)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)))(typescript@4.9.5): + eslint-plugin-jest@27.9.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(jest@29.7.0(@types/node@18.15.0)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)))(typescript@4.9.5): dependencies: '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@4.9.5) eslint: 8.57.1 @@ -12575,7 +12578,7 @@ snapshots: semver: 7.6.3 strip-indent: 3.0.0 - eslint-plugin-unused-imports@2.0.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1): + eslint-plugin-unused-imports@2.0.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1): dependencies: eslint: 8.57.1 eslint-rule-composer: 0.3.0 @@ -12634,6 +12637,8 @@ snapshots: eslint-visitor-keys@3.4.3: {} + eslint-visitor-keys@4.1.0: {} + eslint@8.57.1: dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) @@ -12677,6 +12682,12 @@ snapshots: transitivePeerDependencies: - supports-color + espree@10.2.0: + dependencies: + acorn: 8.13.0 + acorn-jsx: 5.3.2(acorn@8.13.0) + eslint-visitor-keys: 4.1.0 + espree@9.6.1: dependencies: acorn: 8.13.0 @@ -13045,6 +13056,8 @@ snapshots: dependencies: type-fest: 0.20.2 + globals@14.0.0: {} + globalthis@1.0.4: dependencies: define-properties: 1.2.1 From 2094c5495187e4df28433174c341ff8b03b4f27c Mon Sep 17 00:00:00 2001 From: AkaraChen <akarachen@outlook.com> Date: Mon, 21 Oct 2024 16:21:12 +0800 Subject: [PATCH 116/346] build: update eslint config antfu --- web/eslint.config.mjs | 125 ++- web/package.json | 13 +- web/pnpm-lock.yaml | 2103 ++++++++++++++++++++++++++++++----------- 3 files changed, 1638 insertions(+), 603 deletions(-) diff --git a/web/eslint.config.mjs b/web/eslint.config.mjs index 58109b43aa..f9d784920b 100644 --- a/web/eslint.config.mjs +++ b/web/eslint.config.mjs @@ -1,3 +1,4 @@ +import { stylistic, typescript, combine, javascript } from '@antfu/eslint-config' import path from 'node:path' import { fileURLToPath } from 'node:url' import js from '@eslint/js' @@ -11,45 +12,91 @@ const compat = new FlatCompat({ allConfig: js.configs.all, }) -const ignores = [ - '**/node_modules/*', - '**/node_modules/', - '**/dist/', - '**/build/', - '**/out/', - '**/.next/', - // TODO: remove this - '**/*.json', - '**/*.md', -] - -const backup = { - rules: { - '@typescript-eslint/consistent-type-definitions': ['error', 'type'], - '@typescript-eslint/no-var-requires': 'off', - 'no-console': 'off', - 'indent': 'off', - - '@typescript-eslint/indent': ['error', 2, { - SwitchCase: 1, - flatTernaryExpressions: false, - - ignoredNodes: [ - 'PropertyDefinition[decorators]', - 'TSUnionType', - 'FunctionExpression[params]:has(Identifier[decorators])', - ], - }], - - 'react-hooks/exhaustive-deps': 'warn', - 'react/display-name': 'warn', +// storybook plugin not support v9, so add its recommended rules here +const storybook = [ + { + plugins: ['storybook'], + files: ['*.stories.@(ts|tsx|js|jsx|mjs|cjs)', '*.story.@(ts|tsx|js|jsx|mjs|cjs)'], + rules: { + 'react-hooks/rules-of-hooks': 'off', + 'import/no-anonymous-default-export': 'off', + 'storybook/await-interactions': 'error', + 'storybook/context-in-play-function': 'error', + 'storybook/default-exports': 'error', + 'storybook/hierarchy-separator': 'warn', + 'storybook/no-redundant-story-name': 'warn', + 'storybook/prefer-pascal-case': 'warn', + 'storybook/story-exports': 'error', + 'storybook/use-storybook-expect': 'error', + 'storybook/use-storybook-testing-library': 'error', + } }, -} - -const config = [ - { ignores }, - ...compat.extends('next', '@antfu', 'plugin:storybook/recommended'), - backup, + { + plugins: ['storybook'], + files: ['*.stories.@(ts|tsx|js|jsx|mjs|cjs)', '*.story.@(ts|tsx|js|jsx|mjs|cjs)'], + rules: { + 'storybook/no-uninstalled-addons': 'error', + } + } ] -export default config +export default combine( + stylistic({ + lessOpinionated: true, + // original @antfu/eslint-config does not support jsx + jsx: false, + overrides: { + "style/indent": "off", + + // these options does not exist in old version + "style/indent-binary-ops": "off", + "style/multiline-ternary": "off", + + // big change + "style/quote-props": "off", + "style/member-delimiter-style": "off", + "style/quotes": "off", + "style/comma-dangle": "off", + } + }), + typescript({ + overrides: { + // useful, but big change + "ts/no-empty-object-type": "off", + } + }), + // javascript(), + // TODO: remove this when upgrade to nextjs 15 + compat.extends('next'), + { + ignores: [ + '**/node_modules/*', + '**/node_modules/', + '**/dist/', + '**/build/', + '**/out/', + '**/.next/', + '**/public/*', + '**/*.json', + ] + }, + { + // orignal config + rules: { + 'ts/consistent-type-definitions': ['error', 'type'], + 'ts/no-require-imports': 'off', + "no-console": 'off', + "react-hooks/exhaustive-deps": "warn", + "react/display-name": "off", + "curly": "off", + } + }, + storybook, + // need futher research + { + rules: { + // not exist in old version + "antfu/consistent-list-newline": "off" + } + } +) diff --git a/web/package.json b/web/package.json index 464543b551..4c66eaf2d6 100644 --- a/web/package.json +++ b/web/package.json @@ -108,7 +108,7 @@ "zustand": "^4.5.2" }, "devDependencies": { - "@antfu/eslint-config": "^0.36.0", + "@antfu/eslint-config": "^3.8.0", "@chromatic-com/storybook": "^1.9.0", "@eslint/eslintrc": "^3.1.0", "@eslint/js": "^9.13.0", @@ -147,8 +147,8 @@ "bing-translate-api": "^4.0.2", "code-inspector-plugin": "^0.13.0", "cross-env": "^7.0.3", - "eslint": "^8.36.0", - "eslint-config-next": "^14.0.4", + "eslint": "^9.10.0", + "eslint-config-next": "^15.0.0-canary.202", "eslint-plugin-storybook": "^0.9.0", "husky": "^8.0.3", "jest": "^29.7.0", @@ -161,7 +161,10 @@ "tailwindcss": "^3.4.4", "ts-node": "^10.9.2", "typescript": "4.9.5", - "uglify-js": "^3.17.4" + "uglify-js": "^3.17.4", + "@eslint-react/eslint-plugin": "^1.15.0", + "eslint-plugin-react-hooks": "^5.0.0", + "eslint-plugin-react-refresh": "^0.4.12" }, "resolutions": { "@types/react": "~18.2.0", @@ -176,4 +179,4 @@ "eslint --fix" ] } -} +} \ No newline at end of file diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index b69455526f..dc8b54c7c8 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -261,11 +261,14 @@ importers: version: 4.5.5(@types/react@18.2.79)(immer@9.0.21)(react@18.2.0) devDependencies: '@antfu/eslint-config': - specifier: ^0.36.0 - version: 0.36.0(eslint@8.57.1)(jest@29.7.0(@types/node@18.15.0)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)))(typescript@4.9.5) + specifier: ^3.8.0 + version: 3.8.0(@eslint-react/eslint-plugin@1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(@typescript-eslint/utils@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(@vue/compiler-sfc@3.5.12)(eslint-plugin-react-hooks@5.0.0(eslint@9.13.0(jiti@1.21.6)))(eslint-plugin-react-refresh@0.4.13(eslint@9.13.0(jiti@1.21.6)))(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) '@chromatic-com/storybook': specifier: ^1.9.0 version: 1.9.0(react@18.2.0) + '@eslint-react/eslint-plugin': + specifier: ^1.15.0 + version: 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) '@eslint/eslintrc': specifier: ^3.1.0 version: 3.1.0 @@ -378,14 +381,20 @@ importers: specifier: ^7.0.3 version: 7.0.3 eslint: - specifier: ^8.36.0 - version: 8.57.1 + specifier: ^9.10.0 + version: 9.13.0(jiti@1.21.6) eslint-config-next: - specifier: ^14.0.4 - version: 14.2.15(eslint@8.57.1)(typescript@4.9.5) + specifier: ^15.0.0-canary.202 + version: 15.0.0-rc.1(eslint-plugin-import-x@4.3.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + eslint-plugin-react-hooks: + specifier: ^5.0.0 + version: 5.0.0(eslint@9.13.0(jiti@1.21.6)) + eslint-plugin-react-refresh: + specifier: ^0.4.12 + version: 0.4.13(eslint@9.13.0(jiti@1.21.6)) eslint-plugin-storybook: specifier: ^0.9.0 - version: 0.9.0(eslint@8.57.1)(typescript@4.9.5) + version: 0.9.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) husky: specifier: ^8.0.3 version: 8.0.3 @@ -436,26 +445,57 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} - '@antfu/eslint-config-basic@0.36.0': - resolution: {integrity: sha512-2b3ZB7pO00nxAERDXo82iYPjLQ4l/AOMm0CTKmGmqWbN3RB33EIQWzYheZRboSbAVzWpI1/3rg/Gu+7xYVMYHA==} + '@antfu/eslint-config@3.8.0': + resolution: {integrity: sha512-O5QSufPHpKTm0wk1OQ5c2mOZVzCqYV3hIDrt5zt+cOWqiG8YXLPkSOD4fFwjomATtOuUbcLUwkcgY5dErM7aIw==} + hasBin: true peerDependencies: - eslint: '>=7.4.0' + '@eslint-react/eslint-plugin': ^1.5.8 + '@prettier/plugin-xml': ^3.4.1 + '@unocss/eslint-plugin': '>=0.50.0' + astro-eslint-parser: ^1.0.2 + eslint: ^9.10.0 + eslint-plugin-astro: ^1.2.0 + eslint-plugin-format: '>=0.1.0' + eslint-plugin-react-hooks: ^5.0.0 + eslint-plugin-react-refresh: ^0.4.4 + eslint-plugin-solid: ^0.14.3 + eslint-plugin-svelte: '>=2.35.1' + prettier-plugin-astro: ^0.13.0 + prettier-plugin-slidev: ^1.0.5 + svelte-eslint-parser: '>=0.37.0' + peerDependenciesMeta: + '@eslint-react/eslint-plugin': + optional: true + '@prettier/plugin-xml': + optional: true + '@unocss/eslint-plugin': + optional: true + astro-eslint-parser: + optional: true + eslint-plugin-astro: + optional: true + eslint-plugin-format: + optional: true + eslint-plugin-react-hooks: + optional: true + eslint-plugin-react-refresh: + optional: true + eslint-plugin-solid: + optional: true + eslint-plugin-svelte: + optional: true + prettier-plugin-astro: + optional: true + prettier-plugin-slidev: + optional: true + svelte-eslint-parser: + optional: true - '@antfu/eslint-config-ts@0.36.0': - resolution: {integrity: sha512-I/h2ZOPBIqgnALG2fQp6lOBsOXk51QwLDumyEayt7GRnitdP4o9D8i+YAPowrMJ8M3kU7puQUyhWuJmZLgo57A==} - peerDependencies: - eslint: '>=7.4.0' - typescript: '>=3.9' + '@antfu/install-pkg@0.4.1': + resolution: {integrity: sha512-T7yB5QNG29afhWVkVq7XeIMBa5U/vs9mX69YqayXypPRmYzUmzwnYltplHmPtZ4HPCn+sQKeXW8I47wCbuBOjw==} - '@antfu/eslint-config-vue@0.36.0': - resolution: {integrity: sha512-YuTcNlVlrEWX1ESOiPgr+e2Walfd6xt3Toa0kAKJxq2aBS1RWqIi1l3zIVGCHaX72lOrSXNmQ7bryaZyGADGDg==} - peerDependencies: - eslint: '>=7.4.0' - - '@antfu/eslint-config@0.36.0': - resolution: {integrity: sha512-otZ9PfKRT3gnGMMX1gS8URTNPMPCZ69K5jHZvLkYojru0gLBZ3IO5fCvjEZpWqOyIUHtAgg6NWELf1DbEF+NDw==} - peerDependencies: - eslint: '>=7.4.0' + '@antfu/utils@0.7.10': + resolution: {integrity: sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==} '@babel/code-frame@7.25.7': resolution: {integrity: sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==} @@ -1099,6 +1139,14 @@ packages: resolution: {integrity: sha512-vYQ+TcfktEE3GHnLZXHCzXF/sN9dw+KivH8a5cmPyd9YtQs7fZtHrEgsIjWpYycXiweKMo1Lm1RZsjxk8DH3rA==} engines: {node: '>=16.0.0', yarn: '>=1.22.18'} + '@clack/core@0.3.4': + resolution: {integrity: sha512-H4hxZDXgHtWTwV3RAVenqcC4VbJZNegbBjlPvzOzCouXtS2y3sDvlO3IsbrPNWuLWPPlYVYPghQdSF64683Ldw==} + + '@clack/prompts@0.7.0': + resolution: {integrity: sha512-0MhX9/B4iL6Re04jPrttDm+BsP8y6mS7byuv0BvXgdXhbV5PdlsHt55dvNsuBCPZ7xq1oTAOOuotR9NFbQyMSA==} + bundledDependencies: + - is-unicode-supported + '@cspotcode/source-map-support@0.8.1': resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} @@ -1116,6 +1164,14 @@ packages: '@emoji-mart/data@1.2.1': resolution: {integrity: sha512-no2pQMWiBy6gpBEiqGeU77/bFejDqUTRY7KX+0+iur13op3bqUsXdnwoZs6Xb1zbv0gAj5VvS1PWoUUckSr5Dw==} + '@es-joy/jsdoccomment@0.48.0': + resolution: {integrity: sha512-G6QUWIcC+KvSwXNsJyDTHvqUdNoAVJPPgkc3+Uk4WBKqZvoXhlvazOgm9aL0HwihJLQf0l+tOE2UFzXBqCqgDw==} + engines: {node: '>=16'} + + '@es-joy/jsdoccomment@0.49.0': + resolution: {integrity: sha512-xjZTSFgECpb9Ohuk5yMX5RhUEbfeQcuOp8IF60e+wyzWEF0M5xeSgqsfLtvPEX8BIyOX9saZqzuGPmZ8oWc+5Q==} + engines: {node: '>=16'} + '@esbuild/aix-ppc64@0.23.1': resolution: {integrity: sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==} engines: {node: '>=18'} @@ -1260,6 +1316,12 @@ packages: cpu: [x64] os: [win32] + '@eslint-community/eslint-plugin-eslint-comments@4.4.0': + resolution: {integrity: sha512-yljsWl5Qv3IkIRmJ38h3NrHXFCm4EUl55M8doGTF6hvzvFF8kRpextgSrg2dwHev9lzBZyafCr9RelGIyQm6fw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 + '@eslint-community/eslint-utils@4.4.0': resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1270,22 +1332,74 @@ packages: resolution: {integrity: sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint/eslintrc@2.1.4': - resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@eslint-react/ast@1.15.0': + resolution: {integrity: sha512-7rOLLfGER82FQJy7pCFNs4j/47RYTEiPDfMFGAu4W7yerJrvU2rRNqjSwwm1Iq0DrrasBV8a3IVtPYQoDOqycg==} + + '@eslint-react/core@1.15.0': + resolution: {integrity: sha512-T7KirkdempegOxQznW1xclZtv5hQRChgbeYqisPRENkNg90w3uY7ia5iPf6FEZntkja/NF00VUnUetIw4rO0og==} + + '@eslint-react/eslint-plugin@1.15.0': + resolution: {integrity: sha512-5cuu7gNBgwQwgDX1YJugL7ujay0NT27g3UN0qtJAON9WLBv/ESq+qLMxddGwPSljV/XGxhwbbys09Jgww/fy8A==} + engines: {bun: '>=1.0.15', node: '>=18.18.0'} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ^4.9.5 || ^5.3.3 + peerDependenciesMeta: + typescript: + optional: true + + '@eslint-react/jsx@1.15.0': + resolution: {integrity: sha512-VZy8RWPx+2PUuBKaXPtu2qWnWN9SpkdgY3ohkZoGdoqkEYkYaXjvABNByQLwvk2+Ewqt0K+1f8r7QoQi47pQmw==} + + '@eslint-react/shared@1.15.0': + resolution: {integrity: sha512-LRgcKKhNePEJzuwICe3rgUC5KVd4ZhlKys91gMxmUob3RCiUj4BjfAURJMqzwsPGF32WQeHkipw1hWNGpQNdlw==} + + '@eslint-react/tools@1.15.0': + resolution: {integrity: sha512-zdd2K3EV2tWaCzNH60wD159HuX904kWzv+X87yqzZ0Nf2OBUDJ4a561NoDX3Pn8A3E6hFdu666zpIGdeaej9eg==} + + '@eslint-react/types@1.15.0': + resolution: {integrity: sha512-bajL6xIUxZp36fezn5HEhQpL0eJM923hwfRj6cym2Xl0Jn2YgahSztHorsOpId71MYBgn9ERy9yXItcnrz0rsQ==} + + '@eslint-react/var@1.15.0': + resolution: {integrity: sha512-/QycKnbgZRygM/lhHtUFQrvvrswdOyaXfVxwtIFVEYoPHP9q7NaUn0mrBu4VWkXQC9zPk1nWQeC3rZMUxzretg==} + + '@eslint/compat@1.2.1': + resolution: {integrity: sha512-JbHG2TWuCeNzh87fXo+/46Z1LEo9DBA9T188d0fZgGxAD+cNyS6sx9fdiyxjGPBMyQVRlCutTByZ6a5+YMkF7g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^9.10.0 + peerDependenciesMeta: + eslint: + optional: true + + '@eslint/config-array@0.18.0': + resolution: {integrity: sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.7.0': + resolution: {integrity: sha512-xp5Jirz5DyPYlPiKat8jaq0EmYvDXKKpzTbxXMpT9eqlRJkRKIz9AGMdlvYjih+im+QlhWrpvVjl8IPC/lHlUw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/eslintrc@3.1.0': resolution: {integrity: sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@8.57.1': - resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - '@eslint/js@9.13.0': resolution: {integrity: sha512-IFLyoY4d72Z5y/6o/BazFBezupzI/taV8sGumxTAVw3lXG9A6md1Dc34T9s1FoD/an9pJH8RHbAxsaEbBed9lA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/markdown@6.2.1': + resolution: {integrity: sha512-cKVd110hG4ICHmWhIwZJfKmmJBvbiDWyrHODJknAtudKgZtlROGoLX9UEOA0o746zC0hCY4UV4vR+aOGW9S6JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.4': + resolution: {integrity: sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.2.1': + resolution: {integrity: sha512-HFZ4Mp26nbWk9d/BpvP0YNL6W4UoZF0VFcTw/aPPA8RpOxeFQgK+ClABGgAUXs9Y/RGX/l1vOmrqz1MQt9MNuw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@faker-js/faker@7.6.0': resolution: {integrity: sha512-XK6BTq1NDMo9Xqw/YkYyGjSsg44fbNwYRx7QK2CuoQgyy+f1rrTDHoExVM5PsyXCtfl2vs2vVJ0MN0yN6LppRw==} engines: {node: '>=14.0.0', npm: '>=6.0.0'} @@ -1337,18 +1451,21 @@ packages: peerDependencies: react-hook-form: ^7.0.0 - '@humanwhocodes/config-array@0.13.0': - resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==} - engines: {node: '>=10.10.0'} - deprecated: Use @eslint/config-array instead + '@humanfs/core@0.19.0': + resolution: {integrity: sha512-2cbWIHbZVEweE853g8jymffCA+NCMiuqeECeBBLm8dg2oFdjuGJhgN4UAbI+6v0CKbbhvtXA4qV8YR5Ji86nmw==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.5': + resolution: {integrity: sha512-KSPA4umqSG4LHYRodq31VDwKAvaTF4xmVlzM8Aeh4PlU1JQ3IG0wiA8C25d3RQ9nJyM3mBHyI53K06VVL/oFFg==} + engines: {node: '>=18.18.0'} '@humanwhocodes/module-importer@1.0.1': resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} engines: {node: '>=12.22'} - '@humanwhocodes/object-schema@2.0.3': - resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} - deprecated: Use @eslint/object-schema instead + '@humanwhocodes/retry@0.3.1': + resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} + engines: {node: '>=18.18'} '@img/sharp-darwin-arm64@0.33.5': resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} @@ -1662,8 +1779,8 @@ packages: '@next/env@14.2.15': resolution: {integrity: sha512-S1qaj25Wru2dUpcIZMjxeMVSwkt8BK4dmWHHiBuRstcIyOsMapqT4A4jSB6onvqeygkSSmOkyny9VVx8JIGamQ==} - '@next/eslint-plugin-next@14.2.15': - resolution: {integrity: sha512-pKU0iqKRBlFB/ocOI1Ip2CkKePZpYpnw5bEItEkuZ/Nr9FQP1+p7VDWr4VfOdff4i9bFmrOaeaU1bFEyAcxiMQ==} + '@next/eslint-plugin-next@15.0.0-rc.1': + resolution: {integrity: sha512-Nz/tMHzuGPYR0uK57+mxLhVFDTKtCK8HeVnPmDp/L1nrgcgICFZUCYHnKDUM9IUQ1XalzYhrLOlizOadpOosIQ==} '@next/mdx@14.2.15': resolution: {integrity: sha512-OQWxKY5jWtHqPXdN3s5mj/LsD57pxt8CQsY4VQtTfQdQn6rNPd1bjN+kpbtezXdjgrKhvTJAb1yv1XGvzlh0uw==} @@ -1826,6 +1943,10 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} + '@pkgr/core@0.1.1': + resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + '@pmmmwh/react-refresh-webpack-plugin@0.5.15': resolution: {integrity: sha512-LFWllMA55pzB9D34w/wXUCf8+c+IYKuJDgxiZ3qMhl64KRMBHYM1I3VdGaD2BV5FNPV2/S2596bppxHbv2ZydQ==} engines: {node: '>= 10.13'} @@ -2168,6 +2289,12 @@ packages: peerDependencies: storybook: ^8.3.6 + '@stylistic/eslint-plugin@2.9.0': + resolution: {integrity: sha512-OrDyFAYjBT61122MIY1a3SfEgy3YCMgt2vL4eoPmvTwDBwyQhAXurxNQznlRD/jESNfYWfID8Ej+31LljvF7Xg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: '>=8.40.0' + '@svgdotjs/svg.js@3.2.4': resolution: {integrity: sha512-BjJ/7vWNowlX3Z8O4ywT58DqbNRyYlkk6Yz/D13aB7hGmfQTvGX4Tkgtm/ApYlu9M7lCQi15xUEidqMUmdMYwg==} @@ -2561,17 +2688,6 @@ packages: '@types/yargs@17.0.33': resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==} - '@typescript-eslint/eslint-plugin@5.62.0': - resolution: {integrity: sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - '@typescript-eslint/parser': ^5.0.0 - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - '@typescript-eslint/eslint-plugin@8.10.0': resolution: {integrity: sha512-phuB3hoP7FFKbRXxjl+DRlQDuJqhpOnm5MmtROXyWi3uS/Xg2ZXqiQfcG2BJHiN4QKyzdOJi3NEn/qTnjUlkmQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2583,16 +2699,6 @@ packages: typescript: optional: true - '@typescript-eslint/parser@5.62.0': - resolution: {integrity: sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - '@typescript-eslint/parser@8.10.0': resolution: {integrity: sha512-E24l90SxuJhytWJ0pTQydFT46Nk0Z+bsLKo/L8rtQSL93rQ6byd1V/QbDpHUTdLPOMsBCcYXZweADNCfOCmOAg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2611,16 +2717,6 @@ packages: resolution: {integrity: sha512-AgCaEjhfql9MDKjMUxWvH7HjLeBqMCBfIaBbzzIcBbQPZE7CPh1m6FF+L75NUMJFMLYhCywJXIDEMa3//1A0dw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/type-utils@5.62.0': - resolution: {integrity: sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: '*' - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - '@typescript-eslint/type-utils@8.10.0': resolution: {integrity: sha512-PCpUOpyQSpxBn230yIcK+LeCQaXuxrgCm2Zk1S+PTIRJsEfU6nJ0TtwyH8pIwPK/vJoA+7TZtzyAJSGBz+s/dg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2679,6 +2775,19 @@ packages: '@ungap/structured-clone@1.2.0': resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + '@vitest/eslint-plugin@1.1.7': + resolution: {integrity: sha512-pTWGW3y6lH2ukCuuffpan6kFxG6nIuoesbhMiQxskyQMRcCN5t9SXsKrNHvEw3p8wcCsgJoRqFZVkOTn6TjclA==} + peerDependencies: + '@typescript-eslint/utils': '>= 8.0' + eslint: '>= 8.57.0' + typescript: '>= 5.0.0' + vitest: '*' + peerDependenciesMeta: + typescript: + optional: true + vitest: + optional: true + '@vitest/expect@2.0.5': resolution: {integrity: sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA==} @@ -2703,6 +2812,12 @@ packages: '@vue/compiler-dom@3.5.12': resolution: {integrity: sha512-9G6PbJ03uwxLHKQ3P42cMTi85lDRvGLB2rSGOiQqtXELat6uI4n8cNz9yjfVHRPIu+MsK6TE418Giruvgptckg==} + '@vue/compiler-sfc@3.5.12': + resolution: {integrity: sha512-2k973OGo2JuAa5+ZlekuQJtitI5CgLMOwgl94BzMCsKZCX/xiqzJYzapl4opFogKHqwJk34vfsaKpfEhd1k5nw==} + + '@vue/compiler-ssr@3.5.12': + resolution: {integrity: sha512-eLwc7v6bfGBSM7wZOGPmRavSWzNFF6+PdRhE+VFJhNCgHiF8AM7ccoqcv5kBXA2eWUfigD7byekvf/JsOfKvPA==} + '@vue/shared@3.5.12': resolution: {integrity: sha512-L2RPSAwUFbgZH20etwrXyVyCBu9OxRSi8T/38QsvnkJyvq2LufW2lDCOzm7t/U9C1mkhJGWYfCuFBCmIuNivrg==} @@ -2887,6 +3002,10 @@ packages: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} + are-docs-informative@0.0.2: + resolution: {integrity: sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==} + engines: {node: '>=14'} + arg@4.1.3: resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} @@ -3064,6 +3183,9 @@ packages: bing-translate-api@4.0.2: resolution: {integrity: sha512-JJ8XUehnxzOhHU91oy86xEtp8OOMjVEjCZJX042fKxoO19NNvxJ5omeCcxQNFoPbDqVpBJwqiGVquL0oPdQm1Q==} + birecord@0.1.1: + resolution: {integrity: sha512-VUpsf/qykW0heRlC8LooCq28Kxn3mAqKohhDG/49rrsQ1dT1CXyj/pgXS+5BSRzFTR/3DyIBOqQOrGyZOh71Aw==} + bn.js@4.12.0: resolution: {integrity: sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==} @@ -3137,9 +3259,6 @@ packages: builtin-status-codes@3.0.0: resolution: {integrity: sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==} - builtins@5.1.0: - resolution: {integrity: sha512-SW9lzGTLvWTP1AY8xeAMZimqDrIaSdLQUcVr9DMef51niJ022Ri87SwRRKYm4A6iHfkPaiVUu/Duw2Wc4J7kKg==} - busboy@1.6.0: resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} engines: {node: '>=10.16.0'} @@ -3270,6 +3389,10 @@ packages: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} + ci-info@4.0.0: + resolution: {integrity: sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==} + engines: {node: '>=8'} + cipher-base@1.0.4: resolution: {integrity: sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==} @@ -3387,6 +3510,10 @@ packages: resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} engines: {node: '>= 12'} + comment-parser@1.4.1: + resolution: {integrity: sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==} + engines: {node: '>= 12.0.0'} + common-path-prefix@3.0.0: resolution: {integrity: sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==} @@ -3396,6 +3523,9 @@ packages: concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + console-browserify@1.2.0: resolution: {integrity: sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==} @@ -3873,9 +4003,6 @@ packages: dom-serializer@1.4.1: resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==} - dom-serializer@2.0.0: - resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} - domain-browser@4.23.0: resolution: {integrity: sha512-ArzcM/II1wCCujdCNyQjXrAFwS4mrLh4C7DZWlaI8mdh7h3BfKdNd3bKXITfl2PT9FtfQqaGvhi1vPRQPimjGA==} engines: {node: '>=10'} @@ -3892,19 +4019,12 @@ packages: resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==} engines: {node: '>= 4'} - domhandler@5.0.3: - resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} - engines: {node: '>= 4'} - dompurify@3.1.7: resolution: {integrity: sha512-VaTstWtsneJY8xzy7DekmYWEOZcmzIe3Qb3zPd4STve1OBTa+e+WmS1ITQec1fZYXI3HCsOZZiSMpG6oxoWMWQ==} domutils@2.8.0: resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==} - domutils@3.1.0: - resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==} - dot-case@3.0.4: resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} @@ -4062,15 +4182,23 @@ packages: peerDependencies: eslint: '>=6.0.0' - eslint-config-next@14.2.15: - resolution: {integrity: sha512-mKg+NC/8a4JKLZRIOBplxXNdStgxy7lzWuedUaCc8tev+Al9mwDUTujQH6W6qXDH9kycWiVo28tADWGvpBsZcQ==} + eslint-config-flat-gitignore@0.3.0: + resolution: {integrity: sha512-0Ndxo4qGhcewjTzw52TK06Mc00aDtHNTdeeW2JfONgDcLkRO/n/BteMRzNVpLQYxdCC/dFEilfM9fjjpGIJ9Og==} peerDependencies: - eslint: ^7.23.0 || ^8.0.0 + eslint: ^9.5.0 + + eslint-config-next@15.0.0-rc.1: + resolution: {integrity: sha512-RhOlMP/dWBYBBzYjh6ya4OYSxUhkzsoQmbkLvifZgBflD/XCQ+WUd/D1qdSTI9BBkUEeDZ7GOaN5UaIACkQeRA==} + peerDependencies: + eslint: ^7.23.0 || ^8.0.0 || ^9.0.0 typescript: '>=3.3.1' peerDependenciesMeta: typescript: optional: true + eslint-flat-config-utils@0.4.0: + resolution: {integrity: sha512-kfd5kQZC+BMO0YwTol6zxjKX1zAsk8JfSAopbKjKqmENTJcew+yBejuvccAg37cvOrN0Mh+DVbeyznuNWEjt4A==} + eslint-import-resolver-node@0.3.9: resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} @@ -4087,6 +4215,11 @@ packages: eslint-plugin-import-x: optional: true + eslint-merge-processors@0.1.0: + resolution: {integrity: sha512-IvRXXtEajLeyssvW4wJcZ2etxkR9mUf4zpNwgI+m/Uac9RfXHskuJefkHUcawVzePnd6xp24enp5jfgdHzjRdQ==} + peerDependencies: + eslint: '*' + eslint-module-utils@2.12.0: resolution: {integrity: sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==} engines: {node: '>=4'} @@ -4108,23 +4241,27 @@ packages: eslint-import-resolver-webpack: optional: true - eslint-plugin-antfu@0.36.0: - resolution: {integrity: sha512-qLYtjZC2y6d1fvVtG4nvVGoBUDEuUwQsS4E1RwjoEZyONZAkHYDPfeoeULDlPS0IqumSW8uGR6zGSAXi5rrVMg==} - - eslint-plugin-es@4.1.0: - resolution: {integrity: sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ==} - engines: {node: '>=8.10.0'} + eslint-plugin-antfu@2.7.0: + resolution: {integrity: sha512-gZM3jq3ouqaoHmUNszb1Zo2Ux7RckSvkGksjLWz9ipBYGSv1EwwBETN6AdiUXn+RpVHXTbEMPAPlXJazcA6+iA==} peerDependencies: - eslint: '>=4.19.1' + eslint: '*' - eslint-plugin-eslint-comments@3.2.0: - resolution: {integrity: sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ==} - engines: {node: '>=6.5.0'} + eslint-plugin-command@0.2.6: + resolution: {integrity: sha512-T0bHZ1oblW1xUHUVoBKZJR2osSNNGkfZuK4iqboNwuNS/M7tdp3pmURaJtTi/XDzitxaQ02lvOdFH0mUd5QLvQ==} peerDependencies: - eslint: '>=4.19.1' + eslint: '*' - eslint-plugin-html@7.1.0: - resolution: {integrity: sha512-fNLRraV/e6j8e3XYOC9xgND4j+U7b1Rq+OygMlLcMg+wI/IpVbF+ubQa3R78EjKB9njT6TQOlcK5rFKBVVtdfg==} + eslint-plugin-es-x@7.8.0: + resolution: {integrity: sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '>=8' + + eslint-plugin-import-x@4.3.1: + resolution: {integrity: sha512-5TriWkXulDl486XnYYRgsL+VQoS/7mhN/2ci02iLCuL7gdhbiWxnsuL/NTcaKY9fpMgsMFjWZBtIGW7pb+RX0g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 eslint-plugin-import@2.31.0: resolution: {integrity: sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==} @@ -4136,18 +4273,11 @@ packages: '@typescript-eslint/parser': optional: true - eslint-plugin-jest@27.9.0: - resolution: {integrity: sha512-QIT7FH7fNmd9n4se7FFKHbsLKGQiw885Ds6Y/sxKgCZ6natwCsXdgPOADnYVxN2QrRweF0FZWbJ6S7Rsn7llug==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + eslint-plugin-jsdoc@50.4.3: + resolution: {integrity: sha512-uWtwFxGRv6B8sU63HZM5dAGDhgsatb+LONwmILZJhdRALLOkCX2HFZhdL/Kw2ls8SQMAVEfK+LmnEfxInRN8HA==} + engines: {node: '>=18'} peerDependencies: - '@typescript-eslint/eslint-plugin': ^5.0.0 || ^6.0.0 || ^7.0.0 - eslint: ^7.0.0 || ^8.0.0 - jest: '*' - peerDependenciesMeta: - '@typescript-eslint/eslint-plugin': - optional: true - jest: - optional: true + eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 eslint-plugin-jsonc@2.16.0: resolution: {integrity: sha512-Af/ZL5mgfb8FFNleH6KlO4/VdmDuTqmM+SPnWcdoWywTetv7kq+vQe99UyQb9XO3b0OWLVuTH7H0d/PXYCMdSg==} @@ -4161,33 +4291,105 @@ packages: peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 - eslint-plugin-markdown@3.0.1: - resolution: {integrity: sha512-8rqoc148DWdGdmYF6WSQFT3uQ6PO7zXYgeBpHAOAakX/zpq+NvFYbDA/H7PYzHajwtmaOzAwfxyl++x0g1/N9A==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + eslint-plugin-n@17.11.1: + resolution: {integrity: sha512-93IUD82N6tIEgjztVI/l3ElHtC2wTa9boJHrD8iN+NyDxjxz/daZUZKfkedjBZNdg6EqDk4irybUsiPwDqXAEA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - - eslint-plugin-n@15.7.0: - resolution: {integrity: sha512-jDex9s7D/Qial8AGVIHq4W7NswpUD5DPDL2RH8Lzd9EloWUuvUkHfv4FRLMipH5q2UtyurorBkPeNi1wVWNh3Q==} - engines: {node: '>=12.22.0'} - peerDependencies: - eslint: '>=7.0.0' + eslint: '>=8.23.0' eslint-plugin-no-only-tests@3.3.0: resolution: {integrity: sha512-brcKcxGnISN2CcVhXJ/kEQlNa0MEfGRtwKtWA16SkqXHKitaKIMrfemJKLKX1YqDU5C/5JY3PvZXd5jEW04e0Q==} engines: {node: '>=5.0.0'} - eslint-plugin-promise@6.6.0: - resolution: {integrity: sha512-57Zzfw8G6+Gq7axm2Pdo3gW/Rx3h9Yywgn61uE/3elTCOePEHVrn2i5CdfBwA1BLK0Q0WqctICIUSqXZW/VprQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + eslint-plugin-perfectionist@3.9.1: + resolution: {integrity: sha512-9WRzf6XaAxF4Oi5t/3TqKP5zUjERhasHmLFHin2Yw6ZAp/EP/EVA2dr3BhQrrHWCm5SzTMZf0FcjDnBkO2xFkA==} + engines: {node: ^18.0.0 || >=20.0.0} peerDependencies: - eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 + astro-eslint-parser: ^1.0.2 + eslint: '>=8.0.0' + svelte: '>=3.0.0' + svelte-eslint-parser: ^0.41.1 + vue-eslint-parser: '>=9.0.0' + peerDependenciesMeta: + astro-eslint-parser: + optional: true + svelte: + optional: true + svelte-eslint-parser: + optional: true + vue-eslint-parser: + optional: true - eslint-plugin-react-hooks@5.0.0-canary-7118f5dd7-20230705: - resolution: {integrity: sha512-AZYbMo/NW9chdL7vk6HQzQhT+PvTAEVqWk9ziruUoW2kAOcN5qNyelv70e0F1VNQAbvutOC9oc+xfWycI9FxDw==} + eslint-plugin-react-debug@1.15.0: + resolution: {integrity: sha512-zD5WOVPwKNnO4897gz2yjZZcvdGIObKEi4QURDammVEc3sCU0evHcAPEknTC1WEd7T8A4Zu7Vt7sDaUz/DALnA==} + engines: {bun: '>=1.0.15', node: '>=18.18.0'} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ^4.9.5 || ^5.3.3 + peerDependenciesMeta: + typescript: + optional: true + + eslint-plugin-react-dom@1.15.0: + resolution: {integrity: sha512-P8IdPfiEpDR8SHZdnYJzfdSkV++0hHzOJQhLW9eACyuGCBuzLj2gglmPR5gH2RG44R+Iq5+hsUVNv7sklThvRg==} + engines: {bun: '>=1.0.15', node: '>=18.18.0'} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ^4.9.5 || ^5.3.3 + peerDependenciesMeta: + typescript: + optional: true + + eslint-plugin-react-hooks-extra@1.15.0: + resolution: {integrity: sha512-guIcax3c4Z/iWyDwZdo5b0qzqpJrhH4svYIfj+wEpfjRdIwpAvL0xM1uqJKdz8Hbgw1D+6dePSau4zmVkuaMqA==} + engines: {bun: '>=1.0.15', node: '>=18.18.0'} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ^4.9.5 || ^5.3.3 + peerDependenciesMeta: + typescript: + optional: true + + eslint-plugin-react-hooks@5.0.0: + resolution: {integrity: sha512-hIOwI+5hYGpJEc4uPRmz2ulCjAGD/N13Lukkh8cLV0i2IRk/bdZDYjgLVHj+U9Z704kLIdIO6iueGvxNur0sgw==} engines: {node: '>=10'} peerDependencies: - eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 + + eslint-plugin-react-naming-convention@1.15.0: + resolution: {integrity: sha512-XjbkBFEsaGvhDUKCxDCdJ34dsr/XnQu5a7hq6h2aNpnu05VGCAW6CXf3VuyI/sKfj3Em+aX/9eHdcRi12+dmLg==} + engines: {bun: '>=1.0.15', node: '>=18.18.0'} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ^4.9.5 || ^5.3.3 + peerDependenciesMeta: + typescript: + optional: true + + eslint-plugin-react-refresh@0.4.13: + resolution: {integrity: sha512-f1EppwrpJRWmqDTyvAyomFVDYRtrS7iTEqv3nokETnMiMzs2SSTmKRTACce4O2p4jYyowiSMvpdwC/RLcMFhuQ==} + peerDependencies: + eslint: '>=7' + + eslint-plugin-react-web-api@1.15.0: + resolution: {integrity: sha512-LUwzKumBApdKzUgl+9F5/TyJbYGQIOy450s6kr3rLPrc9tk8GQrBmSQKmWh2g7C1x7DIoMNFXeUuAD1q/1AKnw==} + engines: {bun: '>=1.0.15', node: '>=18.18.0'} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ^4.9.5 || ^5.3.3 + peerDependenciesMeta: + typescript: + optional: true + + eslint-plugin-react-x@1.15.0: + resolution: {integrity: sha512-TIZVElFYVXvybmMBVzHPF2hmsaG7greytHd80efUPopxlr+JGjKba6zA3cJAURn+yzN1x2zPJzss2BkB8/48aQ==} + engines: {bun: '>=1.0.15', node: '>=18.18.0'} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ^4.9.5 || ^5.3.3 + peerDependenciesMeta: + typescript: + optional: true eslint-plugin-react@7.37.1: resolution: {integrity: sha512-xwTnwDqzbDRA8uJ7BMxPs/EXRB3i8ZfnOIp8BsxEQkT0nHPp+WWceqGgo6rKb9ctNi8GJLDT4Go5HAWELa/WMg==} @@ -4195,24 +4397,35 @@ packages: peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 + eslint-plugin-regexp@2.6.0: + resolution: {integrity: sha512-FCL851+kislsTEQEMioAlpDuK5+E5vs0hi1bF8cFlPlHcEjeRhuAzEsGikXRreE+0j4WhW2uO54MqTjXtYOi3A==} + engines: {node: ^18 || >=20} + peerDependencies: + eslint: '>=8.44.0' + eslint-plugin-storybook@0.9.0: resolution: {integrity: sha512-qOT/2vQBo0VqrG/BhZv8IdSsKQiyzJw+2Wqq+WFCiblI/PfxLSrGkF/buiXF+HumwfsCyBdaC94UhqhmYFmAvA==} engines: {node: '>= 18'} peerDependencies: eslint: '>=6' - eslint-plugin-unicorn@45.0.2: - resolution: {integrity: sha512-Y0WUDXRyGDMcKLiwgL3zSMpHrXI00xmdyixEGIg90gHnj0PcHY4moNv3Ppje/kDivdAy5vUeUr7z211ImPv2gw==} - engines: {node: '>=14.18'} - peerDependencies: - eslint: '>=8.28.0' - - eslint-plugin-unused-imports@2.0.0: - resolution: {integrity: sha512-3APeS/tQlTrFa167ThtP0Zm0vctjr4M44HMpeg1P4bK6wItarumq0Ma82xorMKdFsWpphQBlRPzw/pxiVELX1A==} + eslint-plugin-toml@0.11.1: + resolution: {integrity: sha512-Y1WuMSzfZpeMIrmlP1nUh3kT8p96mThIq4NnHrYUhg10IKQgGfBZjAWnrg9fBqguiX4iFps/x/3Hb5TxBisfdw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: - '@typescript-eslint/eslint-plugin': ^5.0.0 - eslint: ^8.0.0 + eslint: '>=6.0.0' + + eslint-plugin-unicorn@56.0.0: + resolution: {integrity: sha512-aXpddVz/PQMmd69uxO98PA4iidiVNvA0xOtbpUoz1WhBd4RxOQQYqN618v68drY0hmy5uU2jy1bheKEVWBjlPw==} + engines: {node: '>=18.18'} + peerDependencies: + eslint: '>=8.56.0' + + eslint-plugin-unused-imports@4.1.4: + resolution: {integrity: sha512-YptD6IzQjDardkl0POxnnRBhU1OEePMV0nd6siHaRBbd+lyh6NAhFEobiznKU7kTsSsDeSD62Pe7kAM1b7dAZQ==} + peerDependencies: + '@typescript-eslint/eslint-plugin': ^8.0.0-0 || ^7.0.0 || ^6.0.0 || ^5.0.0 + eslint: ^9.0.0 || ^8.0.0 peerDependenciesMeta: '@typescript-eslint/eslint-plugin': optional: true @@ -4229,9 +4442,11 @@ packages: peerDependencies: eslint: '>=6.0.0' - eslint-rule-composer@0.3.0: - resolution: {integrity: sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==} - engines: {node: '>=4.0.0'} + eslint-processor-vue-blocks@0.1.2: + resolution: {integrity: sha512-PfpJ4uKHnqeL/fXUnzYkOax3aIenlwewXRX8jFinA1a2yCFnLgMuiH3xvCgvHHUlV2xJWQHbCTdiJWGwb3NqpQ==} + peerDependencies: + '@vue/compiler-sfc': ^3.3.0 + eslint: ^8.50.0 || ^9.0.0 eslint-scope@5.1.1: resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} @@ -4241,23 +4456,9 @@ packages: resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - eslint-utils@2.1.0: - resolution: {integrity: sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==} - engines: {node: '>=6'} - - eslint-utils@3.0.0: - resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} - engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} - peerDependencies: - eslint: '>=5' - - eslint-visitor-keys@1.3.0: - resolution: {integrity: sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==} - engines: {node: '>=4'} - - eslint-visitor-keys@2.1.0: - resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==} - engines: {node: '>=10'} + eslint-scope@8.1.0: + resolution: {integrity: sha512-14dSvlhaVhKKsa9Fx1l8A17s7ah7Ef7wCakJ10LYk6+GYmP9yDti2oq2SEwcyndt6knfcZyhyxwY3i9yL78EQw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} eslint-visitor-keys@3.4.3: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} @@ -4267,11 +4468,15 @@ packages: resolution: {integrity: sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint@8.57.1: - resolution: {integrity: sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. + eslint@9.13.0: + resolution: {integrity: sha512-EYZK6SX6zjFHST/HRytOdA/zE72Cq/bfw45LSyuwrdvcclb/gqV8RRQxywOBEWO2+WDpva6UZa4CcDeJKzUCFA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true espree@10.2.0: resolution: {integrity: sha512-upbkBJbckcCNBDBDXEbuhjbP68n+scUd3k/U2EkyM9nw+I/jPiL4cLF/Al06CF96wRltFda16sxDFrxsI1v0/g==} @@ -4371,6 +4576,10 @@ packages: fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + fast-glob@3.3.1: + resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} + engines: {node: '>=8.6.0'} + fast-glob@3.3.2: resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} engines: {node: '>=8.6.0'} @@ -4396,9 +4605,9 @@ packages: fb-watchman@2.0.2: resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} - file-entry-cache@6.0.1: - resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} - engines: {node: ^10.12.0 || >=12.0.0} + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} filesize@10.1.6: resolution: {integrity: sha512-sJslQKU2uM33qH5nqewAwVB2QgR6w1aMNsYUp3aN5rMRyXEwJGmZvaWzeJFNTOXWlHQyBFCWrdj3fV/fsTOX8w==} @@ -4424,6 +4633,10 @@ packages: resolution: {integrity: sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==} engines: {node: '>=14.16'} + find-up-simple@1.0.0: + resolution: {integrity: sha512-q7Us7kcjj2VMePAa02hDAF6d+MzsdsAWEwYyOpwUtlerRBkOEPBCRZrAV4XfcSN8fHAgaD0hP7miwoay6DCprw==} + engines: {node: '>=18'} + find-up@4.1.0: resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} engines: {node: '>=8'} @@ -4440,6 +4653,10 @@ packages: resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} engines: {node: ^10.12.0 || >=12.0.0} + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + flatted@3.3.1: resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} @@ -4550,11 +4767,6 @@ packages: glob-to-regexp@0.4.1: resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} - glob@10.3.10: - resolution: {integrity: sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==} - engines: {node: '>=16 || 14 >=14.17'} - hasBin: true - glob@10.4.5: resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} hasBin: true @@ -4575,6 +4787,10 @@ packages: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} + globals@15.11.0: + resolution: {integrity: sha512-yeyNSjdbyVaWurlwCpcA6XNBrHTMIeDdj0/hnvX/OLJ9ekOXYbLsLinH/MucQyGvNnXhidTdNhTtJaffL2sMfw==} + engines: {node: '>=18'} + globalthis@1.0.4: resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} engines: {node: '>= 0.4'} @@ -4756,9 +4972,6 @@ packages: htmlparser2@6.1.0: resolution: {integrity: sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==} - htmlparser2@8.0.2: - resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} - http-cache-semantics@4.1.1: resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} @@ -4996,6 +5209,12 @@ packages: is-hexadecimal@2.0.1: resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + is-immutable-type@5.0.0: + resolution: {integrity: sha512-mcvHasqbRBWJznuPqqHRKiJgYAz60sZ0mvO3bN70JbkuK7ksfmgc489aKZYxMEjIbRvyOseaTjaRZLRF/xFeRA==} + peerDependencies: + eslint: '*' + typescript: '>=4.7.4' + is-map@2.0.3: resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} engines: {node: '>= 0.4'} @@ -5016,10 +5235,6 @@ packages: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} - is-path-inside@3.0.3: - resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} - engines: {node: '>=8'} - is-plain-obj@4.1.0: resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} engines: {node: '>=12'} @@ -5121,10 +5336,6 @@ packages: resolution: {integrity: sha512-FW5iMbeQ6rBGm/oKgzq2aW4KvAGpxPzYES8N4g4xNXUKpL1mclMvOe+76AcLDTvD+Ze+sOpVhgdAQEKF4L9iGQ==} engines: {node: '>= 0.4'} - jackspeak@2.3.6: - resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} - engines: {node: '>=14'} - jackspeak@3.4.3: resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} @@ -5443,8 +5654,8 @@ packages: resolution: {integrity: sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==} engines: {node: '>= 12.13.0'} - local-pkg@0.4.3: - resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==} + local-pkg@0.5.0: + resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} engines: {node: '>=14'} localforage@1.10.0: @@ -5559,30 +5770,51 @@ packages: mdast-util-find-and-replace@2.2.2: resolution: {integrity: sha512-MTtdFRz/eMDHXzeK6W3dO7mXUlF82Gom4y0oOgvHhh/HXZAGvIQDUvQ0SuUx+j2tv44b8xTHOm8K/9OoRFnXKw==} - mdast-util-from-markdown@0.8.5: - resolution: {integrity: sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==} + mdast-util-find-and-replace@3.0.1: + resolution: {integrity: sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==} mdast-util-from-markdown@1.3.1: resolution: {integrity: sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==} + mdast-util-from-markdown@2.0.1: + resolution: {integrity: sha512-aJEUyzZ6TzlsX2s5B4Of7lN7EQtAxvtradMMglCQDyaTFgse6CmtmdJ15ElnVRlCg1vpNyVtbem0PWzlNieZsA==} + mdast-util-gfm-autolink-literal@1.0.3: resolution: {integrity: sha512-My8KJ57FYEy2W2LyNom4n3E7hKTuQk/0SES0u16tjA9Z3oFkF4RrC/hPAPgjlSpezsOvI8ObcXcElo92wn5IGA==} + mdast-util-gfm-autolink-literal@2.0.1: + resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} + mdast-util-gfm-footnote@1.0.2: resolution: {integrity: sha512-56D19KOGbE00uKVj3sgIykpwKL179QsVFwx/DCW0u/0+URsryacI4MAdNJl0dh+u2PSsD9FtxPFbHCzJ78qJFQ==} + mdast-util-gfm-footnote@2.0.0: + resolution: {integrity: sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==} + mdast-util-gfm-strikethrough@1.0.3: resolution: {integrity: sha512-DAPhYzTYrRcXdMjUtUjKvW9z/FNAMTdU0ORyMcbmkwYNbKocDpdk+PX1L1dQgOID/+vVs1uBQ7ElrBQfZ0cuiQ==} + mdast-util-gfm-strikethrough@2.0.0: + resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} + mdast-util-gfm-table@1.0.7: resolution: {integrity: sha512-jjcpmNnQvrmN5Vx7y7lEc2iIOEytYv7rTvu+MeyAsSHTASGCCRA79Igg2uKssgOs1i1po8s3plW0sTu1wkkLGg==} + mdast-util-gfm-table@2.0.0: + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} + mdast-util-gfm-task-list-item@1.0.2: resolution: {integrity: sha512-PFTA1gzfp1B1UaiJVyhJZA1rm0+Tzn690frc/L8vNX1Jop4STZgOE6bxUhnzdVSB+vm2GU1tIsuQcA9bxTQpMQ==} + mdast-util-gfm-task-list-item@2.0.0: + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} + mdast-util-gfm@2.0.2: resolution: {integrity: sha512-qvZ608nBppZ4icQlhQQIAdc6S3Ffj9RGmzwUKUWuEICFnd1LVkN3EktF7ZHAgfcEdvZB5owU9tQgt99e2TlLjg==} + mdast-util-gfm@3.0.0: + resolution: {integrity: sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==} + mdast-util-math@2.0.2: resolution: {integrity: sha512-8gmkKVp9v6+Tgjtq6SYx9kGPpTf6FVYRa53/DLh479aldR9AyP48qeVOgNZ5X7QUK7nOy4yw7vg6mbiGcs9jWQ==} @@ -5604,6 +5836,9 @@ packages: mdast-util-phrasing@3.0.1: resolution: {integrity: sha512-WmI1gTXUBJo4/ZmSk79Wcb2HcjPJBzM1nlI/OUWA8yk2X9ik3ffNbBGsU+09BFmXaL1IBb9fiuvq6/KMiNycSg==} + mdast-util-phrasing@4.1.0: + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + mdast-util-to-hast@12.3.0: resolution: {integrity: sha512-pits93r8PhnIoU4Vy9bjW39M2jJ6/tdHyja9rrot9uujkN7UTU9SDnE6WNJz/IGyQk3XHX6yNNtrBH6cQzm8Hw==} @@ -5613,12 +5848,15 @@ packages: mdast-util-to-markdown@1.5.0: resolution: {integrity: sha512-bbv7TPv/WC49thZPg3jXuqzuvI45IL2EVAr/KxF0BSdHsU0ceFHOmwQn6evxAh1GaoK/6GQ1wp4R4oW2+LFL/A==} - mdast-util-to-string@2.0.0: - resolution: {integrity: sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==} + mdast-util-to-markdown@2.1.0: + resolution: {integrity: sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==} mdast-util-to-string@3.2.0: resolution: {integrity: sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==} + mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + media-typer@0.3.0: resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} engines: {node: '>= 0.6'} @@ -5653,27 +5891,51 @@ packages: micromark-core-commonmark@1.1.0: resolution: {integrity: sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==} + micromark-core-commonmark@2.0.1: + resolution: {integrity: sha512-CUQyKr1e///ZODyD1U3xit6zXwy1a8q2a1S1HKtIlmgvurrEpaw/Y9y6KSIbF8P59cn/NjzHyO+Q2fAyYLQrAA==} + micromark-extension-gfm-autolink-literal@1.0.5: resolution: {integrity: sha512-z3wJSLrDf8kRDOh2qBtoTRD53vJ+CWIyo7uyZuxf/JAbNJjiHsOpG1y5wxk8drtv3ETAHutCu6N3thkOOgueWg==} + micromark-extension-gfm-autolink-literal@2.1.0: + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} + micromark-extension-gfm-footnote@1.1.2: resolution: {integrity: sha512-Yxn7z7SxgyGWRNa4wzf8AhYYWNrwl5q1Z8ii+CSTTIqVkmGZF1CElX2JI8g5yGoM3GAman9/PVCUFUSJ0kB/8Q==} + micromark-extension-gfm-footnote@2.1.0: + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} + micromark-extension-gfm-strikethrough@1.0.7: resolution: {integrity: sha512-sX0FawVE1o3abGk3vRjOH50L5TTLr3b5XMqnP9YDRb34M0v5OoZhG+OHFz1OffZ9dlwgpTBKaT4XW/AsUVnSDw==} + micromark-extension-gfm-strikethrough@2.1.0: + resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} + micromark-extension-gfm-table@1.0.7: resolution: {integrity: sha512-3ZORTHtcSnMQEKtAOsBQ9/oHp9096pI/UvdPtN7ehKvrmZZ2+bbWhi0ln+I9drmwXMt5boocn6OlwQzNXeVeqw==} + micromark-extension-gfm-table@2.1.0: + resolution: {integrity: sha512-Ub2ncQv+fwD70/l4ou27b4YzfNaCJOvyX4HxXU15m7mpYY+rjuWzsLIPZHJL253Z643RpbcP1oeIJlQ/SKW67g==} + micromark-extension-gfm-tagfilter@1.0.2: resolution: {integrity: sha512-5XWB9GbAUSHTn8VPU8/1DBXMuKYT5uOgEjJb8gN3mW0PNW5OPHpSdojoqf+iq1xo7vWzw/P8bAHY0n6ijpXF7g==} + micromark-extension-gfm-tagfilter@2.0.0: + resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} + micromark-extension-gfm-task-list-item@1.0.5: resolution: {integrity: sha512-RMFXl2uQ0pNQy6Lun2YBYT9g9INXtWJULgbt01D/x8/6yJ2qpKyzdZD3pi6UIkzF++Da49xAelVKUeUMqd5eIQ==} + micromark-extension-gfm-task-list-item@2.1.0: + resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} + micromark-extension-gfm@2.0.3: resolution: {integrity: sha512-vb9OoHqrhCmbRidQv/2+Bc6pkP0FrtlhurxZofvOEy5o8RtuuvTq+RQ1Vw5ZDNrVraQZu3HixESqbG+0iKk/MQ==} + micromark-extension-gfm@3.0.0: + resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + micromark-extension-math@2.1.2: resolution: {integrity: sha512-es0CcOV89VNS9wFmyn+wyFTKweXGW4CEvdaAca6SWRWPyYCbBisnjaHLjWO4Nszuiud84jCpkHsqAJoa768Pvg==} @@ -5695,21 +5957,36 @@ packages: micromark-factory-destination@1.1.0: resolution: {integrity: sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==} + micromark-factory-destination@2.0.0: + resolution: {integrity: sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==} + micromark-factory-label@1.1.0: resolution: {integrity: sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==} + micromark-factory-label@2.0.0: + resolution: {integrity: sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==} + micromark-factory-mdx-expression@1.0.9: resolution: {integrity: sha512-jGIWzSmNfdnkJq05c7b0+Wv0Kfz3NJ3N4cBjnbO4zjXIlxJr+f8lk+5ZmwFvqdAbUy2q6B5rCY//g0QAAaXDWA==} micromark-factory-space@1.1.0: resolution: {integrity: sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==} + micromark-factory-space@2.0.0: + resolution: {integrity: sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==} + micromark-factory-title@1.1.0: resolution: {integrity: sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==} + micromark-factory-title@2.0.0: + resolution: {integrity: sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==} + micromark-factory-whitespace@1.1.0: resolution: {integrity: sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==} + micromark-factory-whitespace@2.0.0: + resolution: {integrity: sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==} + micromark-util-character@1.2.0: resolution: {integrity: sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==} @@ -5719,18 +5996,33 @@ packages: micromark-util-chunked@1.1.0: resolution: {integrity: sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==} + micromark-util-chunked@2.0.0: + resolution: {integrity: sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==} + micromark-util-classify-character@1.1.0: resolution: {integrity: sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==} + micromark-util-classify-character@2.0.0: + resolution: {integrity: sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==} + micromark-util-combine-extensions@1.1.0: resolution: {integrity: sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==} + micromark-util-combine-extensions@2.0.0: + resolution: {integrity: sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==} + micromark-util-decode-numeric-character-reference@1.1.0: resolution: {integrity: sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==} + micromark-util-decode-numeric-character-reference@2.0.1: + resolution: {integrity: sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==} + micromark-util-decode-string@1.1.0: resolution: {integrity: sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==} + micromark-util-decode-string@2.0.0: + resolution: {integrity: sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==} + micromark-util-encode@1.1.0: resolution: {integrity: sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==} @@ -5743,12 +6035,21 @@ packages: micromark-util-html-tag-name@1.2.0: resolution: {integrity: sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==} + micromark-util-html-tag-name@2.0.0: + resolution: {integrity: sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==} + micromark-util-normalize-identifier@1.1.0: resolution: {integrity: sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==} + micromark-util-normalize-identifier@2.0.0: + resolution: {integrity: sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==} + micromark-util-resolve-all@1.1.0: resolution: {integrity: sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==} + micromark-util-resolve-all@2.0.0: + resolution: {integrity: sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==} + micromark-util-sanitize-uri@1.2.0: resolution: {integrity: sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==} @@ -5758,6 +6059,9 @@ packages: micromark-util-subtokenize@1.1.0: resolution: {integrity: sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==} + micromark-util-subtokenize@2.0.1: + resolution: {integrity: sha512-jZNtiFl/1aY73yS3UGQkutD0UbhTt68qnRpw2Pifmz5wV9h8gOVsN70v+Lq/f1rKaU/W8pxRe8y8Q9FX1AOe1Q==} + micromark-util-symbol@1.1.0: resolution: {integrity: sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==} @@ -5770,12 +6074,12 @@ packages: micromark-util-types@2.0.0: resolution: {integrity: sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==} - micromark@2.11.4: - resolution: {integrity: sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==} - micromark@3.2.0: resolution: {integrity: sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==} + micromark@4.0.0: + resolution: {integrity: sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==} + micromatch@4.0.5: resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} engines: {node: '>=8.6'} @@ -5827,6 +6131,10 @@ packages: minimalistic-crypto-utils@1.0.1: resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} + minimatch@10.0.1: + resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==} + engines: {node: 20 || >=22} + minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -5845,6 +6153,9 @@ packages: resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} hasBin: true + mlly@1.7.2: + resolution: {integrity: sha512-tN3dvVHYVz4DhSXinXIk7u9syPYaJvio118uomkovAtWBT+RdbP6Lfh/5Lvo519YMmwBafwlh20IPTXIStscpA==} + monaco-editor@0.52.0: resolution: {integrity: sha512-OeWhNpABLCeTqubfqLMXGsqf6OmPU6pHM85kF3dhy6kq5hnhuVS1p3VrEW/XhWHc71P2tHyS5JFySD8mgs1crw==} @@ -6064,6 +6375,9 @@ packages: package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + package-manager-detector@0.2.2: + resolution: {integrity: sha512-VgXbyrSNsml4eHWIvxxG/nTL4wgybMTXCV2Un/+yEc3aDKKU6nQBZjbeP3Pl3qm9Qg92X/1ng4ffvCeD/zwHgg==} + pako@1.0.11: resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} @@ -6087,6 +6401,14 @@ packages: parse-entities@4.0.1: resolution: {integrity: sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==} + parse-gitignore@2.0.0: + resolution: {integrity: sha512-RmVuCHWsfu0QPNW+mraxh/xjQVw/lhUCUru8Zni3Ctq3AoMhpDTq0OVdKS6iesd6Kqb7viCV3isAL43dciOSog==} + engines: {node: '>=14'} + + parse-imports@2.2.1: + resolution: {integrity: sha512-OL/zLggRp8mFhKL0rNORUTR4yBYujK/uU+xZL+/0Rgm2QE4nLO9v8PzEweSJEbMGKmDRjJE4R3IMJlL2di4JeQ==} + engines: {node: '>= 18'} + parse-json@5.2.0: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} @@ -6138,6 +6460,9 @@ packages: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} + pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + pathval@2.0.0: resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} engines: {node: '>= 14.16'} @@ -6156,6 +6481,10 @@ packages: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} + picomatch@4.0.2: + resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + engines: {node: '>=12'} + pidtree@0.6.0: resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} engines: {node: '>=0.10'} @@ -6180,6 +6509,9 @@ packages: resolution: {integrity: sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==} engines: {node: '>=14.16'} + pkg-types@1.2.1: + resolution: {integrity: sha512-sQoqa8alT3nHjGuTjuKgOnvjo4cljkufdtLMnO2LBP/wRwuDlo1tkaEdMxCRhyGRPacv/ztlZgDPm2b7FAmEvw==} + pluralize@8.0.0: resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} engines: {node: '>=4'} @@ -6624,6 +6956,10 @@ packages: resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} engines: {node: '>=8'} + refa@0.12.1: + resolution: {integrity: sha512-J8rn6v4DBb2nnFqkqwy6/NnTYMcgLA+sLr0iIO41qpv0n+ngb7ksag2tMRl0inb1bbO/esUwzW1vbJi7K0sI0g==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + reflect.getprototypeof@1.0.6: resolution: {integrity: sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==} engines: {node: '>= 0.4'} @@ -6647,6 +6983,10 @@ packages: regex-parser@2.3.0: resolution: {integrity: sha512-TVILVSz2jY5D47F4mA4MppkBrafEaiUWJO/TcZHEIuI13AqoZMkK1WMA4Om1YkYbTx+9Ki1/tSUXbceyr9saRg==} + regexp-ast-analysis@0.7.1: + resolution: {integrity: sha512-sZuz1dYW/ZsfG17WSAG7eS85r5a0dDsvg+7BiiYR5o6lKCAtUrEwdmRmaGF6rwVj3LcmAeYkOWKEPlbPzN3Y3A==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + regexp-tree@0.1.27: resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==} hasBin: true @@ -6655,10 +6995,6 @@ packages: resolution: {integrity: sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==} engines: {node: '>= 0.4'} - regexpp@3.2.0: - resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==} - engines: {node: '>=8'} - regexpu-core@6.1.1: resolution: {integrity: sha512-k67Nb9jvwJcJmVpw0jPttR1/zVfnKf8Km0IPatrU/zJ5XeG3+Slx0xLXs9HByJSzXzrlz5EDvN6yLNMDc2qdnw==} engines: {node: '>=4'} @@ -6666,12 +7002,12 @@ packages: regjsgen@0.8.0: resolution: {integrity: sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==} - regjsparser@0.11.1: - resolution: {integrity: sha512-1DHODs4B8p/mQHU9kr+jv8+wIC9mtG4eBHxWxIq5mhjE3D5oORhCc6deRKzTjs9DcfRFmj9BHSDguZklqCGFWQ==} + regjsparser@0.10.0: + resolution: {integrity: sha512-qx+xQGZVsy55CH0a1hiVwHmqjLryfh7wQyF5HO07XJ9f7dQMY/gPQHhlyDkIzJKC+x2fUCpCcUODUUUFrm7SHA==} hasBin: true - regjsparser@0.9.1: - resolution: {integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==} + regjsparser@0.11.1: + resolution: {integrity: sha512-1DHODs4B8p/mQHU9kr+jv8+wIC9mtG4eBHxWxIq5mhjE3D5oORhCc6deRKzTjs9DcfRFmj9BHSDguZklqCGFWQ==} hasBin: true rehype-external-links@3.0.0: @@ -6812,9 +7148,6 @@ packages: resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} engines: {node: '>= 0.4'} - safe-regex@2.1.1: - resolution: {integrity: sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==} - safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} @@ -6861,6 +7194,10 @@ packages: resolution: {integrity: sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==} engines: {node: '>=0.10.0'} + scslre@0.3.0: + resolution: {integrity: sha512-3A6sD0WYP7+QrjbfNA2FN3FsOaGGFoekCVgTyypy53gPxhbkCIjtO6YWgdrfM+n/8sI8JeXZOIxsHjMTNxQ4nQ==} + engines: {node: ^14.0.0 || >=16.0.0} + semver@5.7.2: resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} hasBin: true @@ -6918,6 +7255,10 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + short-unique-id@5.2.0: + resolution: {integrity: sha512-cMGfwNyfDZ/nzJ2k2M+ClthBIh//GlZl1JEf47Uoa9XR11bz8Pa2T2wQO4bVrRdH48LrIDWJahQziKo3MjhsWg==} + hasBin: true + side-channel@1.0.6: resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} engines: {node: '>= 0.4'} @@ -6942,6 +7283,9 @@ packages: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} + slashes@3.0.12: + resolution: {integrity: sha512-Q9VME8WyGkc7pJf6QEkj3wE+2CnvZMI+XJhwdTPR8Z/kWQRXi7boAWLDibRPyHRTUTPx5FaU7MsyrjI3yLB4HA==} + slice-ansi@5.0.0: resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} engines: {node: '>=12'} @@ -6982,12 +7326,18 @@ packages: spdx-expression-parse@3.0.1: resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + spdx-expression-parse@4.0.0: + resolution: {integrity: sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==} + spdx-license-ids@3.0.20: resolution: {integrity: sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==} sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + stable-hash@0.0.4: + resolution: {integrity: sha512-LjdcbuBeLcdETCrPn9i8AYAZ1eCtu4ECAWtP7UleOiZ9LzVxRzzUZEoZ8zB24nhkQnDWyET0I+3sWokSDS3E7g==} + stack-utils@2.0.6: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} engines: {node: '>=10'} @@ -7028,6 +7378,9 @@ packages: resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} engines: {node: '>=10'} + string-ts@2.2.0: + resolution: {integrity: sha512-VTP0LLZo4Jp9Gz5IiDVMS9WyLx/3IeYh0PXUn0NdPqusUFNgkHPWiEdbB9TU2Iv3myUskraD5WtYEdHUrQEIlQ==} + string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -7170,6 +7523,10 @@ packages: resolution: {integrity: sha512-Vhf+bUa//YSTYKseDiiEuQmhGCoIF3CVBhunm3r/DQnYiGT4JssmnKQc44BIyOZRK2pKjXXAgbhfmbeoC9CJpA==} engines: {node: '>=12.20'} + synckit@0.9.2: + resolution: {integrity: sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==} + engines: {node: ^14.18.0 || >=16.0.0} + tabbable@6.2.0: resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} @@ -7237,6 +7594,9 @@ packages: tiny-invariant@1.3.3: resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + tinyexec@0.3.1: + resolution: {integrity: sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==} + tinyrainbow@1.2.0: resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} engines: {node: '>=14.0.0'} @@ -7263,6 +7623,10 @@ packages: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} + toml-eslint-parser@0.10.0: + resolution: {integrity: sha512-khrZo4buq4qVmsGzS5yQjKe/WsFvV8fGfOjDQN0q4iy9FjRfPWRgTFrU8u1R2iu/SfWLhY9WnCi4Jhdrcbtg+g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + tough-cookie@4.1.4: resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} engines: {node: '>=6'} @@ -7283,6 +7647,11 @@ packages: peerDependencies: typescript: '>=4.2.0' + ts-declaration-location@1.0.4: + resolution: {integrity: sha512-r4JoxYhKULbZuH81Pjrp9OEG5St7XWk7zXwGkLKhmVcjiBVHTJXV5wK6dEa9JKW5QGSTW6b1lOjxAKp8R1SQhg==} + peerDependencies: + typescript: '>=4.0.0' + ts-dedent@2.2.0: resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==} engines: {node: '>=6.10'} @@ -7304,6 +7673,9 @@ packages: '@swc/wasm': optional: true + ts-pattern@5.5.0: + resolution: {integrity: sha512-jqbIpTsa/KKTJYWgPNsFNbLVpwCgzXfFJ1ukNn4I8hMwyQzHMJnk/BqWzggB0xpkILuKzaO/aMYhS0SkaJyKXg==} + ts-pnp@1.2.0: resolution: {integrity: sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw==} engines: {node: '>=6'} @@ -7402,6 +7774,9 @@ packages: engines: {node: '>=4.2.0'} hasBin: true + ufo@1.5.4: + resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} + uglify-js@3.19.3: resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} engines: {node: '>=0.8.0'} @@ -7456,9 +7831,6 @@ packages: unist-util-remove-position@4.0.2: resolution: {integrity: sha512-TkBb0HABNmxzAcfLf4qsIbFbaPDvMO6wa3b3j4VcEzFVaw1LBKwnW4/sRJ/atSLSzoIg41JWEdnE7N6DIhGDGQ==} - unist-util-stringify-position@2.0.3: - resolution: {integrity: sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==} - unist-util-stringify-position@3.0.3: resolution: {integrity: sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==} @@ -7820,84 +8192,62 @@ snapshots: '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 - '@antfu/eslint-config-basic@0.36.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5)': + '@antfu/eslint-config@3.8.0(@eslint-react/eslint-plugin@1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(@typescript-eslint/utils@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(@vue/compiler-sfc@3.5.12)(eslint-plugin-react-hooks@5.0.0(eslint@9.13.0(jiti@1.21.6)))(eslint-plugin-react-refresh@0.4.13(eslint@9.13.0(jiti@1.21.6)))(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5)': dependencies: - eslint: 8.57.1 - eslint-plugin-antfu: 0.36.0(eslint@8.57.1)(typescript@4.9.5) - eslint-plugin-eslint-comments: 3.2.0(eslint@8.57.1) - eslint-plugin-html: 7.1.0 - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1) - eslint-plugin-jsonc: 2.16.0(eslint@8.57.1) - eslint-plugin-markdown: 3.0.1(eslint@8.57.1) - eslint-plugin-n: 15.7.0(eslint@8.57.1) + '@antfu/install-pkg': 0.4.1 + '@clack/prompts': 0.7.0 + '@eslint-community/eslint-plugin-eslint-comments': 4.4.0(eslint@9.13.0(jiti@1.21.6)) + '@eslint/markdown': 6.2.1 + '@stylistic/eslint-plugin': 2.9.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/eslint-plugin': 8.10.0(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/parser': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@vitest/eslint-plugin': 1.1.7(@typescript-eslint/utils@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + eslint: 9.13.0(jiti@1.21.6) + eslint-config-flat-gitignore: 0.3.0(eslint@9.13.0(jiti@1.21.6)) + eslint-flat-config-utils: 0.4.0 + eslint-merge-processors: 0.1.0(eslint@9.13.0(jiti@1.21.6)) + eslint-plugin-antfu: 2.7.0(eslint@9.13.0(jiti@1.21.6)) + eslint-plugin-command: 0.2.6(eslint@9.13.0(jiti@1.21.6)) + eslint-plugin-import-x: 4.3.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + eslint-plugin-jsdoc: 50.4.3(eslint@9.13.0(jiti@1.21.6)) + eslint-plugin-jsonc: 2.16.0(eslint@9.13.0(jiti@1.21.6)) + eslint-plugin-n: 17.11.1(eslint@9.13.0(jiti@1.21.6)) eslint-plugin-no-only-tests: 3.3.0 - eslint-plugin-promise: 6.6.0(eslint@8.57.1) - eslint-plugin-unicorn: 45.0.2(eslint@8.57.1) - eslint-plugin-unused-imports: 2.0.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1) - eslint-plugin-yml: 1.14.0(eslint@8.57.1) + eslint-plugin-perfectionist: 3.9.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5)(vue-eslint-parser@9.4.3(eslint@9.13.0(jiti@1.21.6))) + eslint-plugin-regexp: 2.6.0(eslint@9.13.0(jiti@1.21.6)) + eslint-plugin-toml: 0.11.1(eslint@9.13.0(jiti@1.21.6)) + eslint-plugin-unicorn: 56.0.0(eslint@9.13.0(jiti@1.21.6)) + eslint-plugin-unused-imports: 4.1.4(@typescript-eslint/eslint-plugin@8.10.0(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint@9.13.0(jiti@1.21.6)) + eslint-plugin-vue: 9.29.1(eslint@9.13.0(jiti@1.21.6)) + eslint-plugin-yml: 1.14.0(eslint@9.13.0(jiti@1.21.6)) + eslint-processor-vue-blocks: 0.1.2(@vue/compiler-sfc@3.5.12)(eslint@9.13.0(jiti@1.21.6)) + globals: 15.11.0 jsonc-eslint-parser: 2.4.0 + local-pkg: 0.5.0 + parse-gitignore: 2.0.0 + picocolors: 1.1.1 + toml-eslint-parser: 0.10.0 + vue-eslint-parser: 9.4.3(eslint@9.13.0(jiti@1.21.6)) yaml-eslint-parser: 1.2.3 + yargs: 17.7.2 + optionalDependencies: + '@eslint-react/eslint-plugin': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + eslint-plugin-react-hooks: 5.0.0(eslint@9.13.0(jiti@1.21.6)) + eslint-plugin-react-refresh: 0.4.13(eslint@9.13.0(jiti@1.21.6)) transitivePeerDependencies: - - '@typescript-eslint/eslint-plugin' - - '@typescript-eslint/parser' - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack + - '@typescript-eslint/utils' + - '@vue/compiler-sfc' - supports-color + - svelte - typescript + - vitest - '@antfu/eslint-config-ts@0.36.0(eslint@8.57.1)(jest@29.7.0(@types/node@18.15.0)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)))(typescript@4.9.5)': + '@antfu/install-pkg@0.4.1': dependencies: - '@antfu/eslint-config-basic': 0.36.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) - '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) - '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@4.9.5) - eslint: 8.57.1 - eslint-plugin-jest: 27.9.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(jest@29.7.0(@types/node@18.15.0)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)))(typescript@4.9.5) - typescript: 4.9.5 - transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - jest - - supports-color + package-manager-detector: 0.2.2 + tinyexec: 0.3.1 - '@antfu/eslint-config-vue@0.36.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(jest@29.7.0(@types/node@18.15.0)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)))(typescript@4.9.5)': - dependencies: - '@antfu/eslint-config-basic': 0.36.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) - '@antfu/eslint-config-ts': 0.36.0(eslint@8.57.1)(jest@29.7.0(@types/node@18.15.0)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)))(typescript@4.9.5) - eslint: 8.57.1 - eslint-plugin-vue: 9.29.1(eslint@8.57.1) - local-pkg: 0.4.3 - transitivePeerDependencies: - - '@typescript-eslint/eslint-plugin' - - '@typescript-eslint/parser' - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - jest - - supports-color - - typescript - - '@antfu/eslint-config@0.36.0(eslint@8.57.1)(jest@29.7.0(@types/node@18.15.0)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)))(typescript@4.9.5)': - dependencies: - '@antfu/eslint-config-vue': 0.36.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(jest@29.7.0(@types/node@18.15.0)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)))(typescript@4.9.5) - '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) - '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@4.9.5) - eslint: 8.57.1 - eslint-plugin-eslint-comments: 3.2.0(eslint@8.57.1) - eslint-plugin-html: 7.1.0 - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1) - eslint-plugin-jsonc: 2.16.0(eslint@8.57.1) - eslint-plugin-n: 15.7.0(eslint@8.57.1) - eslint-plugin-promise: 6.6.0(eslint@8.57.1) - eslint-plugin-unicorn: 45.0.2(eslint@8.57.1) - eslint-plugin-vue: 9.29.1(eslint@8.57.1) - eslint-plugin-yml: 1.14.0(eslint@8.57.1) - jsonc-eslint-parser: 2.4.0 - yaml-eslint-parser: 1.2.3 - transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - jest - - supports-color - - typescript + '@antfu/utils@0.7.10': {} '@babel/code-frame@7.25.7': dependencies: @@ -8734,6 +9084,17 @@ snapshots: - '@chromatic-com/playwright' - react + '@clack/core@0.3.4': + dependencies: + picocolors: 1.1.1 + sisteransi: 1.0.5 + + '@clack/prompts@0.7.0': + dependencies: + '@clack/core': 0.3.4 + picocolors: 1.1.1 + sisteransi: 1.0.5 + '@cspotcode/source-map-support@0.8.1': dependencies: '@jridgewell/trace-mapping': 0.3.9 @@ -8751,6 +9112,18 @@ snapshots: '@emoji-mart/data@1.2.1': {} + '@es-joy/jsdoccomment@0.48.0': + dependencies: + comment-parser: 1.4.1 + esquery: 1.6.0 + jsdoc-type-pratt-parser: 4.1.0 + + '@es-joy/jsdoccomment@0.49.0': + dependencies: + comment-parser: 1.4.1 + esquery: 1.6.0 + jsdoc-type-pratt-parser: 4.1.0 + '@esbuild/aix-ppc64@0.23.1': optional: true @@ -8823,27 +9196,140 @@ snapshots: '@esbuild/win32-x64@0.23.1': optional: true - '@eslint-community/eslint-utils@4.4.0(eslint@8.57.1)': + '@eslint-community/eslint-plugin-eslint-comments@4.4.0(eslint@9.13.0(jiti@1.21.6))': dependencies: - eslint: 8.57.1 + escape-string-regexp: 4.0.0 + eslint: 9.13.0(jiti@1.21.6) + ignore: 5.3.2 + + '@eslint-community/eslint-utils@4.4.0(eslint@9.13.0(jiti@1.21.6))': + dependencies: + eslint: 9.13.0(jiti@1.21.6) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.11.1': {} - '@eslint/eslintrc@2.1.4': + '@eslint-react/ast@1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5)': dependencies: - ajv: 6.12.6 - debug: 4.3.7 - espree: 9.6.1 - globals: 13.24.0 - ignore: 5.3.2 - import-fresh: 3.3.0 - js-yaml: 4.1.0 - minimatch: 3.1.2 - strip-json-comments: 3.1.1 + '@eslint-react/tools': 1.15.0 + '@eslint-react/types': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/types': 8.10.0 + '@typescript-eslint/typescript-estree': 8.10.0(typescript@4.9.5) + '@typescript-eslint/utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + birecord: 0.1.1 + string-ts: 2.2.0 + ts-pattern: 5.5.0 + transitivePeerDependencies: + - eslint + - supports-color + - typescript + + '@eslint-react/core@1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5)': + dependencies: + '@eslint-react/ast': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@eslint-react/jsx': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@eslint-react/shared': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@eslint-react/tools': 1.15.0 + '@eslint-react/types': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@eslint-react/var': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/scope-manager': 8.10.0 + '@typescript-eslint/type-utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/types': 8.10.0 + '@typescript-eslint/utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + birecord: 0.1.1 + short-unique-id: 5.2.0 + ts-pattern: 5.5.0 + transitivePeerDependencies: + - eslint + - supports-color + - typescript + + '@eslint-react/eslint-plugin@1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5)': + dependencies: + '@eslint-react/shared': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@eslint-react/tools': 1.15.0 + '@eslint-react/types': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/scope-manager': 8.10.0 + '@typescript-eslint/type-utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/types': 8.10.0 + '@typescript-eslint/utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + eslint: 9.13.0(jiti@1.21.6) + eslint-plugin-react-debug: 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + eslint-plugin-react-dom: 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + eslint-plugin-react-hooks-extra: 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + eslint-plugin-react-naming-convention: 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + eslint-plugin-react-web-api: 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + eslint-plugin-react-x: 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + optionalDependencies: + typescript: 4.9.5 transitivePeerDependencies: - supports-color + '@eslint-react/jsx@1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5)': + dependencies: + '@eslint-react/ast': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@eslint-react/tools': 1.15.0 + '@eslint-react/types': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@eslint-react/var': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/scope-manager': 8.10.0 + '@typescript-eslint/types': 8.10.0 + '@typescript-eslint/utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + ts-pattern: 5.5.0 + transitivePeerDependencies: + - eslint + - supports-color + - typescript + + '@eslint-react/shared@1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5)': + dependencies: + '@eslint-react/tools': 1.15.0 + '@typescript-eslint/utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + picomatch: 4.0.2 + transitivePeerDependencies: + - eslint + - supports-color + - typescript + + '@eslint-react/tools@1.15.0': {} + + '@eslint-react/types@1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5)': + dependencies: + '@eslint-react/tools': 1.15.0 + '@typescript-eslint/types': 8.10.0 + '@typescript-eslint/utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + transitivePeerDependencies: + - eslint + - supports-color + - typescript + + '@eslint-react/var@1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5)': + dependencies: + '@eslint-react/ast': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@eslint-react/tools': 1.15.0 + '@eslint-react/types': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/scope-manager': 8.10.0 + '@typescript-eslint/types': 8.10.0 + '@typescript-eslint/utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + ts-pattern: 5.5.0 + transitivePeerDependencies: + - eslint + - supports-color + - typescript + + '@eslint/compat@1.2.1(eslint@9.13.0(jiti@1.21.6))': + optionalDependencies: + eslint: 9.13.0(jiti@1.21.6) + + '@eslint/config-array@0.18.0': + dependencies: + '@eslint/object-schema': 2.1.4 + debug: 4.3.7 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@eslint/core@0.7.0': {} + '@eslint/eslintrc@3.1.0': dependencies: ajv: 6.12.6 @@ -8858,10 +9344,23 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@8.57.1': {} - '@eslint/js@9.13.0': {} + '@eslint/markdown@6.2.1': + dependencies: + '@eslint/plugin-kit': 0.2.1 + mdast-util-from-markdown: 2.0.1 + mdast-util-gfm: 3.0.0 + micromark-extension-gfm: 3.0.0 + transitivePeerDependencies: + - supports-color + + '@eslint/object-schema@2.1.4': {} + + '@eslint/plugin-kit@0.2.1': + dependencies: + levn: 0.4.1 + '@faker-js/faker@7.6.0': {} '@floating-ui/core@1.6.8': @@ -8914,17 +9413,16 @@ snapshots: dependencies: react-hook-form: 7.53.1(react@18.2.0) - '@humanwhocodes/config-array@0.13.0': + '@humanfs/core@0.19.0': {} + + '@humanfs/node@0.16.5': dependencies: - '@humanwhocodes/object-schema': 2.0.3 - debug: 4.3.7 - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color + '@humanfs/core': 0.19.0 + '@humanwhocodes/retry': 0.3.1 '@humanwhocodes/module-importer@1.0.1': {} - '@humanwhocodes/object-schema@2.0.3': {} + '@humanwhocodes/retry@0.3.1': {} '@img/sharp-darwin-arm64@0.33.5': optionalDependencies: @@ -9410,9 +9908,9 @@ snapshots: '@next/env@14.2.15': {} - '@next/eslint-plugin-next@14.2.15': + '@next/eslint-plugin-next@15.0.0-rc.1': dependencies: - glob: 10.3.10 + fast-glob: 3.3.1 '@next/mdx@14.2.15(@mdx-js/loader@2.3.0(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3)))(@mdx-js/react@2.3.0(react@18.2.0))': dependencies: @@ -9521,6 +10019,8 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true + '@pkgr/core@0.1.1': {} + '@pmmmwh/react-refresh-webpack-plugin@0.5.15(react-refresh@0.14.2)(type-fest@2.19.0)(webpack-hot-middleware@2.26.1)(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3))': dependencies: ansi-html: 0.0.9 @@ -10104,6 +10604,18 @@ snapshots: dependencies: storybook: 8.3.6 + '@stylistic/eslint-plugin@2.9.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5)': + dependencies: + '@typescript-eslint/utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + eslint: 9.13.0(jiti@1.21.6) + eslint-visitor-keys: 4.1.0 + espree: 10.2.0 + estraverse: 5.3.0 + picomatch: 4.0.2 + transitivePeerDependencies: + - supports-color + - typescript + '@svgdotjs/svg.js@3.2.4': {} '@swc/counter@0.1.3': {} @@ -10548,34 +11060,15 @@ snapshots: dependencies: '@types/yargs-parser': 21.0.3 - '@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5)': + '@typescript-eslint/eslint-plugin@8.10.0(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5)': dependencies: '@eslint-community/regexpp': 4.11.1 - '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@4.9.5) - '@typescript-eslint/scope-manager': 5.62.0 - '@typescript-eslint/type-utils': 5.62.0(eslint@8.57.1)(typescript@4.9.5) - '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@4.9.5) - debug: 4.3.7 - eslint: 8.57.1 - graphemer: 1.4.0 - ignore: 5.3.2 - natural-compare-lite: 1.4.0 - semver: 7.6.3 - tsutils: 3.21.0(typescript@4.9.5) - optionalDependencies: - typescript: 4.9.5 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/eslint-plugin@8.10.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5)': - dependencies: - '@eslint-community/regexpp': 4.11.1 - '@typescript-eslint/parser': 8.10.0(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/parser': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) '@typescript-eslint/scope-manager': 8.10.0 - '@typescript-eslint/type-utils': 8.10.0(eslint@8.57.1)(typescript@4.9.5) - '@typescript-eslint/utils': 8.10.0(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/type-utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) '@typescript-eslint/visitor-keys': 8.10.0 - eslint: 8.57.1 + eslint: 9.13.0(jiti@1.21.6) graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 @@ -10585,26 +11078,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5)': - dependencies: - '@typescript-eslint/scope-manager': 5.62.0 - '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5) - debug: 4.3.7 - eslint: 8.57.1 - optionalDependencies: - typescript: 4.9.5 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5)': + '@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5)': dependencies: '@typescript-eslint/scope-manager': 8.10.0 '@typescript-eslint/types': 8.10.0 '@typescript-eslint/typescript-estree': 8.10.0(typescript@4.9.5) '@typescript-eslint/visitor-keys': 8.10.0 debug: 4.3.7 - eslint: 8.57.1 + eslint: 9.13.0(jiti@1.21.6) optionalDependencies: typescript: 4.9.5 transitivePeerDependencies: @@ -10620,22 +11101,10 @@ snapshots: '@typescript-eslint/types': 8.10.0 '@typescript-eslint/visitor-keys': 8.10.0 - '@typescript-eslint/type-utils@5.62.0(eslint@8.57.1)(typescript@4.9.5)': - dependencies: - '@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5) - '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@4.9.5) - debug: 4.3.7 - eslint: 8.57.1 - tsutils: 3.21.0(typescript@4.9.5) - optionalDependencies: - typescript: 4.9.5 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/type-utils@8.10.0(eslint@8.57.1)(typescript@4.9.5)': + '@typescript-eslint/type-utils@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5)': dependencies: '@typescript-eslint/typescript-estree': 8.10.0(typescript@4.9.5) - '@typescript-eslint/utils': 8.10.0(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) debug: 4.3.7 ts-api-utils: 1.3.0(typescript@4.9.5) optionalDependencies: @@ -10677,28 +11146,28 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@5.62.0(eslint@8.57.1)(typescript@4.9.5)': + '@typescript-eslint/utils@5.62.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5)': dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) + '@eslint-community/eslint-utils': 4.4.0(eslint@9.13.0(jiti@1.21.6)) '@types/json-schema': 7.0.15 '@types/semver': 7.5.8 '@typescript-eslint/scope-manager': 5.62.0 '@typescript-eslint/types': 5.62.0 '@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5) - eslint: 8.57.1 + eslint: 9.13.0(jiti@1.21.6) eslint-scope: 5.1.1 semver: 7.6.3 transitivePeerDependencies: - supports-color - typescript - '@typescript-eslint/utils@8.10.0(eslint@8.57.1)(typescript@4.9.5)': + '@typescript-eslint/utils@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5)': dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) + '@eslint-community/eslint-utils': 4.4.0(eslint@9.13.0(jiti@1.21.6)) '@typescript-eslint/scope-manager': 8.10.0 '@typescript-eslint/types': 8.10.0 '@typescript-eslint/typescript-estree': 8.10.0(typescript@4.9.5) - eslint: 8.57.1 + eslint: 9.13.0(jiti@1.21.6) transitivePeerDependencies: - supports-color - typescript @@ -10715,6 +11184,13 @@ snapshots: '@ungap/structured-clone@1.2.0': {} + '@vitest/eslint-plugin@1.1.7(@typescript-eslint/utils@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5)': + dependencies: + '@typescript-eslint/utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + eslint: 9.13.0(jiti@1.21.6) + optionalDependencies: + typescript: 4.9.5 + '@vitest/expect@2.0.5': dependencies: '@vitest/spy': 2.0.5 @@ -10760,6 +11236,23 @@ snapshots: '@vue/compiler-core': 3.5.12 '@vue/shared': 3.5.12 + '@vue/compiler-sfc@3.5.12': + dependencies: + '@babel/parser': 7.25.8 + '@vue/compiler-core': 3.5.12 + '@vue/compiler-dom': 3.5.12 + '@vue/compiler-ssr': 3.5.12 + '@vue/shared': 3.5.12 + estree-walker: 2.0.2 + magic-string: 0.30.12 + postcss: 8.4.47 + source-map-js: 1.2.1 + + '@vue/compiler-ssr@3.5.12': + dependencies: + '@vue/compiler-dom': 3.5.12 + '@vue/shared': 3.5.12 + '@vue/shared@3.5.12': {} '@webassemblyjs/ast@1.12.1': @@ -10966,6 +11459,8 @@ snapshots: normalize-path: 3.0.0 picomatch: 2.3.1 + are-docs-informative@0.0.2: {} + arg@4.1.3: {} arg@5.0.2: {} @@ -11207,6 +11702,8 @@ snapshots: dependencies: got: 11.8.6 + birecord@0.1.1: {} + bn.js@4.12.0: {} bn.js@5.2.1: {} @@ -11316,10 +11813,6 @@ snapshots: builtin-status-codes@3.0.0: {} - builtins@5.1.0: - dependencies: - semver: 7.6.3 - busboy@1.6.0: dependencies: streamsearch: 1.1.0 @@ -11436,6 +11929,8 @@ snapshots: ci-info@3.9.0: {} + ci-info@4.0.0: {} + cipher-base@1.0.4: dependencies: inherits: 2.0.4 @@ -11549,12 +12044,16 @@ snapshots: commander@8.3.0: {} + comment-parser@1.4.1: {} + common-path-prefix@3.0.0: {} commondir@1.0.1: {} concat-map@0.0.1: {} + confbox@0.1.8: {} + console-browserify@1.2.0: {} constants-browserify@1.0.0: {} @@ -12066,12 +12565,6 @@ snapshots: domhandler: 4.3.1 entities: 2.2.0 - dom-serializer@2.0.0: - dependencies: - domelementtype: 2.3.0 - domhandler: 5.0.3 - entities: 4.5.0 - domain-browser@4.23.0: {} domelementtype@2.3.0: {} @@ -12084,10 +12577,6 @@ snapshots: dependencies: domelementtype: 2.3.0 - domhandler@5.0.3: - dependencies: - domelementtype: 2.3.0 - dompurify@3.1.7: {} domutils@2.8.0: @@ -12096,12 +12585,6 @@ snapshots: domelementtype: 2.3.0 domhandler: 4.3.1 - domutils@3.1.0: - dependencies: - dom-serializer: 2.0.0 - domelementtype: 2.3.0 - domhandler: 5.0.3 - dot-case@3.0.4: dependencies: no-case: 3.0.4 @@ -12338,24 +12821,30 @@ snapshots: optionalDependencies: source-map: 0.6.1 - eslint-compat-utils@0.5.1(eslint@8.57.1): + eslint-compat-utils@0.5.1(eslint@9.13.0(jiti@1.21.6)): dependencies: - eslint: 8.57.1 + eslint: 9.13.0(jiti@1.21.6) semver: 7.6.3 - eslint-config-next@14.2.15(eslint@8.57.1)(typescript@4.9.5): + eslint-config-flat-gitignore@0.3.0(eslint@9.13.0(jiti@1.21.6)): dependencies: - '@next/eslint-plugin-next': 14.2.15 + '@eslint/compat': 1.2.1(eslint@9.13.0(jiti@1.21.6)) + eslint: 9.13.0(jiti@1.21.6) + find-up-simple: 1.0.0 + + eslint-config-next@15.0.0-rc.1(eslint-plugin-import-x@4.3.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5): + dependencies: + '@next/eslint-plugin-next': 15.0.0-rc.1 '@rushstack/eslint-patch': 1.10.4 - '@typescript-eslint/eslint-plugin': 8.10.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) - '@typescript-eslint/parser': 8.10.0(eslint@8.57.1)(typescript@4.9.5) - eslint: 8.57.1 + '@typescript-eslint/eslint-plugin': 8.10.0(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/parser': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + eslint: 9.13.0(jiti@1.21.6) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1) - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1) - eslint-plugin-jsx-a11y: 6.10.0(eslint@8.57.1) - eslint-plugin-react: 7.37.1(eslint@8.57.1) - eslint-plugin-react-hooks: 5.0.0-canary-7118f5dd7-20230705(eslint@8.57.1) + eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@4.3.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-plugin-import@2.31.0)(eslint@9.13.0(jiti@1.21.6)) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-typescript@3.6.3)(eslint@9.13.0(jiti@1.21.6)) + eslint-plugin-jsx-a11y: 6.10.0(eslint@9.13.0(jiti@1.21.6)) + eslint-plugin-react: 7.37.1(eslint@9.13.0(jiti@1.21.6)) + eslint-plugin-react-hooks: 5.0.0(eslint@9.13.0(jiti@1.21.6)) optionalDependencies: typescript: 4.9.5 transitivePeerDependencies: @@ -12363,6 +12852,10 @@ snapshots: - eslint-plugin-import-x - supports-color + eslint-flat-config-utils@0.4.0: + dependencies: + pathe: 1.1.2 + eslint-import-resolver-node@0.3.9: dependencies: debug: 3.2.7 @@ -12371,61 +12864,76 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1): + eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@4.3.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-plugin-import@2.31.0)(eslint@9.13.0(jiti@1.21.6)): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.3.7 enhanced-resolve: 5.17.1 - eslint: 8.57.1 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1) + eslint: 9.13.0(jiti@1.21.6) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@4.3.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-plugin-import@2.31.0)(eslint@9.13.0(jiti@1.21.6)))(eslint@9.13.0(jiti@1.21.6)) fast-glob: 3.3.2 get-tsconfig: 4.8.1 is-bun-module: 1.2.1 is-glob: 4.0.3 optionalDependencies: - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-typescript@3.6.3)(eslint@9.13.0(jiti@1.21.6)) + eslint-plugin-import-x: 4.3.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) transitivePeerDependencies: - '@typescript-eslint/parser' - eslint-import-resolver-node - eslint-import-resolver-webpack - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1): + eslint-merge-processors@0.1.0(eslint@9.13.0(jiti@1.21.6)): + dependencies: + eslint: 9.13.0(jiti@1.21.6) + + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@4.3.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-plugin-import@2.31.0)(eslint@9.13.0(jiti@1.21.6)))(eslint@9.13.0(jiti@1.21.6)): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 8.10.0(eslint@8.57.1)(typescript@4.9.5) - eslint: 8.57.1 + '@typescript-eslint/parser': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + eslint: 9.13.0(jiti@1.21.6) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1) + eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@4.3.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-plugin-import@2.31.0)(eslint@9.13.0(jiti@1.21.6)) transitivePeerDependencies: - supports-color - eslint-plugin-antfu@0.36.0(eslint@8.57.1)(typescript@4.9.5): + eslint-plugin-antfu@2.7.0(eslint@9.13.0(jiti@1.21.6)): dependencies: - '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@4.9.5) + '@antfu/utils': 0.7.10 + eslint: 9.13.0(jiti@1.21.6) + + eslint-plugin-command@0.2.6(eslint@9.13.0(jiti@1.21.6)): + dependencies: + '@es-joy/jsdoccomment': 0.48.0 + eslint: 9.13.0(jiti@1.21.6) + + eslint-plugin-es-x@7.8.0(eslint@9.13.0(jiti@1.21.6)): + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@9.13.0(jiti@1.21.6)) + '@eslint-community/regexpp': 4.11.1 + eslint: 9.13.0(jiti@1.21.6) + eslint-compat-utils: 0.5.1(eslint@9.13.0(jiti@1.21.6)) + + eslint-plugin-import-x@4.3.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5): + dependencies: + '@typescript-eslint/utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + debug: 4.3.7 + doctrine: 3.0.0 + eslint: 9.13.0(jiti@1.21.6) + eslint-import-resolver-node: 0.3.9 + get-tsconfig: 4.8.1 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.6.3 + stable-hash: 0.0.4 + tslib: 2.8.0 transitivePeerDependencies: - - eslint - supports-color - typescript - eslint-plugin-es@4.1.0(eslint@8.57.1): - dependencies: - eslint: 8.57.1 - eslint-utils: 2.1.0 - regexpp: 3.2.0 - - eslint-plugin-eslint-comments@3.2.0(eslint@8.57.1): - dependencies: - escape-string-regexp: 1.0.5 - eslint: 8.57.1 - ignore: 5.3.2 - - eslint-plugin-html@7.1.0: - dependencies: - htmlparser2: 8.0.2 - - eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1): + eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-typescript@3.6.3)(eslint@9.13.0(jiti@1.21.6)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.8 @@ -12434,9 +12942,9 @@ snapshots: array.prototype.flatmap: 1.3.2 debug: 3.2.7 doctrine: 2.1.0 - eslint: 8.57.1 + eslint: 9.13.0(jiti@1.21.6) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.10.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@8.57.1))(eslint@8.57.1) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@4.3.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-plugin-import@2.31.0)(eslint@9.13.0(jiti@1.21.6)))(eslint@9.13.0(jiti@1.21.6)) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3 @@ -12448,35 +12956,41 @@ snapshots: string.prototype.trimend: 1.0.8 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/parser': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - eslint-plugin-jest@27.9.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(jest@29.7.0(@types/node@18.15.0)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)))(typescript@4.9.5): + eslint-plugin-jsdoc@50.4.3(eslint@9.13.0(jiti@1.21.6)): dependencies: - '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@4.9.5) - eslint: 8.57.1 - optionalDependencies: - '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) - jest: 29.7.0(@types/node@18.15.0)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)) + '@es-joy/jsdoccomment': 0.49.0 + are-docs-informative: 0.0.2 + comment-parser: 1.4.1 + debug: 4.3.7 + escape-string-regexp: 4.0.0 + eslint: 9.13.0(jiti@1.21.6) + espree: 10.2.0 + esquery: 1.6.0 + parse-imports: 2.2.1 + semver: 7.6.3 + spdx-expression-parse: 4.0.0 + synckit: 0.9.2 transitivePeerDependencies: - supports-color - - typescript - eslint-plugin-jsonc@2.16.0(eslint@8.57.1): + eslint-plugin-jsonc@2.16.0(eslint@9.13.0(jiti@1.21.6)): dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) - eslint: 8.57.1 - eslint-compat-utils: 0.5.1(eslint@8.57.1) + '@eslint-community/eslint-utils': 4.4.0(eslint@9.13.0(jiti@1.21.6)) + eslint: 9.13.0(jiti@1.21.6) + eslint-compat-utils: 0.5.1(eslint@9.13.0(jiti@1.21.6)) espree: 9.6.1 graphemer: 1.4.0 jsonc-eslint-parser: 2.4.0 natural-compare: 1.4.0 synckit: 0.6.2 - eslint-plugin-jsx-a11y@6.10.0(eslint@8.57.1): + eslint-plugin-jsx-a11y@6.10.0(eslint@9.13.0(jiti@1.21.6)): dependencies: aria-query: 5.1.3 array-includes: 3.1.8 @@ -12487,7 +13001,7 @@ snapshots: damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 es-iterator-helpers: 1.1.0 - eslint: 8.57.1 + eslint: 9.13.0(jiti@1.21.6) hasown: 2.0.2 jsx-ast-utils: 3.3.5 language-tags: 1.0.9 @@ -12496,36 +13010,162 @@ snapshots: safe-regex-test: 1.0.3 string.prototype.includes: 2.0.1 - eslint-plugin-markdown@3.0.1(eslint@8.57.1): + eslint-plugin-n@17.11.1(eslint@9.13.0(jiti@1.21.6)): dependencies: - eslint: 8.57.1 - mdast-util-from-markdown: 0.8.5 - transitivePeerDependencies: - - supports-color - - eslint-plugin-n@15.7.0(eslint@8.57.1): - dependencies: - builtins: 5.1.0 - eslint: 8.57.1 - eslint-plugin-es: 4.1.0(eslint@8.57.1) - eslint-utils: 3.0.0(eslint@8.57.1) + '@eslint-community/eslint-utils': 4.4.0(eslint@9.13.0(jiti@1.21.6)) + enhanced-resolve: 5.17.1 + eslint: 9.13.0(jiti@1.21.6) + eslint-plugin-es-x: 7.8.0(eslint@9.13.0(jiti@1.21.6)) + get-tsconfig: 4.8.1 + globals: 15.11.0 ignore: 5.3.2 - is-core-module: 2.15.1 - minimatch: 3.1.2 - resolve: 1.22.8 + minimatch: 9.0.5 semver: 7.6.3 eslint-plugin-no-only-tests@3.3.0: {} - eslint-plugin-promise@6.6.0(eslint@8.57.1): + eslint-plugin-perfectionist@3.9.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5)(vue-eslint-parser@9.4.3(eslint@9.13.0(jiti@1.21.6))): dependencies: - eslint: 8.57.1 + '@typescript-eslint/types': 8.10.0 + '@typescript-eslint/utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + eslint: 9.13.0(jiti@1.21.6) + minimatch: 9.0.5 + natural-compare-lite: 1.4.0 + optionalDependencies: + vue-eslint-parser: 9.4.3(eslint@9.13.0(jiti@1.21.6)) + transitivePeerDependencies: + - supports-color + - typescript - eslint-plugin-react-hooks@5.0.0-canary-7118f5dd7-20230705(eslint@8.57.1): + eslint-plugin-react-debug@1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5): dependencies: - eslint: 8.57.1 + '@eslint-react/ast': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@eslint-react/core': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@eslint-react/jsx': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@eslint-react/shared': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@eslint-react/tools': 1.15.0 + '@eslint-react/types': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@eslint-react/var': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/scope-manager': 8.10.0 + '@typescript-eslint/type-utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/types': 8.10.0 + '@typescript-eslint/utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + eslint: 9.13.0(jiti@1.21.6) + string-ts: 2.2.0 + ts-pattern: 5.5.0 + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color - eslint-plugin-react@7.37.1(eslint@8.57.1): + eslint-plugin-react-dom@1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5): + dependencies: + '@eslint-react/ast': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@eslint-react/core': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@eslint-react/jsx': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@eslint-react/shared': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@eslint-react/tools': 1.15.0 + '@eslint-react/types': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@eslint-react/var': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/scope-manager': 8.10.0 + '@typescript-eslint/types': 8.10.0 + '@typescript-eslint/utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + eslint: 9.13.0(jiti@1.21.6) + ts-pattern: 5.5.0 + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + + eslint-plugin-react-hooks-extra@1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5): + dependencies: + '@eslint-react/ast': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@eslint-react/core': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@eslint-react/jsx': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@eslint-react/shared': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@eslint-react/tools': 1.15.0 + '@eslint-react/types': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@eslint-react/var': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/scope-manager': 8.10.0 + '@typescript-eslint/type-utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/types': 8.10.0 + '@typescript-eslint/utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + eslint: 9.13.0(jiti@1.21.6) + ts-pattern: 5.5.0 + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + + eslint-plugin-react-hooks@5.0.0(eslint@9.13.0(jiti@1.21.6)): + dependencies: + eslint: 9.13.0(jiti@1.21.6) + + eslint-plugin-react-naming-convention@1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5): + dependencies: + '@eslint-react/ast': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@eslint-react/core': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@eslint-react/jsx': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@eslint-react/shared': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@eslint-react/tools': 1.15.0 + '@eslint-react/types': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/scope-manager': 8.10.0 + '@typescript-eslint/type-utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/types': 8.10.0 + '@typescript-eslint/utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + eslint: 9.13.0(jiti@1.21.6) + ts-pattern: 5.5.0 + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + + eslint-plugin-react-refresh@0.4.13(eslint@9.13.0(jiti@1.21.6)): + dependencies: + eslint: 9.13.0(jiti@1.21.6) + + eslint-plugin-react-web-api@1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5): + dependencies: + '@eslint-react/ast': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@eslint-react/core': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@eslint-react/jsx': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@eslint-react/shared': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@eslint-react/tools': 1.15.0 + '@eslint-react/types': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@eslint-react/var': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/scope-manager': 8.10.0 + '@typescript-eslint/types': 8.10.0 + '@typescript-eslint/utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + birecord: 0.1.1 + eslint: 9.13.0(jiti@1.21.6) + ts-pattern: 5.5.0 + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + + eslint-plugin-react-x@1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5): + dependencies: + '@eslint-react/ast': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@eslint-react/core': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@eslint-react/jsx': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@eslint-react/shared': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@eslint-react/tools': 1.15.0 + '@eslint-react/types': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@eslint-react/var': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/scope-manager': 8.10.0 + '@typescript-eslint/type-utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/types': 8.10.0 + '@typescript-eslint/utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + eslint: 9.13.0(jiti@1.21.6) + is-immutable-type: 5.0.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + ts-pattern: 5.5.0 + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + + eslint-plugin-react@7.37.1(eslint@9.13.0(jiti@1.21.6)): dependencies: array-includes: 3.1.8 array.prototype.findlast: 1.2.5 @@ -12533,7 +13173,7 @@ snapshots: array.prototype.tosorted: 1.1.4 doctrine: 2.1.0 es-iterator-helpers: 1.1.0 - eslint: 8.57.1 + eslint: 9.13.0(jiti@1.21.6) estraverse: 5.3.0 hasown: 2.0.2 jsx-ast-utils: 3.3.5 @@ -12547,70 +13187,93 @@ snapshots: string.prototype.matchall: 4.0.11 string.prototype.repeat: 1.0.0 - eslint-plugin-storybook@0.9.0(eslint@8.57.1)(typescript@4.9.5): + eslint-plugin-regexp@2.6.0(eslint@9.13.0(jiti@1.21.6)): + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@9.13.0(jiti@1.21.6)) + '@eslint-community/regexpp': 4.11.1 + comment-parser: 1.4.1 + eslint: 9.13.0(jiti@1.21.6) + jsdoc-type-pratt-parser: 4.1.0 + refa: 0.12.1 + regexp-ast-analysis: 0.7.1 + scslre: 0.3.0 + + eslint-plugin-storybook@0.9.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5): dependencies: '@storybook/csf': 0.0.1 - '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@4.9.5) - eslint: 8.57.1 + '@typescript-eslint/utils': 5.62.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + eslint: 9.13.0(jiti@1.21.6) requireindex: 1.2.0 ts-dedent: 2.2.0 transitivePeerDependencies: - supports-color - typescript - eslint-plugin-unicorn@45.0.2(eslint@8.57.1): + eslint-plugin-toml@0.11.1(eslint@9.13.0(jiti@1.21.6)): + dependencies: + debug: 4.3.7 + eslint: 9.13.0(jiti@1.21.6) + eslint-compat-utils: 0.5.1(eslint@9.13.0(jiti@1.21.6)) + lodash: 4.17.21 + toml-eslint-parser: 0.10.0 + transitivePeerDependencies: + - supports-color + + eslint-plugin-unicorn@56.0.0(eslint@9.13.0(jiti@1.21.6)): dependencies: '@babel/helper-validator-identifier': 7.25.7 - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) - ci-info: 3.9.0 + '@eslint-community/eslint-utils': 4.4.0(eslint@9.13.0(jiti@1.21.6)) + ci-info: 4.0.0 clean-regexp: 1.0.0 - eslint: 8.57.1 + core-js-compat: 3.38.1 + eslint: 9.13.0(jiti@1.21.6) esquery: 1.6.0 + globals: 15.11.0 indent-string: 4.0.0 is-builtin-module: 3.2.1 jsesc: 3.0.2 - lodash: 4.17.21 pluralize: 8.0.0 read-pkg-up: 7.0.1 regexp-tree: 0.1.27 - regjsparser: 0.9.1 - safe-regex: 2.1.1 + regjsparser: 0.10.0 semver: 7.6.3 strip-indent: 3.0.0 - eslint-plugin-unused-imports@2.0.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1): + eslint-plugin-unused-imports@4.1.4(@typescript-eslint/eslint-plugin@8.10.0(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint@9.13.0(jiti@1.21.6)): dependencies: - eslint: 8.57.1 - eslint-rule-composer: 0.3.0 + eslint: 9.13.0(jiti@1.21.6) optionalDependencies: - '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/eslint-plugin': 8.10.0(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) - eslint-plugin-vue@9.29.1(eslint@8.57.1): + eslint-plugin-vue@9.29.1(eslint@9.13.0(jiti@1.21.6)): dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) - eslint: 8.57.1 + '@eslint-community/eslint-utils': 4.4.0(eslint@9.13.0(jiti@1.21.6)) + eslint: 9.13.0(jiti@1.21.6) globals: 13.24.0 natural-compare: 1.4.0 nth-check: 2.1.1 postcss-selector-parser: 6.1.2 semver: 7.6.3 - vue-eslint-parser: 9.4.3(eslint@8.57.1) + vue-eslint-parser: 9.4.3(eslint@9.13.0(jiti@1.21.6)) xml-name-validator: 4.0.0 transitivePeerDependencies: - supports-color - eslint-plugin-yml@1.14.0(eslint@8.57.1): + eslint-plugin-yml@1.14.0(eslint@9.13.0(jiti@1.21.6)): dependencies: debug: 4.3.7 - eslint: 8.57.1 - eslint-compat-utils: 0.5.1(eslint@8.57.1) + eslint: 9.13.0(jiti@1.21.6) + eslint-compat-utils: 0.5.1(eslint@9.13.0(jiti@1.21.6)) lodash: 4.17.21 natural-compare: 1.4.0 yaml-eslint-parser: 1.2.3 transitivePeerDependencies: - supports-color - eslint-rule-composer@0.3.0: {} + eslint-processor-vue-blocks@0.1.2(@vue/compiler-sfc@3.5.12)(eslint@9.13.0(jiti@1.21.6)): + dependencies: + '@vue/compiler-sfc': 3.5.12 + eslint: 9.13.0(jiti@1.21.6) eslint-scope@5.1.1: dependencies: @@ -12622,63 +13285,54 @@ snapshots: esrecurse: 4.3.0 estraverse: 5.3.0 - eslint-utils@2.1.0: + eslint-scope@8.1.0: dependencies: - eslint-visitor-keys: 1.3.0 - - eslint-utils@3.0.0(eslint@8.57.1): - dependencies: - eslint: 8.57.1 - eslint-visitor-keys: 2.1.0 - - eslint-visitor-keys@1.3.0: {} - - eslint-visitor-keys@2.1.0: {} + esrecurse: 4.3.0 + estraverse: 5.3.0 eslint-visitor-keys@3.4.3: {} eslint-visitor-keys@4.1.0: {} - eslint@8.57.1: + eslint@9.13.0(jiti@1.21.6): dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) + '@eslint-community/eslint-utils': 4.4.0(eslint@9.13.0(jiti@1.21.6)) '@eslint-community/regexpp': 4.11.1 - '@eslint/eslintrc': 2.1.4 - '@eslint/js': 8.57.1 - '@humanwhocodes/config-array': 0.13.0 + '@eslint/config-array': 0.18.0 + '@eslint/core': 0.7.0 + '@eslint/eslintrc': 3.1.0 + '@eslint/js': 9.13.0 + '@eslint/plugin-kit': 0.2.1 + '@humanfs/node': 0.16.5 '@humanwhocodes/module-importer': 1.0.1 - '@nodelib/fs.walk': 1.2.8 - '@ungap/structured-clone': 1.2.0 + '@humanwhocodes/retry': 0.3.1 + '@types/estree': 1.0.6 + '@types/json-schema': 7.0.15 ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 debug: 4.3.7 - doctrine: 3.0.0 escape-string-regexp: 4.0.0 - eslint-scope: 7.2.2 - eslint-visitor-keys: 3.4.3 - espree: 9.6.1 + eslint-scope: 8.1.0 + eslint-visitor-keys: 4.1.0 + espree: 10.2.0 esquery: 1.6.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 - file-entry-cache: 6.0.1 + file-entry-cache: 8.0.0 find-up: 5.0.0 glob-parent: 6.0.2 - globals: 13.24.0 - graphemer: 1.4.0 ignore: 5.3.2 imurmurhash: 0.1.4 is-glob: 4.0.3 - is-path-inside: 3.0.3 - js-yaml: 4.1.0 json-stable-stringify-without-jsonify: 1.0.1 - levn: 0.4.1 lodash.merge: 4.6.2 minimatch: 3.1.2 natural-compare: 1.4.0 optionator: 0.9.4 - strip-ansi: 6.0.1 text-table: 0.2.0 + optionalDependencies: + jiti: 1.21.6 transitivePeerDependencies: - supports-color @@ -12826,6 +13480,14 @@ snapshots: fast-deep-equal@3.1.3: {} + fast-glob@3.3.1: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + fast-glob@3.3.2: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -12854,9 +13516,9 @@ snapshots: dependencies: bser: 2.1.1 - file-entry-cache@6.0.1: + file-entry-cache@8.0.0: dependencies: - flat-cache: 3.2.0 + flat-cache: 4.0.1 filesize@10.1.6: {} @@ -12889,6 +13551,8 @@ snapshots: common-path-prefix: 3.0.0 pkg-dir: 7.0.0 + find-up-simple@1.0.0: {} + find-up@4.1.0: dependencies: locate-path: 5.0.0 @@ -12910,6 +13574,11 @@ snapshots: keyv: 4.5.4 rimraf: 3.0.2 + flat-cache@4.0.1: + dependencies: + flatted: 3.3.1 + keyv: 4.5.4 + flatted@3.3.1: {} for-each@0.3.3: @@ -13024,14 +13693,6 @@ snapshots: glob-to-regexp@0.4.1: {} - glob@10.3.10: - dependencies: - foreground-child: 3.3.0 - jackspeak: 2.3.6 - minimatch: 9.0.5 - minipass: 7.1.2 - path-scurry: 1.11.1 - glob@10.4.5: dependencies: foreground-child: 3.3.0 @@ -13058,6 +13719,8 @@ snapshots: globals@14.0.0: {} + globals@15.11.0: {} + globalthis@1.0.4: dependencies: define-properties: 1.2.1 @@ -13340,13 +14003,6 @@ snapshots: domutils: 2.8.0 entities: 2.2.0 - htmlparser2@8.0.2: - dependencies: - domelementtype: 2.3.0 - domhandler: 5.0.3 - domutils: 3.1.0 - entities: 4.5.0 - http-cache-semantics@4.1.1: {} http-errors@2.0.0: @@ -13557,6 +14213,16 @@ snapshots: is-hexadecimal@2.0.1: {} + is-immutable-type@5.0.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5): + dependencies: + '@typescript-eslint/type-utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + eslint: 9.13.0(jiti@1.21.6) + ts-api-utils: 1.3.0(typescript@4.9.5) + ts-declaration-location: 1.0.4(typescript@4.9.5) + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + is-map@2.0.3: {} is-nan@1.3.2: @@ -13572,8 +14238,6 @@ snapshots: is-number@7.0.0: {} - is-path-inside@3.0.3: {} - is-plain-obj@4.1.0: {} is-plain-object@5.0.0: {} @@ -13683,12 +14347,6 @@ snapshots: reflect.getprototypeof: 1.0.6 set-function-name: 2.0.2 - jackspeak@2.3.6: - dependencies: - '@isaacs/cliui': 8.0.2 - optionalDependencies: - '@pkgjs/parseargs': 0.11.0 - jackspeak@3.4.3: dependencies: '@isaacs/cliui': 8.0.2 @@ -14205,7 +14863,10 @@ snapshots: loader-utils@3.3.1: {} - local-pkg@0.4.3: {} + local-pkg@0.5.0: + dependencies: + mlly: 1.7.2 + pkg-types: 1.2.1 localforage@1.10.0: dependencies: @@ -14323,15 +14984,12 @@ snapshots: unist-util-is: 5.2.1 unist-util-visit-parents: 5.1.3 - mdast-util-from-markdown@0.8.5: + mdast-util-find-and-replace@3.0.1: dependencies: - '@types/mdast': 3.0.15 - mdast-util-to-string: 2.0.0 - micromark: 2.11.4 - parse-entities: 2.0.0 - unist-util-stringify-position: 2.0.3 - transitivePeerDependencies: - - supports-color + '@types/mdast': 4.0.4 + escape-string-regexp: 5.0.0 + unist-util-is: 6.0.0 + unist-util-visit-parents: 6.0.1 mdast-util-from-markdown@1.3.1: dependencies: @@ -14350,6 +15008,23 @@ snapshots: transitivePeerDependencies: - supports-color + mdast-util-from-markdown@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + decode-named-character-reference: 1.0.2 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.0 + micromark-util-decode-numeric-character-reference: 2.0.1 + micromark-util-decode-string: 2.0.0 + micromark-util-normalize-identifier: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + mdast-util-gfm-autolink-literal@1.0.3: dependencies: '@types/mdast': 3.0.15 @@ -14357,17 +15032,43 @@ snapshots: mdast-util-find-and-replace: 2.2.2 micromark-util-character: 1.2.0 + mdast-util-gfm-autolink-literal@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-find-and-replace: 3.0.1 + micromark-util-character: 2.1.0 + mdast-util-gfm-footnote@1.0.2: dependencies: '@types/mdast': 3.0.15 mdast-util-to-markdown: 1.5.0 micromark-util-normalize-identifier: 1.1.0 + mdast-util-gfm-footnote@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.1 + mdast-util-to-markdown: 2.1.0 + micromark-util-normalize-identifier: 2.0.0 + transitivePeerDependencies: + - supports-color + mdast-util-gfm-strikethrough@1.0.3: dependencies: '@types/mdast': 3.0.15 mdast-util-to-markdown: 1.5.0 + mdast-util-gfm-strikethrough@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.1 + mdast-util-to-markdown: 2.1.0 + transitivePeerDependencies: + - supports-color + mdast-util-gfm-table@1.0.7: dependencies: '@types/mdast': 3.0.15 @@ -14377,11 +15078,30 @@ snapshots: transitivePeerDependencies: - supports-color + mdast-util-gfm-table@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + markdown-table: 3.0.3 + mdast-util-from-markdown: 2.0.1 + mdast-util-to-markdown: 2.1.0 + transitivePeerDependencies: + - supports-color + mdast-util-gfm-task-list-item@1.0.2: dependencies: '@types/mdast': 3.0.15 mdast-util-to-markdown: 1.5.0 + mdast-util-gfm-task-list-item@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.1 + mdast-util-to-markdown: 2.1.0 + transitivePeerDependencies: + - supports-color + mdast-util-gfm@2.0.2: dependencies: mdast-util-from-markdown: 1.3.1 @@ -14394,6 +15114,18 @@ snapshots: transitivePeerDependencies: - supports-color + mdast-util-gfm@3.0.0: + dependencies: + mdast-util-from-markdown: 2.0.1 + mdast-util-gfm-autolink-literal: 2.0.1 + mdast-util-gfm-footnote: 2.0.0 + mdast-util-gfm-strikethrough: 2.0.0 + mdast-util-gfm-table: 2.0.0 + mdast-util-gfm-task-list-item: 2.0.0 + mdast-util-to-markdown: 2.1.0 + transitivePeerDependencies: + - supports-color + mdast-util-math@2.0.2: dependencies: '@types/mdast': 3.0.15 @@ -14457,6 +15189,11 @@ snapshots: '@types/mdast': 3.0.15 unist-util-is: 5.2.1 + mdast-util-phrasing@4.1.0: + dependencies: + '@types/mdast': 4.0.4 + unist-util-is: 6.0.0 + mdast-util-to-hast@12.3.0: dependencies: '@types/hast': 2.3.10 @@ -14491,12 +15228,25 @@ snapshots: unist-util-visit: 4.1.2 zwitch: 2.0.4 - mdast-util-to-string@2.0.0: {} + mdast-util-to-markdown@2.1.0: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + longest-streak: 3.1.0 + mdast-util-phrasing: 4.1.0 + mdast-util-to-string: 4.0.0 + micromark-util-decode-string: 2.0.0 + unist-util-visit: 5.0.0 + zwitch: 2.0.4 mdast-util-to-string@3.2.0: dependencies: '@types/mdast': 3.0.15 + mdast-util-to-string@4.0.0: + dependencies: + '@types/mdast': 4.0.4 + media-typer@0.3.0: {} memfs@3.5.3: @@ -14561,6 +15311,25 @@ snapshots: micromark-util-types: 1.1.0 uvu: 0.5.6 + micromark-core-commonmark@2.0.1: + dependencies: + decode-named-character-reference: 1.0.2 + devlop: 1.1.0 + micromark-factory-destination: 2.0.0 + micromark-factory-label: 2.0.0 + micromark-factory-space: 2.0.0 + micromark-factory-title: 2.0.0 + micromark-factory-whitespace: 2.0.0 + micromark-util-character: 2.1.0 + micromark-util-chunked: 2.0.0 + micromark-util-classify-character: 2.0.0 + micromark-util-html-tag-name: 2.0.0 + micromark-util-normalize-identifier: 2.0.0 + micromark-util-resolve-all: 2.0.0 + micromark-util-subtokenize: 2.0.1 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + micromark-extension-gfm-autolink-literal@1.0.5: dependencies: micromark-util-character: 1.2.0 @@ -14568,6 +15337,13 @@ snapshots: micromark-util-symbol: 1.1.0 micromark-util-types: 1.1.0 + micromark-extension-gfm-autolink-literal@2.1.0: + dependencies: + micromark-util-character: 2.1.0 + micromark-util-sanitize-uri: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + micromark-extension-gfm-footnote@1.1.2: dependencies: micromark-core-commonmark: 1.1.0 @@ -14579,6 +15355,17 @@ snapshots: micromark-util-types: 1.1.0 uvu: 0.5.6 + micromark-extension-gfm-footnote@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-core-commonmark: 2.0.1 + micromark-factory-space: 2.0.0 + micromark-util-character: 2.1.0 + micromark-util-normalize-identifier: 2.0.0 + micromark-util-sanitize-uri: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + micromark-extension-gfm-strikethrough@1.0.7: dependencies: micromark-util-chunked: 1.1.0 @@ -14588,6 +15375,15 @@ snapshots: micromark-util-types: 1.1.0 uvu: 0.5.6 + micromark-extension-gfm-strikethrough@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.0 + micromark-util-classify-character: 2.0.0 + micromark-util-resolve-all: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + micromark-extension-gfm-table@1.0.7: dependencies: micromark-factory-space: 1.1.0 @@ -14596,10 +15392,22 @@ snapshots: micromark-util-types: 1.1.0 uvu: 0.5.6 + micromark-extension-gfm-table@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.0 + micromark-util-character: 2.1.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + micromark-extension-gfm-tagfilter@1.0.2: dependencies: micromark-util-types: 1.1.0 + micromark-extension-gfm-tagfilter@2.0.0: + dependencies: + micromark-util-types: 2.0.0 + micromark-extension-gfm-task-list-item@1.0.5: dependencies: micromark-factory-space: 1.1.0 @@ -14608,6 +15416,14 @@ snapshots: micromark-util-types: 1.1.0 uvu: 0.5.6 + micromark-extension-gfm-task-list-item@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.0 + micromark-util-character: 2.1.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + micromark-extension-gfm@2.0.3: dependencies: micromark-extension-gfm-autolink-literal: 1.0.5 @@ -14619,6 +15435,17 @@ snapshots: micromark-util-combine-extensions: 1.1.0 micromark-util-types: 1.1.0 + micromark-extension-gfm@3.0.0: + dependencies: + micromark-extension-gfm-autolink-literal: 2.1.0 + micromark-extension-gfm-footnote: 2.1.0 + micromark-extension-gfm-strikethrough: 2.1.0 + micromark-extension-gfm-table: 2.1.0 + micromark-extension-gfm-tagfilter: 2.0.0 + micromark-extension-gfm-task-list-item: 2.1.0 + micromark-util-combine-extensions: 2.0.0 + micromark-util-types: 2.0.0 + micromark-extension-math@2.1.2: dependencies: '@types/katex': 0.16.7 @@ -14686,6 +15513,12 @@ snapshots: micromark-util-symbol: 1.1.0 micromark-util-types: 1.1.0 + micromark-factory-destination@2.0.0: + dependencies: + micromark-util-character: 2.1.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + micromark-factory-label@1.1.0: dependencies: micromark-util-character: 1.2.0 @@ -14693,6 +15526,13 @@ snapshots: micromark-util-types: 1.1.0 uvu: 0.5.6 + micromark-factory-label@2.0.0: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + micromark-factory-mdx-expression@1.0.9: dependencies: '@types/estree': 1.0.6 @@ -14709,6 +15549,11 @@ snapshots: micromark-util-character: 1.2.0 micromark-util-types: 1.1.0 + micromark-factory-space@2.0.0: + dependencies: + micromark-util-character: 2.1.0 + micromark-util-types: 2.0.0 + micromark-factory-title@1.1.0: dependencies: micromark-factory-space: 1.1.0 @@ -14716,6 +15561,13 @@ snapshots: micromark-util-symbol: 1.1.0 micromark-util-types: 1.1.0 + micromark-factory-title@2.0.0: + dependencies: + micromark-factory-space: 2.0.0 + micromark-util-character: 2.1.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + micromark-factory-whitespace@1.1.0: dependencies: micromark-factory-space: 1.1.0 @@ -14723,6 +15575,13 @@ snapshots: micromark-util-symbol: 1.1.0 micromark-util-types: 1.1.0 + micromark-factory-whitespace@2.0.0: + dependencies: + micromark-factory-space: 2.0.0 + micromark-util-character: 2.1.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + micromark-util-character@1.2.0: dependencies: micromark-util-symbol: 1.1.0 @@ -14737,21 +15596,40 @@ snapshots: dependencies: micromark-util-symbol: 1.1.0 + micromark-util-chunked@2.0.0: + dependencies: + micromark-util-symbol: 2.0.0 + micromark-util-classify-character@1.1.0: dependencies: micromark-util-character: 1.2.0 micromark-util-symbol: 1.1.0 micromark-util-types: 1.1.0 + micromark-util-classify-character@2.0.0: + dependencies: + micromark-util-character: 2.1.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + micromark-util-combine-extensions@1.1.0: dependencies: micromark-util-chunked: 1.1.0 micromark-util-types: 1.1.0 + micromark-util-combine-extensions@2.0.0: + dependencies: + micromark-util-chunked: 2.0.0 + micromark-util-types: 2.0.0 + micromark-util-decode-numeric-character-reference@1.1.0: dependencies: micromark-util-symbol: 1.1.0 + micromark-util-decode-numeric-character-reference@2.0.1: + dependencies: + micromark-util-symbol: 2.0.0 + micromark-util-decode-string@1.1.0: dependencies: decode-named-character-reference: 1.0.2 @@ -14759,6 +15637,13 @@ snapshots: micromark-util-decode-numeric-character-reference: 1.1.0 micromark-util-symbol: 1.1.0 + micromark-util-decode-string@2.0.0: + dependencies: + decode-named-character-reference: 1.0.2 + micromark-util-character: 2.1.0 + micromark-util-decode-numeric-character-reference: 2.0.1 + micromark-util-symbol: 2.0.0 + micromark-util-encode@1.1.0: {} micromark-util-encode@2.0.0: {} @@ -14776,14 +15661,24 @@ snapshots: micromark-util-html-tag-name@1.2.0: {} + micromark-util-html-tag-name@2.0.0: {} + micromark-util-normalize-identifier@1.1.0: dependencies: micromark-util-symbol: 1.1.0 + micromark-util-normalize-identifier@2.0.0: + dependencies: + micromark-util-symbol: 2.0.0 + micromark-util-resolve-all@1.1.0: dependencies: micromark-util-types: 1.1.0 + micromark-util-resolve-all@2.0.0: + dependencies: + micromark-util-types: 2.0.0 + micromark-util-sanitize-uri@1.2.0: dependencies: micromark-util-character: 1.2.0 @@ -14803,6 +15698,13 @@ snapshots: micromark-util-types: 1.1.0 uvu: 0.5.6 + micromark-util-subtokenize@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + micromark-util-symbol@1.1.0: {} micromark-util-symbol@2.0.0: {} @@ -14811,13 +15713,6 @@ snapshots: micromark-util-types@2.0.0: {} - micromark@2.11.4: - dependencies: - debug: 4.3.7 - parse-entities: 2.0.0 - transitivePeerDependencies: - - supports-color - micromark@3.2.0: dependencies: '@types/debug': 4.1.12 @@ -14840,6 +15735,28 @@ snapshots: transitivePeerDependencies: - supports-color + micromark@4.0.0: + dependencies: + '@types/debug': 4.1.12 + debug: 4.3.7 + decode-named-character-reference: 1.0.2 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.1 + micromark-factory-space: 2.0.0 + micromark-util-character: 2.1.0 + micromark-util-chunked: 2.0.0 + micromark-util-combine-extensions: 2.0.0 + micromark-util-decode-numeric-character-reference: 2.0.1 + micromark-util-encode: 2.0.0 + micromark-util-normalize-identifier: 2.0.0 + micromark-util-resolve-all: 2.0.0 + micromark-util-sanitize-uri: 2.0.0 + micromark-util-subtokenize: 2.0.1 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + transitivePeerDependencies: + - supports-color + micromatch@4.0.5: dependencies: braces: 3.0.3 @@ -14877,6 +15794,10 @@ snapshots: minimalistic-crypto-utils@1.0.1: {} + minimatch@10.0.1: + dependencies: + brace-expansion: 2.0.1 + minimatch@3.1.2: dependencies: brace-expansion: 1.1.11 @@ -14893,6 +15814,13 @@ snapshots: dependencies: minimist: 1.2.8 + mlly@1.7.2: + dependencies: + acorn: 8.13.0 + pathe: 1.1.2 + pkg-types: 1.2.1 + ufo: 1.5.4 + monaco-editor@0.52.0: {} mri@1.2.0: {} @@ -15130,6 +16058,8 @@ snapshots: package-json-from-dist@1.0.1: {} + package-manager-detector@0.2.2: {} + pako@1.0.11: {} papaparse@5.4.1: {} @@ -15172,6 +16102,13 @@ snapshots: is-decimal: 2.0.1 is-hexadecimal: 2.0.1 + parse-gitignore@2.0.0: {} + + parse-imports@2.2.1: + dependencies: + es-module-lexer: 1.5.4 + slashes: 3.0.12 + parse-json@5.2.0: dependencies: '@babel/code-frame': 7.25.7 @@ -15213,6 +16150,8 @@ snapshots: path-type@4.0.0: {} + pathe@1.1.2: {} + pathval@2.0.0: {} pbkdf2@3.1.2: @@ -15233,6 +16172,8 @@ snapshots: picomatch@2.3.1: {} + picomatch@4.0.2: {} + pidtree@0.6.0: {} pify@2.3.0: {} @@ -15249,6 +16190,12 @@ snapshots: dependencies: find-up: 6.3.0 + pkg-types@1.2.1: + dependencies: + confbox: 0.1.8 + mlly: 1.7.2 + pathe: 1.1.2 + pluralize@8.0.0: {} pnp-webpack-plugin@1.7.0(typescript@4.9.5): @@ -15750,6 +16697,10 @@ snapshots: indent-string: 4.0.0 strip-indent: 3.0.0 + refa@0.12.1: + dependencies: + '@eslint-community/regexpp': 4.11.1 + reflect.getprototypeof@1.0.6: dependencies: call-bind: 1.0.7 @@ -15780,6 +16731,11 @@ snapshots: regex-parser@2.3.0: {} + regexp-ast-analysis@0.7.1: + dependencies: + '@eslint-community/regexpp': 4.11.1 + refa: 0.12.1 + regexp-tree@0.1.27: {} regexp.prototype.flags@1.5.3: @@ -15789,8 +16745,6 @@ snapshots: es-errors: 1.3.0 set-function-name: 2.0.2 - regexpp@3.2.0: {} - regexpu-core@6.1.1: dependencies: regenerate: 1.4.2 @@ -15802,14 +16756,14 @@ snapshots: regjsgen@0.8.0: {} + regjsparser@0.10.0: + dependencies: + jsesc: 0.5.0 + regjsparser@0.11.1: dependencies: jsesc: 3.0.2 - regjsparser@0.9.1: - dependencies: - jsesc: 0.5.0 - rehype-external-links@3.0.0: dependencies: '@types/hast': 3.0.4 @@ -15991,10 +16945,6 @@ snapshots: es-errors: 1.3.0 is-regex: 1.1.4 - safe-regex@2.1.1: - dependencies: - regexp-tree: 0.1.27 - safer-buffer@2.1.2: {} sass-loader@13.3.3(sass@1.80.3)(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3)): @@ -16034,6 +16984,12 @@ snapshots: screenfull@5.2.0: {} + scslre@0.3.0: + dependencies: + '@eslint-community/regexpp': 4.11.1 + refa: 0.12.1 + regexp-ast-analysis: 0.7.1 + semver@5.7.2: {} semver@6.3.1: {} @@ -16130,6 +17086,8 @@ snapshots: shebang-regex@3.0.0: {} + short-unique-id@5.2.0: {} + side-channel@1.0.6: dependencies: call-bind: 1.0.7 @@ -16151,6 +17109,8 @@ snapshots: slash@3.0.0: {} + slashes@3.0.12: {} + slice-ansi@5.0.0: dependencies: ansi-styles: 6.2.1 @@ -16190,10 +17150,17 @@ snapshots: spdx-exceptions: 2.5.0 spdx-license-ids: 3.0.20 + spdx-expression-parse@4.0.0: + dependencies: + spdx-exceptions: 2.5.0 + spdx-license-ids: 3.0.20 + spdx-license-ids@3.0.20: {} sprintf-js@1.0.3: {} + stable-hash@0.0.4: {} + stack-utils@2.0.6: dependencies: escape-string-regexp: 2.0.0 @@ -16237,6 +17204,8 @@ snapshots: char-regex: 1.0.2 strip-ansi: 6.0.1 + string-ts@2.2.0: {} + string-width@4.2.3: dependencies: emoji-regex: 8.0.0 @@ -16387,6 +17356,11 @@ snapshots: dependencies: tslib: 2.8.0 + synckit@0.9.2: + dependencies: + '@pkgr/core': 0.1.1 + tslib: 2.8.0 + tabbable@6.2.0: {} tailwind-merge@2.5.4: {} @@ -16469,6 +17443,8 @@ snapshots: tiny-invariant@1.3.3: {} + tinyexec@0.3.1: {} + tinyrainbow@1.2.0: {} tinyspy@3.0.2: {} @@ -16485,6 +17461,10 @@ snapshots: toidentifier@1.0.1: {} + toml-eslint-parser@0.10.0: + dependencies: + eslint-visitor-keys: 3.4.3 + tough-cookie@4.1.4: dependencies: psl: 1.9.0 @@ -16504,6 +17484,11 @@ snapshots: dependencies: typescript: 4.9.5 + ts-declaration-location@1.0.4(typescript@4.9.5): + dependencies: + minimatch: 10.0.1 + typescript: 4.9.5 + ts-dedent@2.2.0: {} ts-interface-checker@0.1.13: {} @@ -16526,6 +17511,8 @@ snapshots: v8-compile-cache-lib: 3.0.1 yn: 3.1.1 + ts-pattern@5.5.0: {} + ts-pnp@1.2.0(typescript@4.9.5): optionalDependencies: typescript: 4.9.5 @@ -16621,6 +17608,8 @@ snapshots: typescript@4.9.5: {} + ufo@1.5.4: {} + uglify-js@3.19.3: {} unbox-primitive@1.0.2: @@ -16685,10 +17674,6 @@ snapshots: '@types/unist': 2.0.11 unist-util-visit: 4.1.2 - unist-util-stringify-position@2.0.3: - dependencies: - '@types/unist': 2.0.11 - unist-util-stringify-position@3.0.3: dependencies: '@types/unist': 2.0.11 @@ -16845,10 +17830,10 @@ snapshots: void-elements@3.1.0: {} - vue-eslint-parser@9.4.3(eslint@8.57.1): + vue-eslint-parser@9.4.3(eslint@9.13.0(jiti@1.21.6)): dependencies: debug: 4.3.7 - eslint: 8.57.1 + eslint: 9.13.0(jiti@1.21.6) eslint-scope: 7.2.2 eslint-visitor-keys: 3.4.3 espree: 9.6.1 From 0ae085b48a12359f5ecf64c524e850f06a4f1b7b Mon Sep 17 00:00:00 2001 From: AkaraChen <akarachen@outlook.com> Date: Mon, 21 Oct 2024 17:03:04 +0800 Subject: [PATCH 117/346] build: add eslint common rule --- web/eslint.config.mjs | 47 ++++++++++++++++++++++++++++++++++++++++--- web/package.json | 11 +++++----- web/pnpm-lock.yaml | 5 ++++- 3 files changed, 54 insertions(+), 9 deletions(-) diff --git a/web/eslint.config.mjs b/web/eslint.config.mjs index f9d784920b..ce2abce910 100644 --- a/web/eslint.config.mjs +++ b/web/eslint.config.mjs @@ -1,8 +1,9 @@ -import { stylistic, typescript, combine, javascript } from '@antfu/eslint-config' +import { stylistic, typescript, combine, javascript, GLOB_TESTS, GLOB_JSX, GLOB_TSX } from '@antfu/eslint-config' import path from 'node:path' import { fileURLToPath } from 'node:url' import js from '@eslint/js' import { FlatCompat } from '@eslint/eslintrc' +import globals from 'globals' const __filename = fileURLToPath(import.meta.url) const __dirname = path.dirname(__filename) @@ -65,7 +66,12 @@ export default combine( "ts/no-empty-object-type": "off", } }), - // javascript(), + javascript({ + overrides: { + 'no-unused-vars': 'off', + 'no-use-before-define': 'off' + } + }), // TODO: remove this when upgrade to nextjs 15 compat.extends('next'), { @@ -89,6 +95,9 @@ export default combine( "react-hooks/exhaustive-deps": "warn", "react/display-name": "off", "curly": "off", + "unused-imports/no-unused-vars": "warn", + "unused-imports/no-unused-imports": "warn", + "no-undef": "error" } }, storybook, @@ -96,7 +105,39 @@ export default combine( { rules: { // not exist in old version - "antfu/consistent-list-newline": "off" + "antfu/consistent-list-newline": "off", + + // useful, but big change + "no-useless-constructor": "off", + "no-undef": "warn" + } + }, + // suppress error for `no-undef` rule + { + files: GLOB_TESTS, + languageOptions: { + globals: { + ...globals.browser, + ...globals.es2021, + ...globals.node, + ...globals.jest + }, + }, + }, + { + files: [ + GLOB_JSX, + GLOB_TSX, + '**/hooks/*' + ], + languageOptions: { + globals: { + ...globals.browser, + ...globals.es2025, + ...globals.node, + 'React': 'readable', + 'JSX': 'readable', + } } } ) diff --git a/web/package.json b/web/package.json index 4c66eaf2d6..a56f218696 100644 --- a/web/package.json +++ b/web/package.json @@ -53,6 +53,7 @@ "echarts-for-react": "^3.0.2", "emoji-mart": "^5.5.2", "fast-deep-equal": "^3.1.3", + "globals": "^15.11.0", "i18next": "^22.4.13", "i18next-resources-to-backend": "^1.1.3", "immer": "^9.0.19", @@ -110,6 +111,7 @@ "devDependencies": { "@antfu/eslint-config": "^3.8.0", "@chromatic-com/storybook": "^1.9.0", + "@eslint-react/eslint-plugin": "^1.15.0", "@eslint/eslintrc": "^3.1.0", "@eslint/js": "^9.13.0", "@faker-js/faker": "^7.6.0", @@ -147,8 +149,10 @@ "bing-translate-api": "^4.0.2", "code-inspector-plugin": "^0.13.0", "cross-env": "^7.0.3", - "eslint": "^9.10.0", + "eslint": "^9.13.0", "eslint-config-next": "^15.0.0-canary.202", + "eslint-plugin-react-hooks": "^5.0.0", + "eslint-plugin-react-refresh": "^0.4.12", "eslint-plugin-storybook": "^0.9.0", "husky": "^8.0.3", "jest": "^29.7.0", @@ -161,10 +165,7 @@ "tailwindcss": "^3.4.4", "ts-node": "^10.9.2", "typescript": "4.9.5", - "uglify-js": "^3.17.4", - "@eslint-react/eslint-plugin": "^1.15.0", - "eslint-plugin-react-hooks": "^5.0.0", - "eslint-plugin-react-refresh": "^0.4.12" + "uglify-js": "^3.17.4" }, "resolutions": { "@types/react": "~18.2.0", diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index dc8b54c7c8..3aeb8f080c 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -100,6 +100,9 @@ importers: fast-deep-equal: specifier: ^3.1.3 version: 3.1.3 + globals: + specifier: ^15.11.0 + version: 15.11.0 i18next: specifier: ^22.4.13 version: 22.5.1 @@ -381,7 +384,7 @@ importers: specifier: ^7.0.3 version: 7.0.3 eslint: - specifier: ^9.10.0 + specifier: ^9.13.0 version: 9.13.0(jiti@1.21.6) eslint-config-next: specifier: ^15.0.0-canary.202 From 024028bc523e9dcdb33827cd4c16a63e64d09008 Mon Sep 17 00:00:00 2001 From: AkaraChen <akarachen@outlook.com> Date: Tue, 22 Oct 2024 09:49:56 +0800 Subject: [PATCH 118/346] build: sync eslint rule --- web/eslint.config.mjs | 49 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/web/eslint.config.mjs b/web/eslint.config.mjs index ce2abce910..c97b05fab4 100644 --- a/web/eslint.config.mjs +++ b/web/eslint.config.mjs @@ -1,4 +1,7 @@ -import { stylistic, typescript, combine, javascript, GLOB_TESTS, GLOB_JSX, GLOB_TSX } from '@antfu/eslint-config' +import { + GLOB_JSX, GLOB_TESTS, GLOB_TSX, combine, javascript, node, + stylistic, typescript, unicorn + } from '@antfu/eslint-config' import path from 'node:path' import { fileURLToPath } from 'node:url' import js from '@eslint/js' @@ -47,13 +50,15 @@ export default combine( // original @antfu/eslint-config does not support jsx jsx: false, overrides: { + // original config "style/indent": "off", // these options does not exist in old version + // maybe useless "style/indent-binary-ops": "off", "style/multiline-ternary": "off", - // big change + // not exist in old version, and big change "style/quote-props": "off", "style/member-delimiter-style": "off", "style/quotes": "off", @@ -68,10 +73,15 @@ export default combine( }), javascript({ overrides: { + // handled by unused-imports/no-unused-vars 'no-unused-vars': 'off', - 'no-use-before-define': 'off' + + // useless + 'no-use-before-define': 'warn' } }), + unicorn(), + node(), // TODO: remove this when upgrade to nextjs 15 compat.extends('next'), { @@ -89,15 +99,39 @@ export default combine( { // orignal config rules: { + // from old version of antfu/eslint-config + "no-undef": "warn", + 'ts/consistent-type-definitions': ['error', 'type'], + // orignal ts/no-var-requires 'ts/no-require-imports': 'off', "no-console": 'off', "react-hooks/exhaustive-deps": "warn", "react/display-name": "off", + + // orignal config, but removed in new version antfu/eslint-config + // big change "curly": "off", + + // antfu use eslint-plugin-perfectionist to replace this + // will cause big change, so keep the original + // sort-imports + "sort-imports": [ + 'error', + { + ignoreCase: false, + ignoreDeclarationSort: true, + ignoreMemberSort: false, + memberSyntaxSortOrder: ['none', 'all', 'multiple', 'single'], + allowSeparatedGroups: false, + }, + ], + + // antfu migrate to eslint-plugin-unused-imports "unused-imports/no-unused-vars": "warn", "unused-imports/no-unused-imports": "warn", - "no-undef": "error" + + "no-undef": "error", } }, storybook, @@ -106,10 +140,13 @@ export default combine( rules: { // not exist in old version "antfu/consistent-list-newline": "off", + 'node/prefer-global/process': 'off', + 'node/prefer-global/buffer': 'off', + 'node/no-callback-literal': 'off', // useful, but big change - "no-useless-constructor": "off", - "no-undef": "warn" + "unicorn/prefer-number-properties": "warn", + "unicorn/no-new-array": "warn" } }, // suppress error for `no-undef` rule From cdd2a400866eccbeb9f350b339a15665f41b541d Mon Sep 17 00:00:00 2001 From: AkaraChen <akarachen@outlook.com> Date: Mon, 21 Oct 2024 16:21:16 +0800 Subject: [PATCH 119/346] style: minimium codemod --- web/.storybook/preview.tsx | 6 +++--- .../app/(appDetailLayout)/[appId]/develop/page.tsx | 2 +- .../(datasetDetailLayout)/[datasetId]/layout.tsx | 5 ++--- .../config-prompt/simple-prompt-input.tsx | 2 +- .../components/app/configuration/config/index.tsx | 6 +++--- web/app/components/app/configuration/index.tsx | 7 +++---- .../overview/apikey-info-panel/progress/index.tsx | 2 +- .../base/audio-btn/audio.player.manager.ts | 3 ++- web/app/components/base/audio-btn/audio.ts | 2 +- .../components/base/audio-gallery/AudioPlayer.tsx | 2 +- .../components/base/auto-height-textarea/common.tsx | 2 ++ web/app/components/base/emoji-picker/Inner.tsx | 3 ++- web/app/components/base/icons/IconBase.tsx | 2 ++ web/app/components/base/markdown.tsx | 5 ++--- web/app/components/base/mermaid/index.tsx | 10 ++++++---- web/app/components/base/popover/index.tsx | 6 +++--- .../base/prompt-editor/plugins/custom-text/node.tsx | 8 ++++---- .../plugins/variable-value-block/node.tsx | 7 +++---- web/app/components/base/tag-management/index.tsx | 2 +- web/app/components/base/tag-management/selector.tsx | 2 +- .../base/tag-management/tag-item-editor.tsx | 2 +- .../components/datasets/create/step-one/index.tsx | 2 +- .../components/datasets/create/step-two/index.tsx | 10 +++++----- .../external-api/external-api-modal/Form.tsx | 2 ++ web/app/components/datasets/settings/form/index.tsx | 2 +- web/app/components/header/app-nav/index.tsx | 2 +- web/app/components/share/text-generation/index.tsx | 6 +++--- web/app/components/tools/workflow-tool/index.tsx | 2 +- .../nodes/_base/components/variable/utils.ts | 12 ++++++------ .../_base/components/variable/var-reference-vars.tsx | 2 +- .../workflow/nodes/_base/hooks/use-one-step-run.ts | 1 + .../nodes/_base/hooks/use-output-var-list.ts | 2 +- web/app/components/workflow/nodes/assigner/node.tsx | 2 +- web/app/components/workflow/nodes/assigner/panel.tsx | 2 +- web/app/components/workflow/nodes/end/default.ts | 2 +- web/app/components/workflow/nodes/end/panel.tsx | 4 ++-- .../nodes/http/components/edit-body/index.tsx | 2 +- web/app/components/workflow/nodes/tool/use-config.ts | 2 +- .../workflow/nodes/variable-assigner/panel.tsx | 2 +- web/app/signin/_header.tsx | 2 +- web/context/modal-context.tsx | 1 - web/context/provider-context.tsx | 1 - web/i18n/hi-IN/share-app.ts | 2 ++ web/service/base.ts | 3 ++- 44 files changed, 81 insertions(+), 73 deletions(-) diff --git a/web/.storybook/preview.tsx b/web/.storybook/preview.tsx index 49cd24e974..7a254bc79c 100644 --- a/web/.storybook/preview.tsx +++ b/web/.storybook/preview.tsx @@ -1,6 +1,6 @@ import React from 'react' import type { Preview } from '@storybook/react' -import { withThemeByDataAttribute } from '@storybook/addon-themes'; +import { withThemeByDataAttribute } from '@storybook/addon-themes' import I18nServer from '../app/components/i18n-server' import '../app/styles/globals.css' @@ -16,12 +16,12 @@ export const decorators = [ defaultTheme: 'light', attributeName: 'data-theme', }), - Story => { + (Story) => { return <I18nServer> <Story /> </I18nServer> } - ]; + ] const preview: Preview = { parameters: { diff --git a/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/develop/page.tsx b/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/develop/page.tsx index 4101120703..a4ee3922d9 100644 --- a/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/develop/page.tsx +++ b/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/develop/page.tsx @@ -1,5 +1,5 @@ import React from 'react' -import { type Locale } from '@/i18n' +import type { Locale } from '@/i18n' import DevelopMain from '@/app/components/develop' export type IDevelopProps = { diff --git a/web/app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/layout.tsx b/web/app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/layout.tsx index a58027bcd1..fe2f7dfa03 100644 --- a/web/app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/layout.tsx +++ b/web/app/(commonLayout)/datasets/(datasetDetailLayout)/[datasetId]/layout.tsx @@ -8,12 +8,11 @@ import { useBoolean } from 'ahooks' import { Cog8ToothIcon, // CommandLineIcon, - Squares2X2Icon, - // eslint-disable-next-line sort-imports - PuzzlePieceIcon, DocumentTextIcon, PaperClipIcon, + PuzzlePieceIcon, QuestionMarkCircleIcon, + Squares2X2Icon, } from '@heroicons/react/24/outline' import { Cog8ToothIcon as Cog8ToothSolidIcon, diff --git a/web/app/components/app/configuration/config-prompt/simple-prompt-input.tsx b/web/app/components/app/configuration/config-prompt/simple-prompt-input.tsx index d7bfe8534e..e282f6f98e 100644 --- a/web/app/components/app/configuration/config-prompt/simple-prompt-input.tsx +++ b/web/app/components/app/configuration/config-prompt/simple-prompt-input.tsx @@ -9,7 +9,7 @@ import ConfirmAddVar from './confirm-add-var' import s from './style.module.css' import PromptEditorHeightResizeWrap from './prompt-editor-height-resize-wrap' import cn from '@/utils/classnames' -import { type PromptVariable } from '@/models/debug' +import type { PromptVariable } from '@/models/debug' import Tooltip from '@/app/components/base/tooltip' import type { CompletionParams } from '@/types/app' import { AppType } from '@/types/app' diff --git a/web/app/components/app/configuration/config/index.tsx b/web/app/components/app/configuration/config/index.tsx index 12551f508e..0ae3f0af04 100644 --- a/web/app/components/app/configuration/config/index.tsx +++ b/web/app/components/app/configuration/config/index.tsx @@ -19,7 +19,7 @@ import AgentTools from './agent/agent-tools' import ConfigContext from '@/context/debug-configuration' import ConfigPrompt from '@/app/components/app/configuration/config-prompt' import ConfigVar from '@/app/components/app/configuration/config-var' -import { type CitationConfig, type ModelConfig, type ModerationConfig, type MoreLikeThisConfig, type PromptVariable, type SpeechToTextConfig, type SuggestedQuestionsAfterAnswerConfig, type TextToSpeechConfig } from '@/models/debug' +import type { CitationConfig, ModelConfig, ModerationConfig, MoreLikeThisConfig, PromptVariable, SpeechToTextConfig, SuggestedQuestionsAfterAnswerConfig, TextToSpeechConfig } from '@/models/debug' import type { AppType } from '@/types/app' import { ModelModeType } from '@/types/app' import { useModalContext } from '@/context/modal-context' @@ -134,11 +134,11 @@ const Config: FC = () => { annotation: annotationConfig.enabled, setAnnotation: async (value) => { if (value) { - // eslint-disable-next-line @typescript-eslint/no-use-before-define + // eslint-disable-next-line ts/no-use-before-define setIsShowAnnotationConfigInit(true) } else { - // eslint-disable-next-line @typescript-eslint/no-use-before-define + // eslint-disable-next-line ts/no-use-before-define await handleDisableAnnotation(annotationConfig.embedding_model) } }, diff --git a/web/app/components/app/configuration/index.tsx b/web/app/components/app/configuration/index.tsx index 357dc84b7a..0557a3b082 100644 --- a/web/app/components/app/configuration/index.tsx +++ b/web/app/components/app/configuration/index.tsx @@ -55,7 +55,7 @@ import ModelParameterModal from '@/app/components/header/account-setting/model-p import type { FormValue } from '@/app/components/header/account-setting/model-provider-page/declarations' import { useTextGenerationCurrentProviderAndModelAndModelList } from '@/app/components/header/account-setting/model-provider-page/hooks' import { fetchCollectionList } from '@/service/tools' -import { type Collection } from '@/app/components/tools/types' +import type { Collection } from '@/app/components/tools/types' import { useStore as useAppStore } from '@/app/components/app/store' import { getMultipleRetrievalConfig, @@ -142,7 +142,7 @@ const Configuration: FC = () => { const setCompletionParams = (value: FormValue) => { const params = { ...value } - // eslint-disable-next-line @typescript-eslint/no-use-before-define + // eslint-disable-next-line ts/no-use-before-define if ((!params.stop || params.stop.length === 0) && (modeModeTypeRef.current === ModelModeType.completion)) { params.stop = getTempStop() setTempStop([]) @@ -331,7 +331,7 @@ const Configuration: FC = () => { const [canReturnToSimpleMode, setCanReturnToSimpleMode] = useState(true) const setPromptMode = async (mode: PromptMode) => { if (mode === PromptMode.advanced) { - // eslint-disable-next-line @typescript-eslint/no-use-before-define + // eslint-disable-next-line ts/no-use-before-define await migrateToDefaultPrompt() setCanReturnToSimpleMode(true) } @@ -523,7 +523,6 @@ const Configuration: FC = () => { sensitive_word_avoidance: modelConfig.sensitive_word_avoidance, external_data_tools: modelConfig.external_data_tools, dataSets: datasets || [], - // eslint-disable-next-line multiline-ternary agentConfig: res.mode === 'agent-chat' ? { max_iteration: DEFAULT_AGENT_SETTING.max_iteration, ...modelConfig.agent_mode, diff --git a/web/app/components/app/overview/apikey-info-panel/progress/index.tsx b/web/app/components/app/overview/apikey-info-panel/progress/index.tsx index 3a4accbb43..cc8356e754 100644 --- a/web/app/components/app/overview/apikey-info-panel/progress/index.tsx +++ b/web/app/components/app/overview/apikey-info-panel/progress/index.tsx @@ -20,7 +20,7 @@ const Progress: FC<IProgressProps> = ({ className={cn(s.bar, exhausted && s['bar-error'], 'absolute top-0 left-0 right-0 bottom-0')} style={{ width: `${value}%` }} /> - {Array(10).fill(0).map((i, k) => ( + {Array.from({ length: 10 }).fill(0).map((i, k) => ( <div key={k} className={s['bar-item']} /> ))} </div> diff --git a/web/app/components/base/audio-btn/audio.player.manager.ts b/web/app/components/base/audio-btn/audio.player.manager.ts index 17d92f8dc2..9b3349754f 100644 --- a/web/app/components/base/audio-btn/audio.player.manager.ts +++ b/web/app/components/base/audio-btn/audio.player.manager.ts @@ -1,6 +1,6 @@ import AudioPlayer from '@/app/components/base/audio-btn/audio' declare global { - // eslint-disable-next-line @typescript-eslint/consistent-type-definitions + // eslint-disable-next-line ts/consistent-type-definitions interface AudioPlayerManager { instance: AudioPlayerManager } @@ -12,6 +12,7 @@ export class AudioPlayerManager { private audioPlayers: AudioPlayer | null = null private msgId: string | undefined + // eslint-disable-next-line private constructor() { } diff --git a/web/app/components/base/audio-btn/audio.ts b/web/app/components/base/audio-btn/audio.ts index baf675d0be..d7fae02f82 100644 --- a/web/app/components/base/audio-btn/audio.ts +++ b/web/app/components/base/audio-btn/audio.ts @@ -2,7 +2,7 @@ import Toast from '@/app/components/base/toast' import { textToAudioStream } from '@/service/share' declare global { - // eslint-disable-next-line @typescript-eslint/consistent-type-definitions + // eslint-disable-next-line ts/consistent-type-definitions interface Window { ManagedMediaSource: any } diff --git a/web/app/components/base/audio-gallery/AudioPlayer.tsx b/web/app/components/base/audio-gallery/AudioPlayer.tsx index c482981e8a..95d4c69c83 100644 --- a/web/app/components/base/audio-gallery/AudioPlayer.tsx +++ b/web/app/components/base/audio-gallery/AudioPlayer.tsx @@ -55,7 +55,7 @@ const AudioPlayer: React.FC<AudioPlayerProps> = ({ src }) => { audio.load() // Delayed generation of waveform data - // eslint-disable-next-line @typescript-eslint/no-use-before-define + // eslint-disable-next-line ts/no-use-before-define const timer = setTimeout(() => generateWaveformData(src), 1000) return () => { diff --git a/web/app/components/base/auto-height-textarea/common.tsx b/web/app/components/base/auto-height-textarea/common.tsx index c71df04395..98ff0b7272 100644 --- a/web/app/components/base/auto-height-textarea/common.tsx +++ b/web/app/components/base/auto-height-textarea/common.tsx @@ -49,4 +49,6 @@ const AutoHeightTextarea = forwardRef<HTMLTextAreaElement, AutoHeightTextareaPro }, ) +AutoHeightTextarea.displayName = 'AutoHeightTextarea' + export default AutoHeightTextarea diff --git a/web/app/components/base/emoji-picker/Inner.tsx b/web/app/components/base/emoji-picker/Inner.tsx index 36c146a2a0..3d1d1dbb14 100644 --- a/web/app/components/base/emoji-picker/Inner.tsx +++ b/web/app/components/base/emoji-picker/Inner.tsx @@ -12,8 +12,9 @@ import Divider from '@/app/components/base/divider' import { searchEmoji } from '@/utils/emoji' declare global { + // eslint-disable-next-line ts/no-namespace namespace JSX { - // eslint-disable-next-line @typescript-eslint/consistent-type-definitions + // eslint-disable-next-line ts/consistent-type-definitions interface IntrinsicElements { 'em-emoji': React.DetailedHTMLProps< React.HTMLAttributes<HTMLElement>, HTMLElement > } diff --git a/web/app/components/base/icons/IconBase.tsx b/web/app/components/base/icons/IconBase.tsx index 994cd98bcd..4de39e293c 100644 --- a/web/app/components/base/icons/IconBase.tsx +++ b/web/app/components/base/icons/IconBase.tsx @@ -28,4 +28,6 @@ const IconBase = forwardRef<React.MutableRefObject<HTMLOrSVGElement>, IconBasePr }) }) +IconBase.displayName = 'IconBase' + export default IconBase diff --git a/web/app/components/base/markdown.tsx b/web/app/components/base/markdown.tsx index dbe4087882..9e758e8238 100644 --- a/web/app/components/base/markdown.tsx +++ b/web/app/components/base/markdown.tsx @@ -75,7 +75,6 @@ export function PreCode(props: { children: any }) { ) } -// eslint-disable-next-line unused-imports/no-unused-vars const useLazyLoad = (ref: RefObject<Element>): boolean => { const [isIntersecting, setIntersecting] = useState<boolean>(false) @@ -297,11 +296,11 @@ export default class ErrorBoundary extends Component { } render() { - // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // eslint-disable-next-line ts/ban-ts-comment // @ts-expect-error if (this.state.hasError) return <div>Oops! An error occurred. This could be due to an ECharts runtime error or invalid SVG content. <br />(see the browser console for more information)</div> - // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // eslint-disable-next-line ts/ban-ts-comment // @ts-expect-error return this.props.children } diff --git a/web/app/components/base/mermaid/index.tsx b/web/app/components/base/mermaid/index.tsx index dc01338a8c..6642316488 100644 --- a/web/app/components/base/mermaid/index.tsx +++ b/web/app/components/base/mermaid/index.tsx @@ -44,7 +44,7 @@ const Flowchart = React.forwardRef((props: { const chartId = useRef(`flowchart_${CryptoJS.MD5(props.PrimitiveCode).toString()}`) const prevPrimitiveCode = usePrevious(props.PrimitiveCode) const [isLoading, setIsLoading] = useState(true) - const timeRef = useRef<NodeJS.Timeout>() + const timeRef = useRef<number>() const [errMsg, setErrMsg] = useState('') const renderFlowchart = async (PrimitiveCode: string) => { @@ -74,15 +74,15 @@ const Flowchart = React.forwardRef((props: { return } if (timeRef.current) - clearTimeout(timeRef.current) + window.clearTimeout(timeRef.current) - timeRef.current = setTimeout(() => { + timeRef.current = window.setTimeout(() => { renderFlowchart(props.PrimitiveCode) }, 300) }, [props.PrimitiveCode]) return ( - // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // eslint-disable-next-line ts/ban-ts-comment // @ts-expect-error <div ref={ref}> { @@ -108,4 +108,6 @@ const Flowchart = React.forwardRef((props: { ) }) +Flowchart.displayName = 'Flowchart' + export default Flowchart diff --git a/web/app/components/base/popover/index.tsx b/web/app/components/base/popover/index.tsx index 1e7ba76269..8dd20efd7c 100644 --- a/web/app/components/base/popover/index.tsx +++ b/web/app/components/base/popover/index.tsx @@ -34,15 +34,15 @@ export default function CustomPopover({ disabled = false, }: IPopover) { const buttonRef = useRef<HTMLButtonElement>(null) - const timeOutRef = useRef<NodeJS.Timeout | null>(null) + const timeOutRef = useRef<number | null>(null) const onMouseEnter = (isOpen: boolean) => { - timeOutRef.current && clearTimeout(timeOutRef.current) + timeOutRef.current && window.clearTimeout(timeOutRef.current) !isOpen && buttonRef.current?.click() } const onMouseLeave = (isOpen: boolean) => { - timeOutRef.current = setTimeout(() => { + timeOutRef.current = window.setTimeout(() => { isOpen && buttonRef.current?.click() }, timeoutDuration) } diff --git a/web/app/components/base/prompt-editor/plugins/custom-text/node.tsx b/web/app/components/base/prompt-editor/plugins/custom-text/node.tsx index 5df4894c6b..49f4a056db 100644 --- a/web/app/components/base/prompt-editor/plugins/custom-text/node.tsx +++ b/web/app/components/base/prompt-editor/plugins/custom-text/node.tsx @@ -1,4 +1,4 @@ -import type { EditorConfig, NodeKey, SerializedTextNode } from 'lexical' +import type { EditorConfig, SerializedTextNode } from 'lexical' import { $createTextNode, TextNode } from 'lexical' export class CustomTextNode extends TextNode { @@ -10,9 +10,9 @@ export class CustomTextNode extends TextNode { return new CustomTextNode(node.__text, node.__key) } - constructor(text: string, key?: NodeKey) { - super(text, key) - } + // constructor(text: string, key?: NodeKey) { + // super(text, key) + // } createDOM(config: EditorConfig) { const dom = super.createDOM(config) diff --git a/web/app/components/base/prompt-editor/plugins/variable-value-block/node.tsx b/web/app/components/base/prompt-editor/plugins/variable-value-block/node.tsx index 163d4bfac4..34487b257c 100644 --- a/web/app/components/base/prompt-editor/plugins/variable-value-block/node.tsx +++ b/web/app/components/base/prompt-editor/plugins/variable-value-block/node.tsx @@ -1,7 +1,6 @@ import type { EditorConfig, LexicalNode, - NodeKey, SerializedTextNode, } from 'lexical' import { @@ -18,9 +17,9 @@ export class VariableValueBlockNode extends TextNode { return new VariableValueBlockNode(node.__text, node.__key) } - constructor(text: string, key?: NodeKey) { - super(text, key) - } + // constructor(text: string, key?: NodeKey) { + // super(text, key) + // } createDOM(config: EditorConfig): HTMLElement { const element = super.createDOM(config) diff --git a/web/app/components/base/tag-management/index.tsx b/web/app/components/base/tag-management/index.tsx index 9a747910d2..5921d3da31 100644 --- a/web/app/components/base/tag-management/index.tsx +++ b/web/app/components/base/tag-management/index.tsx @@ -30,7 +30,7 @@ const TagManagementModal = ({ show, type }: TagManagementModalProps) => { setTagList(res) } - const [pending, setPending] = useState<Boolean>(false) + const [pending, setPending] = useState<boolean>(false) const [name, setName] = useState<string>('') const createNewTag = async () => { if (!name) diff --git a/web/app/components/base/tag-management/selector.tsx b/web/app/components/base/tag-management/selector.tsx index fd271a82e8..fca8ba1859 100644 --- a/web/app/components/base/tag-management/selector.tsx +++ b/web/app/components/base/tag-management/selector.tsx @@ -54,7 +54,7 @@ const Panel = (props: PanelProps) => { return tagList.filter(tag => tag.type === type && !value.includes(tag.id) && tag.name.includes(keywords)) }, [type, tagList, value, keywords]) - const [creating, setCreating] = useState<Boolean>(false) + const [creating, setCreating] = useState<boolean>(false) const createNewTag = async () => { if (!keywords) return diff --git a/web/app/components/base/tag-management/tag-item-editor.tsx b/web/app/components/base/tag-management/tag-item-editor.tsx index 3735695302..0605f28cf6 100644 --- a/web/app/components/base/tag-management/tag-item-editor.tsx +++ b/web/app/components/base/tag-management/tag-item-editor.tsx @@ -78,7 +78,7 @@ const TagItemEditor: FC<TagItemEditorProps> = ({ } } const [showRemoveModal, setShowRemoveModal] = useState(false) - const [pending, setPending] = useState<Boolean>(false) + const [pending, setPending] = useState<boolean>(false) const removeTag = async (tagID: string) => { if (pending) return diff --git a/web/app/components/datasets/create/step-one/index.tsx b/web/app/components/datasets/create/step-one/index.tsx index 643932e9ae..7450e7f618 100644 --- a/web/app/components/datasets/create/step-one/index.tsx +++ b/web/app/components/datasets/create/step-one/index.tsx @@ -21,7 +21,7 @@ import VectorSpaceFull from '@/app/components/billing/vector-space-full' type IStepOneProps = { datasetId?: string dataSourceType?: DataSourceType - dataSourceTypeDisable: Boolean + dataSourceTypeDisable: boolean hasConnection: boolean onSetting: () => void files: FileItem[] diff --git a/web/app/components/datasets/create/step-two/index.tsx b/web/app/components/datasets/create/step-two/index.tsx index 5d92e30deb..047caec78d 100644 --- a/web/app/components/datasets/create/step-two/index.tsx +++ b/web/app/components/datasets/create/step-two/index.tsx @@ -28,7 +28,7 @@ import Loading from '@/app/components/base/loading' import FloatRightContainer from '@/app/components/base/float-right-container' import RetrievalMethodConfig from '@/app/components/datasets/common/retrieval-method-config' import EconomicalRetrievalMethodConfig from '@/app/components/datasets/common/economical-retrieval-method-config' -import { type RetrievalConfig } from '@/types/app' +import type { RetrievalConfig } from '@/types/app' import { ensureRerankModelSelected, isReRankModelSelected } from '@/app/components/datasets/common/check-rerank-model' import Toast from '@/app/components/base/toast' import { formatNumber } from '@/utils/format' @@ -202,7 +202,7 @@ const StepTwo = ({ } const fetchFileIndexingEstimate = async (docForm = DocForm.TEXT, language?: string) => { - // eslint-disable-next-line @typescript-eslint/no-use-before-define + // eslint-disable-next-line ts/no-use-before-define const res = await didFetchFileIndexingEstimate(getFileIndexingEstimateParams(docForm, language)!) if (segmentationType === SegmentType.CUSTOM) setCustomFileIndexingEstimate(res) @@ -344,7 +344,7 @@ const StepTwo = ({ doc_form: docForm, doc_language: docLanguage, process_rule: getProcessRule(), - // eslint-disable-next-line @typescript-eslint/no-use-before-define + // eslint-disable-next-line ts/no-use-before-define retrieval_model: retrievalConfig, // Readonly. If want to changed, just go to settings page. embedding_model: embeddingModel.model, // Readonly embedding_model_provider: embeddingModel.provider, // Readonly @@ -357,7 +357,7 @@ const StepTwo = ({ rerankDefaultModel, isRerankDefaultModelValid: !!isRerankDefaultModelValid, rerankModelList, - // eslint-disable-next-line @typescript-eslint/no-use-before-define + // eslint-disable-next-line ts/no-use-before-define retrievalConfig, indexMethod: indexMethod as string, }) @@ -367,7 +367,7 @@ const StepTwo = ({ } const postRetrievalConfig = ensureRerankModelSelected({ rerankDefaultModel: rerankDefaultModel!, - // eslint-disable-next-line @typescript-eslint/no-use-before-define + // eslint-disable-next-line ts/no-use-before-define retrievalConfig, indexMethod: indexMethod as string, }) diff --git a/web/app/components/datasets/external-api/external-api-modal/Form.tsx b/web/app/components/datasets/external-api/external-api-modal/Form.tsx index ada01493fe..824b5e6c9e 100644 --- a/web/app/components/datasets/external-api/external-api-modal/Form.tsx +++ b/web/app/components/datasets/external-api/external-api-modal/Form.tsx @@ -87,4 +87,6 @@ const Form: FC<FormProps> = React.memo(({ ) }) +Form.displayName = 'Form' + export default Form diff --git a/web/app/components/datasets/settings/form/index.tsx b/web/app/components/datasets/settings/form/index.tsx index fa8c8de62e..4039873080 100644 --- a/web/app/components/datasets/settings/form/index.tsx +++ b/web/app/components/datasets/settings/form/index.tsx @@ -18,7 +18,7 @@ import { ApiConnectionMod } from '@/app/components/base/icons/src/vender/solid/d import { updateDatasetSetting } from '@/service/datasets' import type { DataSetListResponse } from '@/models/datasets' import DatasetDetailContext from '@/context/dataset-detail' -import { type RetrievalConfig } from '@/types/app' +import type { RetrievalConfig } from '@/types/app' import { useAppContext } from '@/context/app-context' import { ensureRerankModelSelected, isReRankModelSelected } from '@/app/components/datasets/common/check-rerank-model' import ModelSelector from '@/app/components/header/account-setting/model-provider-page/model-selector' diff --git a/web/app/components/header/app-nav/index.tsx b/web/app/components/header/app-nav/index.tsx index d4dd9e3ffd..3ac57926e9 100644 --- a/web/app/components/header/app-nav/index.tsx +++ b/web/app/components/header/app-nav/index.tsx @@ -11,7 +11,7 @@ import { RiRobot2Line, } from '@remixicon/react' import Nav from '../nav' -import { type NavItem } from '../nav/nav-selector' +import type { NavItem } from '../nav/nav-selector' import { fetchAppList } from '@/service/apps' import CreateAppTemplateDialog from '@/app/components/app/create-app-dialog' import CreateAppModal from '@/app/components/app/create-app-modal' diff --git a/web/app/components/share/text-generation/index.tsx b/web/app/components/share/text-generation/index.tsx index a2f6864242..61927e3ff3 100644 --- a/web/app/components/share/text-generation/index.tsx +++ b/web/app/components/share/text-generation/index.tsx @@ -132,9 +132,9 @@ const TextGeneration: FC<IMainProps> = ({ const handleSend = () => { setIsCallBatchAPI(false) setControlSend(Date.now()) - // eslint-disable-next-line @typescript-eslint/no-use-before-define + // eslint-disable-next-line ts/no-use-before-define setAllTaskList([]) // clear batch task running status - // eslint-disable-next-line @typescript-eslint/no-use-before-define + // eslint-disable-next-line ts/no-use-before-define showResSidebar() } @@ -314,7 +314,7 @@ const TextGeneration: FC<IMainProps> = ({ setControlSend(Date.now()) // clear run once task status setControlStopResponding(Date.now()) - // eslint-disable-next-line @typescript-eslint/no-use-before-define + // eslint-disable-next-line ts/no-use-before-define showResSidebar() } const handleCompleted = (completionRes: string, taskId?: number, isSuccess?: boolean) => { diff --git a/web/app/components/tools/workflow-tool/index.tsx b/web/app/components/tools/workflow-tool/index.tsx index 54751a384a..efd01255cf 100644 --- a/web/app/components/tools/workflow-tool/index.tsx +++ b/web/app/components/tools/workflow-tool/index.tsx @@ -37,7 +37,7 @@ const WorkflowToolAsModal: FC<Props> = ({ }) => { const { t } = useTranslation() - const [showEmojiPicker, setShowEmojiPicker] = useState<Boolean>(false) + const [showEmojiPicker, setShowEmojiPicker] = useState<boolean>(false) const [emoji, setEmoji] = useState<Emoji>(payload.icon) const [label, setLabel] = useState<string>(payload.label) const [name, setName] = useState(payload.name) diff --git a/web/app/components/workflow/nodes/_base/components/variable/utils.ts b/web/app/components/workflow/nodes/_base/components/variable/utils.ts index 89ba4e5cf9..dacd16f735 100644 --- a/web/app/components/workflow/nodes/_base/components/variable/utils.ts +++ b/web/app/components/workflow/nodes/_base/components/variable/utils.ts @@ -582,7 +582,7 @@ export const getNodeUsedVars = (node: Node): ValueSelector[] => { break } case BlockEnum.LLM: { - const payload = (data as LLMNodeType) + const payload = data as LLMNodeType const isChatModel = payload.model?.mode === 'chat' let prompts: string[] = [] if (isChatModel) { @@ -620,19 +620,19 @@ export const getNodeUsedVars = (node: Node): ValueSelector[] => { break } case BlockEnum.QuestionClassifier: { - const payload = (data as QuestionClassifierNodeType) + const payload = data as QuestionClassifierNodeType res = [payload.query_variable_selector] const varInInstructions = matchNotSystemVars([payload.instruction || '']) res.push(...varInInstructions) break } case BlockEnum.HttpRequest: { - const payload = (data as HttpNodeType) + const payload = data as HttpNodeType res = matchNotSystemVars([payload.url, payload.headers, payload.params, payload.body.data]) break } case BlockEnum.Tool: { - const payload = (data as ToolNodeType) + const payload = data as ToolNodeType const mixVars = matchNotSystemVars(Object.keys(payload.tool_parameters)?.filter(key => payload.tool_parameters[key].type === ToolVarType.mixed).map(key => payload.tool_parameters[key].value) as string[]) const vars = Object.keys(payload.tool_parameters).filter(key => payload.tool_parameters[key].type === ToolVarType.variable).map(key => payload.tool_parameters[key].value as string) || [] res = [...(mixVars as ValueSelector[]), ...(vars as any)] @@ -650,7 +650,7 @@ export const getNodeUsedVars = (node: Node): ValueSelector[] => { } case BlockEnum.ParameterExtractor: { - const payload = (data as ParameterExtractorNodeType) + const payload = data as ParameterExtractorNodeType res = [payload.query] const varInInstructions = matchNotSystemVars([payload.instruction || '']) res.push(...varInInstructions) @@ -672,7 +672,7 @@ export const getNodeUsedVarPassToServerKey = (node: Node, valueSelector: ValueSe let res: string | string[] = '' switch (type) { case BlockEnum.LLM: { - const payload = (data as LLMNodeType) + const payload = data as LLMNodeType res = [`#${valueSelector.join('.')}#`] if (payload.context?.variable_selector.join('.') === valueSelector.join('.')) res.push('#context#') diff --git a/web/app/components/workflow/nodes/_base/components/variable/var-reference-vars.tsx b/web/app/components/workflow/nodes/_base/components/variable/var-reference-vars.tsx index fdd37d0518..43424aa936 100644 --- a/web/app/components/workflow/nodes/_base/components/variable/var-reference-vars.tsx +++ b/web/app/components/workflow/nodes/_base/components/variable/var-reference-vars.tsx @@ -127,7 +127,7 @@ const Item: FC<ItemProps> = ({ zIndex: 100, }}> {isObj && ( - // eslint-disable-next-line @typescript-eslint/no-use-before-define + // eslint-disable-next-line ts/no-use-before-define <ObjectChildren nodeId={nodeId} title={title} diff --git a/web/app/components/workflow/nodes/_base/hooks/use-one-step-run.ts b/web/app/components/workflow/nodes/_base/hooks/use-one-step-run.ts index 0a6a7a9c1b..31277e99fb 100644 --- a/web/app/components/workflow/nodes/_base/hooks/use-one-step-run.ts +++ b/web/app/components/workflow/nodes/_base/hooks/use-one-step-run.ts @@ -42,6 +42,7 @@ const { checkValid: checkVariableAssignerValid } = VariableAssigner const { checkValid: checkParameterExtractorValid } = ParameterExtractorDefault const { checkValid: checkIterationValid } = IterationDefault +// eslint-disable-next-line ts/no-unsafe-function-type const checkValidFns: Record<BlockEnum, Function> = { [BlockEnum.LLM]: checkLLMValid, [BlockEnum.KnowledgeRetrieval]: checkKnowledgeRetrievalValid, diff --git a/web/app/components/workflow/nodes/_base/hooks/use-output-var-list.ts b/web/app/components/workflow/nodes/_base/hooks/use-output-var-list.ts index c7bce2ef07..f0cb80bbc4 100644 --- a/web/app/components/workflow/nodes/_base/hooks/use-output-var-list.ts +++ b/web/app/components/workflow/nodes/_base/hooks/use-output-var-list.ts @@ -1,7 +1,7 @@ import { useCallback, useState } from 'react' import produce from 'immer' import { useBoolean } from 'ahooks' -import { type OutputVar } from '../../code/types' +import type { OutputVar } from '../../code/types' import type { ValueSelector } from '@/app/components/workflow/types' import { VarType } from '@/app/components/workflow/types' import { diff --git a/web/app/components/workflow/nodes/assigner/node.tsx b/web/app/components/workflow/nodes/assigner/node.tsx index 72745a488a..e95c1dcc27 100644 --- a/web/app/components/workflow/nodes/assigner/node.tsx +++ b/web/app/components/workflow/nodes/assigner/node.tsx @@ -3,7 +3,7 @@ import React from 'react' import { useNodes } from 'reactflow' import { useTranslation } from 'react-i18next' import NodeVariableItem from '../variable-assigner/components/node-variable-item' -import { type AssignerNodeType } from './types' +import type { AssignerNodeType } from './types' import { isConversationVar, isENV, isSystemVar } from '@/app/components/workflow/nodes/_base/components/variable/utils' import { BlockEnum, type Node, type NodeProps } from '@/app/components/workflow/types' diff --git a/web/app/components/workflow/nodes/assigner/panel.tsx b/web/app/components/workflow/nodes/assigner/panel.tsx index ff5a6420f3..213f9a05e7 100644 --- a/web/app/components/workflow/nodes/assigner/panel.tsx +++ b/web/app/components/workflow/nodes/assigner/panel.tsx @@ -8,7 +8,7 @@ import useConfig from './use-config' import { WriteMode } from './types' import type { AssignerNodeType } from './types' import Field from '@/app/components/workflow/nodes/_base/components/field' -import { type NodePanelProps } from '@/app/components/workflow/types' +import type { NodePanelProps } from '@/app/components/workflow/types' import cn from '@/utils/classnames' const i18nPrefix = 'workflow.nodes.assigner' diff --git a/web/app/components/workflow/nodes/end/default.ts b/web/app/components/workflow/nodes/end/default.ts index ceeda5b43b..d144a079cf 100644 --- a/web/app/components/workflow/nodes/end/default.ts +++ b/web/app/components/workflow/nodes/end/default.ts @@ -1,6 +1,6 @@ import { BlockEnum } from '../../types' import type { NodeDefault } from '../../types' -import { type EndNodeType } from './types' +import type { EndNodeType } from './types' import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/constants' const nodeDefault: NodeDefault<EndNodeType> = { diff --git a/web/app/components/workflow/nodes/end/panel.tsx b/web/app/components/workflow/nodes/end/panel.tsx index a74ba51b6d..fc5e498d13 100644 --- a/web/app/components/workflow/nodes/end/panel.tsx +++ b/web/app/components/workflow/nodes/end/panel.tsx @@ -1,4 +1,4 @@ -import { type FC } from 'react' +import type { FC } from 'react' import React from 'react' import { useTranslation } from 'react-i18next' import useConfig from './use-config' @@ -6,7 +6,7 @@ import type { EndNodeType } from './types' import VarList from '@/app/components/workflow/nodes/_base/components/variable/var-list' import Field from '@/app/components/workflow/nodes/_base/components/field' import AddButton from '@/app/components/base/button/add-button' -import { type NodePanelProps } from '@/app/components/workflow/types' +import type { NodePanelProps } from '@/app/components/workflow/types' const i18nPrefix = 'workflow.nodes.end' diff --git a/web/app/components/workflow/nodes/http/components/edit-body/index.tsx b/web/app/components/workflow/nodes/http/components/edit-body/index.tsx index 6e8f4eac3b..3b8306199a 100644 --- a/web/app/components/workflow/nodes/http/components/edit-body/index.tsx +++ b/web/app/components/workflow/nodes/http/components/edit-body/index.tsx @@ -54,7 +54,7 @@ const EditBody: FC<Props> = ({ type: newType, data: '', }) - // eslint-disable-next-line @typescript-eslint/no-use-before-define + // eslint-disable-next-line ts/no-use-before-define setBody([]) // eslint-disable-next-line react-hooks/exhaustive-deps }, [onChange]) diff --git a/web/app/components/workflow/nodes/tool/use-config.ts b/web/app/components/workflow/nodes/tool/use-config.ts index df8ad47985..2d603c99e5 100644 --- a/web/app/components/workflow/nodes/tool/use-config.ts +++ b/web/app/components/workflow/nodes/tool/use-config.ts @@ -162,7 +162,7 @@ const useConfig = (id: string, payload: ToolNodeType) => { const [inputVarValues, doSetInputVarValues] = useState<Record<string, any>>({}) const setInputVarValues = (value: Record<string, any>) => { doSetInputVarValues(value) - // eslint-disable-next-line @typescript-eslint/no-use-before-define + // eslint-disable-next-line ts/no-use-before-define setRunInputData(value) } // fill single run form variable with constant value first time diff --git a/web/app/components/workflow/nodes/variable-assigner/panel.tsx b/web/app/components/workflow/nodes/variable-assigner/panel.tsx index 6152e0f5b8..b25e2656ed 100644 --- a/web/app/components/workflow/nodes/variable-assigner/panel.tsx +++ b/web/app/components/workflow/nodes/variable-assigner/panel.tsx @@ -7,7 +7,7 @@ import useConfig from './use-config' import type { VariableAssignerNodeType } from './types' import VarGroupItem from './components/var-group-item' import cn from '@/utils/classnames' -import { type NodePanelProps } from '@/app/components/workflow/types' +import type { NodePanelProps } from '@/app/components/workflow/types' import Split from '@/app/components/workflow/nodes/_base/components/split' import OutputVars, { VarItem } from '@/app/components/workflow/nodes/_base/components/output-vars' import Switch from '@/app/components/base/switch' diff --git a/web/app/signin/_header.tsx b/web/app/signin/_header.tsx index a9479a3fe4..9d03f18ac4 100644 --- a/web/app/signin/_header.tsx +++ b/web/app/signin/_header.tsx @@ -3,7 +3,7 @@ import React from 'react' import { useContext } from 'use-context-selector' import Select from '@/app/components/base/select/locale' import { languages } from '@/i18n/language' -import { type Locale } from '@/i18n' +import type { Locale } from '@/i18n' import I18n from '@/context/i18n' import LogoSite from '@/app/components/base/logo/logo-site' diff --git a/web/context/modal-context.tsx b/web/context/modal-context.tsx index 727268a29a..813f811a28 100644 --- a/web/context/modal-context.tsx +++ b/web/context/modal-context.tsx @@ -78,7 +78,6 @@ export const useModalContext = () => useContext(ModalContext) // Adding a dangling comma to avoid the generic parsing issue in tsx, see: // https://github.com/microsoft/TypeScript/issues/15713 -// eslint-disable-next-line @typescript-eslint/comma-dangle export const useModalContextSelector = <T,>(selector: (state: ModalContextState) => T): T => useContextSelector(ModalContext, selector) diff --git a/web/context/provider-context.tsx b/web/context/provider-context.tsx index 75747ba79c..814792ef0e 100644 --- a/web/context/provider-context.tsx +++ b/web/context/provider-context.tsx @@ -70,7 +70,6 @@ export const useProviderContext = () => useContext(ProviderContext) // Adding a dangling comma to avoid the generic parsing issue in tsx, see: // https://github.com/microsoft/TypeScript/issues/15713 -// eslint-disable-next-line @typescript-eslint/comma-dangle export const useProviderContextSelector = <T,>(selector: (state: ProviderContextState) => T): T => useContextSelector(ProviderContext, selector) diff --git a/web/i18n/hi-IN/share-app.ts b/web/i18n/hi-IN/share-app.ts index a5c7816fe2..74c23f8fda 100644 --- a/web/i18n/hi-IN/share-app.ts +++ b/web/i18n/hi-IN/share-app.ts @@ -3,6 +3,8 @@ const translation = { welcome: 'आपका स्वागत है', appUnavailable: 'ऐप उपलब्ध नहीं है', appUnknownError: 'अज्ञात त्रुटि, कृपया पुनः प्रयास करें', + // @ts-expect-error TODO: fix this + // eslint-disable-next-line no-dupe-keys appUnknownError: 'ऐप अनुपलब्ध है', }, chat: { diff --git a/web/service/base.ts b/web/service/base.ts index fbdd5c1fd3..f43a23df52 100644 --- a/web/service/base.ts +++ b/web/service/base.ts @@ -559,7 +559,8 @@ export const ssePost = ( } onData?.(str, isFirstMessage, moreInfo) }, onCompleted, onThought, onMessageEnd, onMessageReplace, onFile, onWorkflowStarted, onWorkflowFinished, onNodeStarted, onNodeFinished, onIterationStart, onIterationNext, onIterationFinish, onParallelBranchStarted, onParallelBranchFinished, onTextChunk, onTTSChunk, onTTSEnd, onTextReplace) - }).catch((e) => { + }) + .catch((e) => { if (e.toString() !== 'AbortError: The user aborted a request.' && !e.toString().errorMessage.includes('TypeError: Cannot assign to read only property')) Toast.notify({ type: 'error', message: e }) onError?.(e) From cff9adaf8ed5f15b28e40f9942fb1bd045dea264 Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Tue, 22 Oct 2024 11:06:28 +0800 Subject: [PATCH 120/346] chore: tools ts problems --- web/app/components/workflow/block-selector/tools.tsx | 9 +++++---- web/pnpm-lock.yaml | 8 ++++---- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/web/app/components/workflow/block-selector/tools.tsx b/web/app/components/workflow/block-selector/tools.tsx index 326ad1fde6..a40d2e40c4 100644 --- a/web/app/components/workflow/block-selector/tools.tsx +++ b/web/app/components/workflow/block-selector/tools.tsx @@ -12,6 +12,7 @@ import ToolItem from './tool-item' import { ViewType } from './view-type-select' import Empty from '@/app/components/tools/add-tool-modal/empty' import { useGetLanguage } from '@/context/i18n' +import cn from '@/utils/classnames' type ToolsProps = { showWorkflowEmpty: boolean @@ -30,7 +31,7 @@ const Blocks = ({ const isListView = viewType === ViewType.list const isTreeView = viewType === ViewType.tree - const { letters, groups: groupedTools } = groupItems(tools, tool => tool.label[language][0]) + const { letters, groups: groupedTools } = groupItems(tools, tool => (tool as any).label[language][0]) const toolRefs = useRef({}) const renderGroup = useCallback((toolWithProvider: ToolWithProvider) => { @@ -50,7 +51,7 @@ const Blocks = ({ list.map(tool => ( <ToolItem key={tool.name} - className={isListView && 'mr-6'} + className={cn(isListView && 'mr-6')} isToolPlugin={toolWithProvider.type === CollectionType.builtIn} provider={toolWithProvider} payload={tool} @@ -62,12 +63,12 @@ const Blocks = ({ ) }, [onSelect, language]) - const renderLetterGroup = (letter) => { + const renderLetterGroup = (letter: string) => { const tools = groupedTools[letter] return ( <div key={letter} - ref={el => (toolRefs.current[letter] = el)} + ref={el => ((toolRefs as any).current[letter] = el) as any} > {tools.map(renderGroup)} </div> diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index 3aeb8f080c..9bf9e9870d 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -53,7 +53,7 @@ importers: specifier: ^14.0.4 version: 14.2.15(@mdx-js/loader@2.3.0(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3)))(@mdx-js/react@2.3.0(react@18.2.0)) '@remixicon/react': - specifier: ^4.2.0 + specifier: ^4.3.0 version: 4.3.0(react@18.2.0) '@sentry/react': specifier: ^7.54.0 @@ -12873,7 +12873,7 @@ snapshots: debug: 4.3.7 enhanced-resolve: 5.17.1 eslint: 9.13.0(jiti@1.21.6) - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@4.3.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-plugin-import@2.31.0)(eslint@9.13.0(jiti@1.21.6)))(eslint@9.13.0(jiti@1.21.6)) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.13.0(jiti@1.21.6)) fast-glob: 3.3.2 get-tsconfig: 4.8.1 is-bun-module: 1.2.1 @@ -12891,7 +12891,7 @@ snapshots: dependencies: eslint: 9.13.0(jiti@1.21.6) - eslint-module-utils@2.12.0(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@4.3.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-plugin-import@2.31.0)(eslint@9.13.0(jiti@1.21.6)))(eslint@9.13.0(jiti@1.21.6)): + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.13.0(jiti@1.21.6)): dependencies: debug: 3.2.7 optionalDependencies: @@ -12947,7 +12947,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.13.0(jiti@1.21.6) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@4.3.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-plugin-import@2.31.0)(eslint@9.13.0(jiti@1.21.6)))(eslint@9.13.0(jiti@1.21.6)) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.13.0(jiti@1.21.6)) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3 From 67d02212b4c82e1182f75c76ca59a99d93d7e647 Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Tue, 22 Oct 2024 11:18:30 +0800 Subject: [PATCH 121/346] chore: pnpm --- web/pnpm-lock.yaml | 351 +++++++++++++++++++-------------------------- 1 file changed, 148 insertions(+), 203 deletions(-) diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index 9bf9e9870d..600e7061c4 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -265,7 +265,7 @@ importers: devDependencies: '@antfu/eslint-config': specifier: ^3.8.0 - version: 3.8.0(@eslint-react/eslint-plugin@1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(@typescript-eslint/utils@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(@vue/compiler-sfc@3.5.12)(eslint-plugin-react-hooks@5.0.0(eslint@9.13.0(jiti@1.21.6)))(eslint-plugin-react-refresh@0.4.13(eslint@9.13.0(jiti@1.21.6)))(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + version: 3.8.0(@eslint-react/eslint-plugin@1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(@typescript-eslint/utils@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(@vue/compiler-sfc@3.5.12)(eslint-plugin-react-hooks@5.0.0(eslint@9.13.0(jiti@1.21.6)))(eslint-plugin-react-refresh@0.4.13(eslint@9.13.0(jiti@1.21.6)))(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) '@chromatic-com/storybook': specifier: ^1.9.0 version: 1.9.0(react@18.2.0) @@ -388,7 +388,7 @@ importers: version: 9.13.0(jiti@1.21.6) eslint-config-next: specifier: ^15.0.0-canary.202 - version: 15.0.0-rc.1(eslint-plugin-import-x@4.3.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + version: 15.0.0(eslint-plugin-import-x@4.3.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) eslint-plugin-react-hooks: specifier: ^5.0.0 version: 5.0.0(eslint@9.13.0(jiti@1.21.6)) @@ -1782,8 +1782,8 @@ packages: '@next/env@14.2.15': resolution: {integrity: sha512-S1qaj25Wru2dUpcIZMjxeMVSwkt8BK4dmWHHiBuRstcIyOsMapqT4A4jSB6onvqeygkSSmOkyny9VVx8JIGamQ==} - '@next/eslint-plugin-next@15.0.0-rc.1': - resolution: {integrity: sha512-Nz/tMHzuGPYR0uK57+mxLhVFDTKtCK8HeVnPmDp/L1nrgcgICFZUCYHnKDUM9IUQ1XalzYhrLOlizOadpOosIQ==} + '@next/eslint-plugin-next@15.0.0': + resolution: {integrity: sha512-UG/Gnsq6Sc4wRhO9qk+vc/2v4OfRXH7GEH6/TGlNF5eU/vI9PIO7q+kgd65X2DxJ+qIpHWpzWwlPLmqMi1FE9A==} '@next/mdx@14.2.15': resolution: {integrity: sha512-OQWxKY5jWtHqPXdN3s5mj/LsD57pxt8CQsY4VQtTfQdQn6rNPd1bjN+kpbtezXdjgrKhvTJAb1yv1XGvzlh0uw==} @@ -2610,8 +2610,8 @@ packages: '@types/node@18.15.0': resolution: {integrity: sha512-z6nr0TTEOBGkzLGmbypWOGnpSpSIBorEhC4L+4HeQ2iezKCi4f77kyslRwvHeNitymGQ+oFyIWGP96l/DPSV9w==} - '@types/node@22.7.7': - resolution: {integrity: sha512-SRxCrrg9CL/y54aiMCG3edPKdprgMVGDXjA3gB8UmmBW5TcXzRUYAh8EWzTnSJFAd1rgImPELza+A3bJ+qxz8Q==} + '@types/node@22.7.8': + resolution: {integrity: sha512-a922jJy31vqR5sk+kAdIENJjHblqcZ4RmERviFsER4WJcEONqxKcjNOlk0q7OUfrF5sddT+vng070cdfMlrPLg==} '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} @@ -2691,8 +2691,8 @@ packages: '@types/yargs@17.0.33': resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==} - '@typescript-eslint/eslint-plugin@8.10.0': - resolution: {integrity: sha512-phuB3hoP7FFKbRXxjl+DRlQDuJqhpOnm5MmtROXyWi3uS/Xg2ZXqiQfcG2BJHiN4QKyzdOJi3NEn/qTnjUlkmQ==} + '@typescript-eslint/eslint-plugin@8.11.0': + resolution: {integrity: sha512-KhGn2LjW1PJT2A/GfDpiyOfS4a8xHQv2myUagTM5+zsormOmBlYsnQ6pobJ8XxJmh6hnHwa2Mbe3fPrDJoDhbA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 @@ -2702,8 +2702,8 @@ packages: typescript: optional: true - '@typescript-eslint/parser@8.10.0': - resolution: {integrity: sha512-E24l90SxuJhytWJ0pTQydFT46Nk0Z+bsLKo/L8rtQSL93rQ6byd1V/QbDpHUTdLPOMsBCcYXZweADNCfOCmOAg==} + '@typescript-eslint/parser@8.11.0': + resolution: {integrity: sha512-lmt73NeHdy1Q/2ul295Qy3uninSqi6wQI18XwSpm8w0ZbQXUpjCAWP1Vlv/obudoBiIjJVjlztjQ+d/Md98Yxg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -2716,12 +2716,12 @@ packages: resolution: {integrity: sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - '@typescript-eslint/scope-manager@8.10.0': - resolution: {integrity: sha512-AgCaEjhfql9MDKjMUxWvH7HjLeBqMCBfIaBbzzIcBbQPZE7CPh1m6FF+L75NUMJFMLYhCywJXIDEMa3//1A0dw==} + '@typescript-eslint/scope-manager@8.11.0': + resolution: {integrity: sha512-Uholz7tWhXmA4r6epo+vaeV7yjdKy5QFCERMjs1kMVsLRKIrSdM6o21W2He9ftp5PP6aWOVpD5zvrvuHZC0bMQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/type-utils@8.10.0': - resolution: {integrity: sha512-PCpUOpyQSpxBn230yIcK+LeCQaXuxrgCm2Zk1S+PTIRJsEfU6nJ0TtwyH8pIwPK/vJoA+7TZtzyAJSGBz+s/dg==} + '@typescript-eslint/type-utils@8.11.0': + resolution: {integrity: sha512-ItiMfJS6pQU0NIKAaybBKkuVzo6IdnAhPFZA/2Mba/uBjuPQPet/8+zh5GtLHwmuFRShZx+8lhIs7/QeDHflOg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '*' @@ -2733,8 +2733,8 @@ packages: resolution: {integrity: sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - '@typescript-eslint/types@8.10.0': - resolution: {integrity: sha512-k/E48uzsfJCRRbGLapdZgrX52csmWJ2rcowwPvOZ8lwPUv3xW6CcFeJAXgx4uJm+Ge4+a4tFOkdYvSpxhRhg1w==} + '@typescript-eslint/types@8.11.0': + resolution: {integrity: sha512-tn6sNMHf6EBAYMvmPUaKaVeYvhUsrE6x+bXQTxjQRp360h1giATU0WvgeEys1spbvb5R+VpNOZ+XJmjD8wOUHw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typescript-eslint/typescript-estree@5.62.0': @@ -2746,8 +2746,8 @@ packages: typescript: optional: true - '@typescript-eslint/typescript-estree@8.10.0': - resolution: {integrity: sha512-3OE0nlcOHaMvQ8Xu5gAfME3/tWVDpb/HxtpUZ1WeOAksZ/h/gwrBzCklaGzwZT97/lBbbxJ16dMA98JMEngW4w==} + '@typescript-eslint/typescript-estree@8.11.0': + resolution: {integrity: sha512-yHC3s1z1RCHoCz5t06gf7jH24rr3vns08XXhfEqzYpd6Hll3z/3g23JRi0jM8A47UFKNc3u/y5KIMx8Ynbjohg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '*' @@ -2761,8 +2761,8 @@ packages: peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - '@typescript-eslint/utils@8.10.0': - resolution: {integrity: sha512-Oq4uZ7JFr9d1ZunE/QKy5egcDRXT/FrS2z/nlxzPua2VHFtmMvFNDvpq1m/hq0ra+T52aUezfcjGRIB7vNJF9w==} + '@typescript-eslint/utils@8.11.0': + resolution: {integrity: sha512-CYiX6WZcbXNJV7UNB4PLDIBtSdRmRI/nb0FMyqHPTQD1rMjA0foPLaPUV39C/MxkTd/QKSeX+Gb34PPsDVC35g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -2771,8 +2771,8 @@ packages: resolution: {integrity: sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - '@typescript-eslint/visitor-keys@8.10.0': - resolution: {integrity: sha512-k8nekgqwr7FadWk548Lfph6V3r9OVqjzAIVskE7orMZR23cGJjAOVazsZSJW+ElyjfTM4wx/1g88Mi70DDtG9A==} + '@typescript-eslint/visitor-keys@8.11.0': + resolution: {integrity: sha512-EaewX6lxSjRJnc+99+dqzTeoDZUfyrA52d2/HRrkI830kgovWsmIiTfmr0NZorzqic7ga+1bS60lRBUgR3n/Bw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@ungap/structured-clone@1.2.0': @@ -3021,9 +3021,6 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - aria-query@5.1.3: - resolution: {integrity: sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==} - aria-query@5.3.0: resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} @@ -3238,8 +3235,8 @@ packages: browserify-zlib@0.2.0: resolution: {integrity: sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==} - browserslist@4.24.0: - resolution: {integrity: sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==} + browserslist@4.24.2: + resolution: {integrity: sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -3372,8 +3369,8 @@ packages: resolution: {integrity: sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==} engines: {node: '>= 14.16.0'} - chromatic@11.12.6: - resolution: {integrity: sha512-lt6ekbx3LFLCwGheQrBZAkP2EhrXLPpESk7t45PrsV1DSpu0KOH2ZMN/G9QiF84ZGwj9RPC8BwWbnb2/kd66uA==} + chromatic@11.14.0: + resolution: {integrity: sha512-qt7xXpdrwssBtXWv30aW46HAK10bF4Ep7SMjtMQhD61Fg4IS9aImT0WFeig7utpXYHOx0eSysjwhz0cgYz9SDg==} hasBin: true peerDependencies: '@chromatic-com/cypress': ^0.*.* || ^1.0.0 @@ -3896,10 +3893,6 @@ packages: resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} engines: {node: '>=6'} - deep-equal@2.2.3: - resolution: {integrity: sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==} - engines: {node: '>= 0.4'} - deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} @@ -4116,9 +4109,6 @@ packages: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} - es-get-iterator@1.1.3: - resolution: {integrity: sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==} - es-iterator-helpers@1.1.0: resolution: {integrity: sha512-/SurEfycdyssORP/E+bj4sEu1CWw4EmLDsHynHwSXQ7utgbrMRWW195pTrCjFgFCddf/UkYm3oqKPRq5i8bJbw==} engines: {node: '>= 0.4'} @@ -4190,8 +4180,8 @@ packages: peerDependencies: eslint: ^9.5.0 - eslint-config-next@15.0.0-rc.1: - resolution: {integrity: sha512-RhOlMP/dWBYBBzYjh6ya4OYSxUhkzsoQmbkLvifZgBflD/XCQ+WUd/D1qdSTI9BBkUEeDZ7GOaN5UaIACkQeRA==} + eslint-config-next@15.0.0: + resolution: {integrity: sha512-HFeTwCR2lFEUWmdB00WZrzaak2CvMvxici38gQknA6Bu2HPizSE4PNFGaFzr5GupjBt+SBJ/E0GIP57ZptOD3g==} peerDependencies: eslint: ^7.23.0 || ^8.0.0 || ^9.0.0 typescript: '>=3.3.1' @@ -4288,8 +4278,8 @@ packages: peerDependencies: eslint: '>=6.0.0' - eslint-plugin-jsx-a11y@6.10.0: - resolution: {integrity: sha512-ySOHvXX8eSN6zz8Bywacm7CvGNhUtdjvqfQDVe6020TUK34Cywkw7m0KsCCk1Qtm9G1FayfTN1/7mMYnYO2Bhg==} + eslint-plugin-jsx-a11y@6.10.1: + resolution: {integrity: sha512-zHByM9WTUMnfsDTafGXRiqxp6lFtNoSOWBY6FonVRn3A+BUwN1L/tdBXT40BcBJi0cZjOGTXZ0eD/rTG9fEJ0g==} engines: {node: '>=4.0'} peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 @@ -7355,10 +7345,6 @@ packages: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} - stop-iteration-iterator@1.0.0: - resolution: {integrity: sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==} - engines: {node: '>= 0.4'} - storybook@8.3.6: resolution: {integrity: sha512-9GVbtej6ZzPRUM7KRQ7848506FfHrUiJGqPuIQdoSJd09EmuEoLjmLAgEOmrHBQKgGYMaM7Vh9GsTLim6vwZTQ==} hasBin: true @@ -8195,16 +8181,16 @@ snapshots: '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 - '@antfu/eslint-config@3.8.0(@eslint-react/eslint-plugin@1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(@typescript-eslint/utils@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(@vue/compiler-sfc@3.5.12)(eslint-plugin-react-hooks@5.0.0(eslint@9.13.0(jiti@1.21.6)))(eslint-plugin-react-refresh@0.4.13(eslint@9.13.0(jiti@1.21.6)))(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5)': + '@antfu/eslint-config@3.8.0(@eslint-react/eslint-plugin@1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(@typescript-eslint/utils@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(@vue/compiler-sfc@3.5.12)(eslint-plugin-react-hooks@5.0.0(eslint@9.13.0(jiti@1.21.6)))(eslint-plugin-react-refresh@0.4.13(eslint@9.13.0(jiti@1.21.6)))(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5)': dependencies: '@antfu/install-pkg': 0.4.1 '@clack/prompts': 0.7.0 '@eslint-community/eslint-plugin-eslint-comments': 4.4.0(eslint@9.13.0(jiti@1.21.6)) '@eslint/markdown': 6.2.1 '@stylistic/eslint-plugin': 2.9.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) - '@typescript-eslint/eslint-plugin': 8.10.0(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) - '@typescript-eslint/parser': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) - '@vitest/eslint-plugin': 1.1.7(@typescript-eslint/utils@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/eslint-plugin': 8.11.0(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/parser': 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@vitest/eslint-plugin': 1.1.7(@typescript-eslint/utils@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) eslint: 9.13.0(jiti@1.21.6) eslint-config-flat-gitignore: 0.3.0(eslint@9.13.0(jiti@1.21.6)) eslint-flat-config-utils: 0.4.0 @@ -8220,7 +8206,7 @@ snapshots: eslint-plugin-regexp: 2.6.0(eslint@9.13.0(jiti@1.21.6)) eslint-plugin-toml: 0.11.1(eslint@9.13.0(jiti@1.21.6)) eslint-plugin-unicorn: 56.0.0(eslint@9.13.0(jiti@1.21.6)) - eslint-plugin-unused-imports: 4.1.4(@typescript-eslint/eslint-plugin@8.10.0(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint@9.13.0(jiti@1.21.6)) + eslint-plugin-unused-imports: 4.1.4(@typescript-eslint/eslint-plugin@8.11.0(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint@9.13.0(jiti@1.21.6)) eslint-plugin-vue: 9.29.1(eslint@9.13.0(jiti@1.21.6)) eslint-plugin-yml: 1.14.0(eslint@9.13.0(jiti@1.21.6)) eslint-processor-vue-blocks: 0.1.2(@vue/compiler-sfc@3.5.12)(eslint@9.13.0(jiti@1.21.6)) @@ -8301,7 +8287,7 @@ snapshots: dependencies: '@babel/compat-data': 7.25.8 '@babel/helper-validator-option': 7.25.7 - browserslist: 4.24.0 + browserslist: 4.24.2 lru-cache: 5.1.1 semver: 6.3.1 @@ -9077,7 +9063,7 @@ snapshots: '@chromatic-com/storybook@1.9.0(react@18.2.0)': dependencies: - chromatic: 11.12.6 + chromatic: 11.14.0 filesize: 10.1.6 jsonfile: 6.1.0 react-confetti: 6.1.0(react@18.2.0) @@ -9216,9 +9202,9 @@ snapshots: dependencies: '@eslint-react/tools': 1.15.0 '@eslint-react/types': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) - '@typescript-eslint/types': 8.10.0 - '@typescript-eslint/typescript-estree': 8.10.0(typescript@4.9.5) - '@typescript-eslint/utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/types': 8.11.0 + '@typescript-eslint/typescript-estree': 8.11.0(typescript@4.9.5) + '@typescript-eslint/utils': 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) birecord: 0.1.1 string-ts: 2.2.0 ts-pattern: 5.5.0 @@ -9235,10 +9221,10 @@ snapshots: '@eslint-react/tools': 1.15.0 '@eslint-react/types': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) '@eslint-react/var': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) - '@typescript-eslint/scope-manager': 8.10.0 - '@typescript-eslint/type-utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) - '@typescript-eslint/types': 8.10.0 - '@typescript-eslint/utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/scope-manager': 8.11.0 + '@typescript-eslint/type-utils': 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/types': 8.11.0 + '@typescript-eslint/utils': 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) birecord: 0.1.1 short-unique-id: 5.2.0 ts-pattern: 5.5.0 @@ -9252,10 +9238,10 @@ snapshots: '@eslint-react/shared': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) '@eslint-react/tools': 1.15.0 '@eslint-react/types': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) - '@typescript-eslint/scope-manager': 8.10.0 - '@typescript-eslint/type-utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) - '@typescript-eslint/types': 8.10.0 - '@typescript-eslint/utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/scope-manager': 8.11.0 + '@typescript-eslint/type-utils': 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/types': 8.11.0 + '@typescript-eslint/utils': 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) eslint: 9.13.0(jiti@1.21.6) eslint-plugin-react-debug: 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) eslint-plugin-react-dom: 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) @@ -9274,9 +9260,9 @@ snapshots: '@eslint-react/tools': 1.15.0 '@eslint-react/types': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) '@eslint-react/var': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) - '@typescript-eslint/scope-manager': 8.10.0 - '@typescript-eslint/types': 8.10.0 - '@typescript-eslint/utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/scope-manager': 8.11.0 + '@typescript-eslint/types': 8.11.0 + '@typescript-eslint/utils': 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) ts-pattern: 5.5.0 transitivePeerDependencies: - eslint @@ -9286,7 +9272,7 @@ snapshots: '@eslint-react/shared@1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5)': dependencies: '@eslint-react/tools': 1.15.0 - '@typescript-eslint/utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/utils': 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) picomatch: 4.0.2 transitivePeerDependencies: - eslint @@ -9298,8 +9284,8 @@ snapshots: '@eslint-react/types@1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5)': dependencies: '@eslint-react/tools': 1.15.0 - '@typescript-eslint/types': 8.10.0 - '@typescript-eslint/utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/types': 8.11.0 + '@typescript-eslint/utils': 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) transitivePeerDependencies: - eslint - supports-color @@ -9310,9 +9296,9 @@ snapshots: '@eslint-react/ast': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) '@eslint-react/tools': 1.15.0 '@eslint-react/types': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) - '@typescript-eslint/scope-manager': 8.10.0 - '@typescript-eslint/types': 8.10.0 - '@typescript-eslint/utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/scope-manager': 8.11.0 + '@typescript-eslint/types': 8.11.0 + '@typescript-eslint/utils': 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) ts-pattern: 5.5.0 transitivePeerDependencies: - eslint @@ -9911,7 +9897,7 @@ snapshots: '@next/env@14.2.15': {} - '@next/eslint-plugin-next@15.0.0-rc.1': + '@next/eslint-plugin-next@15.0.0': dependencies: fast-glob: 3.3.1 @@ -10341,7 +10327,7 @@ snapshots: '@storybook/builder-webpack5@8.3.6(esbuild@0.23.1)(storybook@8.3.6)(typescript@4.9.5)(uglify-js@3.19.3)': dependencies: '@storybook/core-webpack': 8.3.6(storybook@8.3.6) - '@types/node': 22.7.7 + '@types/node': 22.7.8 '@types/semver': 7.5.8 browser-assert: 1.2.1 case-sensitive-paths-webpack-plugin: 2.4.0 @@ -10384,7 +10370,7 @@ snapshots: '@storybook/core-webpack@8.3.6(storybook@8.3.6)': dependencies: - '@types/node': 22.7.7 + '@types/node': 22.7.8 storybook: 8.3.6 ts-dedent: 2.2.0 @@ -10461,7 +10447,7 @@ snapshots: '@storybook/preset-react-webpack': 8.3.6(@storybook/test@8.3.6(storybook@8.3.6))(esbuild@0.23.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(storybook@8.3.6)(typescript@4.9.5)(uglify-js@3.19.3) '@storybook/react': 8.3.6(@storybook/test@8.3.6(storybook@8.3.6))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(storybook@8.3.6)(typescript@4.9.5) '@storybook/test': 8.3.6(storybook@8.3.6) - '@types/node': 22.7.7 + '@types/node': 22.7.8 '@types/semver': 7.5.8 babel-loader: 9.2.1(@babel/core@7.25.8)(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3)) css-loader: 6.11.0(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3)) @@ -10514,7 +10500,7 @@ snapshots: '@storybook/core-webpack': 8.3.6(storybook@8.3.6) '@storybook/react': 8.3.6(@storybook/test@8.3.6(storybook@8.3.6))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(storybook@8.3.6)(typescript@4.9.5) '@storybook/react-docgen-typescript-plugin': 1.0.6--canary.9.0c3f3b7.0(typescript@4.9.5)(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3)) - '@types/node': 22.7.7 + '@types/node': 22.7.8 '@types/semver': 7.5.8 find-up: 5.0.0 fs-extra: 11.2.0 @@ -10571,7 +10557,7 @@ snapshots: '@storybook/theming': 8.3.6(storybook@8.3.6) '@types/escodegen': 0.0.6 '@types/estree': 0.0.51 - '@types/node': 22.7.7 + '@types/node': 22.7.8 acorn: 7.4.1 acorn-jsx: 5.3.2(acorn@7.4.1) acorn-walk: 7.2.0 @@ -10609,7 +10595,7 @@ snapshots: '@stylistic/eslint-plugin@2.9.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5)': dependencies: - '@typescript-eslint/utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/utils': 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) eslint: 9.13.0(jiti@1.21.6) eslint-visitor-keys: 4.1.0 espree: 10.2.0 @@ -10980,7 +10966,7 @@ snapshots: '@types/node@18.15.0': {} - '@types/node@22.7.7': + '@types/node@22.7.8': dependencies: undici-types: 6.19.8 @@ -11063,14 +11049,14 @@ snapshots: dependencies: '@types/yargs-parser': 21.0.3 - '@typescript-eslint/eslint-plugin@8.10.0(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5)': + '@typescript-eslint/eslint-plugin@8.11.0(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5)': dependencies: '@eslint-community/regexpp': 4.11.1 - '@typescript-eslint/parser': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) - '@typescript-eslint/scope-manager': 8.10.0 - '@typescript-eslint/type-utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) - '@typescript-eslint/utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) - '@typescript-eslint/visitor-keys': 8.10.0 + '@typescript-eslint/parser': 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/scope-manager': 8.11.0 + '@typescript-eslint/type-utils': 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/utils': 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/visitor-keys': 8.11.0 eslint: 9.13.0(jiti@1.21.6) graphemer: 1.4.0 ignore: 5.3.2 @@ -11081,12 +11067,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5)': + '@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5)': dependencies: - '@typescript-eslint/scope-manager': 8.10.0 - '@typescript-eslint/types': 8.10.0 - '@typescript-eslint/typescript-estree': 8.10.0(typescript@4.9.5) - '@typescript-eslint/visitor-keys': 8.10.0 + '@typescript-eslint/scope-manager': 8.11.0 + '@typescript-eslint/types': 8.11.0 + '@typescript-eslint/typescript-estree': 8.11.0(typescript@4.9.5) + '@typescript-eslint/visitor-keys': 8.11.0 debug: 4.3.7 eslint: 9.13.0(jiti@1.21.6) optionalDependencies: @@ -11099,15 +11085,15 @@ snapshots: '@typescript-eslint/types': 5.62.0 '@typescript-eslint/visitor-keys': 5.62.0 - '@typescript-eslint/scope-manager@8.10.0': + '@typescript-eslint/scope-manager@8.11.0': dependencies: - '@typescript-eslint/types': 8.10.0 - '@typescript-eslint/visitor-keys': 8.10.0 + '@typescript-eslint/types': 8.11.0 + '@typescript-eslint/visitor-keys': 8.11.0 - '@typescript-eslint/type-utils@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5)': + '@typescript-eslint/type-utils@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5)': dependencies: - '@typescript-eslint/typescript-estree': 8.10.0(typescript@4.9.5) - '@typescript-eslint/utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/typescript-estree': 8.11.0(typescript@4.9.5) + '@typescript-eslint/utils': 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) debug: 4.3.7 ts-api-utils: 1.3.0(typescript@4.9.5) optionalDependencies: @@ -11118,7 +11104,7 @@ snapshots: '@typescript-eslint/types@5.62.0': {} - '@typescript-eslint/types@8.10.0': {} + '@typescript-eslint/types@8.11.0': {} '@typescript-eslint/typescript-estree@5.62.0(typescript@4.9.5)': dependencies: @@ -11134,10 +11120,10 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@8.10.0(typescript@4.9.5)': + '@typescript-eslint/typescript-estree@8.11.0(typescript@4.9.5)': dependencies: - '@typescript-eslint/types': 8.10.0 - '@typescript-eslint/visitor-keys': 8.10.0 + '@typescript-eslint/types': 8.11.0 + '@typescript-eslint/visitor-keys': 8.11.0 debug: 4.3.7 fast-glob: 3.3.2 is-glob: 4.0.3 @@ -11164,12 +11150,12 @@ snapshots: - supports-color - typescript - '@typescript-eslint/utils@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5)': + '@typescript-eslint/utils@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5)': dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@9.13.0(jiti@1.21.6)) - '@typescript-eslint/scope-manager': 8.10.0 - '@typescript-eslint/types': 8.10.0 - '@typescript-eslint/typescript-estree': 8.10.0(typescript@4.9.5) + '@typescript-eslint/scope-manager': 8.11.0 + '@typescript-eslint/types': 8.11.0 + '@typescript-eslint/typescript-estree': 8.11.0(typescript@4.9.5) eslint: 9.13.0(jiti@1.21.6) transitivePeerDependencies: - supports-color @@ -11180,16 +11166,16 @@ snapshots: '@typescript-eslint/types': 5.62.0 eslint-visitor-keys: 3.4.3 - '@typescript-eslint/visitor-keys@8.10.0': + '@typescript-eslint/visitor-keys@8.11.0': dependencies: - '@typescript-eslint/types': 8.10.0 + '@typescript-eslint/types': 8.11.0 eslint-visitor-keys: 3.4.3 '@ungap/structured-clone@1.2.0': {} - '@vitest/eslint-plugin@1.1.7(@typescript-eslint/utils@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5)': + '@vitest/eslint-plugin@1.1.7(@typescript-eslint/utils@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5)': dependencies: - '@typescript-eslint/utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/utils': 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) eslint: 9.13.0(jiti@1.21.6) optionalDependencies: typescript: 4.9.5 @@ -11474,10 +11460,6 @@ snapshots: argparse@2.0.1: {} - aria-query@5.1.3: - dependencies: - deep-equal: 2.2.3 - aria-query@5.3.0: dependencies: dequal: 2.0.3 @@ -11585,7 +11567,7 @@ snapshots: autoprefixer@10.4.20(postcss@8.4.47): dependencies: - browserslist: 4.24.0 + browserslist: 4.24.2 caniuse-lite: 1.0.30001669 fraction.js: 4.3.7 normalize-range: 0.1.2 @@ -11792,12 +11774,12 @@ snapshots: dependencies: pako: 1.0.11 - browserslist@4.24.0: + browserslist@4.24.2: dependencies: caniuse-lite: 1.0.30001669 electron-to-chromium: 1.5.41 node-releases: 2.0.18 - update-browserslist-db: 1.1.1(browserslist@4.24.0) + update-browserslist-db: 1.1.1(browserslist@4.24.2) bser@2.1.1: dependencies: @@ -11926,7 +11908,7 @@ snapshots: dependencies: readdirp: 4.0.2 - chromatic@11.12.6: {} + chromatic@11.14.0: {} chrome-trace-event@1.0.4: {} @@ -12081,7 +12063,7 @@ snapshots: core-js-compat@3.38.1: dependencies: - browserslist: 4.24.0 + browserslist: 4.24.2 core-js-pure@3.38.1: {} @@ -12458,27 +12440,6 @@ snapshots: deep-eql@5.0.2: {} - deep-equal@2.2.3: - dependencies: - array-buffer-byte-length: 1.0.1 - call-bind: 1.0.7 - es-get-iterator: 1.1.3 - get-intrinsic: 1.2.4 - is-arguments: 1.1.1 - is-array-buffer: 3.0.4 - is-date-object: 1.0.5 - is-regex: 1.1.4 - is-shared-array-buffer: 1.0.3 - isarray: 2.0.5 - object-is: 1.1.6 - object-keys: 1.1.1 - object.assign: 4.1.5 - regexp.prototype.flags: 1.5.3 - side-channel: 1.0.6 - which-boxed-primitive: 1.0.2 - which-collection: 1.0.2 - which-typed-array: 1.1.15 - deep-is@0.1.4: {} deepmerge@4.3.1: {} @@ -12719,18 +12680,6 @@ snapshots: es-errors@1.3.0: {} - es-get-iterator@1.1.3: - dependencies: - call-bind: 1.0.7 - get-intrinsic: 1.2.4 - has-symbols: 1.0.3 - is-arguments: 1.1.1 - is-map: 2.0.3 - is-set: 2.0.3 - is-string: 1.0.7 - isarray: 2.0.5 - stop-iteration-iterator: 1.0.0 - es-iterator-helpers@1.1.0: dependencies: call-bind: 1.0.7 @@ -12835,17 +12784,17 @@ snapshots: eslint: 9.13.0(jiti@1.21.6) find-up-simple: 1.0.0 - eslint-config-next@15.0.0-rc.1(eslint-plugin-import-x@4.3.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5): + eslint-config-next@15.0.0(eslint-plugin-import-x@4.3.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5): dependencies: - '@next/eslint-plugin-next': 15.0.0-rc.1 + '@next/eslint-plugin-next': 15.0.0 '@rushstack/eslint-patch': 1.10.4 - '@typescript-eslint/eslint-plugin': 8.10.0(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) - '@typescript-eslint/parser': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/eslint-plugin': 8.11.0(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/parser': 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) eslint: 9.13.0(jiti@1.21.6) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@4.3.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-plugin-import@2.31.0)(eslint@9.13.0(jiti@1.21.6)) - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-typescript@3.6.3)(eslint@9.13.0(jiti@1.21.6)) - eslint-plugin-jsx-a11y: 6.10.0(eslint@9.13.0(jiti@1.21.6)) + eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@4.3.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-plugin-import@2.31.0)(eslint@9.13.0(jiti@1.21.6)) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-typescript@3.6.3)(eslint@9.13.0(jiti@1.21.6)) + eslint-plugin-jsx-a11y: 6.10.1(eslint@9.13.0(jiti@1.21.6)) eslint-plugin-react: 7.37.1(eslint@9.13.0(jiti@1.21.6)) eslint-plugin-react-hooks: 5.0.0(eslint@9.13.0(jiti@1.21.6)) optionalDependencies: @@ -12867,19 +12816,19 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@4.3.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-plugin-import@2.31.0)(eslint@9.13.0(jiti@1.21.6)): + eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@4.3.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-plugin-import@2.31.0)(eslint@9.13.0(jiti@1.21.6)): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.3.7 enhanced-resolve: 5.17.1 eslint: 9.13.0(jiti@1.21.6) - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.13.0(jiti@1.21.6)) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.13.0(jiti@1.21.6)) fast-glob: 3.3.2 get-tsconfig: 4.8.1 is-bun-module: 1.2.1 is-glob: 4.0.3 optionalDependencies: - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-typescript@3.6.3)(eslint@9.13.0(jiti@1.21.6)) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-typescript@3.6.3)(eslint@9.13.0(jiti@1.21.6)) eslint-plugin-import-x: 4.3.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) transitivePeerDependencies: - '@typescript-eslint/parser' @@ -12891,14 +12840,14 @@ snapshots: dependencies: eslint: 9.13.0(jiti@1.21.6) - eslint-module-utils@2.12.0(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.13.0(jiti@1.21.6)): + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.13.0(jiti@1.21.6)): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/parser': 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) eslint: 9.13.0(jiti@1.21.6) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@4.3.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-plugin-import@2.31.0)(eslint@9.13.0(jiti@1.21.6)) + eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@4.3.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-plugin-import@2.31.0)(eslint@9.13.0(jiti@1.21.6)) transitivePeerDependencies: - supports-color @@ -12921,7 +12870,7 @@ snapshots: eslint-plugin-import-x@4.3.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5): dependencies: - '@typescript-eslint/utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/utils': 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) debug: 4.3.7 doctrine: 3.0.0 eslint: 9.13.0(jiti@1.21.6) @@ -12936,7 +12885,7 @@ snapshots: - supports-color - typescript - eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-typescript@3.6.3)(eslint@9.13.0(jiti@1.21.6)): + eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-typescript@3.6.3)(eslint@9.13.0(jiti@1.21.6)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.8 @@ -12947,7 +12896,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.13.0(jiti@1.21.6) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.13.0(jiti@1.21.6)) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.13.0(jiti@1.21.6)) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3 @@ -12959,7 +12908,7 @@ snapshots: string.prototype.trimend: 1.0.8 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/parser': 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -12993,9 +12942,9 @@ snapshots: natural-compare: 1.4.0 synckit: 0.6.2 - eslint-plugin-jsx-a11y@6.10.0(eslint@9.13.0(jiti@1.21.6)): + eslint-plugin-jsx-a11y@6.10.1(eslint@9.13.0(jiti@1.21.6)): dependencies: - aria-query: 5.1.3 + aria-query: 5.3.2 array-includes: 3.1.8 array.prototype.flatmap: 1.3.2 ast-types-flow: 0.0.8 @@ -13029,8 +12978,8 @@ snapshots: eslint-plugin-perfectionist@3.9.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5)(vue-eslint-parser@9.4.3(eslint@9.13.0(jiti@1.21.6))): dependencies: - '@typescript-eslint/types': 8.10.0 - '@typescript-eslint/utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/types': 8.11.0 + '@typescript-eslint/utils': 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) eslint: 9.13.0(jiti@1.21.6) minimatch: 9.0.5 natural-compare-lite: 1.4.0 @@ -13049,10 +12998,10 @@ snapshots: '@eslint-react/tools': 1.15.0 '@eslint-react/types': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) '@eslint-react/var': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) - '@typescript-eslint/scope-manager': 8.10.0 - '@typescript-eslint/type-utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) - '@typescript-eslint/types': 8.10.0 - '@typescript-eslint/utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/scope-manager': 8.11.0 + '@typescript-eslint/type-utils': 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/types': 8.11.0 + '@typescript-eslint/utils': 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) eslint: 9.13.0(jiti@1.21.6) string-ts: 2.2.0 ts-pattern: 5.5.0 @@ -13070,9 +13019,9 @@ snapshots: '@eslint-react/tools': 1.15.0 '@eslint-react/types': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) '@eslint-react/var': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) - '@typescript-eslint/scope-manager': 8.10.0 - '@typescript-eslint/types': 8.10.0 - '@typescript-eslint/utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/scope-manager': 8.11.0 + '@typescript-eslint/types': 8.11.0 + '@typescript-eslint/utils': 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) eslint: 9.13.0(jiti@1.21.6) ts-pattern: 5.5.0 optionalDependencies: @@ -13089,10 +13038,10 @@ snapshots: '@eslint-react/tools': 1.15.0 '@eslint-react/types': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) '@eslint-react/var': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) - '@typescript-eslint/scope-manager': 8.10.0 - '@typescript-eslint/type-utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) - '@typescript-eslint/types': 8.10.0 - '@typescript-eslint/utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/scope-manager': 8.11.0 + '@typescript-eslint/type-utils': 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/types': 8.11.0 + '@typescript-eslint/utils': 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) eslint: 9.13.0(jiti@1.21.6) ts-pattern: 5.5.0 optionalDependencies: @@ -13112,10 +13061,10 @@ snapshots: '@eslint-react/shared': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) '@eslint-react/tools': 1.15.0 '@eslint-react/types': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) - '@typescript-eslint/scope-manager': 8.10.0 - '@typescript-eslint/type-utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) - '@typescript-eslint/types': 8.10.0 - '@typescript-eslint/utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/scope-manager': 8.11.0 + '@typescript-eslint/type-utils': 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/types': 8.11.0 + '@typescript-eslint/utils': 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) eslint: 9.13.0(jiti@1.21.6) ts-pattern: 5.5.0 optionalDependencies: @@ -13136,9 +13085,9 @@ snapshots: '@eslint-react/tools': 1.15.0 '@eslint-react/types': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) '@eslint-react/var': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) - '@typescript-eslint/scope-manager': 8.10.0 - '@typescript-eslint/types': 8.10.0 - '@typescript-eslint/utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/scope-manager': 8.11.0 + '@typescript-eslint/types': 8.11.0 + '@typescript-eslint/utils': 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) birecord: 0.1.1 eslint: 9.13.0(jiti@1.21.6) ts-pattern: 5.5.0 @@ -13156,10 +13105,10 @@ snapshots: '@eslint-react/tools': 1.15.0 '@eslint-react/types': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) '@eslint-react/var': 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) - '@typescript-eslint/scope-manager': 8.10.0 - '@typescript-eslint/type-utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) - '@typescript-eslint/types': 8.10.0 - '@typescript-eslint/utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/scope-manager': 8.11.0 + '@typescript-eslint/type-utils': 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/types': 8.11.0 + '@typescript-eslint/utils': 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) eslint: 9.13.0(jiti@1.21.6) is-immutable-type: 5.0.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) ts-pattern: 5.5.0 @@ -13242,11 +13191,11 @@ snapshots: semver: 7.6.3 strip-indent: 3.0.0 - eslint-plugin-unused-imports@4.1.4(@typescript-eslint/eslint-plugin@8.10.0(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint@9.13.0(jiti@1.21.6)): + eslint-plugin-unused-imports@4.1.4(@typescript-eslint/eslint-plugin@8.11.0(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint@9.13.0(jiti@1.21.6)): dependencies: eslint: 9.13.0(jiti@1.21.6) optionalDependencies: - '@typescript-eslint/eslint-plugin': 8.10.0(@typescript-eslint/parser@8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/eslint-plugin': 8.11.0(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) eslint-plugin-vue@9.29.1(eslint@9.13.0(jiti@1.21.6)): dependencies: @@ -14218,7 +14167,7 @@ snapshots: is-immutable-type@5.0.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5): dependencies: - '@typescript-eslint/type-utils': 8.10.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@typescript-eslint/type-utils': 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) eslint: 9.13.0(jiti@1.21.6) ts-api-utils: 1.3.0(typescript@4.9.5) ts-declaration-location: 1.0.4(typescript@4.9.5) @@ -17174,10 +17123,6 @@ snapshots: statuses@2.0.1: {} - stop-iteration-iterator@1.0.0: - dependencies: - internal-slot: 1.0.7 - storybook@8.3.6: dependencies: '@storybook/core': 8.3.6 @@ -17720,9 +17665,9 @@ snapshots: optionalDependencies: webpack-sources: 3.2.3 - update-browserslist-db@1.1.1(browserslist@4.24.0): + update-browserslist-db@1.1.1(browserslist@4.24.2): dependencies: - browserslist: 4.24.0 + browserslist: 4.24.2 escalade: 3.2.0 picocolors: 1.1.1 @@ -17899,7 +17844,7 @@ snapshots: '@webassemblyjs/wasm-parser': 1.12.1 acorn: 8.13.0 acorn-import-attributes: 1.9.5(acorn@8.13.0) - browserslist: 4.24.0 + browserslist: 4.24.2 chrome-trace-event: 1.0.4 enhanced-resolve: 5.17.1 es-module-lexer: 1.5.4 From f215db87e305cf3a996c363bb66d18f49d522cbc Mon Sep 17 00:00:00 2001 From: AkaraChen <akarachen@outlook.com> Date: Tue, 22 Oct 2024 11:36:42 +0800 Subject: [PATCH 122/346] build: fix eslint undef --- web/eslint.config.mjs | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/web/eslint.config.mjs b/web/eslint.config.mjs index c97b05fab4..3406f3ddcf 100644 --- a/web/eslint.config.mjs +++ b/web/eslint.config.mjs @@ -82,8 +82,10 @@ export default combine( }), unicorn(), node(), - // TODO: remove this when upgrade to nextjs 15 - compat.extends('next'), + ...process.env.ESLINT_CONFIG_INSPECTOR + ? [] + // TODO: remove this when upgrade to nextjs 15 + : [compat.extends('next')], { ignores: [ '**/node_modules/*', @@ -130,8 +132,16 @@ export default combine( // antfu migrate to eslint-plugin-unused-imports "unused-imports/no-unused-vars": "warn", "unused-imports/no-unused-imports": "warn", + }, - "no-undef": "error", + languageOptions: { + globals: { + ...globals.browser, + ...globals.es2025, + ...globals.node, + 'React': 'readable', + 'JSX': 'readable', + } } }, storybook, @@ -157,24 +167,8 @@ export default combine( ...globals.browser, ...globals.es2021, ...globals.node, - ...globals.jest + ...globals.jest, }, }, }, - { - files: [ - GLOB_JSX, - GLOB_TSX, - '**/hooks/*' - ], - languageOptions: { - globals: { - ...globals.browser, - ...globals.es2025, - ...globals.node, - 'React': 'readable', - 'JSX': 'readable', - } - } - } ) From f8c3189f4dac81fc66480441d90079cecfd6078d Mon Sep 17 00:00:00 2001 From: AkaraChen <akarachen@outlook.com> Date: Tue, 22 Oct 2024 11:43:23 +0800 Subject: [PATCH 123/346] build: fix eslint undef --- web/eslint.config.mjs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/web/eslint.config.mjs b/web/eslint.config.mjs index 3406f3ddcf..efd3cac12a 100644 --- a/web/eslint.config.mjs +++ b/web/eslint.config.mjs @@ -102,7 +102,8 @@ export default combine( // orignal config rules: { // from old version of antfu/eslint-config - "no-undef": "warn", + // typescript will handle this, see https://typescript-eslint.io/troubleshooting/faqs/eslint/#i-get-errors-from-the-no-undef-rule-about-global-variables-not-being-defined-even-though-there-are-no-typescript-errors + "no-undef": "off", 'ts/consistent-type-definitions': ['error', 'type'], // orignal ts/no-var-requires From 15fe63546591d6d98868a155694bc1983bc5a88b Mon Sep 17 00:00:00 2001 From: Yi <yxiaoisme@gmail.com> Date: Tue, 22 Oct 2024 13:43:01 +0800 Subject: [PATCH 124/346] chore: install package from GitHub --- .../install-from-github/index.tsx | 109 ++++++++++++++---- web/app/components/plugins/types.ts | 15 +++ web/service/plugins.ts | 9 ++ 3 files changed, 113 insertions(+), 20 deletions(-) diff --git a/web/app/components/plugins/install-plugin/install-from-github/index.tsx b/web/app/components/plugins/install-plugin/install-from-github/index.tsx index d882bff796..7d3fa3a12b 100644 --- a/web/app/components/plugins/install-plugin/install-from-github/index.tsx +++ b/web/app/components/plugins/install-plugin/install-from-github/index.tsx @@ -5,6 +5,9 @@ import Modal from '@/app/components/base/modal' import Button from '@/app/components/base/button' import type { Item } from '@/app/components/base/select' import { PortalSelect } from '@/app/components/base/select' +import type { GitHubRepoReleaseResponse } from '@/app/components/plugins/types' +import { installPackageFromGitHub } from '@/service/plugins' +import Toast from '@/app/components/base/toast' type InstallFromGitHubProps = { onClose: () => void @@ -12,38 +15,104 @@ type InstallFromGitHubProps = { type InstallStep = 'url' | 'version' | 'package' | 'installed' +type GitHubUrlInfo = { + isValid: boolean + owner?: string + repo?: string +} + const InstallFromGitHub: React.FC<InstallFromGitHubProps> = ({ onClose }) => { const [step, setStep] = useState<InstallStep>('url') const [repoUrl, setRepoUrl] = useState('') const [selectedVersion, setSelectedVersion] = useState('') const [selectedPackage, setSelectedPackage] = useState('') + const [releases, setReleases] = useState<GitHubRepoReleaseResponse[]>([]) - // Mock data - replace with actual data fetched from the backend - const versions: Item[] = [ - { value: '1.0.1', name: '1.0.1' }, - { value: '1.2.0', name: '1.2.0' }, - { value: '1.2.1', name: '1.2.1' }, - { value: '1.3.2', name: '1.3.2' }, - ] - const packages: Item[] = [ - { value: 'package1', name: 'Package 1' }, - { value: 'package2', name: 'Package 2' }, - { value: 'package3', name: 'Package 3' }, - ] + const versions: Item[] = releases.map(release => ({ + value: release.tag_name, + name: release.tag_name, + })) - const handleNext = () => { + const packages: Item[] = selectedVersion + ? (releases + .find(release => release.tag_name === selectedVersion) + ?.assets.map(asset => ({ + value: asset.browser_download_url, + name: asset.name, + })) || []) + : [] + + const parseGitHubUrl = (url: string): GitHubUrlInfo => { + const githubUrlRegex = /^https:\/\/github\.com\/([^/]+)\/([^/]+)\/?$/ + const match = url.match(githubUrlRegex) + + if (match) { + return { + isValid: true, + owner: match[1], + repo: match[2], + } + } + + return { isValid: false } + } + + const handleInstall = async () => { + try { + const response = await installPackageFromGitHub({ repo: repoUrl, version: selectedVersion, package: selectedPackage }) + if (response.plugin_unique_identifier) { + setStep('installed') + console.log('Package installed:') + } + else { + console.error('Failed to install package:') + } + } + catch (error) { + console.error('Error installing package:') + } + } + + const handleNext = async () => { switch (step) { - case 'url': - // TODO: Validate URL and fetch versions - setStep('version') + case 'url': { + const { isValid, owner, repo } = parseGitHubUrl(repoUrl) + if (!isValid || !owner || !repo) { + Toast.notify({ + type: 'error', + message: 'Invalid GitHub URL. Please enter a valid URL in the format: https://github.com/owner/repo', + }) + break + } + try { + const res = await fetch(`https://api.github.com/repos/${owner}/${repo}/releases`) + if (!res.ok) + throw new Error('Failed to fetch releases') + const data = await res.json() + const formattedReleases = data.map((release: any) => ({ + tag_name: release.tag_name, + assets: release.assets.map((asset: any) => ({ + browser_download_url: asset.browser_download_url, + id: asset.id, + name: asset.name, + })), + })) + setReleases(formattedReleases) + setStep('version') + } + catch (error) { + Toast.notify({ + type: 'error', + message: 'Failed to fetch repository release', + }) + } break + } case 'version': - // TODO: Validate version and fetch packages setStep('package') break case 'package': - // TODO: Handle installation - setStep('installed') + handleInstall() break } } @@ -181,7 +250,7 @@ const InstallFromGitHub: React.FC<InstallFromGitHubProps> = ({ onClose }) => { className='min-w-[72px]' onClick={onClose} > - Cancel + {step === 'url' ? 'Cancel' : 'Back'} </Button> <Button variant='primary' diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts index 2becf1e43d..eb8327cd40 100644 --- a/web/app/components/plugins/types.ts +++ b/web/app/components/plugins/types.ts @@ -142,3 +142,18 @@ export type UpdateEndpointRequest = { settings: Record<string, any> name: string } + +export type GitHubAsset = { + id: number + name: string + browser_download_url: string +} + +export type GitHubRepoReleaseResponse = { + tag_name: string + assets: GitHubAsset[] +} + +export type InstallPackageResponse = { + plugin_unique_identifier: string +} diff --git a/web/service/plugins.ts b/web/service/plugins.ts index c5eb55c5c9..c072179913 100644 --- a/web/service/plugins.ts +++ b/web/service/plugins.ts @@ -5,6 +5,7 @@ import type { EndpointOperationResponse, EndpointsRequest, EndpointsResponse, + InstallPackageResponse, UpdateEndpointRequest, } from '@/app/components/plugins/types' @@ -37,3 +38,11 @@ export const disableEndpoint: Fetcher<EndpointOperationResponse, { url: string; // url = /workspaces/current/endpoints/disable return post<EndpointOperationResponse>(url, { body: { endpoint_id: endpointID } }) } + +export const installPackageFromGitHub: Fetcher<InstallPackageResponse, { repo: string; version: string; package: string }> = ({ repo, version, package: packageName }) => { + return post<InstallPackageResponse>('/workspaces/current/plugin/upload/github', { + body: { repo, version, package: packageName }, + }) +} + +// export const fetchInstalledPluginsList: Fetcher< From 0e53cc0e8c299a9fcf1ce3eb179474a4cb6e3bc0 Mon Sep 17 00:00:00 2001 From: AkaraChen <akarachen@outlook.com> Date: Tue, 22 Oct 2024 14:15:22 +0800 Subject: [PATCH 125/346] fix: eslint indent --- web/eslint.config.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/eslint.config.mjs b/web/eslint.config.mjs index efd3cac12a..e8ab0fd8b3 100644 --- a/web/eslint.config.mjs +++ b/web/eslint.config.mjs @@ -51,7 +51,7 @@ export default combine( jsx: false, overrides: { // original config - "style/indent": "off", + "style/indent": ["error", 2], // these options does not exist in old version // maybe useless From 510ce057f7f8154a087bfd3d4a0694efb03827d2 Mon Sep 17 00:00:00 2001 From: nite-knite <nkCoding@gmail.com> Date: Tue, 22 Oct 2024 14:18:55 +0800 Subject: [PATCH 126/346] chore: add package manager setting to vscode setting example --- web/.vscode/settings.example.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/web/.vscode/settings.example.json b/web/.vscode/settings.example.json index a2dfe7c669..ce5c9d6b01 100644 --- a/web/.vscode/settings.example.json +++ b/web/.vscode/settings.example.json @@ -21,5 +21,6 @@ "editor.defaultFormatter": "vscode.json-language-features" }, "typescript.tsdk": "node_modules/typescript/lib", - "typescript.enablePromptUseWorkspaceTsdk": true + "typescript.enablePromptUseWorkspaceTsdk": true, + "npm.packageManager": "pnpm" } From 4873e6e2a1486ad6e2d7e9a9d6d36ce137ee4eb7 Mon Sep 17 00:00:00 2001 From: AkaraChen <akarachen@outlook.com> Date: Tue, 22 Oct 2024 15:32:48 +0800 Subject: [PATCH 127/346] build: fix eslint stylistic --- web/eslint.config.mjs | 126 ++++++++++++++++++++++++------------------ 1 file changed, 73 insertions(+), 53 deletions(-) diff --git a/web/eslint.config.mjs b/web/eslint.config.mjs index e8ab0fd8b3..2ff4d704fd 100644 --- a/web/eslint.config.mjs +++ b/web/eslint.config.mjs @@ -1,7 +1,7 @@ import { - GLOB_JSX, GLOB_TESTS, GLOB_TSX, combine, javascript, node, - stylistic, typescript, unicorn - } from '@antfu/eslint-config' + GLOB_TESTS, combine, javascript, node, + stylistic, typescript, unicorn, +} from '@antfu/eslint-config' import path from 'node:path' import { fileURLToPath } from 'node:url' import js from '@eslint/js' @@ -21,27 +21,27 @@ const storybook = [ { plugins: ['storybook'], files: ['*.stories.@(ts|tsx|js|jsx|mjs|cjs)', '*.story.@(ts|tsx|js|jsx|mjs|cjs)'], - rules: { - 'react-hooks/rules-of-hooks': 'off', - 'import/no-anonymous-default-export': 'off', - 'storybook/await-interactions': 'error', - 'storybook/context-in-play-function': 'error', - 'storybook/default-exports': 'error', - 'storybook/hierarchy-separator': 'warn', - 'storybook/no-redundant-story-name': 'warn', - 'storybook/prefer-pascal-case': 'warn', - 'storybook/story-exports': 'error', - 'storybook/use-storybook-expect': 'error', - 'storybook/use-storybook-testing-library': 'error', - } + rules: { + 'react-hooks/rules-of-hooks': 'off', + 'import/no-anonymous-default-export': 'off', + 'storybook/await-interactions': 'error', + 'storybook/context-in-play-function': 'error', + 'storybook/default-exports': 'error', + 'storybook/hierarchy-separator': 'warn', + 'storybook/no-redundant-story-name': 'warn', + 'storybook/prefer-pascal-case': 'warn', + 'storybook/story-exports': 'error', + 'storybook/use-storybook-expect': 'error', + 'storybook/use-storybook-testing-library': 'error', + }, }, { plugins: ['storybook'], files: ['*.stories.@(ts|tsx|js|jsx|mjs|cjs)', '*.story.@(ts|tsx|js|jsx|mjs|cjs)'], - rules: { - 'storybook/no-uninstalled-addons': 'error', - } - } + rules: { + 'storybook/no-uninstalled-addons': 'error', + }, + }, ] export default combine( @@ -49,27 +49,41 @@ export default combine( lessOpinionated: true, // original @antfu/eslint-config does not support jsx jsx: false, + semi: false, + quotes: 'single', overrides: { // original config - "style/indent": ["error", 2], + 'style/indent': ['error', 2], + 'style/quotes': ['error', 'single'], + 'curly': ['error', 'multi-line'], + 'style/comma-spacing': ['error', { before: false, after: true }], + 'style/quote-props': ['warn', 'consistent-as-needed'], // these options does not exist in old version // maybe useless - "style/indent-binary-ops": "off", - "style/multiline-ternary": "off", + 'style/indent-binary-ops': 'off', + 'style/multiline-ternary': 'off', + 'antfu/top-level-function': 'off', + 'antfu/curly': 'off', + 'antfu/consistent-chaining': 'off', + + // copy from eslint-config-antfu 0.36.0 + 'style/brace-style': ['error', 'stroustrup', { allowSingleLine: true }], + 'style/dot-location': ['error', 'property'], + 'style/object-curly-newline': ['error', { consistent: true, multiline: true }], + 'style/object-property-newline': ['error', { allowMultiplePropertiesPerLine: true }], + 'style/template-curly-spacing': ['error', 'never'], + 'style/keyword-spacing': 'off', // not exist in old version, and big change - "style/quote-props": "off", - "style/member-delimiter-style": "off", - "style/quotes": "off", - "style/comma-dangle": "off", - } + 'style/member-delimiter-style': 'off', + }, }), typescript({ overrides: { // useful, but big change - "ts/no-empty-object-type": "off", - } + 'ts/no-empty-object-type': 'off', + }, }), javascript({ overrides: { @@ -77,8 +91,8 @@ export default combine( 'no-unused-vars': 'off', // useless - 'no-use-before-define': 'warn' - } + 'no-use-before-define': 'warn', + }, }), unicorn(), node(), @@ -96,30 +110,36 @@ export default combine( '**/.next/', '**/public/*', '**/*.json', - ] + ], }, { // orignal config rules: { // from old version of antfu/eslint-config // typescript will handle this, see https://typescript-eslint.io/troubleshooting/faqs/eslint/#i-get-errors-from-the-no-undef-rule-about-global-variables-not-being-defined-even-though-there-are-no-typescript-errors - "no-undef": "off", + 'no-undef': 'off', 'ts/consistent-type-definitions': ['error', 'type'], // orignal ts/no-var-requires 'ts/no-require-imports': 'off', - "no-console": 'off', - "react-hooks/exhaustive-deps": "warn", - "react/display-name": "off", + 'no-console': 'off', + 'react-hooks/exhaustive-deps': 'warn', + 'react/display-name': 'off', + 'array-callback-return': ['error', { + allowImplicit: false, + checkForEach: false, + }], - // orignal config, but removed in new version antfu/eslint-config - // big change - "curly": "off", + // copy from eslint-config-antfu 0.36.0 + 'camelcase': 'off', + 'curly': ['error', 'multi-or-nest', 'consistent'], + 'default-case-last': 'error', + 'dot-notation': ['error', { allowKeywords: true }], + 'new-cap': ['error', { newIsCap: true, capIsNew: false, properties: true }], // antfu use eslint-plugin-perfectionist to replace this - // will cause big change, so keep the original - // sort-imports - "sort-imports": [ + // will cause big change, so keep the original sort-imports + 'sort-imports': [ 'error', { ignoreCase: false, @@ -131,8 +151,8 @@ export default combine( ], // antfu migrate to eslint-plugin-unused-imports - "unused-imports/no-unused-vars": "warn", - "unused-imports/no-unused-imports": "warn", + 'unused-imports/no-unused-vars': 'warn', + 'unused-imports/no-unused-imports': 'warn', }, languageOptions: { @@ -140,25 +160,25 @@ export default combine( ...globals.browser, ...globals.es2025, ...globals.node, - 'React': 'readable', - 'JSX': 'readable', - } - } + React: 'readable', + JSX: 'readable', + }, + }, }, storybook, // need futher research { rules: { // not exist in old version - "antfu/consistent-list-newline": "off", + 'antfu/consistent-list-newline': 'off', 'node/prefer-global/process': 'off', 'node/prefer-global/buffer': 'off', 'node/no-callback-literal': 'off', // useful, but big change - "unicorn/prefer-number-properties": "warn", - "unicorn/no-new-array": "warn" - } + 'unicorn/prefer-number-properties': 'warn', + 'unicorn/no-new-array': 'warn', + }, }, // suppress error for `no-undef` rule { From ff31f0540a6199daf78d586c5b5920e6c691ec97 Mon Sep 17 00:00:00 2001 From: AkaraChen <akarachen@outlook.com> Date: Tue, 22 Oct 2024 15:32:58 +0800 Subject: [PATCH 128/346] style: lint --- web/.storybook/main.ts | 28 ++++++------- web/.storybook/preview.tsx | 40 +++++++++---------- web/app/components/app/overview/appChart.tsx | 6 +-- .../app/overview/embedded/index.tsx | 8 ++-- .../base/portal-to-follow-elem/index.tsx | 6 +-- .../install-from-github/index.tsx | 2 +- web/hooks/use-metadata.ts | 28 ++++++------- 7 files changed, 59 insertions(+), 59 deletions(-) diff --git a/web/.storybook/main.ts b/web/.storybook/main.ts index 74e95821de..fecf774e98 100644 --- a/web/.storybook/main.ts +++ b/web/.storybook/main.ts @@ -1,19 +1,19 @@ import type { StorybookConfig } from '@storybook/nextjs' const config: StorybookConfig = { - // stories: ['../stories/**/*.mdx', '../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)'], - stories: ['../app/components/**/*.stories.@(js|jsx|mjs|ts|tsx)'], - addons: [ - '@storybook/addon-onboarding', - '@storybook/addon-links', - '@storybook/addon-essentials', - '@chromatic-com/storybook', - '@storybook/addon-interactions', - ], - framework: { - name: '@storybook/nextjs', - options: {}, - }, - staticDirs: ['../public'], + // stories: ['../stories/**/*.mdx', '../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)'], + stories: ['../app/components/**/*.stories.@(js|jsx|mjs|ts|tsx)'], + addons: [ + '@storybook/addon-onboarding', + '@storybook/addon-links', + '@storybook/addon-essentials', + '@chromatic-com/storybook', + '@storybook/addon-interactions', + ], + framework: { + name: '@storybook/nextjs', + options: {}, + }, + staticDirs: ['../public'], } export default config diff --git a/web/.storybook/preview.tsx b/web/.storybook/preview.tsx index 7a254bc79c..55328602f9 100644 --- a/web/.storybook/preview.tsx +++ b/web/.storybook/preview.tsx @@ -8,30 +8,30 @@ import '../app/styles/markdown.scss' import './storybook.css' export const decorators = [ - withThemeByDataAttribute({ - themes: { - light: 'light', - dark: 'dark', - }, - defaultTheme: 'light', - attributeName: 'data-theme', - }), - (Story) => { - return <I18nServer> - <Story /> - </I18nServer> - } - ] + withThemeByDataAttribute({ + themes: { + light: 'light', + dark: 'dark', + }, + defaultTheme: 'light', + attributeName: 'data-theme', + }), + (Story) => { + return <I18nServer> + <Story /> + </I18nServer> + }, +] const preview: Preview = { parameters: { - controls: { - matchers: { - color: /(background|color)$/i, - date: /Date$/i, - }, - }, + controls: { + matchers: { + color: /(background|color)$/i, + date: /Date$/i, + }, }, + }, } export default preview diff --git a/web/app/components/app/overview/appChart.tsx b/web/app/components/app/overview/appChart.tsx index e0788bcda3..d1426caa27 100644 --- a/web/app/components/app/overview/appChart.tsx +++ b/web/app/components/app/overview/appChart.tsx @@ -216,8 +216,8 @@ const Chart: React.FC<IChartProps> = ({ return `<div style='color:#6B7280;font-size:12px'>${params.name}</div> <div style='font-size:14px;color:#1F2A37'>${valueFormatter((params.data as any)[yField])} ${!CHART_TYPE_CONFIG[chartType].showTokens - ? '' - : `<span style='font-size:12px'> + ? '' + : `<span style='font-size:12px'> <span style='margin-left:4px;color:#6B7280'>(</span> <span style='color:#FF8A4C'>~$${get(params.data, 'total_price', 0)}</span> <span style='color:#6B7280'>)</span> @@ -243,7 +243,7 @@ const Chart: React.FC<IChartProps> = ({ ? '' : <span>{t('appOverview.analysis.tokenUsage.consumed')} Tokens<span className='text-sm'> <span className='ml-1 text-gray-500'>(</span> - <span className='text-orange-400'>~{sum(statistics.map(item => parseFloat(get(item, 'total_price', '0')))).toLocaleString('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 4 })}</span> + <span className='text-orange-400'>~{sum(statistics.map(item => Number.parseFloat(get(item, 'total_price', '0')))).toLocaleString('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 4 })}</span> <span className='text-gray-500'>)</span> </span></span>} textStyle={{ main: `!text-3xl !font-normal ${sumData === 0 ? '!text-gray-300' : ''}` }} /> diff --git a/web/app/components/app/overview/embedded/index.tsx b/web/app/components/app/overview/embedded/index.tsx index b71a3c3fdf..1e8fb68e49 100644 --- a/web/app/components/app/overview/embedded/index.tsx +++ b/web/app/components/app/overview/embedded/index.tsx @@ -35,12 +35,12 @@ const OPTION_MAP = { `<script> window.difyChatbotConfig = { token: '${token}'${isTestEnv - ? `, + ? `, isDev: true` - : ''}${IS_CE_EDITION - ? `, + : ''}${IS_CE_EDITION + ? `, baseUrl: '${url}'` - : ''} + : ''} } </script> <script diff --git a/web/app/components/base/portal-to-follow-elem/index.tsx b/web/app/components/base/portal-to-follow-elem/index.tsx index 4a380e6abd..3d24c6ee99 100644 --- a/web/app/components/base/portal-to-follow-elem/index.tsx +++ b/web/app/components/base/portal-to-follow-elem/index.tsx @@ -106,7 +106,7 @@ export function PortalToFollowElem({ } export const PortalToFollowElemTrigger = React.forwardRef< -HTMLElement, + HTMLElement, React.HTMLProps<HTMLElement> & { asChild?: boolean } >(({ children, asChild = false, ...props }, propRef) => { const context = usePortalToFollowElemContext() @@ -141,8 +141,8 @@ React.HTMLProps<HTMLElement> & { asChild?: boolean } PortalToFollowElemTrigger.displayName = 'PortalToFollowElemTrigger' export const PortalToFollowElemContent = React.forwardRef< -HTMLDivElement, -React.HTMLProps<HTMLDivElement> + HTMLDivElement, + React.HTMLProps<HTMLDivElement> >(({ style, ...props }, propRef) => { const context = usePortalToFollowElemContext() const ref = useMergeRefs([context.refs.setFloating, propRef]) diff --git a/web/app/components/plugins/install-plugin/install-from-github/index.tsx b/web/app/components/plugins/install-plugin/install-from-github/index.tsx index 7d3fa3a12b..86da094dc8 100644 --- a/web/app/components/plugins/install-plugin/install-from-github/index.tsx +++ b/web/app/components/plugins/install-plugin/install-from-github/index.tsx @@ -240,7 +240,7 @@ const InstallFromGitHub: React.FC<InstallFromGitHubProps> = ({ onClose }) => { className='min-w-[72px]' onClick={onClose} > - Close + Close </Button> ) : ( diff --git a/web/hooks/use-metadata.ts b/web/hooks/use-metadata.ts index 6a4965f2bf..2cb15ba958 100644 --- a/web/hooks/use-metadata.ts +++ b/web/hooks/use-metadata.ts @@ -9,22 +9,22 @@ export type metadataType = DocType | 'originInfo' | 'technicalParameters' type MetadataMap = Record< - metadataType, - { - text: string - allowEdit?: boolean - icon?: React.ReactNode - iconName?: string - subFieldsMap: Record< - string, + metadataType, { - label: string - inputType?: inputType - field?: string - render?: (value: any, total?: number) => React.ReactNode | string + text: string + allowEdit?: boolean + icon?: React.ReactNode + iconName?: string + subFieldsMap: Record< + string, + { + label: string + inputType?: inputType + field?: string + render?: (value: any, total?: number) => React.ReactNode | string + } + > } - > - } > const fieldPrefix = 'datasetDocuments.metadata.field' From 1387f406a306fd261e9ade2534a96310bc10862d Mon Sep 17 00:00:00 2001 From: Yi <yxiaoisme@gmail.com> Date: Tue, 22 Oct 2024 16:40:27 +0800 Subject: [PATCH 129/346] fix: log format --- .../install-from-github/index.tsx | 154 ++++++++++-------- web/app/components/plugins/types.ts | 7 + 2 files changed, 96 insertions(+), 65 deletions(-) diff --git a/web/app/components/plugins/install-plugin/install-from-github/index.tsx b/web/app/components/plugins/install-plugin/install-from-github/index.tsx index 7d3fa3a12b..e34948c479 100644 --- a/web/app/components/plugins/install-plugin/install-from-github/index.tsx +++ b/web/app/components/plugins/install-plugin/install-from-github/index.tsx @@ -6,37 +6,46 @@ import Button from '@/app/components/base/button' import type { Item } from '@/app/components/base/select' import { PortalSelect } from '@/app/components/base/select' import type { GitHubRepoReleaseResponse } from '@/app/components/plugins/types' -import { installPackageFromGitHub } from '@/service/plugins' +import { InstallStep } from '../../types' import Toast from '@/app/components/base/toast' type InstallFromGitHubProps = { onClose: () => void } -type InstallStep = 'url' | 'version' | 'package' | 'installed' - type GitHubUrlInfo = { isValid: boolean owner?: string repo?: string } -const InstallFromGitHub: React.FC<InstallFromGitHubProps> = ({ onClose }) => { - const [step, setStep] = useState<InstallStep>('url') - const [repoUrl, setRepoUrl] = useState('') - const [selectedVersion, setSelectedVersion] = useState('') - const [selectedPackage, setSelectedPackage] = useState('') - const [releases, setReleases] = useState<GitHubRepoReleaseResponse[]>([]) +type InstallState = { + step: InstallStep + repoUrl: string + selectedVersion: string + selectedPackage: string + releases: GitHubRepoReleaseResponse[] +} - const versions: Item[] = releases.map(release => ({ +const InstallFromGitHub: React.FC<InstallFromGitHubProps> = ({ onClose }) => { + const [state, setState] = useState<InstallState>({ + step: InstallStep.url, + repoUrl: '', + selectedVersion: '', + selectedPackage: '', + releases: [], + }) + + const versions: Item[] = state.releases.map(release => ({ value: release.tag_name, name: release.tag_name, })) - const packages: Item[] = selectedVersion - ? (releases - .find(release => release.tag_name === selectedVersion) - ?.assets.map(asset => ({ + const packages: Item[] = state.selectedVersion + ? (state.releases + .find(release => release.tag_name === state.selectedVersion) + ?.assets +.map(asset => ({ value: asset.browser_download_url, name: asset.name, })) || []) @@ -58,25 +67,26 @@ const InstallFromGitHub: React.FC<InstallFromGitHubProps> = ({ onClose }) => { } const handleInstall = async () => { - try { - const response = await installPackageFromGitHub({ repo: repoUrl, version: selectedVersion, package: selectedPackage }) - if (response.plugin_unique_identifier) { - setStep('installed') - console.log('Package installed:') - } - else { - console.error('Failed to install package:') - } - } - catch (error) { - console.error('Error installing package:') - } + // try { + // const response = await installPackageFromGitHub({ repo: state.repoUrl, version: state.selectedVersion, package: state.selectedPackage }) + // if (response.plugin_unique_identifier) { + // setState(prevState => ({...prevState, step: InstallStep.installed})) + // console.log('Package installed:') + // } + // else { + // console.error('Failed to install package:') + // } + // } + // catch (error) { + // console.error('Error installing package:') + // } + setState(prevState => ({ ...prevState, step: InstallStep.installed })) } const handleNext = async () => { - switch (step) { - case 'url': { - const { isValid, owner, repo } = parseGitHubUrl(repoUrl) + switch (state.step) { + case InstallStep.url: { + const { isValid, owner, repo } = parseGitHubUrl(state.repoUrl) if (!isValid || !owner || !repo) { Toast.notify({ type: 'error', @@ -97,8 +107,7 @@ const InstallFromGitHub: React.FC<InstallFromGitHubProps> = ({ onClose }) => { name: asset.name, })), })) - setReleases(formattedReleases) - setStep('version') + setState(prevState => ({ ...prevState, releases: formattedReleases, step: InstallStep.version })) } catch (error) { Toast.notify({ @@ -108,23 +117,36 @@ const InstallFromGitHub: React.FC<InstallFromGitHubProps> = ({ onClose }) => { } break } - case 'version': - setStep('package') + case InstallStep.version: + setState(prevState => ({ ...prevState, step: InstallStep.package })) break - case 'package': + case InstallStep.package: handleInstall() break } } + const handleBack = () => { + setState((prevState) => { + switch (prevState.step) { + case InstallStep.version: + return { ...prevState, step: InstallStep.url } + case InstallStep.package: + return { ...prevState, step: InstallStep.version } + default: + return prevState + } + }) + } + const isInputValid = () => { - switch (step) { - case 'url': - return !!repoUrl.trim() - case 'version': - return !!selectedVersion - case 'package': - return !!selectedPackage + switch (state.step) { + case InstallStep.url: + return !!state.repoUrl.trim() + case InstallStep.version: + return !!state.selectedVersion + case InstallStep.package: + return !!state.selectedPackage default: return true } @@ -132,13 +154,15 @@ const InstallFromGitHub: React.FC<InstallFromGitHubProps> = ({ onClose }) => { const InfoRow = ({ label, value }: { label: string; value: string }) => ( <div className='flex items-center gap-3'> - <div className='flex w-[72px] items-center gap-2'> - <div className='text-text-tertiary system-sm-medium'> + <div className='flex-shrink-0 w-[72px] items-center gap-2'> + <div className='text-text-tertiary system-sm-medium truncate'> {label} </div> </div> - <div className='flex-grow overflow-hidden text-text-secondary text-ellipsis system-sm-medium'> - {value} + <div className='flex-grow overflow-hidden'> + <div className='text-text-secondary text-ellipsis system-sm-medium'> + {value} + </div> </div> </div> ) @@ -157,12 +181,12 @@ const InstallFromGitHub: React.FC<InstallFromGitHubProps> = ({ onClose }) => { Install plugin from GitHub </div> <div className='self-stretch text-text-tertiary system-xs-regular'> - {step !== 'installed' && 'Please make sure that you only install plugins from a trusted source.'} + {state.step !== InstallStep.installed && 'Please make sure that you only install plugins from a trusted source.'} </div> </div> </div> - <div className={`flex px-6 py-3 flex-col justify-center items-start self-stretch ${step === 'installed' ? 'gap-2' : 'gap-4'}`}> - {step === 'url' && ( + <div className={`flex px-6 py-3 flex-col justify-center items-start self-stretch ${state.step === InstallStep.installed ? 'gap-2' : 'gap-4'}`}> + {state.step === InstallStep.url && ( <> <label htmlFor='repoUrl' @@ -174,8 +198,8 @@ const InstallFromGitHub: React.FC<InstallFromGitHubProps> = ({ onClose }) => { type='url' id='repoUrl' name='repoUrl' - value={repoUrl} - onChange={e => setRepoUrl(e.target.value)} // TODO: needs to verify the url + value={state.repoUrl} + onChange={e => setState(prevState => ({ ...prevState, repoUrl: e.target.value }))} // TODO: needs to verify the url className='flex items-center self-stretch rounded-lg border border-components-input-border-active bg-components-input-bg-active shadows-shadow-xs p-2 gap-[2px] flex-grow overflow-hidden text-components-input-text-filled text-ellipsis system-sm-regular' @@ -183,7 +207,7 @@ const InstallFromGitHub: React.FC<InstallFromGitHubProps> = ({ onClose }) => { /> </> )} - {step === 'version' && ( + {state.step === InstallStep.version && ( <> <label htmlFor='version' @@ -192,15 +216,15 @@ const InstallFromGitHub: React.FC<InstallFromGitHubProps> = ({ onClose }) => { <span className='system-sm-semibold'>Select version</span> </label> <PortalSelect - value={selectedVersion} - onSelect={item => setSelectedVersion(item.value as string)} + value={state.selectedVersion} + onSelect={item => setState(prevState => ({ ...prevState, selectedVersion: item.value as string }))} items={versions} placeholder="Please select a version" popupClassName='w-[432px] z-[1001]' /> </> )} - {step === 'package' && ( + {state.step === InstallStep.package && ( <> <label htmlFor='package' @@ -209,22 +233,22 @@ const InstallFromGitHub: React.FC<InstallFromGitHubProps> = ({ onClose }) => { <span className='system-sm-semibold'>Select package</span> </label> <PortalSelect - value={selectedPackage} - onSelect={item => setSelectedPackage(item.value as string)} + value={state.selectedPackage} + onSelect={item => setState(prevState => ({ ...prevState, selectedPackage: item.value as string }))} items={packages} placeholder="Please select a package" popupClassName='w-[432px] z-[1001]' /> </> )} - {step === 'installed' && ( + {state.step === InstallStep.installed && ( <> <div className='text-text-secondary system-md-regular'>The plugin has been installed successfully.</div> <div className='flex w-full p-4 flex-col justify-center items-start gap-2 rounded-2xl bg-background-section-burn'> {[ - { label: 'Repository', value: repoUrl }, - { label: 'Version', value: selectedVersion }, - { label: 'Package', value: selectedPackage }, + { label: 'Repository', value: state.repoUrl }, + { label: 'Version', value: state.selectedVersion }, + { label: 'Package', value: state.selectedPackage }, ].map(({ label, value }) => ( <InfoRow key={label} label={label} value={value} /> ))} @@ -233,7 +257,7 @@ const InstallFromGitHub: React.FC<InstallFromGitHubProps> = ({ onClose }) => { )} </div> <div className='flex p-6 pt-5 justify-end items-center gap-2 self-stretch'> - {step === 'installed' + {state.step === InstallStep.installed ? ( <Button variant='primary' @@ -248,9 +272,9 @@ const InstallFromGitHub: React.FC<InstallFromGitHubProps> = ({ onClose }) => { <Button variant='secondary' className='min-w-[72px]' - onClick={onClose} + onClick={state.step === InstallStep.url ? onClose : handleBack} > - {step === 'url' ? 'Cancel' : 'Back'} + {state.step === InstallStep.url ? 'Cancel' : 'Back'} </Button> <Button variant='primary' @@ -258,7 +282,7 @@ const InstallFromGitHub: React.FC<InstallFromGitHubProps> = ({ onClose }) => { onClick={handleNext} disabled={!isInputValid()} > - {step === 'package' ? 'Install' : 'Next'} + {state.step === InstallStep.package ? 'Install' : 'Next'} </Button> </> )} diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts index eb8327cd40..b6f00802f3 100644 --- a/web/app/components/plugins/types.ts +++ b/web/app/components/plugins/types.ts @@ -116,6 +116,13 @@ export type Permissions = { canDebugger: PermissionType } +export enum InstallStep { + url = 'url', + version = 'version', + package = 'package', + installed = 'installed' +} + // endpoint export type CreateEndpointRequest = { plugin_unique_identifier: string From 5fddb235168380915d523610c23347e6c02ee714 Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Tue, 22 Oct 2024 17:21:25 +0800 Subject: [PATCH 130/346] feat: install progress --- web/app/components/plugins/card/index.tsx | 2 +- .../install-from-local-package/index.tsx | 119 ++++++++---------- .../steps/install.tsx | 63 ++++++++++ .../steps/installed.tsx | 44 +++++++ .../steps/uploading.tsx | 76 +++++++++++ .../plugins/install-plugin/utils.ts | 21 ++++ .../components/plugins/plugin-page/index.tsx | 6 +- .../plugin-page/install-plugin-dropdown.tsx | 6 +- web/app/components/plugins/types.ts | 8 ++ 9 files changed, 272 insertions(+), 73 deletions(-) create mode 100644 web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx create mode 100644 web/app/components/plugins/install-plugin/install-from-local-package/steps/installed.tsx create mode 100644 web/app/components/plugins/install-plugin/install-from-local-package/steps/uploading.tsx create mode 100644 web/app/components/plugins/install-plugin/utils.ts diff --git a/web/app/components/plugins/card/index.tsx b/web/app/components/plugins/card/index.tsx index 049d92536b..1ba801eac3 100644 --- a/web/app/components/plugins/card/index.tsx +++ b/web/app/components/plugins/card/index.tsx @@ -11,7 +11,7 @@ import Placeholder from './base/placeholder' import cn from '@/utils/classnames' import { useGetLanguage } from '@/context/i18n' -type Props = { +export type Props = { className?: string payload: Plugin titleLeft?: React.ReactNode diff --git a/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx b/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx index 6fd0feead9..f3e618ad08 100644 --- a/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx +++ b/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx @@ -1,57 +1,47 @@ 'use client' -import React, { useCallback, useEffect, useState } from 'react' +import React, { useCallback, useState } from 'react' import { useContext } from 'use-context-selector' -import { RiLoader2Line } from '@remixicon/react' -import Card from '../../card' -import { toolNotion } from '../../card/card-mock' import Modal from '@/app/components/base/modal' -import Button from '@/app/components/base/button' import I18n from '@/context/i18n' +import type { PluginDeclaration } from '../../types' +import { InstallStep } from '../../types' +import Uploading from './steps/uploading' +import Install from './steps/install' +import Installed from './steps/installed' type InstallFromLocalPackageProps = { file: File + onSuccess: () => void onClose: () => void } -const InstallFromLocalPackage: React.FC<InstallFromLocalPackageProps> = ({ onClose }) => { - const [status, setStatus] = useState<'uploading' | 'ready' | 'installing' | 'installed'>('uploading') +const InstallFromLocalPackage: React.FC<InstallFromLocalPackageProps> = ({ + file, + onClose +}) => { + const [step, setStep] = useState<InstallStep>(InstallStep.uploading) const { locale } = useContext(I18n) - useEffect(() => { - const timer = setTimeout(() => setStatus('ready'), 1500) - return () => clearTimeout(timer) + const [uniqueIdentifier, setUniqueIdentifier] = useState<string | null>(null) + const [manifest, setManifest] = useState<PluginDeclaration | null>({ + name: 'Notion Sync', + description: 'Sync your Notion notes with Dify', + } as any) + + const handleUploaded = useCallback((result: { + uniqueIdentifier: string + manifest: PluginDeclaration + }) => { + setUniqueIdentifier(result.uniqueIdentifier) + setManifest(result.manifest) + setStep(InstallStep.readyToInstall) }, []) - const handleInstall = useCallback(async () => { - setStatus('installing') - await new Promise(resolve => setTimeout(resolve, 1000)) - setStatus('installed') + const handleInstalled = useCallback(async () => { + setStep(InstallStep.installed) }, []) - const renderStatusMessage = () => { - switch (status) { - case 'uploading': - return ( - <div className='flex items-center gap-1 self-stretch'> - <RiLoader2Line className='text-text-accent w-4 h-4' /> - <div className='text-text-secondary system-md-regular'> - Uploading notion-sync.difypkg ... - </div> - </div> - ) - case 'installed': - return <p className='text-text-secondary system-md-regular'>The plugin has been installed successfully.</p> - default: - return ( - <div className='text-text-secondary system-md-regular'> - <p>About to install the following plugin.</p> - <p>Please make sure that you only install plugins from a <span className='system-md-semibold'>trusted source</span>.</p> - </div> - ) - } - } - return ( <Modal isShow={true} @@ -64,39 +54,30 @@ const InstallFromLocalPackage: React.FC<InstallFromLocalPackageProps> = ({ onClo Install plugin </div> </div> - <div className='flex flex-col px-6 py-3 justify-center items-start gap-4 self-stretch'> - {renderStatusMessage()} - <div className='flex p-2 items-start content-start gap-1 self-stretch flex-wrap rounded-2xl bg-background-section-burn'> - <Card - className='w-full' - payload={status === 'uploading' ? { name: 'notion-sync' } as any : toolNotion as any} - isLoading={status === 'uploading'} - loadingFileName='notion-sync.difypkg' - installed={status === 'installed'} + {step === InstallStep.uploading && ( + <Uploading + file={file} + onCancel={onClose} + onUploaded={handleUploaded} + /> + )} + { + step === InstallStep.readyToInstall && ( + <Install + payload={manifest!} + onCancel={onClose} + onInstalled={handleInstalled} /> - </div> - </div> - <div className='flex p-6 pt-5 justify-end items-center gap-2 self-stretch'> - {status === 'installed' - ? ( - <Button variant='primary' onClick={onClose}>Close</Button> - ) - : ( - <> - <Button variant='secondary' className='min-w-[72px]' onClick={onClose}> - Cancel - </Button> - <Button - variant='primary' - className='min-w-[72px]' - disabled={status !== 'ready'} - onClick={handleInstall} - > - {status === 'installing' ? 'Installing...' : 'Install'} - </Button> - </> - )} - </div> + ) + } + { + step === InstallStep.installed && ( + <Installed + payload={manifest!} + onCancel={onClose} + /> + ) + } </Modal> ) } diff --git a/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx b/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx new file mode 100644 index 0000000000..6ccfd8a88a --- /dev/null +++ b/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx @@ -0,0 +1,63 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import type { PluginDeclaration } from '../../../types' +import Card from '../../../card' +import { pluginManifestToCardPluginProps } from '../../utils' +import Button from '@/app/components/base/button' +import { sleep } from '@/utils' + +type Props = { + payload: PluginDeclaration + onCancel: () => void + onInstalled: () => void +} + +const Installed: FC<Props> = ({ + payload, + onCancel, + onInstalled, +}) => { + const [isInstalling, setIsInstalling] = React.useState(false) + + const handleInstall = async () => { + if (isInstalling) return + setIsInstalling(true) + await sleep(1500) + onInstalled() + } + + return ( + <> + <div className='flex flex-col px-6 py-3 justify-center items-start gap-4 self-stretch'> + <div className='text-text-secondary system-md-regular'> + <p>About to install the following plugin.</p> + <p>Please make sure that you only install plugins from a <span className='system-md-semibold'>trusted source</span>.</p> + </div> + <div className='flex p-2 items-start content-start gap-1 self-stretch flex-wrap rounded-2xl bg-background-section-burn'> + <Card + className='w-full' + payload={pluginManifestToCardPluginProps(payload)} + /> + </div> + </div> + {/* Action Buttons */} + <div className='flex p-6 pt-5 justify-end items-center gap-2 self-stretch'> + {!isInstalling && ( + <Button variant='secondary' className='min-w-[72px]' onClick={onCancel}> + Cancel + </Button> + )} + <Button + variant='primary' + className='min-w-[72px]' + disabled={isInstalling} + onClick={handleInstall} + > + {isInstalling ? 'Installing...' : 'Install'} + </Button> + </div> + </> + ) +} +export default React.memo(Installed) diff --git a/web/app/components/plugins/install-plugin/install-from-local-package/steps/installed.tsx b/web/app/components/plugins/install-plugin/install-from-local-package/steps/installed.tsx new file mode 100644 index 0000000000..fa07359ecc --- /dev/null +++ b/web/app/components/plugins/install-plugin/install-from-local-package/steps/installed.tsx @@ -0,0 +1,44 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import type { PluginDeclaration } from '../../../types' +import Card from '../../../card' +import Button from '@/app/components/base/button' +import { pluginManifestToCardPluginProps } from '../../utils' + +type Props = { + payload: PluginDeclaration + onCancel: () => void + +} + +const Installed: FC<Props> = ({ + payload, + onCancel +}) => { + return ( + <> + <div className='flex flex-col px-6 py-3 justify-center items-start gap-4 self-stretch'> + <p className='text-text-secondary system-md-regular'>The plugin has been installed successfully.</p> + <div className='flex p-2 items-start content-start gap-1 self-stretch flex-wrap rounded-2xl bg-background-section-burn'> + <Card + className='w-full' + payload={pluginManifestToCardPluginProps(payload)} + installed + /> + </div> + </div> + {/* Action Buttons */} + <div className='flex p-6 pt-5 justify-end items-center gap-2 self-stretch'> + <Button + variant='primary' + className='min-w-[72px]' + onClick={onCancel} + > + close + </Button> + </div> + </> + ) +} +export default React.memo(Installed) diff --git a/web/app/components/plugins/install-plugin/install-from-local-package/steps/uploading.tsx b/web/app/components/plugins/install-plugin/install-from-local-package/steps/uploading.tsx new file mode 100644 index 0000000000..5f2ce5ce74 --- /dev/null +++ b/web/app/components/plugins/install-plugin/install-from-local-package/steps/uploading.tsx @@ -0,0 +1,76 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import { RiLoader2Line } from '@remixicon/react' +import Card from '../../../card' +import type { PluginDeclaration } from '../../../types' +import Button from '@/app/components/base/button' +import { sleep } from '@/utils' + +type Props = { + file: File + onCancel: () => void + onUploaded: (result: { + uniqueIdentifier: string + manifest: PluginDeclaration + }) => void +} + +const Uploading: FC<Props> = ({ + file, + onCancel, + onUploaded, +}) => { + const fileName = file.name + const handleUpload = async () => { + await sleep(1500) + onUploaded({ + uniqueIdentifier: 'yeuoly/neko:0.0.1@5395654da2c0b919b3d9b946a1a0545b737004380765e5f3b8c49976d3276c87', + manifest: { + name: 'Notion Sync', + description: 'Sync your Notion notes with Dify', + } as any, + }) + } + + React.useEffect(() => { + handleUpload() + }, []) + return ( + <> + <div className='flex flex-col px-6 py-3 justify-center items-start gap-4 self-stretch'> + <div className='flex items-center gap-1 self-stretch'> + <RiLoader2Line className='text-text-accent w-4 h-4' /> + <div className='text-text-secondary system-md-regular'> + Uploading {fileName}... + </div> + </div> + <div className='flex p-2 items-start content-start gap-1 self-stretch flex-wrap rounded-2xl bg-background-section-burn'> + <Card + className='w-full' + payload={{ name: fileName } as any} + isLoading + loadingFileName={fileName} + installed={false} + /> + </div> + </div> + + {/* Action Buttons */} + <div className='flex p-6 pt-5 justify-end items-center gap-2 self-stretch'> + <Button variant='secondary' className='min-w-[72px]' onClick={onCancel}> + Cancel + </Button> + <Button + variant='primary' + className='min-w-[72px]' + disabled + > + installing + </Button> + </div> + </> + ) +} + +export default React.memo(Uploading) diff --git a/web/app/components/plugins/install-plugin/utils.ts b/web/app/components/plugins/install-plugin/utils.ts new file mode 100644 index 0000000000..f3d9158d53 --- /dev/null +++ b/web/app/components/plugins/install-plugin/utils.ts @@ -0,0 +1,21 @@ +import type { Plugin, PluginDeclaration } from "../types" + +export const pluginManifestToCardPluginProps = (pluginManifest: PluginDeclaration): Plugin => { + return { + type: pluginManifest.category, + category: pluginManifest.category, + name: pluginManifest.name, + version: pluginManifest.version, + latest_version: '', + org: pluginManifest.author, + label: pluginManifest.label, + brief: pluginManifest.description, + icon: pluginManifest.icon, + introduction: '', + repository: '', + install_count: 0, + endpoint: { + settings: [] + } + } +} diff --git a/web/app/components/plugins/plugin-page/index.tsx b/web/app/components/plugins/plugin-page/index.tsx index 66c2cd1318..598c2d7015 100644 --- a/web/app/components/plugins/plugin-page/index.tsx +++ b/web/app/components/plugins/plugin-page/index.tsx @@ -149,7 +149,11 @@ const PluginPage = ({ <span className="system-xs-regular">Drop plugin package here to install</span> </div> {currentFile && ( - <InstallFromLocalPackage file={currentFile} onClose={removeFile ?? (() => { })} /> + <InstallFromLocalPackage + file={currentFile} + onClose={removeFile ?? (() => { })} + onSuccess={() => { }} + /> )} <input ref={fileUploader} diff --git a/web/app/components/plugins/plugin-page/install-plugin-dropdown.tsx b/web/app/components/plugins/plugin-page/install-plugin-dropdown.tsx index e3c3a77755..cd682f42b7 100644 --- a/web/app/components/plugins/plugin-page/install-plugin-dropdown.tsx +++ b/web/app/components/plugins/plugin-page/install-plugin-dropdown.tsx @@ -94,11 +94,13 @@ const InstallPluginDropdown = () => { </PortalToFollowElemContent> </div> {selectedAction === 'marketplace' && <InstallFromMarketplace onClose={() => setSelectedAction(null)} />} - {selectedAction === 'github' && <InstallFromGitHub onClose={() => setSelectedAction(null)}/>} + {selectedAction === 'github' && <InstallFromGitHub onClose={() => setSelectedAction(null)} />} {selectedAction === 'local' && selectedFile && (<InstallFromLocalPackage file={selectedFile} - onClose={() => setSelectedAction(null)}/> + onClose={() => setSelectedAction(null)} + onSuccess={() => { }} + /> ) } </PortalToFollowElem> diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts index b6f00802f3..adf8c5a0f5 100644 --- a/web/app/components/plugins/types.ts +++ b/web/app/components/plugins/types.ts @@ -52,6 +52,7 @@ export type EndpointListItem = { hook_id: string } +// Plugin manifest export type PluginDeclaration = { version: string author: string @@ -150,6 +151,13 @@ export type UpdateEndpointRequest = { name: string } +export enum InstallStep { + uploading = 'uploading', + readyToInstall = 'readyToInstall', + installing = 'installing', + installed = 'installed', +} + export type GitHubAsset = { id: number name: string From 583b0e9f979b754e26d31e04f705260df1e042a6 Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Tue, 22 Oct 2024 17:29:58 +0800 Subject: [PATCH 131/346] chore: remove replicated types --- web/app/components/plugins/types.ts | 33 ++++++++++++----------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts index adf8c5a0f5..936b8d1860 100644 --- a/web/app/components/plugins/types.ts +++ b/web/app/components/plugins/types.ts @@ -88,20 +88,20 @@ export type PluginDetail = { } export type Plugin = { - 'type': PluginType - 'org': string - 'name': string - 'version': string - 'latest_version': string - 'icon': string - 'label': Record<Locale, string> - 'brief': Record<Locale, string> + type: PluginType + org: string + name: string + version: string + latest_version: string + icon: string + label: Record<Locale, string> + brief: Record<Locale, string> // Repo readme.md content - 'introduction': string - 'repository': string - 'category': string - 'install_count': number - 'endpoint': { + introduction: string + repository: string + category: string + install_count: number + endpoint: { settings: CredentialFormSchemaBase[] } } @@ -117,13 +117,6 @@ export type Permissions = { canDebugger: PermissionType } -export enum InstallStep { - url = 'url', - version = 'version', - package = 'package', - installed = 'installed' -} - // endpoint export type CreateEndpointRequest = { plugin_unique_identifier: string From a567cff80981df784fe26b8fa0ceee70722c73d8 Mon Sep 17 00:00:00 2001 From: Yi <yxiaoisme@gmail.com> Date: Tue, 22 Oct 2024 17:51:14 +0800 Subject: [PATCH 132/346] chore: update the install from GitHub component --- .../install-from-github/index.tsx | 193 +++++------------- .../install-from-github/steps/installed.tsx | 50 +++++ .../install-from-github/steps/setPackage.tsx | 49 +++++ .../install-from-github/steps/setURL.tsx | 50 +++++ .../install-from-github/steps/setVersion.tsx | 49 +++++ web/app/components/plugins/types.ts | 36 ++-- 6 files changed, 266 insertions(+), 161 deletions(-) create mode 100644 web/app/components/plugins/install-plugin/install-from-github/steps/installed.tsx create mode 100644 web/app/components/plugins/install-plugin/install-from-github/steps/setPackage.tsx create mode 100644 web/app/components/plugins/install-plugin/install-from-github/steps/setURL.tsx create mode 100644 web/app/components/plugins/install-plugin/install-from-github/steps/setVersion.tsx diff --git a/web/app/components/plugins/install-plugin/install-from-github/index.tsx b/web/app/components/plugins/install-plugin/install-from-github/index.tsx index 055c13b567..731c7db7ac 100644 --- a/web/app/components/plugins/install-plugin/install-from-github/index.tsx +++ b/web/app/components/plugins/install-plugin/install-from-github/index.tsx @@ -2,12 +2,14 @@ import React, { useState } from 'react' import Modal from '@/app/components/base/modal' -import Button from '@/app/components/base/button' import type { Item } from '@/app/components/base/select' -import { PortalSelect } from '@/app/components/base/select' import type { GitHubRepoReleaseResponse } from '@/app/components/plugins/types' -import { InstallStep } from '../../types' +import { InstallStepFromGitHub } from '../../types' import Toast from '@/app/components/base/toast' +import SetURL from './steps/setURL' +import SetVersion from './steps/setVersion' +import SetPackage from './steps/setPackage' +import Installed from './steps/installed' type InstallFromGitHubProps = { onClose: () => void @@ -20,7 +22,7 @@ type GitHubUrlInfo = { } type InstallState = { - step: InstallStep + step: InstallStepFromGitHub repoUrl: string selectedVersion: string selectedPackage: string @@ -29,7 +31,7 @@ type InstallState = { const InstallFromGitHub: React.FC<InstallFromGitHubProps> = ({ onClose }) => { const [state, setState] = useState<InstallState>({ - step: InstallStep.url, + step: InstallStepFromGitHub.setUrl, repoUrl: '', selectedVersion: '', selectedPackage: '', @@ -45,7 +47,7 @@ const InstallFromGitHub: React.FC<InstallFromGitHubProps> = ({ onClose }) => { ? (state.releases .find(release => release.tag_name === state.selectedVersion) ?.assets -.map(asset => ({ + .map(asset => ({ value: asset.browser_download_url, name: asset.name, })) || []) @@ -80,12 +82,12 @@ const InstallFromGitHub: React.FC<InstallFromGitHubProps> = ({ onClose }) => { // catch (error) { // console.error('Error installing package:') // } - setState(prevState => ({ ...prevState, step: InstallStep.installed })) + setState(prevState => ({ ...prevState, step: InstallStepFromGitHub.installed })) } const handleNext = async () => { switch (state.step) { - case InstallStep.url: { + case InstallStepFromGitHub.setUrl: { const { isValid, owner, repo } = parseGitHubUrl(state.repoUrl) if (!isValid || !owner || !repo) { Toast.notify({ @@ -107,7 +109,7 @@ const InstallFromGitHub: React.FC<InstallFromGitHubProps> = ({ onClose }) => { name: asset.name, })), })) - setState(prevState => ({ ...prevState, releases: formattedReleases, step: InstallStep.version })) + setState(prevState => ({ ...prevState, releases: formattedReleases, step: InstallStepFromGitHub.setVersion })) } catch (error) { Toast.notify({ @@ -117,10 +119,10 @@ const InstallFromGitHub: React.FC<InstallFromGitHubProps> = ({ onClose }) => { } break } - case InstallStep.version: - setState(prevState => ({ ...prevState, step: InstallStep.package })) + case InstallStepFromGitHub.setVersion: + setState(prevState => ({ ...prevState, step: InstallStepFromGitHub.setPackage })) break - case InstallStep.package: + case InstallStepFromGitHub.setPackage: handleInstall() break } @@ -129,44 +131,15 @@ const InstallFromGitHub: React.FC<InstallFromGitHubProps> = ({ onClose }) => { const handleBack = () => { setState((prevState) => { switch (prevState.step) { - case InstallStep.version: - return { ...prevState, step: InstallStep.url } - case InstallStep.package: - return { ...prevState, step: InstallStep.version } + case InstallStepFromGitHub.setVersion: + return { ...prevState, step: InstallStepFromGitHub.setUrl } + case InstallStepFromGitHub.setPackage: + return { ...prevState, step: InstallStepFromGitHub.setVersion } default: return prevState } }) } - - const isInputValid = () => { - switch (state.step) { - case InstallStep.url: - return !!state.repoUrl.trim() - case InstallStep.version: - return !!state.selectedVersion - case InstallStep.package: - return !!state.selectedPackage - default: - return true - } - } - - const InfoRow = ({ label, value }: { label: string; value: string }) => ( - <div className='flex items-center gap-3'> - <div className='flex-shrink-0 w-[72px] items-center gap-2'> - <div className='text-text-tertiary system-sm-medium truncate'> - {label} - </div> - </div> - <div className='flex-grow overflow-hidden'> - <div className='text-text-secondary text-ellipsis system-sm-medium'> - {value} - </div> - </div> - </div> - ) - return ( <Modal isShow={true} @@ -181,112 +154,46 @@ const InstallFromGitHub: React.FC<InstallFromGitHubProps> = ({ onClose }) => { Install plugin from GitHub </div> <div className='self-stretch text-text-tertiary system-xs-regular'> - {state.step !== InstallStep.installed && 'Please make sure that you only install plugins from a trusted source.'} + {state.step !== InstallStepFromGitHub.installed && 'Please make sure that you only install plugins from a trusted source.'} </div> </div> </div> - <div className={`flex px-6 py-3 flex-col justify-center items-start self-stretch ${state.step === InstallStep.installed ? 'gap-2' : 'gap-4'}`}> - {state.step === InstallStep.url && ( - <> - <label - htmlFor='repoUrl' - className='flex flex-col justify-center items-start self-stretch text-text-secondary' - > - <span className='system-sm-semibold'>GitHub repository</span> - </label> - <input - type='url' - id='repoUrl' - name='repoUrl' - value={state.repoUrl} - onChange={e => setState(prevState => ({ ...prevState, repoUrl: e.target.value }))} // TODO: needs to verify the url - className='flex items-center self-stretch rounded-lg border border-components-input-border-active - bg-components-input-bg-active shadows-shadow-xs p-2 gap-[2px] flex-grow overflow-hidden - text-components-input-text-filled text-ellipsis system-sm-regular' - placeholder='Please enter GitHub repo URL' - /> - </> + <div className={`flex px-6 py-3 flex-col justify-center items-start self-stretch ${state.step === InstallStepFromGitHub.installed ? 'gap-2' : 'gap-4'}`}> + {state.step === InstallStepFromGitHub.setUrl && ( + <SetURL + repoUrl={state.repoUrl} + onChange={value => setState(prevState => ({ ...prevState, repoUrl: value }))} + onNext={handleNext} + onCancel={onClose} + /> )} - {state.step === InstallStep.version && ( - <> - <label - htmlFor='version' - className='flex flex-col justify-center items-start self-stretch text-text-secondary' - > - <span className='system-sm-semibold'>Select version</span> - </label> - <PortalSelect - value={state.selectedVersion} - onSelect={item => setState(prevState => ({ ...prevState, selectedVersion: item.value as string }))} - items={versions} - placeholder="Please select a version" - popupClassName='w-[432px] z-[1001]' - /> - </> + {state.step === InstallStepFromGitHub.setVersion && ( + <SetVersion + selectedVersion={state.selectedVersion} + versions={versions} + onSelect={item => setState(prevState => ({ ...prevState, selectedVersion: item.value as string }))} + onNext={handleNext} + onBack={handleBack} + /> )} - {state.step === InstallStep.package && ( - <> - <label - htmlFor='package' - className='flex flex-col justify-center items-start self-stretch text-text-secondary' - > - <span className='system-sm-semibold'>Select package</span> - </label> - <PortalSelect - value={state.selectedPackage} - onSelect={item => setState(prevState => ({ ...prevState, selectedPackage: item.value as string }))} - items={packages} - placeholder="Please select a package" - popupClassName='w-[432px] z-[1001]' - /> - </> + {state.step === InstallStepFromGitHub.setPackage && ( + <SetPackage + selectedPackage={state.selectedPackage} + packages={packages} + onSelect={item => setState(prevState => ({ ...prevState, selectedPackage: item.value as string }))} + onInstall={handleInstall} + onBack={handleBack} + /> )} - {state.step === InstallStep.installed && ( - <> - <div className='text-text-secondary system-md-regular'>The plugin has been installed successfully.</div> - <div className='flex w-full p-4 flex-col justify-center items-start gap-2 rounded-2xl bg-background-section-burn'> - {[ - { label: 'Repository', value: state.repoUrl }, - { label: 'Version', value: state.selectedVersion }, - { label: 'Package', value: state.selectedPackage }, - ].map(({ label, value }) => ( - <InfoRow key={label} label={label} value={value} /> - ))} - </div> - </> + {state.step === InstallStepFromGitHub.installed && ( + <Installed + repoUrl={state.repoUrl} + selectedVersion={state.selectedVersion} + selectedPackage={state.selectedPackage} + onClose={onClose} + /> )} </div> - <div className='flex p-6 pt-5 justify-end items-center gap-2 self-stretch'> - {state.step === InstallStep.installed - ? ( - <Button - variant='primary' - className='min-w-[72px]' - onClick={onClose} - > - Close - </Button> - ) - : ( - <> - <Button - variant='secondary' - className='min-w-[72px]' - onClick={state.step === InstallStep.url ? onClose : handleBack} - > - {state.step === InstallStep.url ? 'Cancel' : 'Back'} - </Button> - <Button - variant='primary' - className='min-w-[72px]' - onClick={handleNext} - disabled={!isInputValid()} - > - {state.step === InstallStep.package ? 'Install' : 'Next'} - </Button> - </> - )} - </div> </Modal> ) } diff --git a/web/app/components/plugins/install-plugin/install-from-github/steps/installed.tsx b/web/app/components/plugins/install-plugin/install-from-github/steps/installed.tsx new file mode 100644 index 0000000000..be6dc5b312 --- /dev/null +++ b/web/app/components/plugins/install-plugin/install-from-github/steps/installed.tsx @@ -0,0 +1,50 @@ +import React from 'react' +import Button from '@/app/components/base/button' + +type InstalledProps = { + repoUrl: string + selectedVersion: string + selectedPackage: string + onClose: () => void +} + +const InfoRow = ({ label, value }: { label: string; value: string }) => ( + <div className='flex items-center gap-3'> + <div className='flex-shrink-0 w-[72px] items-center gap-2'> + <div className='text-text-tertiary system-sm-medium truncate'> + {label} + </div> + </div> + <div className='flex-grow overflow-hidden'> + <div className='text-text-secondary text-ellipsis system-sm-medium'> + {value} + </div> + </div> + </div> +) + +const Installed: React.FC<InstalledProps> = ({ repoUrl, selectedVersion, selectedPackage, onClose }) => ( + <> + <div className='text-text-secondary system-md-regular'>The plugin has been installed successfully.</div> + <div className='flex w-full p-4 flex-col justify-center items-start gap-2 rounded-2xl bg-background-section-burn'> + {[ + { label: 'Repository', value: repoUrl }, + { label: 'Version', value: selectedVersion }, + { label: 'Package', value: selectedPackage }, + ].map(({ label, value }) => ( + <InfoRow key={label} label={label} value={value} /> + ))} + </div> + <div className='flex justify-end items-center gap-2 self-stretch mt-4'> + <Button + variant='primary' + className='min-w-[72px]' + onClick={onClose} + > + Close + </Button> + </div> + </> +) + +export default Installed diff --git a/web/app/components/plugins/install-plugin/install-from-github/steps/setPackage.tsx b/web/app/components/plugins/install-plugin/install-from-github/steps/setPackage.tsx new file mode 100644 index 0000000000..2abadb8eb8 --- /dev/null +++ b/web/app/components/plugins/install-plugin/install-from-github/steps/setPackage.tsx @@ -0,0 +1,49 @@ +import React from 'react' +import type { Item } from '@/app/components/base/select' +import { PortalSelect } from '@/app/components/base/select' +import Button from '@/app/components/base/button' + +type SetPackageProps = { + selectedPackage: string + packages: Item[] + onSelect: (item: Item) => void + onInstall: () => void + onBack: () => void +} + +const SetPackage: React.FC<SetPackageProps> = ({ selectedPackage, packages, onSelect, onInstall, onBack }) => ( + <> + <label + htmlFor='package' + className='flex flex-col justify-center items-start self-stretch text-text-secondary' + > + <span className='system-sm-semibold'>Select package</span> + </label> + <PortalSelect + value={selectedPackage} + onSelect={onSelect} + items={packages} + placeholder="Please select a package" + popupClassName='w-[432px] z-[1001]' + /> + <div className='flex justify-end items-center gap-2 self-stretch mt-4'> + <Button + variant='secondary' + className='min-w-[72px]' + onClick={onBack} + > + Back + </Button> + <Button + variant='primary' + className='min-w-[72px]' + onClick={onInstall} + disabled={!selectedPackage} + > + Install + </Button> + </div> + </> +) + +export default SetPackage diff --git a/web/app/components/plugins/install-plugin/install-from-github/steps/setURL.tsx b/web/app/components/plugins/install-plugin/install-from-github/steps/setURL.tsx new file mode 100644 index 0000000000..a4bfd9f3f3 --- /dev/null +++ b/web/app/components/plugins/install-plugin/install-from-github/steps/setURL.tsx @@ -0,0 +1,50 @@ +import React from 'react' +import Button from '@/app/components/base/button' + +type SetURLProps = { + repoUrl: string + onChange: (value: string) => void + onNext: () => void + onCancel: () => void +} + +const SetURL: React.FC<SetURLProps> = ({ repoUrl, onChange, onNext, onCancel }) => ( + <> + <label + htmlFor='repoUrl' + className='flex flex-col justify-center items-start self-stretch text-text-secondary' + > + <span className='system-sm-semibold'>GitHub repository</span> + </label> + <input + type='url' + id='repoUrl' + name='repoUrl' + value={repoUrl} + onChange={e => onChange(e.target.value)} + className='flex items-center self-stretch rounded-lg border border-components-input-border-active + bg-components-input-bg-active shadows-shadow-xs p-2 gap-[2px] flex-grow overflow-hidden + text-components-input-text-filled text-ellipsis system-sm-regular' + placeholder='Please enter GitHub repo URL' + /> + <div className='flex justify-end items-center gap-2 self-stretch mt-4'> + <Button + variant='secondary' + className='min-w-[72px]' + onClick={onCancel} + > + Cancel + </Button> + <Button + variant='primary' + className='min-w-[72px]' + onClick={onNext} + disabled={!repoUrl.trim()} + > + Next + </Button> + </div> + </> +) + +export default SetURL diff --git a/web/app/components/plugins/install-plugin/install-from-github/steps/setVersion.tsx b/web/app/components/plugins/install-plugin/install-from-github/steps/setVersion.tsx new file mode 100644 index 0000000000..a3f72f0f29 --- /dev/null +++ b/web/app/components/plugins/install-plugin/install-from-github/steps/setVersion.tsx @@ -0,0 +1,49 @@ +import React from 'react' +import type { Item } from '@/app/components/base/select' +import { PortalSelect } from '@/app/components/base/select' +import Button from '@/app/components/base/button' + +type SetVersionProps = { + selectedVersion: string + versions: Item[] + onSelect: (item: Item) => void + onNext: () => void + onBack: () => void +} + +const SetVersion: React.FC<SetVersionProps> = ({ selectedVersion, versions, onSelect, onNext, onBack }) => ( + <> + <label + htmlFor='version' + className='flex flex-col justify-center items-start self-stretch text-text-secondary' + > + <span className='system-sm-semibold'>Select version</span> + </label> + <PortalSelect + value={selectedVersion} + onSelect={onSelect} + items={versions} + placeholder="Please select a version" + popupClassName='w-[432px] z-[1001]' + /> + <div className='flex justify-end items-center gap-2 self-stretch mt-4'> + <Button + variant='secondary' + className='min-w-[72px]' + onClick={onBack} + > + Back + </Button> + <Button + variant='primary' + className='min-w-[72px]' + onClick={onNext} + disabled={!selectedVersion} + > + Next + </Button> + </div> + </> +) + +export default SetVersion diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts index adf8c5a0f5..1ac4b44762 100644 --- a/web/app/components/plugins/types.ts +++ b/web/app/components/plugins/types.ts @@ -88,20 +88,20 @@ export type PluginDetail = { } export type Plugin = { - 'type': PluginType - 'org': string - 'name': string - 'version': string - 'latest_version': string - 'icon': string - 'label': Record<Locale, string> - 'brief': Record<Locale, string> + type: PluginType + org: string + name: string + version: string + latest_version: string + icon: string + label: Record<Locale, string> + brief: Record<Locale, string> // Repo readme.md content - 'introduction': string - 'repository': string - 'category': string - 'install_count': number - 'endpoint': { + introduction: string + repository: string + category: string + install_count: number + endpoint: { settings: CredentialFormSchemaBase[] } } @@ -117,11 +117,11 @@ export type Permissions = { canDebugger: PermissionType } -export enum InstallStep { - url = 'url', - version = 'version', - package = 'package', - installed = 'installed' +export enum InstallStepFromGitHub { + setUrl = 'url', + setVersion = 'version', + setPackage = 'package', + installed = 'installed', } // endpoint From 5267f34e76d2ee8e224e557ef98662b364729f92 Mon Sep 17 00:00:00 2001 From: -LAN- <laipz8200@outlook.com> Date: Tue, 22 Oct 2024 17:52:22 +0800 Subject: [PATCH 133/346] fix(segments): return empty string instead of "null" for text, log, and markdown properties (#9651) --- api/core/variables/segments.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/api/core/variables/segments.py b/api/core/variables/segments.py index 782798411e..b71882b043 100644 --- a/api/core/variables/segments.py +++ b/api/core/variables/segments.py @@ -56,15 +56,15 @@ class NoneSegment(Segment): @property def text(self) -> str: - return "null" + return "" @property def log(self) -> str: - return "null" + return "" @property def markdown(self) -> str: - return "null" + return "" class StringSegment(Segment): From d700abff0a5f150fccb1eced1a7ea2acf01bc301 Mon Sep 17 00:00:00 2001 From: KVOJJJin <jzongcode@gmail.com> Date: Tue, 22 Oct 2024 17:54:48 +0800 Subject: [PATCH 134/346] Fix: type missing of remote file in chat (#9652) --- web/app/components/base/file-uploader/utils.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/web/app/components/base/file-uploader/utils.ts b/web/app/components/base/file-uploader/utils.ts index e22594a129..4c7ef0d89b 100644 --- a/web/app/components/base/file-uploader/utils.ts +++ b/web/app/components/base/file-uploader/utils.ts @@ -44,6 +44,9 @@ export const fileUpload: FileUpload = ({ } export const getFileExtension = (fileName: string, fileMimetype: string) => { + if (fileMimetype) + return mime.getExtension(fileMimetype) || '' + if (fileName) { const fileNamePair = fileName.split('.') const fileNamePairLength = fileNamePair.length @@ -52,9 +55,6 @@ export const getFileExtension = (fileName: string, fileMimetype: string) => { return fileNamePair[fileNamePairLength - 1] } - if (fileMimetype) - return mime.getExtension(fileMimetype) || '' - return '' } From 7751070da80ff519b3f7aad83a69332fcfb1e9e7 Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Tue, 22 Oct 2024 18:11:47 +0800 Subject: [PATCH 135/346] chore: install from local i18n --- .../install-from-local-package/index.tsx | 17 ++++++++++++----- .../steps/install.tsx | 17 +++++++++++++---- .../steps/installed.tsx | 6 ++++-- .../steps/uploading.tsx | 14 ++++++++++---- web/i18n/en-US/common.ts | 1 + web/i18n/en-US/plugin.ts | 9 +++++++++ web/i18n/zh-Hans/common.ts | 1 + web/i18n/zh-Hans/plugin.ts | 9 +++++++++ 8 files changed, 59 insertions(+), 15 deletions(-) diff --git a/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx b/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx index f3e618ad08..ab378f3d2d 100644 --- a/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx +++ b/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx @@ -1,14 +1,15 @@ 'use client' import React, { useCallback, useState } from 'react' -import { useContext } from 'use-context-selector' import Modal from '@/app/components/base/modal' -import I18n from '@/context/i18n' import type { PluginDeclaration } from '../../types' import { InstallStep } from '../../types' import Uploading from './steps/uploading' import Install from './steps/install' import Installed from './steps/installed' +import { useTranslation } from 'react-i18next' + +const i18nPrefix = 'plugin.installModal' type InstallFromLocalPackageProps = { file: File @@ -18,12 +19,18 @@ type InstallFromLocalPackageProps = { const InstallFromLocalPackage: React.FC<InstallFromLocalPackageProps> = ({ file, - onClose + onClose, }) => { + const { t } = useTranslation() const [step, setStep] = useState<InstallStep>(InstallStep.uploading) - const { locale } = useContext(I18n) const [uniqueIdentifier, setUniqueIdentifier] = useState<string | null>(null) + + const getTitle = useCallback(() => { + if (step === InstallStep.installed) + return t(`${i18nPrefix}.installedSuccessfully`) + return t(`${i18nPrefix}.installPlugin`) + }, []) const [manifest, setManifest] = useState<PluginDeclaration | null>({ name: 'Notion Sync', description: 'Sync your Notion notes with Dify', @@ -51,7 +58,7 @@ const InstallFromLocalPackage: React.FC<InstallFromLocalPackageProps> = ({ > <div className='flex pt-6 pl-6 pb-3 pr-14 items-start gap-2 self-stretch'> <div className='self-stretch text-text-primary title-2xl-semi-bold'> - Install plugin + {getTitle()} </div> </div> {step === InstallStep.uploading && ( diff --git a/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx b/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx index 6ccfd8a88a..a20da68447 100644 --- a/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx +++ b/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx @@ -6,6 +6,9 @@ import Card from '../../../card' import { pluginManifestToCardPluginProps } from '../../utils' import Button from '@/app/components/base/button' import { sleep } from '@/utils' +import { Trans, useTranslation } from 'react-i18next' + +const i18nPrefix = 'plugin.installModal' type Props = { payload: PluginDeclaration @@ -18,6 +21,7 @@ const Installed: FC<Props> = ({ onCancel, onInstalled, }) => { + const { t } = useTranslation() const [isInstalling, setIsInstalling] = React.useState(false) const handleInstall = async () => { @@ -31,8 +35,13 @@ const Installed: FC<Props> = ({ <> <div className='flex flex-col px-6 py-3 justify-center items-start gap-4 self-stretch'> <div className='text-text-secondary system-md-regular'> - <p>About to install the following plugin.</p> - <p>Please make sure that you only install plugins from a <span className='system-md-semibold'>trusted source</span>.</p> + <p>{t(`${i18nPrefix}.readyToInstall`)}</p> + <p> + <Trans + i18nKey={`${i18nPrefix}.fromTrustSource`} + components={{ trustSource: <span className='system-md-semibold' /> }} + /> + </p> </div> <div className='flex p-2 items-start content-start gap-1 self-stretch flex-wrap rounded-2xl bg-background-section-burn'> <Card @@ -45,7 +54,7 @@ const Installed: FC<Props> = ({ <div className='flex p-6 pt-5 justify-end items-center gap-2 self-stretch'> {!isInstalling && ( <Button variant='secondary' className='min-w-[72px]' onClick={onCancel}> - Cancel + {t('common.operation.cancel')} </Button> )} <Button @@ -54,7 +63,7 @@ const Installed: FC<Props> = ({ disabled={isInstalling} onClick={handleInstall} > - {isInstalling ? 'Installing...' : 'Install'} + {t(`${i18nPrefix}.${isInstalling ? 'installing' : 'install'}`)} </Button> </div> </> diff --git a/web/app/components/plugins/install-plugin/install-from-local-package/steps/installed.tsx b/web/app/components/plugins/install-plugin/install-from-local-package/steps/installed.tsx index fa07359ecc..34fad51691 100644 --- a/web/app/components/plugins/install-plugin/install-from-local-package/steps/installed.tsx +++ b/web/app/components/plugins/install-plugin/install-from-local-package/steps/installed.tsx @@ -5,6 +5,7 @@ import type { PluginDeclaration } from '../../../types' import Card from '../../../card' import Button from '@/app/components/base/button' import { pluginManifestToCardPluginProps } from '../../utils' +import { useTranslation } from 'react-i18next' type Props = { payload: PluginDeclaration @@ -14,8 +15,9 @@ type Props = { const Installed: FC<Props> = ({ payload, - onCancel + onCancel, }) => { + const { t } = useTranslation() return ( <> <div className='flex flex-col px-6 py-3 justify-center items-start gap-4 self-stretch'> @@ -35,7 +37,7 @@ const Installed: FC<Props> = ({ className='min-w-[72px]' onClick={onCancel} > - close + {t('common.operation.close')} </Button> </div> </> diff --git a/web/app/components/plugins/install-plugin/install-from-local-package/steps/uploading.tsx b/web/app/components/plugins/install-plugin/install-from-local-package/steps/uploading.tsx index 5f2ce5ce74..043897f068 100644 --- a/web/app/components/plugins/install-plugin/install-from-local-package/steps/uploading.tsx +++ b/web/app/components/plugins/install-plugin/install-from-local-package/steps/uploading.tsx @@ -6,6 +6,9 @@ import Card from '../../../card' import type { PluginDeclaration } from '../../../types' import Button from '@/app/components/base/button' import { sleep } from '@/utils' +import { useTranslation } from 'react-i18next' + +const i18nPrefix = 'plugin.installModal' type Props = { file: File @@ -21,9 +24,10 @@ const Uploading: FC<Props> = ({ onCancel, onUploaded, }) => { + const { t } = useTranslation() const fileName = file.name const handleUpload = async () => { - await sleep(1500) + await sleep(3000) onUploaded({ uniqueIdentifier: 'yeuoly/neko:0.0.1@5395654da2c0b919b3d9b946a1a0545b737004380765e5f3b8c49976d3276c87', manifest: { @@ -42,7 +46,9 @@ const Uploading: FC<Props> = ({ <div className='flex items-center gap-1 self-stretch'> <RiLoader2Line className='text-text-accent w-4 h-4' /> <div className='text-text-secondary system-md-regular'> - Uploading {fileName}... + {t(`${i18nPrefix}.uploadingPackage`, { + packageName: fileName, + })} </div> </div> <div className='flex p-2 items-start content-start gap-1 self-stretch flex-wrap rounded-2xl bg-background-section-burn'> @@ -59,14 +65,14 @@ const Uploading: FC<Props> = ({ {/* Action Buttons */} <div className='flex p-6 pt-5 justify-end items-center gap-2 self-stretch'> <Button variant='secondary' className='min-w-[72px]' onClick={onCancel}> - Cancel + {t('common.operation.cancel')} </Button> <Button variant='primary' className='min-w-[72px]' disabled > - installing + {t(`${i18nPrefix}.install`)} </Button> </div> </> diff --git a/web/i18n/en-US/common.ts b/web/i18n/en-US/common.ts index 29d5581f35..654d9ec404 100644 --- a/web/i18n/en-US/common.ts +++ b/web/i18n/en-US/common.ts @@ -39,6 +39,7 @@ const translation = { duplicate: 'Duplicate', rename: 'Rename', audioSourceUnavailable: 'AudioSource is unavailable', + close: 'Close', }, errorMsg: { fieldRequired: '{{field}} is required', diff --git a/web/i18n/en-US/plugin.ts b/web/i18n/en-US/plugin.ts index b2ce5654ad..6f6579d9d4 100644 --- a/web/i18n/en-US/plugin.ts +++ b/web/i18n/en-US/plugin.ts @@ -59,6 +59,15 @@ const translation = { deleteContentRight: ' plugin?', usedInApps: 'This plugin is being used in {{num}} apps.', }, + installModal: { + installPlugin: 'Install Plugin', + installedSuccessfully: 'Install successful', + install: 'Install', + installing: 'Installing...', + uploadingPackage: 'Uploading {{packageName}}...', + readyToInstall: 'About to install the following plugin.', + fromTrustSource: 'Please make sure that you only install plugins from a <trustSource>trusted source</trustSource>.', + }, upgrade: { title: 'Upgrade Plugin', successfulTitle: 'Upgrade successful', diff --git a/web/i18n/zh-Hans/common.ts b/web/i18n/zh-Hans/common.ts index e683708e04..a783bf8424 100644 --- a/web/i18n/zh-Hans/common.ts +++ b/web/i18n/zh-Hans/common.ts @@ -39,6 +39,7 @@ const translation = { duplicate: '复制', rename: '重命名', audioSourceUnavailable: '音源不可用', + close: '关闭', }, errorMsg: { fieldRequired: '{{field}} 为必填项', diff --git a/web/i18n/zh-Hans/plugin.ts b/web/i18n/zh-Hans/plugin.ts index 69f0aeb079..35e522fd84 100644 --- a/web/i18n/zh-Hans/plugin.ts +++ b/web/i18n/zh-Hans/plugin.ts @@ -59,6 +59,15 @@ const translation = { deleteContentRight: ' 插件?', usedInApps: '此插件正在 {{num}} 个应用中使用。', }, + installModal: { + installPlugin: '安装插件', + installedSuccessfully: '安装成功', + install: '安装', + installing: '安装中...', + uploadingPackage: '上传 {{packageName}} 中...', + readyToInstall: '即将安装以下插件。', + fromTrustSource: '请保证仅从<trustSource>可信源</trustSource>安装插件。', + }, upgrade: { title: '升级插件', successfulTitle: '升级成功', From 3ae05a672d883696dc6839eb4ee0f049b4eb07cb Mon Sep 17 00:00:00 2001 From: zxhlyh <jasonapring2015@outlook.com> Date: Tue, 22 Oct 2024 18:24:13 +0800 Subject: [PATCH 136/346] fix: webapp answer icon (#9654) --- .../base/chat/chat-with-history/chat-wrapper.tsx | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/web/app/components/base/chat/chat-with-history/chat-wrapper.tsx b/web/app/components/base/chat/chat-with-history/chat-wrapper.tsx index ea68953fff..e632b14969 100644 --- a/web/app/components/base/chat/chat-with-history/chat-wrapper.tsx +++ b/web/app/components/base/chat/chat-with-history/chat-wrapper.tsx @@ -15,6 +15,7 @@ import { getUrl, stopChatMessageResponding, } from '@/service/share' +import AnswerIcon from '@/app/components/base/answer-icon' const ChatWrapper = () => { const { @@ -87,7 +88,6 @@ const ChatWrapper = () => { ) }, [ chatListRef, - appConfig, currentConversationId, currentConversationItem, handleSend, @@ -150,6 +150,15 @@ const ChatWrapper = () => { isMobile, ]) + const answerIcon = (appData?.site && appData.site.use_icon_as_answer_icon) + ? <AnswerIcon + iconType={appData.site.icon_type} + icon={appData.site.icon} + background={appData.site.icon_background} + imageUrl={appData.site.icon_url} + /> + : null + return ( <div className='h-full bg-chatbot-bg overflow-hidden' @@ -171,6 +180,7 @@ const ChatWrapper = () => { allToolIcons={appMeta?.tool_icons || {}} onFeedback={handleFeedback} suggestedQuestions={suggestedQuestions} + answerIcon={answerIcon} hideProcessDetail themeBuilder={themeBuilder} /> From 7d7e0f9800fff48cb89187cab4f938fd25207bf8 Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Tue, 22 Oct 2024 18:26:17 +0800 Subject: [PATCH 137/346] fix: tool use file caused error (#9660) --- .../nodes/tool/components/input-var-list.tsx | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/web/app/components/workflow/nodes/tool/components/input-var-list.tsx b/web/app/components/workflow/nodes/tool/components/input-var-list.tsx index 41be301a4b..9d9940b8e9 100644 --- a/web/app/components/workflow/nodes/tool/components/input-var-list.tsx +++ b/web/app/components/workflow/nodes/tool/components/input-var-list.tsx @@ -99,6 +99,18 @@ const InputVarList: FC<Props> = ({ } }, [value, onChange]) + const handleFileChange = useCallback((variable: string) => { + return (varValue: ValueSelector | string) => { + const newValue = produce(value, (draft: ToolVarInputs) => { + draft[variable] = { + type: VarKindType.variable, + value: varValue, + } + }) + onChange(newValue) + } + }, [value, onChange]) + const [inputsIsFocus, setInputsIsFocus] = useState<Record<string, boolean>>({}) const handleInputFocus = useCallback((variable: string) => { return (value: boolean) => { @@ -129,7 +141,8 @@ const InputVarList: FC<Props> = ({ const isSelect = type === FormTypeEnum.select const isFile = type === FormTypeEnum.file const isFileArray = type === FormTypeEnum.files - const isString = type !== FormTypeEnum.textNumber && type !== FormTypeEnum.files && type !== FormTypeEnum.select + const isString = !isNumber && !isSelect && !isFile && !isFileArray + return ( <div key={variable} className='space-y-1'> <div className='flex items-center h-[18px] space-x-2'> @@ -158,7 +171,6 @@ const InputVarList: FC<Props> = ({ value={varInput?.type === VarKindType.constant ? (varInput?.value || '') : (varInput?.value || [])} onChange={handleNotMixedTypeChange(variable)} onOpen={handleOpen(index)} - isSupportConstantValue={isSupportConstantValue} defaultVarKindType={varInput?.type} filterVar={isNumber ? filterVar : undefined} availableVars={isSelect ? availableVars : undefined} @@ -170,8 +182,8 @@ const InputVarList: FC<Props> = ({ readonly={readOnly} isShowNodeName nodeId={nodeId} - value={varInput?.type === VarKindType.constant ? (varInput?.value || '') : (varInput?.value || [])} - onChange={handleNotMixedTypeChange(variable)} + value={varInput?.value || []} + onChange={handleFileChange(variable)} onOpen={handleOpen(index)} defaultVarKindType={VarKindType.variable} filterVar={(varPayload: Var) => varPayload.type === VarType.file} @@ -182,8 +194,8 @@ const InputVarList: FC<Props> = ({ readonly={readOnly} isShowNodeName nodeId={nodeId} - value={varInput?.type === VarKindType.constant ? (varInput?.value || '') : (varInput?.value || [])} - onChange={handleNotMixedTypeChange(variable)} + value={varInput?.value || []} + onChange={handleFileChange(variable)} onOpen={handleOpen(index)} defaultVarKindType={VarKindType.variable} filterVar={(varPayload: Var) => varPayload.type === VarType.arrayFile} From ff956cb546d3cb4220df51fea068319e40bccd90 Mon Sep 17 00:00:00 2001 From: zxhlyh <jasonapring2015@outlook.com> Date: Tue, 22 Oct 2024 18:31:39 +0800 Subject: [PATCH 138/346] Fix/retrieval setting weight default value (#9622) --- .../configuration/dataset-config/index.tsx | 19 ++++++- .../params-config/config-content.tsx | 2 +- .../dataset-config/params-config/index.tsx | 57 ++----------------- .../components/app/configuration/index.tsx | 14 ++++- .../nodes/knowledge-retrieval/use-config.ts | 12 ++-- .../nodes/knowledge-retrieval/utils.ts | 49 +++++++++++++++- web/models/datasets.ts | 8 --- 7 files changed, 86 insertions(+), 75 deletions(-) diff --git a/web/app/components/app/configuration/dataset-config/index.tsx b/web/app/components/app/configuration/dataset-config/index.tsx index c98e90b18e..2c082d8815 100644 --- a/web/app/components/app/configuration/dataset-config/index.tsx +++ b/web/app/components/app/configuration/dataset-config/index.tsx @@ -13,6 +13,11 @@ import ContextVar from './context-var' import ConfigContext from '@/context/debug-configuration' import { AppType } from '@/types/app' import type { DataSet } from '@/models/datasets' +import { + getMultipleRetrievalConfig, +} from '@/app/components/workflow/nodes/knowledge-retrieval/utils' +import { useModelListAndDefaultModelAndCurrentProviderAndModel } from '@/app/components/header/account-setting/model-provider-page/hooks' +import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations' const Icon = ( <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> @@ -31,13 +36,25 @@ const DatasetConfig: FC = () => { setModelConfig, showSelectDataSet, isAgent, + datasetConfigs, + setDatasetConfigs, } = useContext(ConfigContext) const formattingChangedDispatcher = useFormattingChangedDispatcher() const hasData = dataSet.length > 0 + const { + currentModel: currentRerankModel, + } = useModelListAndDefaultModelAndCurrentProviderAndModel(ModelTypeEnum.rerank) + const onRemove = (id: string) => { - setDataSet(dataSet.filter(item => item.id !== id)) + const filteredDataSets = dataSet.filter(item => item.id !== id) + setDataSet(filteredDataSets) + const retrievalConfig = getMultipleRetrievalConfig(datasetConfigs as any, filteredDataSets, dataSet, !!currentRerankModel) + setDatasetConfigs({ + ...(datasetConfigs as any), + ...retrievalConfig, + }) formattingChangedDispatcher() } diff --git a/web/app/components/app/configuration/dataset-config/params-config/config-content.tsx b/web/app/components/app/configuration/dataset-config/params-config/config-content.tsx index 0068a7abbf..f4c7c4ff19 100644 --- a/web/app/components/app/configuration/dataset-config/params-config/config-content.tsx +++ b/web/app/components/app/configuration/dataset-config/params-config/config-content.tsx @@ -55,7 +55,7 @@ const ConfigContent: FC<Props> = ({ retrieval_model: RETRIEVE_TYPE.multiWay, }, isInWorkflow) } - }, [type]) + }, [type, datasetConfigs, isInWorkflow, onChange]) const { modelList: rerankModelList, diff --git a/web/app/components/app/configuration/dataset-config/params-config/index.tsx b/web/app/components/app/configuration/dataset-config/params-config/index.tsx index c8c8acccd3..207d4ba81d 100644 --- a/web/app/components/app/configuration/dataset-config/params-config/index.tsx +++ b/web/app/components/app/configuration/dataset-config/params-config/index.tsx @@ -16,7 +16,6 @@ import type { DataSet } from '@/models/datasets' import type { DatasetConfigs } from '@/models/debug' import { getMultipleRetrievalConfig, - getSelectedDatasetsMode, } from '@/app/components/workflow/nodes/knowledge-retrieval/utils' type ParamsConfigProps = { @@ -37,57 +36,8 @@ const ParamsConfig = ({ const [tempDataSetConfigs, setTempDataSetConfigs] = useState(datasetConfigs) useEffect(() => { - const { - allEconomic, - allHighQuality, - allHighQualityFullTextSearch, - allHighQualityVectorSearch, - allExternal, - mixtureHighQualityAndEconomic, - inconsistentEmbeddingModel, - mixtureInternalAndExternal, - } = getSelectedDatasetsMode(selectedDatasets) - - if (allEconomic || allHighQuality || allHighQualityFullTextSearch || allHighQualityVectorSearch || (allExternal && selectedDatasets.length === 1)) - setRerankSettingModalOpen(false) - - if (mixtureHighQualityAndEconomic || inconsistentEmbeddingModel || mixtureInternalAndExternal || (allExternal && selectedDatasets.length > 1)) - setRerankSettingModalOpen(true) - }, [selectedDatasets]) - - useEffect(() => { - const { - allEconomic, - allInternal, - allExternal, - } = getSelectedDatasetsMode(selectedDatasets) - const { datasets, retrieval_model, score_threshold_enabled, ...restConfigs } = datasetConfigs - let rerankEnable = restConfigs.reranking_enable - - if (((allInternal && allEconomic) || allExternal) && !restConfigs.reranking_model?.reranking_provider_name && rerankEnable === undefined) - rerankEnable = false - - setTempDataSetConfigs({ - ...getMultipleRetrievalConfig({ - top_k: restConfigs.top_k, - score_threshold: restConfigs.score_threshold, - reranking_model: restConfigs.reranking_model && { - provider: restConfigs.reranking_model.reranking_provider_name, - model: restConfigs.reranking_model.reranking_model_name, - }, - reranking_mode: restConfigs.reranking_mode, - weights: restConfigs.weights, - reranking_enable: rerankEnable, - }, selectedDatasets), - reranking_model: restConfigs.reranking_model && { - reranking_provider_name: restConfigs.reranking_model.reranking_provider_name, - reranking_model_name: restConfigs.reranking_model.reranking_model_name, - }, - retrieval_model, - score_threshold_enabled, - datasets, - }) - }, [selectedDatasets, datasetConfigs]) + setTempDataSetConfigs(datasetConfigs) + }, [datasetConfigs]) const { defaultModel: rerankDefaultModel, @@ -135,7 +85,7 @@ const ParamsConfig = ({ reranking_mode: restConfigs.reranking_mode, weights: restConfigs.weights, reranking_enable: restConfigs.reranking_enable, - }, selectedDatasets) + }, selectedDatasets, selectedDatasets, !!isRerankDefaultModelValid) setTempDataSetConfigs({ ...retrievalConfig, @@ -180,6 +130,7 @@ const ParamsConfig = ({ <div className='mt-6 flex justify-end'> <Button className='mr-2 flex-shrink-0' onClick={() => { + setTempDataSetConfigs(datasetConfigs) setRerankSettingModalOpen(false) }}>{t('common.operation.cancel')}</Button> <Button variant='primary' className='flex-shrink-0' onClick={handleSave} >{t('common.operation.save')}</Button> diff --git a/web/app/components/app/configuration/index.tsx b/web/app/components/app/configuration/index.tsx index fab7b238c4..434b54ab91 100644 --- a/web/app/components/app/configuration/index.tsx +++ b/web/app/components/app/configuration/index.tsx @@ -38,7 +38,7 @@ import ConfigContext from '@/context/debug-configuration' import Config from '@/app/components/app/configuration/config' import Debug from '@/app/components/app/configuration/debug' import Confirm from '@/app/components/base/confirm' -import { ModelFeatureEnum } from '@/app/components/header/account-setting/model-provider-page/declarations' +import { ModelFeatureEnum, ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations' import { ToastContext } from '@/app/components/base/toast' import { fetchAppDetail, updateAppModelConfig } from '@/service/apps' import { promptVariablesToUserInputsForm, userInputsFormToPromptVariables } from '@/utils/model-config' @@ -53,7 +53,10 @@ import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints' import Drawer from '@/app/components/base/drawer' import ModelParameterModal from '@/app/components/header/account-setting/model-provider-page/model-parameter-modal' import type { FormValue } from '@/app/components/header/account-setting/model-provider-page/declarations' -import { useTextGenerationCurrentProviderAndModelAndModelList } from '@/app/components/header/account-setting/model-provider-page/hooks' +import { + useModelListAndDefaultModelAndCurrentProviderAndModel, + useTextGenerationCurrentProviderAndModelAndModelList, +} from '@/app/components/header/account-setting/model-provider-page/hooks' import { fetchCollectionList } from '@/service/tools' import { type Collection } from '@/app/components/tools/types' import { useStore as useAppStore } from '@/app/components/app/store' @@ -217,6 +220,9 @@ const Configuration: FC = () => { const [isShowSelectDataSet, { setTrue: showSelectDataSet, setFalse: hideSelectDataSet }] = useBoolean(false) const selectedIds = dataSets.map(item => item.id) const [rerankSettingModalOpen, setRerankSettingModalOpen] = useState(false) + const { + currentModel: currentRerankModel, + } = useModelListAndDefaultModelAndCurrentProviderAndModel(ModelTypeEnum.rerank) const handleSelect = (data: DataSet[]) => { if (isEqual(data.map(item => item.id), dataSets.map(item => item.id))) { hideSelectDataSet() @@ -263,7 +269,7 @@ const Configuration: FC = () => { reranking_mode: restConfigs.reranking_mode, weights: restConfigs.weights, reranking_enable: restConfigs.reranking_enable, - }, newDatasets) + }, newDatasets, dataSets, !!currentRerankModel) setDatasetConfigs({ ...retrievalConfig, @@ -603,9 +609,11 @@ const Configuration: FC = () => { syncToPublishedConfig(config) setPublishedConfig(config) + const retrievalConfig = getMultipleRetrievalConfig(modelConfig.dataset_configs, datasets, datasets, !!currentRerankModel) setDatasetConfigs({ retrieval_model: RETRIEVE_TYPE.multiWay, ...modelConfig.dataset_configs, + ...retrievalConfig, }) setHasFetchedDetail(true) }) diff --git a/web/app/components/workflow/nodes/knowledge-retrieval/use-config.ts b/web/app/components/workflow/nodes/knowledge-retrieval/use-config.ts index 01c1e31ccc..d280a2d63e 100644 --- a/web/app/components/workflow/nodes/knowledge-retrieval/use-config.ts +++ b/web/app/components/workflow/nodes/knowledge-retrieval/use-config.ts @@ -163,7 +163,7 @@ const useConfig = (id: string, payload: KnowledgeRetrievalNodeType) => { draft.retrieval_mode = newMode if (newMode === RETRIEVE_TYPE.multiWay) { const multipleRetrievalConfig = draft.multiple_retrieval_config - draft.multiple_retrieval_config = getMultipleRetrievalConfig(multipleRetrievalConfig!, selectedDatasets) + draft.multiple_retrieval_config = getMultipleRetrievalConfig(multipleRetrievalConfig!, selectedDatasets, selectedDatasets, !!currentRerankModel) } else { const hasSetModel = draft.single_retrieval_config?.model?.provider @@ -180,14 +180,14 @@ const useConfig = (id: string, payload: KnowledgeRetrievalNodeType) => { } }) setInputs(newInputs) - }, [currentModel?.model, currentModel?.model_properties?.mode, currentProvider?.provider, inputs, setInputs, selectedDatasets]) + }, [currentModel?.model, currentModel?.model_properties?.mode, currentProvider?.provider, inputs, setInputs, selectedDatasets, currentRerankModel]) const handleMultipleRetrievalConfigChange = useCallback((newConfig: MultipleRetrievalConfig) => { const newInputs = produce(inputs, (draft) => { - draft.multiple_retrieval_config = getMultipleRetrievalConfig(newConfig!, selectedDatasets) + draft.multiple_retrieval_config = getMultipleRetrievalConfig(newConfig!, selectedDatasets, selectedDatasets, !!currentRerankModel) }) setInputs(newInputs) - }, [inputs, setInputs, selectedDatasets]) + }, [inputs, setInputs, selectedDatasets, currentRerankModel]) // datasets useEffect(() => { @@ -231,7 +231,7 @@ const useConfig = (id: string, payload: KnowledgeRetrievalNodeType) => { if (payload.retrieval_mode === RETRIEVE_TYPE.multiWay && newDatasets.length > 0) { const multipleRetrievalConfig = draft.multiple_retrieval_config - draft.multiple_retrieval_config = getMultipleRetrievalConfig(multipleRetrievalConfig!, newDatasets) + draft.multiple_retrieval_config = getMultipleRetrievalConfig(multipleRetrievalConfig!, newDatasets, selectedDatasets, !!currentRerankModel) } }) setInputs(newInputs) @@ -243,7 +243,7 @@ const useConfig = (id: string, payload: KnowledgeRetrievalNodeType) => { || (allExternal && newDatasets.length > 1) ) setRerankModelOpen(true) - }, [inputs, setInputs, payload.retrieval_mode]) + }, [inputs, setInputs, payload.retrieval_mode, selectedDatasets, currentRerankModel]) const filterVar = useCallback((varPayload: Var) => { return varPayload.type === VarType.string diff --git a/web/app/components/workflow/nodes/knowledge-retrieval/utils.ts b/web/app/components/workflow/nodes/knowledge-retrieval/utils.ts index e48777d948..fd3d3ebab9 100644 --- a/web/app/components/workflow/nodes/knowledge-retrieval/utils.ts +++ b/web/app/components/workflow/nodes/knowledge-retrieval/utils.ts @@ -1,4 +1,7 @@ -import { uniq } from 'lodash-es' +import { + uniq, + xorBy, +} from 'lodash-es' import type { MultipleRetrievalConfig } from './types' import type { DataSet, @@ -15,7 +18,9 @@ export const checkNodeValid = () => { return true } -export const getSelectedDatasetsMode = (datasets: DataSet[]) => { +export const getSelectedDatasetsMode = (datasets: DataSet[] = []) => { + if (datasets === null) + datasets = [] let allHighQuality = true let allHighQualityVectorSearch = true let allHighQualityFullTextSearch = true @@ -85,7 +90,14 @@ export const getSelectedDatasetsMode = (datasets: DataSet[]) => { } as SelectedDatasetsMode } -export const getMultipleRetrievalConfig = (multipleRetrievalConfig: MultipleRetrievalConfig, selectedDatasets: DataSet[]) => { +export const getMultipleRetrievalConfig = ( + multipleRetrievalConfig: MultipleRetrievalConfig, + selectedDatasets: DataSet[], + originalDatasets: DataSet[], + isValidRerankModel?: boolean, +) => { + const shouldSetWeightDefaultValue = xorBy(selectedDatasets, originalDatasets, 'id').length > 0 + const { allHighQuality, allHighQualityVectorSearch, @@ -123,6 +135,37 @@ export const getMultipleRetrievalConfig = (multipleRetrievalConfig: MultipleRetr result.reranking_mode = RerankingModeEnum.WeightedScore if (allHighQuality && !inconsistentEmbeddingModel && (reranking_mode === RerankingModeEnum.WeightedScore || reranking_mode === undefined) && allInternal && !weights) { + if (!isValidRerankModel) + result.reranking_mode = RerankingModeEnum.WeightedScore + else + result.reranking_mode = RerankingModeEnum.RerankingModel + + result.weights = { + vector_setting: { + vector_weight: allHighQualityVectorSearch + ? DEFAULT_WEIGHTED_SCORE.allHighQualityVectorSearch.semantic + : allHighQualityFullTextSearch + ? DEFAULT_WEIGHTED_SCORE.allHighQualityFullTextSearch.semantic + : DEFAULT_WEIGHTED_SCORE.other.semantic, + embedding_provider_name: selectedDatasets[0].embedding_model_provider, + embedding_model_name: selectedDatasets[0].embedding_model, + }, + keyword_setting: { + keyword_weight: allHighQualityVectorSearch + ? DEFAULT_WEIGHTED_SCORE.allHighQualityVectorSearch.keyword + : allHighQualityFullTextSearch + ? DEFAULT_WEIGHTED_SCORE.allHighQualityFullTextSearch.keyword + : DEFAULT_WEIGHTED_SCORE.other.keyword, + }, + } + } + + if (shouldSetWeightDefaultValue && allHighQuality && !inconsistentEmbeddingModel && (reranking_mode === RerankingModeEnum.WeightedScore || reranking_mode === undefined || !isValidRerankModel) && allInternal && weights) { + if (!isValidRerankModel) + result.reranking_mode = RerankingModeEnum.WeightedScore + else + result.reranking_mode = RerankingModeEnum.RerankingModel + result.weights = { vector_setting: { vector_weight: allHighQualityVectorSearch diff --git a/web/models/datasets.ts b/web/models/datasets.ts index 81a750968b..1ecaa3e10b 100644 --- a/web/models/datasets.ts +++ b/web/models/datasets.ts @@ -566,14 +566,6 @@ export const DEFAULT_WEIGHTED_SCORE = { semantic: 0, keyword: 1.0, }, - semanticFirst: { - semantic: 0.7, - keyword: 0.3, - }, - keywordFirst: { - semantic: 0.3, - keyword: 0.7, - }, other: { semantic: 0.7, keyword: 0.3, From 18a266eac2d791d3c613dbe597e90bd1ad639448 Mon Sep 17 00:00:00 2001 From: Yi <yxiaoisme@gmail.com> Date: Tue, 22 Oct 2024 18:39:23 +0800 Subject: [PATCH 139/346] chore: i18n for install from GitHub section --- .../install-from-github/index.tsx | 24 ++---- .../install-from-github/steps/installed.tsx | 50 ++++++------ .../install-from-github/steps/setPackage.tsx | 70 +++++++++-------- .../install-from-github/steps/setURL.tsx | 78 ++++++++++--------- .../install-from-github/steps/setVersion.tsx | 70 +++++++++-------- .../filter-management/search-box.tsx | 3 +- web/app/components/plugins/types.ts | 14 ++++ web/i18n/en-US/plugin.ts | 21 +++++ web/i18n/zh-Hans/plugin.ts | 21 +++++ 9 files changed, 206 insertions(+), 145 deletions(-) diff --git a/web/app/components/plugins/install-plugin/install-from-github/index.tsx b/web/app/components/plugins/install-plugin/install-from-github/index.tsx index 731c7db7ac..06c4c0797a 100644 --- a/web/app/components/plugins/install-plugin/install-from-github/index.tsx +++ b/web/app/components/plugins/install-plugin/install-from-github/index.tsx @@ -3,33 +3,21 @@ import React, { useState } from 'react' import Modal from '@/app/components/base/modal' import type { Item } from '@/app/components/base/select' -import type { GitHubRepoReleaseResponse } from '@/app/components/plugins/types' +import type { GitHubUrlInfo, InstallState } from '@/app/components/plugins/types' import { InstallStepFromGitHub } from '../../types' import Toast from '@/app/components/base/toast' import SetURL from './steps/setURL' import SetVersion from './steps/setVersion' import SetPackage from './steps/setPackage' import Installed from './steps/installed' +import { useTranslation } from 'react-i18next' type InstallFromGitHubProps = { onClose: () => void } -type GitHubUrlInfo = { - isValid: boolean - owner?: string - repo?: string -} - -type InstallState = { - step: InstallStepFromGitHub - repoUrl: string - selectedVersion: string - selectedPackage: string - releases: GitHubRepoReleaseResponse[] -} - const InstallFromGitHub: React.FC<InstallFromGitHubProps> = ({ onClose }) => { + const { t } = useTranslation() const [state, setState] = useState<InstallState>({ step: InstallStepFromGitHub.setUrl, repoUrl: '', @@ -92,7 +80,7 @@ const InstallFromGitHub: React.FC<InstallFromGitHubProps> = ({ onClose }) => { if (!isValid || !owner || !repo) { Toast.notify({ type: 'error', - message: 'Invalid GitHub URL. Please enter a valid URL in the format: https://github.com/owner/repo', + message: t('plugin.error.inValidGitHubUrl'), }) break } @@ -151,10 +139,10 @@ const InstallFromGitHub: React.FC<InstallFromGitHubProps> = ({ onClose }) => { <div className='flex pt-6 pl-6 pb-3 pr-14 items-start gap-2 self-stretch'> <div className='flex flex-col items-start gap-1 flex-grow'> <div className='self-stretch text-text-primary title-2xl-semi-bold'> - Install plugin from GitHub + {t('plugin.installFromGitHub.installPlugin')} </div> <div className='self-stretch text-text-tertiary system-xs-regular'> - {state.step !== InstallStepFromGitHub.installed && 'Please make sure that you only install plugins from a trusted source.'} + {state.step !== InstallStepFromGitHub.installed && t('plugin.installFromGitHub.installNote')} </div> </div> </div> diff --git a/web/app/components/plugins/install-plugin/install-from-github/steps/installed.tsx b/web/app/components/plugins/install-plugin/install-from-github/steps/installed.tsx index be6dc5b312..97be133451 100644 --- a/web/app/components/plugins/install-plugin/install-from-github/steps/installed.tsx +++ b/web/app/components/plugins/install-plugin/install-from-github/steps/installed.tsx @@ -1,5 +1,6 @@ import React from 'react' import Button from '@/app/components/base/button' +import { useTranslation } from 'react-i18next' type InstalledProps = { repoUrl: string @@ -23,28 +24,31 @@ const InfoRow = ({ label, value }: { label: string; value: string }) => ( </div> ) -const Installed: React.FC<InstalledProps> = ({ repoUrl, selectedVersion, selectedPackage, onClose }) => ( - <> - <div className='text-text-secondary system-md-regular'>The plugin has been installed successfully.</div> - <div className='flex w-full p-4 flex-col justify-center items-start gap-2 rounded-2xl bg-background-section-burn'> - {[ - { label: 'Repository', value: repoUrl }, - { label: 'Version', value: selectedVersion }, - { label: 'Package', value: selectedPackage }, - ].map(({ label, value }) => ( - <InfoRow key={label} label={label} value={value} /> - ))} - </div> - <div className='flex justify-end items-center gap-2 self-stretch mt-4'> - <Button - variant='primary' - className='min-w-[72px]' - onClick={onClose} - > - Close - </Button> - </div> - </> -) +const Installed: React.FC<InstalledProps> = ({ repoUrl, selectedVersion, selectedPackage, onClose }) => { + const { t } = useTranslation() + return ( + <> + <div className='text-text-secondary system-md-regular'>The plugin has been installed successfully.</div> + <div className='flex w-full p-4 flex-col justify-center items-start gap-2 rounded-2xl bg-background-section-burn'> + {[ + { label: t('plugin.installModal.labels.repository'), value: repoUrl }, + { label: t('plugin.installModal.labels.version'), value: selectedVersion }, + { label: t('plugin.installModal.labels.package'), value: selectedPackage }, + ].map(({ label, value }) => ( + <InfoRow key={label} label={label} value={value} /> + ))} + </div> + <div className='flex justify-end items-center gap-2 self-stretch mt-4'> + <Button + variant='primary' + className='min-w-[72px]' + onClick={onClose} + > + {t('plugin.installModal.close')} + </Button> + </div> + </> + ) +} export default Installed diff --git a/web/app/components/plugins/install-plugin/install-from-github/steps/setPackage.tsx b/web/app/components/plugins/install-plugin/install-from-github/steps/setPackage.tsx index 2abadb8eb8..2db55aa56f 100644 --- a/web/app/components/plugins/install-plugin/install-from-github/steps/setPackage.tsx +++ b/web/app/components/plugins/install-plugin/install-from-github/steps/setPackage.tsx @@ -2,6 +2,7 @@ import React from 'react' import type { Item } from '@/app/components/base/select' import { PortalSelect } from '@/app/components/base/select' import Button from '@/app/components/base/button' +import { useTranslation } from 'react-i18next' type SetPackageProps = { selectedPackage: string @@ -11,39 +12,42 @@ type SetPackageProps = { onBack: () => void } -const SetPackage: React.FC<SetPackageProps> = ({ selectedPackage, packages, onSelect, onInstall, onBack }) => ( - <> - <label - htmlFor='package' - className='flex flex-col justify-center items-start self-stretch text-text-secondary' - > - <span className='system-sm-semibold'>Select package</span> - </label> - <PortalSelect - value={selectedPackage} - onSelect={onSelect} - items={packages} - placeholder="Please select a package" - popupClassName='w-[432px] z-[1001]' - /> - <div className='flex justify-end items-center gap-2 self-stretch mt-4'> - <Button - variant='secondary' - className='min-w-[72px]' - onClick={onBack} +const SetPackage: React.FC<SetPackageProps> = ({ selectedPackage, packages, onSelect, onInstall, onBack }) => { + const { t } = useTranslation() + return ( + <> + <label + htmlFor='package' + className='flex flex-col justify-center items-start self-stretch text-text-secondary' > - Back - </Button> - <Button - variant='primary' - className='min-w-[72px]' - onClick={onInstall} - disabled={!selectedPackage} - > - Install - </Button> - </div> - </> -) + <span className='system-sm-semibold'>{t('plugin.installFromGitHub.selectPackage')}</span> + </label> + <PortalSelect + value={selectedPackage} + onSelect={onSelect} + items={packages} + placeholder={t('plugin.installFromGitHub.selectPackagePlaceholder') || ''} + popupClassName='w-[432px] z-[1001]' + /> + <div className='flex justify-end items-center gap-2 self-stretch mt-4'> + <Button + variant='secondary' + className='min-w-[72px]' + onClick={onBack} + > + {t('plugin.installModal.back')} + </Button> + <Button + variant='primary' + className='min-w-[72px]' + onClick={onInstall} + disabled={!selectedPackage} + > + {t('plugin.installModal.install')} + </Button> + </div> + </> + ) +} export default SetPackage diff --git a/web/app/components/plugins/install-plugin/install-from-github/steps/setURL.tsx b/web/app/components/plugins/install-plugin/install-from-github/steps/setURL.tsx index a4bfd9f3f3..9ec6cd6eee 100644 --- a/web/app/components/plugins/install-plugin/install-from-github/steps/setURL.tsx +++ b/web/app/components/plugins/install-plugin/install-from-github/steps/setURL.tsx @@ -1,5 +1,6 @@ import React from 'react' import Button from '@/app/components/base/button' +import { useTranslation } from 'react-i18next' type SetURLProps = { repoUrl: string @@ -8,43 +9,46 @@ type SetURLProps = { onCancel: () => void } -const SetURL: React.FC<SetURLProps> = ({ repoUrl, onChange, onNext, onCancel }) => ( - <> - <label - htmlFor='repoUrl' - className='flex flex-col justify-center items-start self-stretch text-text-secondary' - > - <span className='system-sm-semibold'>GitHub repository</span> - </label> - <input - type='url' - id='repoUrl' - name='repoUrl' - value={repoUrl} - onChange={e => onChange(e.target.value)} - className='flex items-center self-stretch rounded-lg border border-components-input-border-active - bg-components-input-bg-active shadows-shadow-xs p-2 gap-[2px] flex-grow overflow-hidden - text-components-input-text-filled text-ellipsis system-sm-regular' - placeholder='Please enter GitHub repo URL' - /> - <div className='flex justify-end items-center gap-2 self-stretch mt-4'> - <Button - variant='secondary' - className='min-w-[72px]' - onClick={onCancel} +const SetURL: React.FC<SetURLProps> = ({ repoUrl, onChange, onNext, onCancel }) => { + const { t } = useTranslation() + return ( + <> + <label + htmlFor='repoUrl' + className='flex flex-col justify-center items-start self-stretch text-text-secondary' > - Cancel - </Button> - <Button - variant='primary' - className='min-w-[72px]' - onClick={onNext} - disabled={!repoUrl.trim()} - > - Next - </Button> - </div> - </> -) + <span className='system-sm-semibold'>{t('plugin.installFromGitHub.gitHubRepo')}</span> + </label> + <input + type='url' + id='repoUrl' + name='repoUrl' + value={repoUrl} + onChange={e => onChange(e.target.value)} + className='flex items-center self-stretch rounded-lg border border-components-input-border-active + bg-components-input-bg-active shadows-shadow-xs p-2 gap-[2px] flex-grow overflow-hidden + text-components-input-text-filled text-ellipsis system-sm-regular' + placeholder='Please enter GitHub repo URL' + /> + <div className='flex justify-end items-center gap-2 self-stretch mt-4'> + <Button + variant='secondary' + className='min-w-[72px]' + onClick={onCancel} + > + {t('plugin.installModal.cancel')} + </Button> + <Button + variant='primary' + className='min-w-[72px]' + onClick={onNext} + disabled={!repoUrl.trim()} + > + {t('plugin.installModal.next')} + </Button> + </div> + </> + ) +} export default SetURL diff --git a/web/app/components/plugins/install-plugin/install-from-github/steps/setVersion.tsx b/web/app/components/plugins/install-plugin/install-from-github/steps/setVersion.tsx index a3f72f0f29..042ab2b093 100644 --- a/web/app/components/plugins/install-plugin/install-from-github/steps/setVersion.tsx +++ b/web/app/components/plugins/install-plugin/install-from-github/steps/setVersion.tsx @@ -2,6 +2,7 @@ import React from 'react' import type { Item } from '@/app/components/base/select' import { PortalSelect } from '@/app/components/base/select' import Button from '@/app/components/base/button' +import { useTranslation } from 'react-i18next' type SetVersionProps = { selectedVersion: string @@ -11,39 +12,42 @@ type SetVersionProps = { onBack: () => void } -const SetVersion: React.FC<SetVersionProps> = ({ selectedVersion, versions, onSelect, onNext, onBack }) => ( - <> - <label - htmlFor='version' - className='flex flex-col justify-center items-start self-stretch text-text-secondary' - > - <span className='system-sm-semibold'>Select version</span> - </label> - <PortalSelect - value={selectedVersion} - onSelect={onSelect} - items={versions} - placeholder="Please select a version" - popupClassName='w-[432px] z-[1001]' - /> - <div className='flex justify-end items-center gap-2 self-stretch mt-4'> - <Button - variant='secondary' - className='min-w-[72px]' - onClick={onBack} +const SetVersion: React.FC<SetVersionProps> = ({ selectedVersion, versions, onSelect, onNext, onBack }) => { + const { t } = useTranslation() + return ( + <> + <label + htmlFor='version' + className='flex flex-col justify-center items-start self-stretch text-text-secondary' > - Back - </Button> - <Button - variant='primary' - className='min-w-[72px]' - onClick={onNext} - disabled={!selectedVersion} - > - Next - </Button> - </div> - </> -) + <span className='system-sm-semibold'>{t('plugin.installFromGitHub.selectVersion')}</span> + </label> + <PortalSelect + value={selectedVersion} + onSelect={onSelect} + items={versions} + placeholder={t('plugin.installFromGitHub.selectVersionPlaceholder') || ''} + popupClassName='w-[432px] z-[1001]' + /> + <div className='flex justify-end items-center gap-2 self-stretch mt-4'> + <Button + variant='secondary' + className='min-w-[72px]' + onClick={onBack} + > + {t('plugin.installModal.back')} + </Button> + <Button + variant='primary' + className='min-w-[72px]' + onClick={onNext} + disabled={!selectedVersion} + > + {t('plugin.installModal.next')} + </Button> + </div> + </> + ) +} export default SetVersion diff --git a/web/app/components/plugins/plugin-page/filter-management/search-box.tsx b/web/app/components/plugins/plugin-page/filter-management/search-box.tsx index fa158aadf0..1b67a9a112 100644 --- a/web/app/components/plugins/plugin-page/filter-management/search-box.tsx +++ b/web/app/components/plugins/plugin-page/filter-management/search-box.tsx @@ -12,7 +12,8 @@ const SearchBox: React.FC<SearchBoxProps> = ({ }) => { return ( <Input - wrapperClassName='flex w-[200px] items-center rounded-lg bg-components-input-bg-normal' + wrapperClassName='flex w-[200px] items-center rounded-lg' + className='bg-components-input-bg-normal' showLeftIcon value={searchQuery} placeholder='Search' diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts index 1ac4b44762..654625a6bd 100644 --- a/web/app/components/plugins/types.ts +++ b/web/app/components/plugins/types.ts @@ -124,6 +124,20 @@ export enum InstallStepFromGitHub { installed = 'installed', } +export type InstallState = { + step: InstallStepFromGitHub + repoUrl: string + selectedVersion: string + selectedPackage: string + releases: GitHubRepoReleaseResponse[] +} + +export type GitHubUrlInfo = { + isValid: boolean + owner?: string + repo?: string +} + // endpoint export type CreateEndpointRequest = { plugin_unique_identifier: string diff --git a/web/i18n/en-US/plugin.ts b/web/i18n/en-US/plugin.ts index 6f6579d9d4..cf426e2b4e 100644 --- a/web/i18n/en-US/plugin.ts +++ b/web/i18n/en-US/plugin.ts @@ -67,6 +67,24 @@ const translation = { uploadingPackage: 'Uploading {{packageName}}...', readyToInstall: 'About to install the following plugin.', fromTrustSource: 'Please make sure that you only install plugins from a <trustSource>trusted source</trustSource>.', + labels: { + repository: 'Repository', + version: 'Version', + package: 'Package', + }, + close: 'Close', + cancel: 'Cancel', + back: 'Back', + next: 'Next', + }, + installFromGitHub: { + installPlugin: 'Install plugin from GitHub', + gitHubRepo: 'GitHub repository', + selectVersion: 'Select version', + selectVersionPlaceholder: 'Please select a version', + installNote: 'Please make sure that you only install plugins from a trusted source.', + selectPackage: 'Select package', + selectPackagePlaceholder: 'Please select a package', }, upgrade: { title: 'Upgrade Plugin', @@ -77,6 +95,9 @@ const translation = { upgrading: 'Upgrading...', close: 'Close', }, + error: { + inValidGitHubUrl: 'Invalid GitHub URL. Please enter a valid URL in the format: https://github.com/owner/repo', + }, } export default translation diff --git a/web/i18n/zh-Hans/plugin.ts b/web/i18n/zh-Hans/plugin.ts index 35e522fd84..2d5a39b7df 100644 --- a/web/i18n/zh-Hans/plugin.ts +++ b/web/i18n/zh-Hans/plugin.ts @@ -67,6 +67,24 @@ const translation = { uploadingPackage: '上传 {{packageName}} 中...', readyToInstall: '即将安装以下插件。', fromTrustSource: '请保证仅从<trustSource>可信源</trustSource>安装插件。', + labels: { + repository: '仓库', + version: '版本', + package: '包', + }, + close: '关闭', + cancel: '取消', + back: '返回', + next: '下一步', + }, + installFromGitHub: { + installPlugin: '从 GitHub 安装插件', + gitHubRepo: 'GitHub 仓库', + selectVersion: '选择版本', + selectVersionPlaceholder: '请选择一个版本', + installNote: '请确保只从可信源安装插件。', + selectPackage: '选择包', + selectPackagePlaceholder: '请选择一个包', }, upgrade: { title: '升级插件', @@ -77,6 +95,9 @@ const translation = { upgrading: '升级中...', close: '关闭', }, + error: { + inValidGitHubUrl: '无效的 GitHub URL。请输入格式为 https://github.com/owner/repo 的有效 URL', + }, } export default translation From e8a6e90a6127b3c1d8ca2a4fe573c6ba4578ffb7 Mon Sep 17 00:00:00 2001 From: tkoshida <tyskos@gmail.com> Date: Tue, 22 Oct 2024 22:12:03 +0900 Subject: [PATCH 140/346] fix: environment variables for ModelProvider and Tool Position are not working (#9650) --- docker/docker-compose.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml index 614b1ccc6b..5edcfda5f4 100644 --- a/docker/docker-compose.yaml +++ b/docker/docker-compose.yaml @@ -227,6 +227,12 @@ x-shared-env: &shared-api-worker-env HTTP_REQUEST_NODE_MAX_BINARY_SIZE: ${HTTP_REQUEST_NODE_MAX_BINARY_SIZE:-10485760} HTTP_REQUEST_NODE_MAX_TEXT_SIZE: ${HTTP_REQUEST_NODE_MAX_TEXT_SIZE:-1048576} APP_MAX_EXECUTION_TIME: ${APP_MAX_EXECUTION_TIME:-12000} + POSITION_TOOL_PINS: ${POSITION_TOOL_PINS:-} + POSITION_TOOL_INCLUDES: ${POSITION_TOOL_INCLUDES:-} + POSITION_TOOL_EXCLUDES: ${POSITION_TOOL_EXCLUDES:-} + POSITION_PROVIDER_PINS: ${POSITION_PROVIDER_PINS:-} + POSITION_PROVIDER_INCLUDES: ${POSITION_PROVIDER_INCLUDES:-} + POSITION_PROVIDER_EXCLUDES: ${POSITION_PROVIDER_EXCLUDES:-} services: # API service From 6827c4038b14d6706a0c3ee631f26a6048cbfaac Mon Sep 17 00:00:00 2001 From: Hash Brown <hi@xzd.me> Date: Tue, 22 Oct 2024 21:17:54 +0800 Subject: [PATCH 141/346] Web app support sending message using numpad enter (#9659) --- web/app/components/base/chat/chat/chat-input-area/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/app/components/base/chat/chat/chat-input-area/index.tsx b/web/app/components/base/chat/chat/chat-input-area/index.tsx index f1e72d2556..05aaaa6bc2 100644 --- a/web/app/components/base/chat/chat/chat-input-area/index.tsx +++ b/web/app/components/base/chat/chat/chat-input-area/index.tsx @@ -96,7 +96,7 @@ const ChatInputArea = ({ } const handleKeyUp = (e: React.KeyboardEvent<HTMLTextAreaElement>) => { - if (e.code === 'Enter') { + if (e.key === 'Enter') { e.preventDefault() // prevent send message when using input method enter if (!e.shiftKey && !isUseInputMethod.current) @@ -106,7 +106,7 @@ const ChatInputArea = ({ const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => { isUseInputMethod.current = e.nativeEvent.isComposing - if (e.code === 'Enter' && !e.shiftKey) { + if (e.key === 'Enter' && !e.shiftKey) { setQuery(query.replace(/\n$/, '')) e.preventDefault() } From a9db06f5e744ca262ba08ef834cadd3e62b7c0c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B0=E5=9C=A8=E4=BF=AE=E8=A1=8C=E7=9A=84=E5=A4=A7?= =?UTF-8?q?=E8=A1=97=E4=B8=8A?= <hgnulb@163.com> Date: Tue, 22 Oct 2024 21:31:34 +0800 Subject: [PATCH 142/346] feat(Tools): Refactor the base table plugin (#9182) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 黎斌 <libin.23@bytedance.com> --- .../builtin/feishu_base/_assets/icon.png | Bin 0 -> 7253 bytes .../builtin/feishu_base/_assets/icon.svg | 47 --- .../builtin/feishu_base/feishu_base.py | 5 +- .../builtin/feishu_base/feishu_base.yaml | 28 +- .../feishu_base/tools/add_base_record.py | 56 ---- .../feishu_base/tools/add_base_record.yaml | 66 ---- .../builtin/feishu_base/tools/add_records.py | 21 ++ .../feishu_base/tools/add_records.yaml | 91 ++++++ .../builtin/feishu_base/tools/create_base.py | 43 +-- .../feishu_base/tools/create_base.yaml | 39 +-- .../feishu_base/tools/create_base_table.py | 48 --- .../feishu_base/tools/create_base_table.yaml | 106 ------ .../builtin/feishu_base/tools/create_table.py | 20 ++ .../feishu_base/tools/create_table.yaml | 61 ++++ .../feishu_base/tools/delete_base_records.py | 56 ---- .../tools/delete_base_records.yaml | 60 ---- .../feishu_base/tools/delete_base_tables.py | 46 --- .../feishu_base/tools/delete_base_tables.yaml | 48 --- .../feishu_base/tools/delete_records.py | 20 ++ .../feishu_base/tools/delete_records.yaml | 86 +++++ .../feishu_base/tools/delete_tables.py | 19 ++ .../feishu_base/tools/delete_tables.yaml | 49 +++ .../feishu_base/tools/get_base_info.py | 40 +-- .../feishu_base/tools/get_base_info.yaml | 45 +-- .../tools/get_tenant_access_token.py | 48 --- .../tools/get_tenant_access_token.yaml | 39 --- .../feishu_base/tools/list_base_records.py | 65 ---- .../feishu_base/tools/list_base_records.yaml | 108 ------- .../feishu_base/tools/list_base_tables.py | 47 --- .../feishu_base/tools/list_base_tables.yaml | 65 ---- .../builtin/feishu_base/tools/list_tables.py | 19 ++ .../feishu_base/tools/list_tables.yaml | 50 +++ .../feishu_base/tools/read_base_record.py | 49 --- .../feishu_base/tools/read_base_record.yaml | 60 ---- .../builtin/feishu_base/tools/read_records.py | 21 ++ .../feishu_base/tools/read_records.yaml | 86 +++++ .../feishu_base/tools/search_records.py | 39 +++ .../feishu_base/tools/search_records.yaml | 163 ++++++++++ .../feishu_base/tools/update_base_record.py | 60 ---- .../feishu_base/tools/update_base_record.yaml | 78 ----- .../feishu_base/tools/update_records.py | 21 ++ .../feishu_base/tools/update_records.yaml | 91 ++++++ api/core/tools/utils/feishu_api_utils.py | 303 ++++++++++++++++++ 43 files changed, 1230 insertions(+), 1282 deletions(-) create mode 100644 api/core/tools/provider/builtin/feishu_base/_assets/icon.png delete mode 100644 api/core/tools/provider/builtin/feishu_base/_assets/icon.svg delete mode 100644 api/core/tools/provider/builtin/feishu_base/tools/add_base_record.py delete mode 100644 api/core/tools/provider/builtin/feishu_base/tools/add_base_record.yaml create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/add_records.py create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/add_records.yaml delete mode 100644 api/core/tools/provider/builtin/feishu_base/tools/create_base_table.py delete mode 100644 api/core/tools/provider/builtin/feishu_base/tools/create_base_table.yaml create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/create_table.py create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/create_table.yaml delete mode 100644 api/core/tools/provider/builtin/feishu_base/tools/delete_base_records.py delete mode 100644 api/core/tools/provider/builtin/feishu_base/tools/delete_base_records.yaml delete mode 100644 api/core/tools/provider/builtin/feishu_base/tools/delete_base_tables.py delete mode 100644 api/core/tools/provider/builtin/feishu_base/tools/delete_base_tables.yaml create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/delete_records.py create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/delete_records.yaml create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/delete_tables.py create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/delete_tables.yaml delete mode 100644 api/core/tools/provider/builtin/feishu_base/tools/get_tenant_access_token.py delete mode 100644 api/core/tools/provider/builtin/feishu_base/tools/get_tenant_access_token.yaml delete mode 100644 api/core/tools/provider/builtin/feishu_base/tools/list_base_records.py delete mode 100644 api/core/tools/provider/builtin/feishu_base/tools/list_base_records.yaml delete mode 100644 api/core/tools/provider/builtin/feishu_base/tools/list_base_tables.py delete mode 100644 api/core/tools/provider/builtin/feishu_base/tools/list_base_tables.yaml create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/list_tables.py create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/list_tables.yaml delete mode 100644 api/core/tools/provider/builtin/feishu_base/tools/read_base_record.py delete mode 100644 api/core/tools/provider/builtin/feishu_base/tools/read_base_record.yaml create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/read_records.py create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/read_records.yaml create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/search_records.py create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/search_records.yaml delete mode 100644 api/core/tools/provider/builtin/feishu_base/tools/update_base_record.py delete mode 100644 api/core/tools/provider/builtin/feishu_base/tools/update_base_record.yaml create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/update_records.py create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/update_records.yaml diff --git a/api/core/tools/provider/builtin/feishu_base/_assets/icon.png b/api/core/tools/provider/builtin/feishu_base/_assets/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..787427e7218058678986333768b33a0aafd1eb58 GIT binary patch literal 7253 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 literal 0 HcmV?d00001 diff --git a/api/core/tools/provider/builtin/feishu_base/_assets/icon.svg b/api/core/tools/provider/builtin/feishu_base/_assets/icon.svg deleted file mode 100644 index 2663a0f59e..0000000000 --- a/api/core/tools/provider/builtin/feishu_base/_assets/icon.svg +++ /dev/null @@ -1,47 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> -<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="240px" height="240px" viewBox="0 0 240 240" enable-background="new 0 0 240 240" xml:space="preserve"> <image id="image0" width="240" height="240" x="0" y="0" - xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAPAAAADwCAMAAAAJixmgAAAAIGNIUk0AAHomAACAhAAA+gAAAIDo -AAB1MAAA6mAAADqYAAAXcJy6UTwAAAINUExURQAAAJ9g6qNg6qRd6KNe6aVg6J9g6p9g359a6qRd -66Ne66Re66Rd66Rd66Re7Z9g559g76Ne7aRe6qJd76Fe66Ne66Re66Vd7KNc6aRe66Nd66Re7KRd -66Nc6p9g36Re7KRf7KRe7KNe7KNc76Va6qVd66Ne66Re66Nd6qRb6KRe66Zd66Ve7KJd6aNe66Fe -7KRd6p9Y56Re66Je6qRb6qNe66Re7KNc56Jf6qNe6qRe6qFe6KNe6qRf66Rf66Ne7KNe6qRe6qRd -66Rd7KFe6aNc6qNe6qJd7Z9b6KNd659Z7KNd66Ne6aRe66Re7KNc66Nd66Ne66Jd6qNe6qNc6aJd -6qNd6qRe66Jd7KFe6qJe66Re6qNe66Jd66Jd6aRd6qRd66Va759V6qVd6qFe56Ne6KJd6KRe66Zj -67eB79Gu9eLM+OjX+uXS+dSz9bJ37s6p9LV87q9y7de49vn1/f///9q99qlo7NGu9Kxt7d/H+Pz5 -/vz6/qdj68CQ8e7h+/Pq/Maa8rqG8NzC9/Pr/Myk8+DH+OXR+cyk9Pn1/ujW+u3g+7iB7+vc+r2L -8N3C9//+//bw/cmf87uG8OPM+ebR+axt7Muk8/Dm/Mif8/n0/c+p9MOV8fHm++7g+/n0/vbv/bqG -78CQ8Kxu7cCR8ePM+LqH8MCP8bV87+LM+bqF8Muk9OLL+NSy9bqF75VHsr4AAABndFJOUwAYSHCA -WDAQMJfn57+PVyAQb98/gO/mllDPr1/ebwiHn+6eLzCvf/63OL4/xkfOT58g9odfZ65Aj3fHT2+X -j3f3z7efgEjPRzi3KKd/7sZAv+6fri+P3rY3X77G5j9oxn4fGGCAbzcMFjqxAAAAAWJLR0R1qGqY -+wAAAAd0SU1FB+gGDQkfBmABjhYAAAXYSURBVHja7d35WxtFGAfwbUGDtRWKilAwFg+2VHtwqa31 -qlfV1qta7/vYkDQhJFnTliQWhFYoDaVY8ECw3vffaHgefZ5CZvbZIbMz83a/35/ngfkwx+5m3iyW -hSAIgiAIgiAIgiAIgiAIQjAbNtbVa0vdNRuvjSjlNly3ydGd6zdvuaFRDbdpa7Nu7f9p3nJjU/De -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" /> -</svg> diff --git a/api/core/tools/provider/builtin/feishu_base/feishu_base.py b/api/core/tools/provider/builtin/feishu_base/feishu_base.py index 04056af53b..f301ec5355 100644 --- a/api/core/tools/provider/builtin/feishu_base/feishu_base.py +++ b/api/core/tools/provider/builtin/feishu_base/feishu_base.py @@ -1,8 +1,7 @@ -from core.tools.provider.builtin.feishu_base.tools.get_tenant_access_token import GetTenantAccessTokenTool from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController +from core.tools.utils.feishu_api_utils import auth class FeishuBaseProvider(BuiltinToolProviderController): def _validate_credentials(self, credentials: dict) -> None: - GetTenantAccessTokenTool() - pass + auth(credentials) diff --git a/api/core/tools/provider/builtin/feishu_base/feishu_base.yaml b/api/core/tools/provider/builtin/feishu_base/feishu_base.yaml index f3dcbb6136..456dd8c88f 100644 --- a/api/core/tools/provider/builtin/feishu_base/feishu_base.yaml +++ b/api/core/tools/provider/builtin/feishu_base/feishu_base.yaml @@ -5,10 +5,32 @@ identity: en_US: Feishu Base zh_Hans: 飞书多维表格 description: - en_US: Feishu Base - zh_Hans: 飞书多维表格 - icon: icon.svg + en_US: | + Feishu base, requires the following permissions: bitable:app. + zh_Hans: | + 飞书多维表格,需要开通以下权限: bitable:app。 + icon: icon.png tags: - social - productivity credentials_for_provider: + app_id: + type: text-input + required: true + label: + en_US: APP ID + placeholder: + en_US: Please input your feishu app id + zh_Hans: 请输入你的飞书 app id + help: + en_US: Get your app_id and app_secret from Feishu + zh_Hans: 从飞书获取您的 app_id 和 app_secret + url: https://open.larkoffice.com/app + app_secret: + type: secret-input + required: true + label: + en_US: APP Secret + placeholder: + en_US: Please input your app secret + zh_Hans: 请输入你的飞书 app secret diff --git a/api/core/tools/provider/builtin/feishu_base/tools/add_base_record.py b/api/core/tools/provider/builtin/feishu_base/tools/add_base_record.py deleted file mode 100644 index 4a605fbffe..0000000000 --- a/api/core/tools/provider/builtin/feishu_base/tools/add_base_record.py +++ /dev/null @@ -1,56 +0,0 @@ -import json -from typing import Any, Union - -import httpx - -from core.tools.entities.tool_entities import ToolInvokeMessage -from core.tools.tool.builtin_tool import BuiltinTool - - -class AddBaseRecordTool(BuiltinTool): - def _invoke( - self, user_id: str, tool_parameters: dict[str, Any] - ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: - url = "https://open.feishu.cn/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/records" - - access_token = tool_parameters.get("Authorization", "") - if not access_token: - return self.create_text_message("Invalid parameter access_token") - - app_token = tool_parameters.get("app_token", "") - if not app_token: - return self.create_text_message("Invalid parameter app_token") - - table_id = tool_parameters.get("table_id", "") - if not table_id: - return self.create_text_message("Invalid parameter table_id") - - fields = tool_parameters.get("fields", "") - if not fields: - return self.create_text_message("Invalid parameter fields") - - headers = { - "Content-Type": "application/json", - "Authorization": f"Bearer {access_token}", - } - - params = {} - payload = {"fields": json.loads(fields)} - - try: - res = httpx.post( - url.format(app_token=app_token, table_id=table_id), - headers=headers, - params=params, - json=payload, - timeout=30, - ) - res_json = res.json() - if res.is_success: - return self.create_text_message(text=json.dumps(res_json)) - else: - return self.create_text_message( - f"Failed to add base record, status code: {res.status_code}, response: {res.text}" - ) - except Exception as e: - return self.create_text_message("Failed to add base record. {}".format(e)) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/add_base_record.yaml b/api/core/tools/provider/builtin/feishu_base/tools/add_base_record.yaml deleted file mode 100644 index 3ce0154efd..0000000000 --- a/api/core/tools/provider/builtin/feishu_base/tools/add_base_record.yaml +++ /dev/null @@ -1,66 +0,0 @@ -identity: - name: add_base_record - author: Doug Lea - label: - en_US: Add Base Record - zh_Hans: 在多维表格数据表中新增一条记录 -description: - human: - en_US: Add Base Record - zh_Hans: | - 在多维表格数据表中新增一条记录,详细请参考:https://open.larkoffice.com/document/server-docs/docs/bitable-v1/app-table-record/create - llm: Add a new record in the multidimensional table data table. -parameters: - - name: Authorization - type: string - required: true - label: - en_US: token - zh_Hans: 凭证 - human_description: - en_US: API access token parameter, tenant_access_token or user_access_token - zh_Hans: API 的访问凭证参数,tenant_access_token 或 user_access_token - llm_description: API access token parameter, tenant_access_token or user_access_token - form: llm - - - name: app_token - type: string - required: true - label: - en_US: app_token - zh_Hans: 多维表格 - human_description: - en_US: bitable app token - zh_Hans: 多维表格的唯一标识符 app_token - llm_description: bitable app token - form: llm - - - name: table_id - type: string - required: true - label: - en_US: table_id - zh_Hans: 多维表格的数据表 - human_description: - en_US: bitable table id - zh_Hans: 多维表格数据表的唯一标识符 table_id - llm_description: bitable table id - form: llm - - - name: fields - type: string - required: true - label: - en_US: fields - zh_Hans: 数据表的列字段内容 - human_description: - en_US: The fields of the Base data table are the columns of the data table. - zh_Hans: | - 要增加一行多维表格记录,字段结构拼接如下:{"多行文本":"多行文本内容","单选":"选项1","多选":["选项1","选项2"],"复选框":true,"人员":[{"id":"ou_2910013f1e6456f16a0ce75ede950a0a"}],"群组":[{"id":"oc_cd07f55f14d6f4a4f1b51504e7e97f48"}],"电话号码":"13026162666"} - 当前接口支持的字段类型为:多行文本、单选、条码、多选、日期、人员、附件、复选框、超链接、数字、单向关联、双向关联、电话号码、地理位置。 - 不同类型字段的数据结构请参考数据结构概述:https://open.larkoffice.com/document/server-docs/docs/bitable-v1/bitable-structure - llm_description: | - 要增加一行多维表格记录,字段结构拼接如下:{"多行文本":"多行文本内容","单选":"选项1","多选":["选项1","选项2"],"复选框":true,"人员":[{"id":"ou_2910013f1e6456f16a0ce75ede950a0a"}],"群组":[{"id":"oc_cd07f55f14d6f4a4f1b51504e7e97f48"}],"电话号码":"13026162666"} - 当前接口支持的字段类型为:多行文本、单选、条码、多选、日期、人员、附件、复选框、超链接、数字、单向关联、双向关联、电话号码、地理位置。 - 不同类型字段的数据结构请参考数据结构概述:https://open.larkoffice.com/document/server-docs/docs/bitable-v1/bitable-structure - form: llm diff --git a/api/core/tools/provider/builtin/feishu_base/tools/add_records.py b/api/core/tools/provider/builtin/feishu_base/tools/add_records.py new file mode 100644 index 0000000000..905f8b7880 --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/add_records.py @@ -0,0 +1,21 @@ +from typing import Any + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.tool.builtin_tool import BuiltinTool +from core.tools.utils.feishu_api_utils import FeishuRequest + + +class AddRecordsTool(BuiltinTool): + def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage: + app_id = self.runtime.credentials.get("app_id") + app_secret = self.runtime.credentials.get("app_secret") + client = FeishuRequest(app_id, app_secret) + + app_token = tool_parameters.get("app_token") + table_id = tool_parameters.get("table_id") + table_name = tool_parameters.get("table_name") + records = tool_parameters.get("records") + user_id_type = tool_parameters.get("user_id_type", "open_id") + + res = client.add_records(app_token, table_id, table_name, records, user_id_type) + return self.create_json_message(res) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/add_records.yaml b/api/core/tools/provider/builtin/feishu_base/tools/add_records.yaml new file mode 100644 index 0000000000..f2a93490dc --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/add_records.yaml @@ -0,0 +1,91 @@ +identity: + name: add_records + author: Doug Lea + label: + en_US: Add Records + zh_Hans: 新增多条记录 +description: + human: + en_US: Add Multiple Records to Multidimensional Table + zh_Hans: 在多维表格数据表中新增多条记录 + llm: A tool for adding multiple records to a multidimensional table. (在多维表格数据表中新增多条记录) +parameters: + - name: app_token + type: string + required: true + label: + en_US: app_token + zh_Hans: app_token + human_description: + en_US: Unique identifier for the multidimensional table, supports inputting document URL. + zh_Hans: 多维表格的唯一标识符,支持输入文档 URL。 + llm_description: 多维表格的唯一标识符,支持输入文档 URL。 + form: llm + + - name: table_id + type: string + required: false + label: + en_US: table_id + zh_Hans: table_id + human_description: + en_US: Unique identifier for the multidimensional table data, either table_id or table_name must be provided, cannot be empty simultaneously. + zh_Hans: 多维表格数据表的唯一标识符,table_id 和 table_name 至少需要提供一个,不能同时为空。 + llm_description: 多维表格数据表的唯一标识符,table_id 和 table_name 至少需要提供一个,不能同时为空。 + form: llm + + - name: table_name + type: string + required: false + label: + en_US: table_name + zh_Hans: table_name + human_description: + en_US: Name of the multidimensional table data, either table_name or table_id must be provided, cannot be empty simultaneously. + zh_Hans: 多维表格数据表的名称,table_name 和 table_id 至少需要提供一个,不能同时为空。 + llm_description: 多维表格数据表的名称,table_name 和 table_id 至少需要提供一个,不能同时为空。 + form: llm + + - name: records + type: string + required: true + label: + en_US: records + zh_Hans: 记录列表 + human_description: + en_US: | + List of records to be added in this request. Example value: [{"multi-line-text":"text content","single_select":"option 1","date":1674206443000}] + For supported field types, refer to the integration guide (https://open.larkoffice.com/document/server-docs/docs/bitable-v1/notification). For data structures of different field types, refer to the data structure overview (https://open.larkoffice.com/document/server-docs/docs/bitable-v1/bitable-structure). + zh_Hans: | + 本次请求将要新增的记录列表,示例值:[{"多行文本":"文本内容","单选":"选项 1","日期":1674206443000}]。 + 当前接口支持的字段类型请参考接入指南(https://open.larkoffice.com/document/server-docs/docs/bitable-v1/notification),不同类型字段的数据结构请参考数据结构概述(https://open.larkoffice.com/document/server-docs/docs/bitable-v1/bitable-structure)。 + llm_description: | + 本次请求将要新增的记录列表,示例值:[{"多行文本":"文本内容","单选":"选项 1","日期":1674206443000}]。 + 当前接口支持的字段类型请参考接入指南(https://open.larkoffice.com/document/server-docs/docs/bitable-v1/notification),不同类型字段的数据结构请参考数据结构概述(https://open.larkoffice.com/document/server-docs/docs/bitable-v1/bitable-structure)。 + form: llm + + - name: user_id_type + type: select + required: false + options: + - value: open_id + label: + en_US: open_id + zh_Hans: open_id + - value: union_id + label: + en_US: union_id + zh_Hans: union_id + - value: user_id + label: + en_US: user_id + zh_Hans: user_id + default: "open_id" + label: + en_US: user_id_type + zh_Hans: 用户 ID 类型 + human_description: + en_US: User ID type, optional values are open_id, union_id, user_id, with a default value of open_id. + zh_Hans: 用户 ID 类型,可选值有 open_id、union_id、user_id,默认值为 open_id。 + llm_description: 用户 ID 类型,可选值有 open_id、union_id、user_id,默认值为 open_id。 + form: form diff --git a/api/core/tools/provider/builtin/feishu_base/tools/create_base.py b/api/core/tools/provider/builtin/feishu_base/tools/create_base.py index 6b755e2007..f074acc5ff 100644 --- a/api/core/tools/provider/builtin/feishu_base/tools/create_base.py +++ b/api/core/tools/provider/builtin/feishu_base/tools/create_base.py @@ -1,41 +1,18 @@ -import json -from typing import Any, Union - -import httpx +from typing import Any from core.tools.entities.tool_entities import ToolInvokeMessage from core.tools.tool.builtin_tool import BuiltinTool +from core.tools.utils.feishu_api_utils import FeishuRequest class CreateBaseTool(BuiltinTool): - def _invoke( - self, user_id: str, tool_parameters: dict[str, Any] - ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: - url = "https://open.feishu.cn/open-apis/bitable/v1/apps" + def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage: + app_id = self.runtime.credentials.get("app_id") + app_secret = self.runtime.credentials.get("app_secret") + client = FeishuRequest(app_id, app_secret) - access_token = tool_parameters.get("Authorization", "") - if not access_token: - return self.create_text_message("Invalid parameter access_token") + name = tool_parameters.get("name") + folder_token = tool_parameters.get("folder_token") - name = tool_parameters.get("name", "") - folder_token = tool_parameters.get("folder_token", "") - - headers = { - "Content-Type": "application/json", - "Authorization": f"Bearer {access_token}", - } - - params = {} - payload = {"name": name, "folder_token": folder_token} - - try: - res = httpx.post(url, headers=headers, params=params, json=payload, timeout=30) - res_json = res.json() - if res.is_success: - return self.create_text_message(text=json.dumps(res_json)) - else: - return self.create_text_message( - f"Failed to create base, status code: {res.status_code}, response: {res.text}" - ) - except Exception as e: - return self.create_text_message("Failed to create base. {}".format(e)) + res = client.create_base(name, folder_token) + return self.create_json_message(res) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/create_base.yaml b/api/core/tools/provider/builtin/feishu_base/tools/create_base.yaml index 76c76a916d..3ec91a90e7 100644 --- a/api/core/tools/provider/builtin/feishu_base/tools/create_base.yaml +++ b/api/core/tools/provider/builtin/feishu_base/tools/create_base.yaml @@ -6,32 +6,21 @@ identity: zh_Hans: 创建多维表格 description: human: - en_US: Create base + en_US: Create Multidimensional Table in Specified Directory zh_Hans: 在指定目录下创建多维表格 - llm: A tool for create a multidimensional table in the specified directory. + llm: A tool for creating a multidimensional table in a specified directory. (在指定目录下创建多维表格) parameters: - - name: Authorization - type: string - required: true - label: - en_US: token - zh_Hans: 凭证 - human_description: - en_US: API access token parameter, tenant_access_token or user_access_token - zh_Hans: API 的访问凭证参数,tenant_access_token 或 user_access_token - llm_description: API access token parameter, tenant_access_token or user_access_token - form: llm - - name: name type: string required: false label: en_US: name - zh_Hans: name + zh_Hans: 多维表格 App 名字 human_description: - en_US: Base App Name - zh_Hans: 多维表格App名字 - llm_description: Base App Name + en_US: | + Name of the multidimensional table App. Example value: "A new multidimensional table". + zh_Hans: 多维表格 App 名字,示例值:"一篇新的多维表格"。 + llm_description: 多维表格 App 名字,示例值:"一篇新的多维表格"。 form: llm - name: folder_token @@ -39,9 +28,15 @@ parameters: required: false label: en_US: folder_token - zh_Hans: 多维表格App归属文件夹 + zh_Hans: 多维表格 App 归属文件夹 human_description: - en_US: Base App home folder. The default is empty, indicating that Base will be created in the cloud space root directory. - zh_Hans: 多维表格App归属文件夹。默认为空,表示多维表格将被创建在云空间根目录。 - llm_description: Base App home folder. The default is empty, indicating that Base will be created in the cloud space root directory. + en_US: | + Folder where the multidimensional table App belongs. Default is empty, meaning the table will be created in the root directory of the cloud space. Example values: Fa3sfoAgDlMZCcdcJy1cDFg8nJc or https://svi136aogf123.feishu.cn/drive/folder/Fa3sfoAgDlMZCcdcJy1cDFg8nJc. + The folder_token must be an existing folder and supports inputting folder token or folder URL. + zh_Hans: | + 多维表格 App 归属文件夹。默认为空,表示多维表格将被创建在云空间根目录。示例值: Fa3sfoAgDlMZCcdcJy1cDFg8nJc 或者 https://svi136aogf123.feishu.cn/drive/folder/Fa3sfoAgDlMZCcdcJy1cDFg8nJc。 + folder_token 必须是已存在的文件夹,支持输入文件夹 token 或者文件夹 URL。 + llm_description: | + 多维表格 App 归属文件夹。默认为空,表示多维表格将被创建在云空间根目录。示例值: Fa3sfoAgDlMZCcdcJy1cDFg8nJc 或者 https://svi136aogf123.feishu.cn/drive/folder/Fa3sfoAgDlMZCcdcJy1cDFg8nJc。 + folder_token 必须是已存在的文件夹,支持输入文件夹 token 或者文件夹 URL。 form: llm diff --git a/api/core/tools/provider/builtin/feishu_base/tools/create_base_table.py b/api/core/tools/provider/builtin/feishu_base/tools/create_base_table.py deleted file mode 100644 index b05d700113..0000000000 --- a/api/core/tools/provider/builtin/feishu_base/tools/create_base_table.py +++ /dev/null @@ -1,48 +0,0 @@ -import json -from typing import Any, Union - -import httpx - -from core.tools.entities.tool_entities import ToolInvokeMessage -from core.tools.tool.builtin_tool import BuiltinTool - - -class CreateBaseTableTool(BuiltinTool): - def _invoke( - self, user_id: str, tool_parameters: dict[str, Any] - ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: - url = "https://open.feishu.cn/open-apis/bitable/v1/apps/{app_token}/tables" - - access_token = tool_parameters.get("Authorization", "") - if not access_token: - return self.create_text_message("Invalid parameter access_token") - - app_token = tool_parameters.get("app_token", "") - if not app_token: - return self.create_text_message("Invalid parameter app_token") - - name = tool_parameters.get("name", "") - - fields = tool_parameters.get("fields", "") - if not fields: - return self.create_text_message("Invalid parameter fields") - - headers = { - "Content-Type": "application/json", - "Authorization": f"Bearer {access_token}", - } - - params = {} - payload = {"table": {"name": name, "fields": json.loads(fields)}} - - try: - res = httpx.post(url.format(app_token=app_token), headers=headers, params=params, json=payload, timeout=30) - res_json = res.json() - if res.is_success: - return self.create_text_message(text=json.dumps(res_json)) - else: - return self.create_text_message( - f"Failed to create base table, status code: {res.status_code}, response: {res.text}" - ) - except Exception as e: - return self.create_text_message("Failed to create base table. {}".format(e)) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/create_base_table.yaml b/api/core/tools/provider/builtin/feishu_base/tools/create_base_table.yaml deleted file mode 100644 index 48c46bec14..0000000000 --- a/api/core/tools/provider/builtin/feishu_base/tools/create_base_table.yaml +++ /dev/null @@ -1,106 +0,0 @@ -identity: - name: create_base_table - author: Doug Lea - label: - en_US: Create Base Table - zh_Hans: 多维表格新增一个数据表 -description: - human: - en_US: Create base table - zh_Hans: | - 多维表格新增一个数据表,详细请参考:https://open.larkoffice.com/document/server-docs/docs/bitable-v1/app-table/create - llm: A tool for add a new data table to the multidimensional table. -parameters: - - name: Authorization - type: string - required: true - label: - en_US: token - zh_Hans: 凭证 - human_description: - en_US: API access token parameter, tenant_access_token or user_access_token - zh_Hans: API 的访问凭证参数,tenant_access_token 或 user_access_token - llm_description: API access token parameter, tenant_access_token or user_access_token - form: llm - - - name: app_token - type: string - required: true - label: - en_US: app_token - zh_Hans: 多维表格 - human_description: - en_US: bitable app token - zh_Hans: 多维表格的唯一标识符 app_token - llm_description: bitable app token - form: llm - - - name: name - type: string - required: false - label: - en_US: name - zh_Hans: name - human_description: - en_US: Multidimensional table data table name - zh_Hans: 多维表格数据表名称 - llm_description: Multidimensional table data table name - form: llm - - - name: fields - type: string - required: true - label: - en_US: fields - zh_Hans: fields - human_description: - en_US: Initial fields of the data table - zh_Hans: | - 数据表的初始字段,格式为:[{"field_name":"多行文本","type":1},{"field_name":"数字","type":2},{"field_name":"单选","type":3},{"field_name":"多选","type":4},{"field_name":"日期","type":5}]。 - field_name:字段名; - type: 字段类型;可选值有 - 1:多行文本 - 2:数字 - 3:单选 - 4:多选 - 5:日期 - 7:复选框 - 11:人员 - 13:电话号码 - 15:超链接 - 17:附件 - 18:单向关联 - 20:公式 - 21:双向关联 - 22:地理位置 - 23:群组 - 1001:创建时间 - 1002:最后更新时间 - 1003:创建人 - 1004:修改人 - 1005:自动编号 - llm_description: | - 数据表的初始字段,格式为:[{"field_name":"多行文本","type":1},{"field_name":"数字","type":2},{"field_name":"单选","type":3},{"field_name":"多选","type":4},{"field_name":"日期","type":5}]。 - field_name:字段名; - type: 字段类型;可选值有 - 1:多行文本 - 2:数字 - 3:单选 - 4:多选 - 5:日期 - 7:复选框 - 11:人员 - 13:电话号码 - 15:超链接 - 17:附件 - 18:单向关联 - 20:公式 - 21:双向关联 - 22:地理位置 - 23:群组 - 1001:创建时间 - 1002:最后更新时间 - 1003:创建人 - 1004:修改人 - 1005:自动编号 - form: llm diff --git a/api/core/tools/provider/builtin/feishu_base/tools/create_table.py b/api/core/tools/provider/builtin/feishu_base/tools/create_table.py new file mode 100644 index 0000000000..81f2617545 --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/create_table.py @@ -0,0 +1,20 @@ +from typing import Any + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.tool.builtin_tool import BuiltinTool +from core.tools.utils.feishu_api_utils import FeishuRequest + + +class CreateTableTool(BuiltinTool): + def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage: + app_id = self.runtime.credentials.get("app_id") + app_secret = self.runtime.credentials.get("app_secret") + client = FeishuRequest(app_id, app_secret) + + app_token = tool_parameters.get("app_token") + table_name = tool_parameters.get("table_name") + default_view_name = tool_parameters.get("default_view_name") + fields = tool_parameters.get("fields") + + res = client.create_table(app_token, table_name, default_view_name, fields) + return self.create_json_message(res) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/create_table.yaml b/api/core/tools/provider/builtin/feishu_base/tools/create_table.yaml new file mode 100644 index 0000000000..8b1007b9a5 --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/create_table.yaml @@ -0,0 +1,61 @@ +identity: + name: create_table + author: Doug Lea + label: + en_US: Create Table + zh_Hans: 新增数据表 +description: + human: + en_US: Add a Data Table to Multidimensional Table + zh_Hans: 在多维表格中新增一个数据表 + llm: A tool for adding a data table to a multidimensional table. (在多维表格中新增一个数据表) +parameters: + - name: app_token + type: string + required: true + label: + en_US: app_token + zh_Hans: app_token + human_description: + en_US: Unique identifier for the multidimensional table, supports inputting document URL. + zh_Hans: 多维表格的唯一标识符,支持输入文档 URL。 + llm_description: 多维表格的唯一标识符,支持输入文档 URL。 + form: llm + + - name: table_name + type: string + required: true + label: + en_US: Table Name + zh_Hans: 数据表名称 + human_description: + en_US: | + The name of the data table, length range: 1 character to 100 characters. + zh_Hans: 数据表名称,长度范围:1 字符 ~ 100 字符。 + llm_description: 数据表名称,长度范围:1 字符 ~ 100 字符。 + form: llm + + - name: default_view_name + type: string + required: false + label: + en_US: Default View Name + zh_Hans: 默认表格视图的名称 + human_description: + en_US: The name of the default table view, defaults to "Table" if not filled. + zh_Hans: 默认表格视图的名称,不填则默认为"表格"。 + llm_description: 默认表格视图的名称,不填则默认为"表格"。 + form: llm + + - name: fields + type: string + required: true + label: + en_US: Initial Fields + zh_Hans: 初始字段 + human_description: + en_US: | + Initial fields of the data table, format: [ { "field_name": "Multi-line Text","type": 1 },{ "field_name": "Number","type": 2 },{ "field_name": "Single Select","type": 3 },{ "field_name": "Multiple Select","type": 4 },{ "field_name": "Date","type": 5 } ]. For field details, refer to: https://open.larkoffice.com/document/server-docs/docs/bitable-v1/app-table-field/guide + zh_Hans: 数据表的初始字段,格式为:[{"field_name":"多行文本","type":1},{"field_name":"数字","type":2},{"field_name":"单选","type":3},{"field_name":"多选","type":4},{"field_name":"日期","type":5}]。字段详情参考:https://open.larkoffice.com/document/server-docs/docs/bitable-v1/app-table-field/guide + llm_description: 数据表的初始字段,格式为:[{"field_name":"多行文本","type":1},{"field_name":"数字","type":2},{"field_name":"单选","type":3},{"field_name":"多选","type":4},{"field_name":"日期","type":5}]。字段详情参考:https://open.larkoffice.com/document/server-docs/docs/bitable-v1/app-table-field/guide + form: llm diff --git a/api/core/tools/provider/builtin/feishu_base/tools/delete_base_records.py b/api/core/tools/provider/builtin/feishu_base/tools/delete_base_records.py deleted file mode 100644 index 862eb2171b..0000000000 --- a/api/core/tools/provider/builtin/feishu_base/tools/delete_base_records.py +++ /dev/null @@ -1,56 +0,0 @@ -import json -from typing import Any, Union - -import httpx - -from core.tools.entities.tool_entities import ToolInvokeMessage -from core.tools.tool.builtin_tool import BuiltinTool - - -class DeleteBaseRecordsTool(BuiltinTool): - def _invoke( - self, user_id: str, tool_parameters: dict[str, Any] - ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: - url = "https://open.feishu.cn/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/records/batch_delete" - - access_token = tool_parameters.get("Authorization", "") - if not access_token: - return self.create_text_message("Invalid parameter access_token") - - app_token = tool_parameters.get("app_token", "") - if not app_token: - return self.create_text_message("Invalid parameter app_token") - - table_id = tool_parameters.get("table_id", "") - if not table_id: - return self.create_text_message("Invalid parameter table_id") - - record_ids = tool_parameters.get("record_ids", "") - if not record_ids: - return self.create_text_message("Invalid parameter record_ids") - - headers = { - "Content-Type": "application/json", - "Authorization": f"Bearer {access_token}", - } - - params = {} - payload = {"records": json.loads(record_ids)} - - try: - res = httpx.post( - url.format(app_token=app_token, table_id=table_id), - headers=headers, - params=params, - json=payload, - timeout=30, - ) - res_json = res.json() - if res.is_success: - return self.create_text_message(text=json.dumps(res_json)) - else: - return self.create_text_message( - f"Failed to delete base records, status code: {res.status_code}, response: {res.text}" - ) - except Exception as e: - return self.create_text_message("Failed to delete base records. {}".format(e)) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/delete_base_records.yaml b/api/core/tools/provider/builtin/feishu_base/tools/delete_base_records.yaml deleted file mode 100644 index 595b287029..0000000000 --- a/api/core/tools/provider/builtin/feishu_base/tools/delete_base_records.yaml +++ /dev/null @@ -1,60 +0,0 @@ -identity: - name: delete_base_records - author: Doug Lea - label: - en_US: Delete Base Records - zh_Hans: 在多维表格数据表中删除多条记录 -description: - human: - en_US: Delete base records - zh_Hans: | - 该接口用于删除多维表格数据表中的多条记录,单次调用中最多删除 500 条记录。 - llm: A tool for delete multiple records in a multidimensional table data table, up to 500 records can be deleted in a single call. -parameters: - - name: Authorization - type: string - required: true - label: - en_US: token - zh_Hans: 凭证 - human_description: - en_US: API access token parameter, tenant_access_token or user_access_token - zh_Hans: API 的访问凭证参数,tenant_access_token 或 user_access_token - llm_description: API access token parameter, tenant_access_token or user_access_token - form: llm - - - name: app_token - type: string - required: true - label: - en_US: app_token - zh_Hans: 多维表格 - human_description: - en_US: bitable app token - zh_Hans: 多维表格的唯一标识符 app_token - llm_description: bitable app token - form: llm - - - name: table_id - type: string - required: true - label: - en_US: table_id - zh_Hans: 多维表格的数据表 - human_description: - en_US: bitable table id - zh_Hans: 多维表格数据表的唯一标识符 table_id - llm_description: bitable table id - form: llm - - - name: record_ids - type: string - required: true - label: - en_US: record_ids - zh_Hans: record_ids - human_description: - en_US: A list of multiple record IDs to be deleted, for example ["recwNXzPQv","recpCsf4ME"] - zh_Hans: 待删除的多条记录id列表,示例为 ["recwNXzPQv","recpCsf4ME"] - llm_description: A list of multiple record IDs to be deleted, for example ["recwNXzPQv","recpCsf4ME"] - form: llm diff --git a/api/core/tools/provider/builtin/feishu_base/tools/delete_base_tables.py b/api/core/tools/provider/builtin/feishu_base/tools/delete_base_tables.py deleted file mode 100644 index f512186303..0000000000 --- a/api/core/tools/provider/builtin/feishu_base/tools/delete_base_tables.py +++ /dev/null @@ -1,46 +0,0 @@ -import json -from typing import Any, Union - -import httpx - -from core.tools.entities.tool_entities import ToolInvokeMessage -from core.tools.tool.builtin_tool import BuiltinTool - - -class DeleteBaseTablesTool(BuiltinTool): - def _invoke( - self, user_id: str, tool_parameters: dict[str, Any] - ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: - url = "https://open.feishu.cn/open-apis/bitable/v1/apps/{app_token}/tables/batch_delete" - - access_token = tool_parameters.get("Authorization", "") - if not access_token: - return self.create_text_message("Invalid parameter access_token") - - app_token = tool_parameters.get("app_token", "") - if not app_token: - return self.create_text_message("Invalid parameter app_token") - - table_ids = tool_parameters.get("table_ids", "") - if not table_ids: - return self.create_text_message("Invalid parameter table_ids") - - headers = { - "Content-Type": "application/json", - "Authorization": f"Bearer {access_token}", - } - - params = {} - payload = {"table_ids": json.loads(table_ids)} - - try: - res = httpx.post(url.format(app_token=app_token), headers=headers, params=params, json=payload, timeout=30) - res_json = res.json() - if res.is_success: - return self.create_text_message(text=json.dumps(res_json)) - else: - return self.create_text_message( - f"Failed to delete base tables, status code: {res.status_code}, response: {res.text}" - ) - except Exception as e: - return self.create_text_message("Failed to delete base tables. {}".format(e)) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/delete_base_tables.yaml b/api/core/tools/provider/builtin/feishu_base/tools/delete_base_tables.yaml deleted file mode 100644 index 5d72814363..0000000000 --- a/api/core/tools/provider/builtin/feishu_base/tools/delete_base_tables.yaml +++ /dev/null @@ -1,48 +0,0 @@ -identity: - name: delete_base_tables - author: Doug Lea - label: - en_US: Delete Base Tables - zh_Hans: 删除多维表格中的数据表 -description: - human: - en_US: Delete base tables - zh_Hans: | - 删除多维表格中的数据表 - llm: A tool for deleting a data table in a multidimensional table -parameters: - - name: Authorization - type: string - required: true - label: - en_US: token - zh_Hans: 凭证 - human_description: - en_US: API access token parameter, tenant_access_token or user_access_token - zh_Hans: API 的访问凭证参数,tenant_access_token 或 user_access_token - llm_description: API access token parameter, tenant_access_token or user_access_token - form: llm - - - name: app_token - type: string - required: true - label: - en_US: app_token - zh_Hans: 多维表格 - human_description: - en_US: bitable app token - zh_Hans: 多维表格的唯一标识符 app_token - llm_description: bitable app token - form: llm - - - name: table_ids - type: string - required: true - label: - en_US: table_ids - zh_Hans: table_ids - human_description: - en_US: The ID list of the data tables to be deleted. Currently, a maximum of 50 data tables can be deleted at a time. The example is ["tbl1TkhyTWDkSoZ3","tblsRc9GRRXKqhvW"] - zh_Hans: 待删除数据表的id列表,当前一次操作最多支持50个数据表,示例为 ["tbl1TkhyTWDkSoZ3","tblsRc9GRRXKqhvW"] - llm_description: The ID list of the data tables to be deleted. Currently, a maximum of 50 data tables can be deleted at a time. The example is ["tbl1TkhyTWDkSoZ3","tblsRc9GRRXKqhvW"] - form: llm diff --git a/api/core/tools/provider/builtin/feishu_base/tools/delete_records.py b/api/core/tools/provider/builtin/feishu_base/tools/delete_records.py new file mode 100644 index 0000000000..c896a2c81b --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/delete_records.py @@ -0,0 +1,20 @@ +from typing import Any + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.tool.builtin_tool import BuiltinTool +from core.tools.utils.feishu_api_utils import FeishuRequest + + +class DeleteRecordsTool(BuiltinTool): + def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage: + app_id = self.runtime.credentials.get("app_id") + app_secret = self.runtime.credentials.get("app_secret") + client = FeishuRequest(app_id, app_secret) + + app_token = tool_parameters.get("app_token") + table_id = tool_parameters.get("table_id") + table_name = tool_parameters.get("table_name") + record_ids = tool_parameters.get("record_ids") + + res = client.delete_records(app_token, table_id, table_name, record_ids) + return self.create_json_message(res) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/delete_records.yaml b/api/core/tools/provider/builtin/feishu_base/tools/delete_records.yaml new file mode 100644 index 0000000000..c30ebd630c --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/delete_records.yaml @@ -0,0 +1,86 @@ +identity: + name: delete_records + author: Doug Lea + label: + en_US: Delete Records + zh_Hans: 删除多条记录 +description: + human: + en_US: Delete Multiple Records from Multidimensional Table + zh_Hans: 删除多维表格数据表中的多条记录 + llm: A tool for deleting multiple records from a multidimensional table. (删除多维表格数据表中的多条记录) +parameters: + - name: app_token + type: string + required: true + label: + en_US: app_token + zh_Hans: app_token + human_description: + en_US: Unique identifier for the multidimensional table, supports inputting document URL. + zh_Hans: 多维表格的唯一标识符,支持输入文档 URL。 + llm_description: 多维表格的唯一标识符,支持输入文档 URL。 + form: llm + + - name: table_id + type: string + required: false + label: + en_US: table_id + zh_Hans: table_id + human_description: + en_US: Unique identifier for the multidimensional table data, either table_id or table_name must be provided, cannot be empty simultaneously. + zh_Hans: 多维表格数据表的唯一标识符,table_id 和 table_name 至少需要提供一个,不能同时为空。 + llm_description: 多维表格数据表的唯一标识符,table_id 和 table_name 至少需要提供一个,不能同时为空。 + form: llm + + - name: table_name + type: string + required: false + label: + en_US: table_name + zh_Hans: table_name + human_description: + en_US: Name of the multidimensional table data, either table_name or table_id must be provided, cannot be empty simultaneously. + zh_Hans: 多维表格数据表的名称,table_name 和 table_id 至少需要提供一个,不能同时为空。 + llm_description: 多维表格数据表的名称,table_name 和 table_id 至少需要提供一个,不能同时为空。 + form: llm + + - name: record_ids + type: string + required: true + label: + en_US: Record IDs + zh_Hans: 记录 ID 列表 + human_description: + en_US: | + List of IDs for the records to be deleted, example value: ["recwNXzPQv"]. + zh_Hans: 删除的多条记录 ID 列表,示例值:["recwNXzPQv"]。 + llm_description: 删除的多条记录 ID 列表,示例值:["recwNXzPQv"]。 + form: llm + + - name: user_id_type + type: select + required: false + options: + - value: open_id + label: + en_US: open_id + zh_Hans: open_id + - value: union_id + label: + en_US: union_id + zh_Hans: union_id + - value: user_id + label: + en_US: user_id + zh_Hans: user_id + default: "open_id" + label: + en_US: user_id_type + zh_Hans: 用户 ID 类型 + human_description: + en_US: User ID type, optional values are open_id, union_id, user_id, with a default value of open_id. + zh_Hans: 用户 ID 类型,可选值有 open_id、union_id、user_id,默认值为 open_id。 + llm_description: 用户 ID 类型,可选值有 open_id、union_id、user_id,默认值为 open_id。 + form: form diff --git a/api/core/tools/provider/builtin/feishu_base/tools/delete_tables.py b/api/core/tools/provider/builtin/feishu_base/tools/delete_tables.py new file mode 100644 index 0000000000..f732a16da6 --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/delete_tables.py @@ -0,0 +1,19 @@ +from typing import Any + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.tool.builtin_tool import BuiltinTool +from core.tools.utils.feishu_api_utils import FeishuRequest + + +class DeleteTablesTool(BuiltinTool): + def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage: + app_id = self.runtime.credentials.get("app_id") + app_secret = self.runtime.credentials.get("app_secret") + client = FeishuRequest(app_id, app_secret) + + app_token = tool_parameters.get("app_token") + table_ids = tool_parameters.get("table_ids") + table_names = tool_parameters.get("table_names") + + res = client.delete_tables(app_token, table_ids, table_names) + return self.create_json_message(res) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/delete_tables.yaml b/api/core/tools/provider/builtin/feishu_base/tools/delete_tables.yaml new file mode 100644 index 0000000000..498126eae5 --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/delete_tables.yaml @@ -0,0 +1,49 @@ +identity: + name: delete_tables + author: Doug Lea + label: + en_US: Delete Tables + zh_Hans: 删除数据表 +description: + human: + en_US: Batch Delete Data Tables from Multidimensional Table + zh_Hans: 批量删除多维表格中的数据表 + llm: A tool for batch deleting data tables from a multidimensional table. (批量删除多维表格中的数据表) +parameters: + - name: app_token + type: string + required: true + label: + en_US: app_token + zh_Hans: app_token + human_description: + en_US: Unique identifier for the multidimensional table, supports inputting document URL. + zh_Hans: 多维表格的唯一标识符,支持输入文档 URL。 + llm_description: 多维表格的唯一标识符,支持输入文档 URL。 + form: llm + + - name: table_ids + type: string + required: false + label: + en_US: Table IDs + zh_Hans: 数据表 ID + human_description: + en_US: | + IDs of the tables to be deleted. Each operation supports deleting up to 50 tables. Example: ["tbl1TkhyTWDkSoZ3"]. Ensure that either table_ids or table_names is not empty. + zh_Hans: 待删除的数据表的 ID,每次操作最多支持删除 50 个数据表。示例值:["tbl1TkhyTWDkSoZ3"]。请确保 table_ids 和 table_names 至少有一个不为空。 + llm_description: 待删除的数据表的 ID,每次操作最多支持删除 50 个数据表。示例值:["tbl1TkhyTWDkSoZ3"]。请确保 table_ids 和 table_names 至少有一个不为空。 + form: llm + + - name: table_names + type: string + required: false + label: + en_US: Table Names + zh_Hans: 数据表名称 + human_description: + en_US: | + Names of the tables to be deleted. Each operation supports deleting up to 50 tables. Example: ["Table1", "Table2"]. Ensure that either table_names or table_ids is not empty. + zh_Hans: 待删除的数据表的名称,每次操作最多支持删除 50 个数据表。示例值:["数据表1", "数据表2"]。请确保 table_names 和 table_ids 至少有一个不为空。 + llm_description: 待删除的数据表的名称,每次操作最多支持删除 50 个数据表。示例值:["数据表1", "数据表2"]。请确保 table_names 和 table_ids 至少有一个不为空。 + form: llm diff --git a/api/core/tools/provider/builtin/feishu_base/tools/get_base_info.py b/api/core/tools/provider/builtin/feishu_base/tools/get_base_info.py index f664bbeed0..a74e9be288 100644 --- a/api/core/tools/provider/builtin/feishu_base/tools/get_base_info.py +++ b/api/core/tools/provider/builtin/feishu_base/tools/get_base_info.py @@ -1,39 +1,17 @@ -import json -from typing import Any, Union - -import httpx +from typing import Any from core.tools.entities.tool_entities import ToolInvokeMessage from core.tools.tool.builtin_tool import BuiltinTool +from core.tools.utils.feishu_api_utils import FeishuRequest class GetBaseInfoTool(BuiltinTool): - def _invoke( - self, user_id: str, tool_parameters: dict[str, Any] - ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: - url = "https://open.feishu.cn/open-apis/bitable/v1/apps/{app_token}" + def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage: + app_id = self.runtime.credentials.get("app_id") + app_secret = self.runtime.credentials.get("app_secret") + client = FeishuRequest(app_id, app_secret) - access_token = tool_parameters.get("Authorization", "") - if not access_token: - return self.create_text_message("Invalid parameter access_token") + app_token = tool_parameters.get("app_token") - app_token = tool_parameters.get("app_token", "") - if not app_token: - return self.create_text_message("Invalid parameter app_token") - - headers = { - "Content-Type": "application/json", - "Authorization": f"Bearer {access_token}", - } - - try: - res = httpx.get(url.format(app_token=app_token), headers=headers, timeout=30) - res_json = res.json() - if res.is_success: - return self.create_text_message(text=json.dumps(res_json)) - else: - return self.create_text_message( - f"Failed to get base info, status code: {res.status_code}, response: {res.text}" - ) - except Exception as e: - return self.create_text_message("Failed to get base info. {}".format(e)) + res = client.get_base_info(app_token) + return self.create_json_message(res) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/get_base_info.yaml b/api/core/tools/provider/builtin/feishu_base/tools/get_base_info.yaml index de08689018..eb0e7a26c0 100644 --- a/api/core/tools/provider/builtin/feishu_base/tools/get_base_info.yaml +++ b/api/core/tools/provider/builtin/feishu_base/tools/get_base_info.yaml @@ -6,49 +6,18 @@ identity: zh_Hans: 获取多维表格元数据 description: human: - en_US: Get base info - zh_Hans: | - 获取多维表格元数据,响应体如下: - { - "code": 0, - "msg": "success", - "data": { - "app": { - "app_token": "appbcbWCzen6D8dezhoCH2RpMAh", - "name": "mybase", - "revision": 1, - "is_advanced": false, - "time_zone": "Asia/Beijing" - } - } - } - app_token: 多维表格的 app_token; - name: 多维表格的名字; - revision: 多维表格的版本号; - is_advanced: 多维表格是否开启了高级权限。取值包括:(true-表示开启了高级权限,false-表示关闭了高级权限); - time_zone: 文档时区; - llm: A tool to get Base Metadata, imported parameter is Unique Device Identifier app_token of Base, app_token is required. + en_US: Get Metadata Information of Specified Multidimensional Table + zh_Hans: 获取指定多维表格的元数据信息 + llm: A tool for getting metadata information of a specified multidimensional table. (获取指定多维表格的元数据信息) parameters: - - name: Authorization - type: string - required: true - label: - en_US: token - zh_Hans: 凭证 - human_description: - en_US: API access token parameter, tenant_access_token or user_access_token - zh_Hans: API 的访问凭证参数,tenant_access_token 或 user_access_token - llm_description: API access token parameter, tenant_access_token or user_access_token - form: llm - - name: app_token type: string required: true label: en_US: app_token - zh_Hans: 多维表格 + zh_Hans: app_token human_description: - en_US: bitable app token - zh_Hans: 多维表格的唯一标识符 app_token - llm_description: bitable app token + en_US: Unique identifier for the multidimensional table, supports inputting document URL. + zh_Hans: 多维表格的唯一标识符,支持输入文档 URL。 + llm_description: 多维表格的唯一标识符,支持输入文档 URL。 form: llm diff --git a/api/core/tools/provider/builtin/feishu_base/tools/get_tenant_access_token.py b/api/core/tools/provider/builtin/feishu_base/tools/get_tenant_access_token.py deleted file mode 100644 index 2ea61d0068..0000000000 --- a/api/core/tools/provider/builtin/feishu_base/tools/get_tenant_access_token.py +++ /dev/null @@ -1,48 +0,0 @@ -import json -from typing import Any, Union - -import httpx - -from core.tools.entities.tool_entities import ToolInvokeMessage -from core.tools.tool.builtin_tool import BuiltinTool - - -class GetTenantAccessTokenTool(BuiltinTool): - def _invoke( - self, user_id: str, tool_parameters: dict[str, Any] - ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: - url = "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal" - - app_id = tool_parameters.get("app_id", "") - if not app_id: - return self.create_text_message("Invalid parameter app_id") - - app_secret = tool_parameters.get("app_secret", "") - if not app_secret: - return self.create_text_message("Invalid parameter app_secret") - - headers = { - "Content-Type": "application/json", - } - params = {} - payload = {"app_id": app_id, "app_secret": app_secret} - - """ - { - "code": 0, - "msg": "ok", - "tenant_access_token": "t-caecc734c2e3328a62489fe0648c4b98779515d3", - "expire": 7200 - } - """ - try: - res = httpx.post(url, headers=headers, params=params, json=payload, timeout=30) - res_json = res.json() - if res.is_success: - return self.create_text_message(text=json.dumps(res_json)) - else: - return self.create_text_message( - f"Failed to get tenant access token, status code: {res.status_code}, response: {res.text}" - ) - except Exception as e: - return self.create_text_message("Failed to get tenant access token. {}".format(e)) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/get_tenant_access_token.yaml b/api/core/tools/provider/builtin/feishu_base/tools/get_tenant_access_token.yaml deleted file mode 100644 index 88acc27e06..0000000000 --- a/api/core/tools/provider/builtin/feishu_base/tools/get_tenant_access_token.yaml +++ /dev/null @@ -1,39 +0,0 @@ -identity: - name: get_tenant_access_token - author: Doug Lea - label: - en_US: Get Tenant Access Token - zh_Hans: 获取飞书自建应用的 tenant_access_token -description: - human: - en_US: Get tenant access token - zh_Hans: | - 获取飞书自建应用的 tenant_access_token,响应体示例: - {"code":0,"msg":"ok","tenant_access_token":"t-caecc734c2e3328a62489fe0648c4b98779515d3","expire":7200} - tenant_access_token: 租户访问凭证; - expire: tenant_access_token 的过期时间,单位为秒; - llm: A tool for obtaining a tenant access token. The input parameters must include app_id and app_secret. -parameters: - - name: app_id - type: string - required: true - label: - en_US: app_id - zh_Hans: 应用唯一标识 - human_description: - en_US: app_id is the unique identifier of the Lark Open Platform application - zh_Hans: app_id 是飞书开放平台应用的唯一标识 - llm_description: app_id is the unique identifier of the Lark Open Platform application - form: llm - - - name: app_secret - type: secret-input - required: true - label: - en_US: app_secret - zh_Hans: 应用秘钥 - human_description: - en_US: app_secret is the secret key of the application - zh_Hans: app_secret 是应用的秘钥 - llm_description: app_secret is the secret key of the application - form: llm diff --git a/api/core/tools/provider/builtin/feishu_base/tools/list_base_records.py b/api/core/tools/provider/builtin/feishu_base/tools/list_base_records.py deleted file mode 100644 index e579d02f69..0000000000 --- a/api/core/tools/provider/builtin/feishu_base/tools/list_base_records.py +++ /dev/null @@ -1,65 +0,0 @@ -import json -from typing import Any, Union - -import httpx - -from core.tools.entities.tool_entities import ToolInvokeMessage -from core.tools.tool.builtin_tool import BuiltinTool - - -class ListBaseRecordsTool(BuiltinTool): - def _invoke( - self, user_id: str, tool_parameters: dict[str, Any] - ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: - url = "https://open.feishu.cn/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/records/search" - - access_token = tool_parameters.get("Authorization", "") - if not access_token: - return self.create_text_message("Invalid parameter access_token") - - app_token = tool_parameters.get("app_token", "") - if not app_token: - return self.create_text_message("Invalid parameter app_token") - - table_id = tool_parameters.get("table_id", "") - if not table_id: - return self.create_text_message("Invalid parameter table_id") - - page_token = tool_parameters.get("page_token", "") - page_size = tool_parameters.get("page_size", "") - sort_condition = tool_parameters.get("sort_condition", "") - filter_condition = tool_parameters.get("filter_condition", "") - - headers = { - "Content-Type": "application/json", - "Authorization": f"Bearer {access_token}", - } - - params = { - "page_token": page_token, - "page_size": page_size, - } - - payload = {"automatic_fields": True} - if sort_condition: - payload["sort"] = json.loads(sort_condition) - if filter_condition: - payload["filter"] = json.loads(filter_condition) - - try: - res = httpx.post( - url.format(app_token=app_token, table_id=table_id), - headers=headers, - params=params, - json=payload, - timeout=30, - ) - res_json = res.json() - if res.is_success: - return self.create_text_message(text=json.dumps(res_json)) - else: - return self.create_text_message( - f"Failed to list base records, status code: {res.status_code}, response: {res.text}" - ) - except Exception as e: - return self.create_text_message("Failed to list base records. {}".format(e)) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/list_base_records.yaml b/api/core/tools/provider/builtin/feishu_base/tools/list_base_records.yaml deleted file mode 100644 index 8647c880a6..0000000000 --- a/api/core/tools/provider/builtin/feishu_base/tools/list_base_records.yaml +++ /dev/null @@ -1,108 +0,0 @@ -identity: - name: list_base_records - author: Doug Lea - label: - en_US: List Base Records - zh_Hans: 查询多维表格数据表中的现有记录 -description: - human: - en_US: List base records - zh_Hans: | - 查询多维表格数据表中的现有记录,单次最多查询 500 行记录,支持分页获取。 - llm: Query existing records in a multidimensional table data table. A maximum of 500 rows of records can be queried at a time, and paging retrieval is supported. -parameters: - - name: Authorization - type: string - required: true - label: - en_US: token - zh_Hans: 凭证 - human_description: - en_US: API access token parameter, tenant_access_token or user_access_token - zh_Hans: API 的访问凭证参数,tenant_access_token 或 user_access_token - llm_description: API access token parameter, tenant_access_token or user_access_token - form: llm - - - name: app_token - type: string - required: true - label: - en_US: app_token - zh_Hans: 多维表格 - human_description: - en_US: bitable app token - zh_Hans: 多维表格的唯一标识符 app_token - llm_description: bitable app token - form: llm - - - name: table_id - type: string - required: true - label: - en_US: table_id - zh_Hans: 多维表格的数据表 - human_description: - en_US: bitable table id - zh_Hans: 多维表格数据表的唯一标识符 table_id - llm_description: bitable table id - form: llm - - - name: page_token - type: string - required: false - label: - en_US: page_token - zh_Hans: 分页标记 - human_description: - en_US: Pagination mark. If it is not filled in the first request, it means to traverse from the beginning. - zh_Hans: 分页标记,第一次请求不填,表示从头开始遍历。 - llm_description: 分页标记,第一次请求不填,表示从头开始遍历;分页查询结果还有更多项时会同时返回新的 page_token,下次遍历可采用该 page_token 获取查询结果。 - form: llm - - - name: page_size - type: number - required: false - default: 20 - label: - en_US: page_size - zh_Hans: 分页大小 - human_description: - en_US: paging size - zh_Hans: 分页大小,默认值为 20,最大值为 100。 - llm_description: The default value of paging size is 20 and the maximum value is 100. - form: llm - - - name: sort_condition - type: string - required: false - label: - en_US: sort_condition - zh_Hans: 排序条件 - human_description: - en_US: sort condition - zh_Hans: | - 排序条件,格式为:[{"field_name":"多行文本","desc":true}]。 - field_name: 字段名称; - desc: 是否倒序排序; - llm_description: | - Sorting conditions, the format is: [{"field_name":"multi-line text","desc":true}]. - form: llm - - - name: filter_condition - type: string - required: false - label: - en_US: filter_condition - zh_Hans: 筛选条件 - human_description: - en_US: filter condition - zh_Hans: | - 筛选条件,格式为:{"conjunction":"and","conditions":[{"field_name":"字段1","operator":"is","value":["文本内容"]}]}。 - conjunction:条件逻辑连接词; - conditions:筛选条件集合; - field_name:筛选条件的左值,值为字段的名称; - operator:条件运算符; - value:目标值; - llm_description: | - The format of the filter condition is: {"conjunction":"and","conditions":[{"field_name":"Field 1","operator":"is","value":["text content"]}]}. - form: llm diff --git a/api/core/tools/provider/builtin/feishu_base/tools/list_base_tables.py b/api/core/tools/provider/builtin/feishu_base/tools/list_base_tables.py deleted file mode 100644 index 4ec9a476bc..0000000000 --- a/api/core/tools/provider/builtin/feishu_base/tools/list_base_tables.py +++ /dev/null @@ -1,47 +0,0 @@ -import json -from typing import Any, Union - -import httpx - -from core.tools.entities.tool_entities import ToolInvokeMessage -from core.tools.tool.builtin_tool import BuiltinTool - - -class ListBaseTablesTool(BuiltinTool): - def _invoke( - self, user_id: str, tool_parameters: dict[str, Any] - ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: - url = "https://open.feishu.cn/open-apis/bitable/v1/apps/{app_token}/tables" - - access_token = tool_parameters.get("Authorization", "") - if not access_token: - return self.create_text_message("Invalid parameter access_token") - - app_token = tool_parameters.get("app_token", "") - if not app_token: - return self.create_text_message("Invalid parameter app_token") - - page_token = tool_parameters.get("page_token", "") - page_size = tool_parameters.get("page_size", "") - - headers = { - "Content-Type": "application/json", - "Authorization": f"Bearer {access_token}", - } - - params = { - "page_token": page_token, - "page_size": page_size, - } - - try: - res = httpx.get(url.format(app_token=app_token), headers=headers, params=params, timeout=30) - res_json = res.json() - if res.is_success: - return self.create_text_message(text=json.dumps(res_json)) - else: - return self.create_text_message( - f"Failed to list base tables, status code: {res.status_code}, response: {res.text}" - ) - except Exception as e: - return self.create_text_message("Failed to list base tables. {}".format(e)) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/list_base_tables.yaml b/api/core/tools/provider/builtin/feishu_base/tools/list_base_tables.yaml deleted file mode 100644 index 9887124a28..0000000000 --- a/api/core/tools/provider/builtin/feishu_base/tools/list_base_tables.yaml +++ /dev/null @@ -1,65 +0,0 @@ -identity: - name: list_base_tables - author: Doug Lea - label: - en_US: List Base Tables - zh_Hans: 根据 app_token 获取多维表格下的所有数据表 -description: - human: - en_US: List base tables - zh_Hans: | - 根据 app_token 获取多维表格下的所有数据表 - llm: A tool for getting all data tables under a multidimensional table based on app_token. -parameters: - - name: Authorization - type: string - required: true - label: - en_US: token - zh_Hans: 凭证 - human_description: - en_US: API access token parameter, tenant_access_token or user_access_token - zh_Hans: API 的访问凭证参数,tenant_access_token 或 user_access_token - llm_description: API access token parameter, tenant_access_token or user_access_token - form: llm - - - name: app_token - type: string - required: true - label: - en_US: app_token - zh_Hans: 多维表格 - human_description: - en_US: bitable app token - zh_Hans: 多维表格的唯一标识符 app_token - llm_description: bitable app token - form: llm - - - name: page_token - type: string - required: false - label: - en_US: page_token - zh_Hans: 分页标记 - human_description: - en_US: Pagination mark. If it is not filled in the first request, it means to traverse from the beginning. - zh_Hans: 分页标记,第一次请求不填,表示从头开始遍历。 - llm_description: | - Pagination token. If it is not filled in the first request, it means to start traversal from the beginning. - If there are more items in the pagination query result, a new page_token will be returned at the same time. - The page_token can be used to obtain the query result in the next traversal. - 分页标记,第一次请求不填,表示从头开始遍历;分页查询结果还有更多项时会同时返回新的 page_token,下次遍历可采用该 page_token 获取查询结果。 - form: llm - - - name: page_size - type: number - required: false - default: 20 - label: - en_US: page_size - zh_Hans: 分页大小 - human_description: - en_US: paging size - zh_Hans: 分页大小,默认值为 20,最大值为 100。 - llm_description: The default value of paging size is 20 and the maximum value is 100. - form: llm diff --git a/api/core/tools/provider/builtin/feishu_base/tools/list_tables.py b/api/core/tools/provider/builtin/feishu_base/tools/list_tables.py new file mode 100644 index 0000000000..c7768a496d --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/list_tables.py @@ -0,0 +1,19 @@ +from typing import Any + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.tool.builtin_tool import BuiltinTool +from core.tools.utils.feishu_api_utils import FeishuRequest + + +class ListTablesTool(BuiltinTool): + def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage: + app_id = self.runtime.credentials.get("app_id") + app_secret = self.runtime.credentials.get("app_secret") + client = FeishuRequest(app_id, app_secret) + + app_token = tool_parameters.get("app_token") + page_token = tool_parameters.get("page_token") + page_size = tool_parameters.get("page_size", 20) + + res = client.list_tables(app_token, page_token, page_size) + return self.create_json_message(res) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/list_tables.yaml b/api/core/tools/provider/builtin/feishu_base/tools/list_tables.yaml new file mode 100644 index 0000000000..5a3891bd45 --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/list_tables.yaml @@ -0,0 +1,50 @@ +identity: + name: list_tables + author: Doug Lea + label: + en_US: List Tables + zh_Hans: 列出数据表 +description: + human: + en_US: Get All Data Tables under Multidimensional Table + zh_Hans: 获取多维表格下的所有数据表 + llm: A tool for getting all data tables under a multidimensional table. (获取多维表格下的所有数据表) +parameters: + - name: app_token + type: string + required: true + label: + en_US: app_token + zh_Hans: app_token + human_description: + en_US: Unique identifier for the multidimensional table, supports inputting document URL. + zh_Hans: 多维表格的唯一标识符,支持输入文档 URL。 + llm_description: 多维表格的唯一标识符,支持输入文档 URL。 + form: llm + + - name: page_size + type: number + required: false + default: 20 + label: + en_US: page_size + zh_Hans: 分页大小 + human_description: + en_US: | + Page size, default value: 20, maximum value: 100. + zh_Hans: 分页大小,默认值:20,最大值:100。 + llm_description: 分页大小,默认值:20,最大值:100。 + form: llm + + - name: page_token + type: string + required: false + label: + en_US: page_token + zh_Hans: 分页标记 + human_description: + en_US: | + Page token, leave empty for the first request to start from the beginning; a new page_token will be returned if there are more items in the paginated query results, which can be used for the next traversal. Example value: "tblsRc9GRRXKqhvW". + zh_Hans: 分页标记,第一次请求不填,表示从头开始遍历;分页查询结果还有更多项时会同时返回新的 page_token,下次遍历可采用该 page_token 获取查询结果。示例值:"tblsRc9GRRXKqhvW"。 + llm_description: 分页标记,第一次请求不填,表示从头开始遍历;分页查询结果还有更多项时会同时返回新的 page_token,下次遍历可采用该 page_token 获取查询结果。示例值:"tblsRc9GRRXKqhvW"。 + form: llm diff --git a/api/core/tools/provider/builtin/feishu_base/tools/read_base_record.py b/api/core/tools/provider/builtin/feishu_base/tools/read_base_record.py deleted file mode 100644 index fb818f8380..0000000000 --- a/api/core/tools/provider/builtin/feishu_base/tools/read_base_record.py +++ /dev/null @@ -1,49 +0,0 @@ -import json -from typing import Any, Union - -import httpx - -from core.tools.entities.tool_entities import ToolInvokeMessage -from core.tools.tool.builtin_tool import BuiltinTool - - -class ReadBaseRecordTool(BuiltinTool): - def _invoke( - self, user_id: str, tool_parameters: dict[str, Any] - ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: - url = "https://open.feishu.cn/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/records/{record_id}" - - access_token = tool_parameters.get("Authorization", "") - if not access_token: - return self.create_text_message("Invalid parameter access_token") - - app_token = tool_parameters.get("app_token", "") - if not app_token: - return self.create_text_message("Invalid parameter app_token") - - table_id = tool_parameters.get("table_id", "") - if not table_id: - return self.create_text_message("Invalid parameter table_id") - - record_id = tool_parameters.get("record_id", "") - if not record_id: - return self.create_text_message("Invalid parameter record_id") - - headers = { - "Content-Type": "application/json", - "Authorization": f"Bearer {access_token}", - } - - try: - res = httpx.get( - url.format(app_token=app_token, table_id=table_id, record_id=record_id), headers=headers, timeout=30 - ) - res_json = res.json() - if res.is_success: - return self.create_text_message(text=json.dumps(res_json)) - else: - return self.create_text_message( - f"Failed to read base record, status code: {res.status_code}, response: {res.text}" - ) - except Exception as e: - return self.create_text_message("Failed to read base record. {}".format(e)) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/read_base_record.yaml b/api/core/tools/provider/builtin/feishu_base/tools/read_base_record.yaml deleted file mode 100644 index 400e9a1021..0000000000 --- a/api/core/tools/provider/builtin/feishu_base/tools/read_base_record.yaml +++ /dev/null @@ -1,60 +0,0 @@ -identity: - name: read_base_record - author: Doug Lea - label: - en_US: Read Base Record - zh_Hans: 根据 record_id 的值检索多维表格数据表的记录 -description: - human: - en_US: Read base record - zh_Hans: | - 根据 record_id 的值检索多维表格数据表的记录 - llm: Retrieve records from a multidimensional table based on the value of record_id -parameters: - - name: Authorization - type: string - required: true - label: - en_US: token - zh_Hans: 凭证 - human_description: - en_US: API access token parameter, tenant_access_token or user_access_token - zh_Hans: API 的访问凭证参数,tenant_access_token 或 user_access_token - llm_description: API access token parameter, tenant_access_token or user_access_token - form: llm - - - name: app_token - type: string - required: true - label: - en_US: app_token - zh_Hans: 多维表格 - human_description: - en_US: bitable app token - zh_Hans: 多维表格的唯一标识符 app_token - llm_description: bitable app token - form: llm - - - name: table_id - type: string - required: true - label: - en_US: table_id - zh_Hans: 多维表格的数据表 - human_description: - en_US: bitable table id - zh_Hans: 多维表格数据表的唯一标识符 table_id - llm_description: bitable table id - form: llm - - - name: record_id - type: string - required: true - label: - en_US: record_id - zh_Hans: 单条记录的 id - human_description: - en_US: The id of a single record - zh_Hans: 单条记录的 id - llm_description: The id of a single record - form: llm diff --git a/api/core/tools/provider/builtin/feishu_base/tools/read_records.py b/api/core/tools/provider/builtin/feishu_base/tools/read_records.py new file mode 100644 index 0000000000..46f3df4ff0 --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/read_records.py @@ -0,0 +1,21 @@ +from typing import Any + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.tool.builtin_tool import BuiltinTool +from core.tools.utils.feishu_api_utils import FeishuRequest + + +class ReadRecordsTool(BuiltinTool): + def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage: + app_id = self.runtime.credentials.get("app_id") + app_secret = self.runtime.credentials.get("app_secret") + client = FeishuRequest(app_id, app_secret) + + app_token = tool_parameters.get("app_token") + table_id = tool_parameters.get("table_id") + table_name = tool_parameters.get("table_name") + record_ids = tool_parameters.get("record_ids") + user_id_type = tool_parameters.get("user_id_type", "open_id") + + res = client.read_records(app_token, table_id, table_name, record_ids, user_id_type) + return self.create_json_message(res) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/read_records.yaml b/api/core/tools/provider/builtin/feishu_base/tools/read_records.yaml new file mode 100644 index 0000000000..911e667cfc --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/read_records.yaml @@ -0,0 +1,86 @@ +identity: + name: read_records + author: Doug Lea + label: + en_US: Read Records + zh_Hans: 批量获取记录 +description: + human: + en_US: Batch Retrieve Records from Multidimensional Table + zh_Hans: 批量获取多维表格数据表中的记录信息 + llm: A tool for batch retrieving records from a multidimensional table, supporting up to 100 records per call. (批量获取多维表格数据表中的记录信息,单次调用最多支持查询 100 条记录) + +parameters: + - name: app_token + type: string + required: true + label: + en_US: app_token + zh_Hans: app_token + human_description: + en_US: Unique identifier for the multidimensional table, supports inputting document URL. + zh_Hans: 多维表格的唯一标识符,支持输入文档 URL。 + llm_description: 多维表格的唯一标识符,支持输入文档 URL。 + form: llm + + - name: table_id + type: string + required: false + label: + en_US: table_id + zh_Hans: table_id + human_description: + en_US: Unique identifier for the multidimensional table data, either table_id or table_name must be provided, cannot be empty simultaneously. + zh_Hans: 多维表格数据表的唯一标识符,table_id 和 table_name 至少需要提供一个,不能同时为空。 + llm_description: 多维表格数据表的唯一标识符,table_id 和 table_name 至少需要提供一个,不能同时为空。 + form: llm + + - name: table_name + type: string + required: false + label: + en_US: table_name + zh_Hans: table_name + human_description: + en_US: Name of the multidimensional table data, either table_name or table_id must be provided, cannot be empty simultaneously. + zh_Hans: 多维表格数据表的名称,table_name 和 table_id 至少需要提供一个,不能同时为空。 + llm_description: 多维表格数据表的名称,table_name 和 table_id 至少需要提供一个,不能同时为空。 + form: llm + + - name: record_ids + type: string + required: true + label: + en_US: record_ids + zh_Hans: 记录 ID 列表 + human_description: + en_US: List of record IDs, which can be obtained by calling the "Query Records API". + zh_Hans: 记录 ID 列表,可以通过调用"查询记录接口"获取。 + llm_description: 记录 ID 列表,可以通过调用"查询记录接口"获取。 + form: llm + + - name: user_id_type + type: select + required: false + options: + - value: open_id + label: + en_US: open_id + zh_Hans: open_id + - value: union_id + label: + en_US: union_id + zh_Hans: union_id + - value: user_id + label: + en_US: user_id + zh_Hans: user_id + default: "open_id" + label: + en_US: user_id_type + zh_Hans: 用户 ID 类型 + human_description: + en_US: User ID type, optional values are open_id, union_id, user_id, with a default value of open_id. + zh_Hans: 用户 ID 类型,可选值有 open_id、union_id、user_id,默认值为 open_id。 + llm_description: 用户 ID 类型,可选值有 open_id、union_id、user_id,默认值为 open_id。 + form: form diff --git a/api/core/tools/provider/builtin/feishu_base/tools/search_records.py b/api/core/tools/provider/builtin/feishu_base/tools/search_records.py new file mode 100644 index 0000000000..c959496735 --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/search_records.py @@ -0,0 +1,39 @@ +from typing import Any + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.tool.builtin_tool import BuiltinTool +from core.tools.utils.feishu_api_utils import FeishuRequest + + +class SearchRecordsTool(BuiltinTool): + def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage: + app_id = self.runtime.credentials.get("app_id") + app_secret = self.runtime.credentials.get("app_secret") + client = FeishuRequest(app_id, app_secret) + + app_token = tool_parameters.get("app_token") + table_id = tool_parameters.get("table_id") + table_name = tool_parameters.get("table_name") + view_id = tool_parameters.get("view_id") + field_names = tool_parameters.get("field_names") + sort = tool_parameters.get("sort") + filters = tool_parameters.get("filter") + page_token = tool_parameters.get("page_token") + automatic_fields = tool_parameters.get("automatic_fields", False) + user_id_type = tool_parameters.get("user_id_type", "open_id") + page_size = tool_parameters.get("page_size", 20) + + res = client.search_record( + app_token, + table_id, + table_name, + view_id, + field_names, + sort, + filters, + page_token, + automatic_fields, + user_id_type, + page_size, + ) + return self.create_json_message(res) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/search_records.yaml b/api/core/tools/provider/builtin/feishu_base/tools/search_records.yaml new file mode 100644 index 0000000000..6cac4b0524 --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/search_records.yaml @@ -0,0 +1,163 @@ +identity: + name: search_records + author: Doug Lea + label: + en_US: Search Records + zh_Hans: 查询记录 +description: + human: + en_US: Query records in a multidimensional table, up to 500 rows per query. + zh_Hans: 查询多维表格数据表中的记录,单次最多查询 500 行记录。 + llm: A tool for querying records in a multidimensional table, up to 500 rows per query. (查询多维表格数据表中的记录,单次最多查询 500 行记录) +parameters: + - name: app_token + type: string + required: true + label: + en_US: app_token + zh_Hans: app_token + human_description: + en_US: Unique identifier for the multidimensional table, supports inputting document URL. + zh_Hans: 多维表格的唯一标识符,支持输入文档 URL。 + llm_description: 多维表格的唯一标识符,支持输入文档 URL。 + form: llm + + - name: table_id + type: string + required: false + label: + en_US: table_id + zh_Hans: table_id + human_description: + en_US: Unique identifier for the multidimensional table data, either table_id or table_name must be provided, cannot be empty simultaneously. + zh_Hans: 多维表格数据表的唯一标识符,table_id 和 table_name 至少需要提供一个,不能同时为空。 + llm_description: 多维表格数据表的唯一标识符,table_id 和 table_name 至少需要提供一个,不能同时为空。 + form: llm + + - name: table_name + type: string + required: false + label: + en_US: table_name + zh_Hans: table_name + human_description: + en_US: Name of the multidimensional table data, either table_name or table_id must be provided, cannot be empty simultaneously. + zh_Hans: 多维表格数据表的名称,table_name 和 table_id 至少需要提供一个,不能同时为空。 + llm_description: 多维表格数据表的名称,table_name 和 table_id 至少需要提供一个,不能同时为空。 + form: llm + + - name: view_id + type: string + required: false + label: + en_US: view_id + zh_Hans: 视图唯一标识 + human_description: + en_US: | + Unique identifier for a view in a multidimensional table. It can be found in the URL's query parameter with the key 'view'. For example: https://svi136aogf123.feishu.cn/base/KWC8bYsYXahYqGsTtqectNn9n3e?table=tblE8a2fmBIEflaE&view=vewlkAVpRx. + zh_Hans: 多维表格中视图的唯一标识,可在多维表格的 URL 地址栏中找到,query 参数中 key 为 view 的部分。例如:https://svi136aogf123.feishu.cn/base/KWC8bYsYXahYqGsTtqectNn9n3e?table=tblE8a2fmBIEflaE&view=vewlkAVpRx。 + llm_description: 多维表格中视图的唯一标识,可在多维表格的 URL 地址栏中找到,query 参数中 key 为 view 的部分。例如:https://svi136aogf123.feishu.cn/base/KWC8bYsYXahYqGsTtqectNn9n3e?table=tblE8a2fmBIEflaE&view=vewlkAVpRx。 + form: llm + + - name: field_names + type: string + required: false + label: + en_US: field_names + zh_Hans: 字段名称 + human_description: + en_US: | + Field names to specify which fields to include in the returned records. Example value: ["Field1", "Field2"]. + zh_Hans: 字段名称,用于指定本次查询返回记录中包含的字段。示例值:["字段1","字段2"]。 + llm_description: 字段名称,用于指定本次查询返回记录中包含的字段。示例值:["字段1","字段2"]。 + form: llm + + - name: sort + type: string + required: false + label: + en_US: sort + zh_Hans: 排序条件 + human_description: + en_US: | + Sorting conditions, for example: [{"field_name":"Multiline Text","desc":true}]. + zh_Hans: 排序条件,例如:[{"field_name":"多行文本","desc":true}]。 + llm_description: 排序条件,例如:[{"field_name":"多行文本","desc":true}]。 + form: llm + + - name: filter + type: string + required: false + label: + en_US: filter + zh_Hans: 筛选条件 + human_description: + en_US: Object containing filter information. For details on how to fill in the filter, refer to the record filter parameter guide (https://open.larkoffice.com/document/uAjLw4CM/ukTMukTMukTM/reference/bitable-v1/app-table-record/record-filter-guide). + zh_Hans: 包含条件筛选信息的对象。了解如何填写 filter,参考记录筛选参数填写指南(https://open.larkoffice.com/document/uAjLw4CM/ukTMukTMukTM/reference/bitable-v1/app-table-record/record-filter-guide)。 + llm_description: 包含条件筛选信息的对象。了解如何填写 filter,参考记录筛选参数填写指南(https://open.larkoffice.com/document/uAjLw4CM/ukTMukTMukTM/reference/bitable-v1/app-table-record/record-filter-guide)。 + form: llm + + - name: automatic_fields + type: boolean + required: false + label: + en_US: automatic_fields + zh_Hans: automatic_fields + human_description: + en_US: Whether to return automatically calculated fields. Default is false, meaning they are not returned. + zh_Hans: 是否返回自动计算的字段。默认为 false,表示不返回。 + llm_description: 是否返回自动计算的字段。默认为 false,表示不返回。 + form: form + + - name: user_id_type + type: select + required: false + options: + - value: open_id + label: + en_US: open_id + zh_Hans: open_id + - value: union_id + label: + en_US: union_id + zh_Hans: union_id + - value: user_id + label: + en_US: user_id + zh_Hans: user_id + default: "open_id" + label: + en_US: user_id_type + zh_Hans: 用户 ID 类型 + human_description: + en_US: User ID type, optional values are open_id, union_id, user_id, with a default value of open_id. + zh_Hans: 用户 ID 类型,可选值有 open_id、union_id、user_id,默认值为 open_id。 + llm_description: 用户 ID 类型,可选值有 open_id、union_id、user_id,默认值为 open_id。 + form: form + + - name: page_size + type: number + required: false + default: 20 + label: + en_US: page_size + zh_Hans: 分页大小 + human_description: + en_US: | + Page size, default value: 20, maximum value: 500. + zh_Hans: 分页大小,默认值:20,最大值:500。 + llm_description: 分页大小,默认值:20,最大值:500。 + form: llm + + - name: page_token + type: string + required: false + label: + en_US: page_token + zh_Hans: 分页标记 + human_description: + en_US: | + Page token, leave empty for the first request to start from the beginning; a new page_token will be returned if there are more items in the paginated query results, which can be used for the next traversal. Example value: "tblsRc9GRRXKqhvW". + zh_Hans: 分页标记,第一次请求不填,表示从头开始遍历;分页查询结果还有更多项时会同时返回新的 page_token,下次遍历可采用该 page_token 获取查询结果。示例值:"tblsRc9GRRXKqhvW"。 + llm_description: 分页标记,第一次请求不填,表示从头开始遍历;分页查询结果还有更多项时会同时返回新的 page_token,下次遍历可采用该 page_token 获取查询结果。示例值:"tblsRc9GRRXKqhvW"。 + form: llm diff --git a/api/core/tools/provider/builtin/feishu_base/tools/update_base_record.py b/api/core/tools/provider/builtin/feishu_base/tools/update_base_record.py deleted file mode 100644 index 6d7e33f3ff..0000000000 --- a/api/core/tools/provider/builtin/feishu_base/tools/update_base_record.py +++ /dev/null @@ -1,60 +0,0 @@ -import json -from typing import Any, Union - -import httpx - -from core.tools.entities.tool_entities import ToolInvokeMessage -from core.tools.tool.builtin_tool import BuiltinTool - - -class UpdateBaseRecordTool(BuiltinTool): - def _invoke( - self, user_id: str, tool_parameters: dict[str, Any] - ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: - url = "https://open.feishu.cn/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/records/{record_id}" - - access_token = tool_parameters.get("Authorization", "") - if not access_token: - return self.create_text_message("Invalid parameter access_token") - - app_token = tool_parameters.get("app_token", "") - if not app_token: - return self.create_text_message("Invalid parameter app_token") - - table_id = tool_parameters.get("table_id", "") - if not table_id: - return self.create_text_message("Invalid parameter table_id") - - record_id = tool_parameters.get("record_id", "") - if not record_id: - return self.create_text_message("Invalid parameter record_id") - - fields = tool_parameters.get("fields", "") - if not fields: - return self.create_text_message("Invalid parameter fields") - - headers = { - "Content-Type": "application/json", - "Authorization": f"Bearer {access_token}", - } - - params = {} - payload = {"fields": json.loads(fields)} - - try: - res = httpx.put( - url.format(app_token=app_token, table_id=table_id, record_id=record_id), - headers=headers, - params=params, - json=payload, - timeout=30, - ) - res_json = res.json() - if res.is_success: - return self.create_text_message(text=json.dumps(res_json)) - else: - return self.create_text_message( - f"Failed to update base record, status code: {res.status_code}, response: {res.text}" - ) - except Exception as e: - return self.create_text_message("Failed to update base record. {}".format(e)) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/update_base_record.yaml b/api/core/tools/provider/builtin/feishu_base/tools/update_base_record.yaml deleted file mode 100644 index 788798c4b3..0000000000 --- a/api/core/tools/provider/builtin/feishu_base/tools/update_base_record.yaml +++ /dev/null @@ -1,78 +0,0 @@ -identity: - name: update_base_record - author: Doug Lea - label: - en_US: Update Base Record - zh_Hans: 更新多维表格数据表中的一条记录 -description: - human: - en_US: Update base record - zh_Hans: | - 更新多维表格数据表中的一条记录,详细请参考:https://open.larkoffice.com/document/server-docs/docs/bitable-v1/app-table-record/update - llm: Update a record in a multidimensional table data table -parameters: - - name: Authorization - type: string - required: true - label: - en_US: token - zh_Hans: 凭证 - human_description: - en_US: API access token parameter, tenant_access_token or user_access_token - zh_Hans: API 的访问凭证参数,tenant_access_token 或 user_access_token - llm_description: API access token parameter, tenant_access_token or user_access_token - form: llm - - - name: app_token - type: string - required: true - label: - en_US: app_token - zh_Hans: 多维表格 - human_description: - en_US: bitable app token - zh_Hans: 多维表格的唯一标识符 app_token - llm_description: bitable app token - form: llm - - - name: table_id - type: string - required: true - label: - en_US: table_id - zh_Hans: 多维表格的数据表 - human_description: - en_US: bitable table id - zh_Hans: 多维表格数据表的唯一标识符 table_id - llm_description: bitable table id - form: llm - - - name: record_id - type: string - required: true - label: - en_US: record_id - zh_Hans: 单条记录的 id - human_description: - en_US: The id of a single record - zh_Hans: 单条记录的 id - llm_description: The id of a single record - form: llm - - - name: fields - type: string - required: true - label: - en_US: fields - zh_Hans: 数据表的列字段内容 - human_description: - en_US: The fields of a multidimensional table data table, that is, the columns of the data table. - zh_Hans: | - 要更新一行多维表格记录,字段结构拼接如下:{"多行文本":"多行文本内容","单选":"选项1","多选":["选项1","选项2"],"复选框":true,"人员":[{"id":"ou_2910013f1e6456f16a0ce75ede950a0a"}],"群组":[{"id":"oc_cd07f55f14d6f4a4f1b51504e7e97f48"}],"电话号码":"13026162666"} - 当前接口支持的字段类型为:多行文本、单选、条码、多选、日期、人员、附件、复选框、超链接、数字、单向关联、双向关联、电话号码、地理位置。 - 不同类型字段的数据结构请参考数据结构概述:https://open.larkoffice.com/document/server-docs/docs/bitable-v1/bitable-structure - llm_description: | - 要更新一行多维表格记录,字段结构拼接如下:{"多行文本":"多行文本内容","单选":"选项1","多选":["选项1","选项2"],"复选框":true,"人员":[{"id":"ou_2910013f1e6456f16a0ce75ede950a0a"}],"群组":[{"id":"oc_cd07f55f14d6f4a4f1b51504e7e97f48"}],"电话号码":"13026162666"} - 当前接口支持的字段类型为:多行文本、单选、条码、多选、日期、人员、附件、复选框、超链接、数字、单向关联、双向关联、电话号码、地理位置。 - 不同类型字段的数据结构请参考数据结构概述:https://open.larkoffice.com/document/server-docs/docs/bitable-v1/bitable-structure - form: llm diff --git a/api/core/tools/provider/builtin/feishu_base/tools/update_records.py b/api/core/tools/provider/builtin/feishu_base/tools/update_records.py new file mode 100644 index 0000000000..a7b0363875 --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/update_records.py @@ -0,0 +1,21 @@ +from typing import Any + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.tool.builtin_tool import BuiltinTool +from core.tools.utils.feishu_api_utils import FeishuRequest + + +class UpdateRecordsTool(BuiltinTool): + def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage: + app_id = self.runtime.credentials.get("app_id") + app_secret = self.runtime.credentials.get("app_secret") + client = FeishuRequest(app_id, app_secret) + + app_token = tool_parameters.get("app_token") + table_id = tool_parameters.get("table_id") + table_name = tool_parameters.get("table_name") + records = tool_parameters.get("records") + user_id_type = tool_parameters.get("user_id_type", "open_id") + + res = client.update_records(app_token, table_id, table_name, records, user_id_type) + return self.create_json_message(res) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/update_records.yaml b/api/core/tools/provider/builtin/feishu_base/tools/update_records.yaml new file mode 100644 index 0000000000..68117e7136 --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/update_records.yaml @@ -0,0 +1,91 @@ +identity: + name: update_records + author: Doug Lea + label: + en_US: Update Records + zh_Hans: 更新多条记录 +description: + human: + en_US: Update Multiple Records in Multidimensional Table + zh_Hans: 更新多维表格数据表中的多条记录 + llm: A tool for updating multiple records in a multidimensional table. (更新多维表格数据表中的多条记录) +parameters: + - name: app_token + type: string + required: true + label: + en_US: app_token + zh_Hans: app_token + human_description: + en_US: Unique identifier for the multidimensional table, supports inputting document URL. + zh_Hans: 多维表格的唯一标识符,支持输入文档 URL。 + llm_description: 多维表格的唯一标识符,支持输入文档 URL。 + form: llm + + - name: table_id + type: string + required: false + label: + en_US: table_id + zh_Hans: table_id + human_description: + en_US: Unique identifier for the multidimensional table data, either table_id or table_name must be provided, cannot be empty simultaneously. + zh_Hans: 多维表格数据表的唯一标识符,table_id 和 table_name 至少需要提供一个,不能同时为空。 + llm_description: 多维表格数据表的唯一标识符,table_id 和 table_name 至少需要提供一个,不能同时为空。 + form: llm + + - name: table_name + type: string + required: false + label: + en_US: table_name + zh_Hans: table_name + human_description: + en_US: Name of the multidimensional table data, either table_name or table_id must be provided, cannot be empty simultaneously. + zh_Hans: 多维表格数据表的名称,table_name 和 table_id 至少需要提供一个,不能同时为空。 + llm_description: 多维表格数据表的名称,table_name 和 table_id 至少需要提供一个,不能同时为空。 + form: llm + + - name: records + type: string + required: true + label: + en_US: records + zh_Hans: 记录列表 + human_description: + en_US: | + List of records to be updated in this request. Example value: [{"fields":{"multi-line-text":"text content","single_select":"option 1","date":1674206443000},"record_id":"recupK4f4RM5RX"}]. + For supported field types, refer to the integration guide (https://open.larkoffice.com/document/server-docs/docs/bitable-v1/notification). For data structures of different field types, refer to the data structure overview (https://open.larkoffice.com/document/server-docs/docs/bitable-v1/bitable-structure). + zh_Hans: | + 本次请求将要更新的记录列表,示例值:[{"fields":{"多行文本":"文本内容","单选":"选项 1","日期":1674206443000},"record_id":"recupK4f4RM5RX"}]。 + 当前接口支持的字段类型请参考接入指南(https://open.larkoffice.com/document/server-docs/docs/bitable-v1/notification),不同类型字段的数据结构请参考数据结构概述(https://open.larkoffice.com/document/server-docs/docs/bitable-v1/bitable-structure)。 + llm_description: | + 本次请求将要更新的记录列表,示例值:[{"fields":{"多行文本":"文本内容","单选":"选项 1","日期":1674206443000},"record_id":"recupK4f4RM5RX"}]。 + 当前接口支持的字段类型请参考接入指南(https://open.larkoffice.com/document/server-docs/docs/bitable-v1/notification),不同类型字段的数据结构请参考数据结构概述(https://open.larkoffice.com/document/server-docs/docs/bitable-v1/bitable-structure)。 + form: llm + + - name: user_id_type + type: select + required: false + options: + - value: open_id + label: + en_US: open_id + zh_Hans: open_id + - value: union_id + label: + en_US: union_id + zh_Hans: union_id + - value: user_id + label: + en_US: user_id + zh_Hans: user_id + default: "open_id" + label: + en_US: user_id_type + zh_Hans: 用户 ID 类型 + human_description: + en_US: User ID type, optional values are open_id, union_id, user_id, with a default value of open_id. + zh_Hans: 用户 ID 类型,可选值有 open_id、union_id、user_id,默认值为 open_id。 + llm_description: 用户 ID 类型,可选值有 open_id、union_id、user_id,默认值为 open_id。 + form: form diff --git a/api/core/tools/utils/feishu_api_utils.py b/api/core/tools/utils/feishu_api_utils.py index 245b296d18..722cf4b538 100644 --- a/api/core/tools/utils/feishu_api_utils.py +++ b/api/core/tools/utils/feishu_api_utils.py @@ -1,3 +1,4 @@ +import json from typing import Optional import httpx @@ -17,6 +18,41 @@ def auth(credentials): raise ToolProviderCredentialValidationError(str(e)) +def convert_add_records(json_str): + try: + data = json.loads(json_str) + if not isinstance(data, list): + raise ValueError("Parsed data must be a list") + converted_data = [{"fields": json.dumps(item, ensure_ascii=False)} for item in data] + return converted_data + except json.JSONDecodeError: + raise ValueError("The input string is not valid JSON") + except Exception as e: + raise ValueError(f"An error occurred while processing the data: {e}") + + +def convert_update_records(json_str): + try: + data = json.loads(json_str) + if not isinstance(data, list): + raise ValueError("Parsed data must be a list") + + converted_data = [ + {"fields": json.dumps(record["fields"], ensure_ascii=False), "record_id": record["record_id"]} + for record in data + if "fields" in record and "record_id" in record + ] + + if len(converted_data) != len(data): + raise ValueError("Each record must contain 'fields' and 'record_id'") + + return converted_data + except json.JSONDecodeError: + raise ValueError("The input string is not valid JSON") + except Exception as e: + raise ValueError(f"An error occurred while processing the data: {e}") + + class FeishuRequest: API_BASE_URL = "https://lark-plugin-api.solutionsuite.cn/lark-plugin" @@ -517,3 +553,270 @@ class FeishuRequest: } res = self._send_request(url, method="GET", params=params) return res.get("data") + + def create_base( + self, + name: str, + folder_token: str, + ) -> dict: + # 创建多维表格 + url = f"{self.API_BASE_URL}/base/create_base" + payload = { + "name": name, + "folder_token": folder_token, + } + res = self._send_request(url, payload=payload) + return res.get("data") + + def add_records( + self, + app_token: str, + table_id: str, + table_name: str, + records: str, + user_id_type: str = "open_id", + ) -> dict: + # 新增多条记录 + url = f"{self.API_BASE_URL}/base/add_records" + params = { + "app_token": app_token, + "table_id": table_id, + "table_name": table_name, + "user_id_type": user_id_type, + } + payload = { + "records": convert_add_records(records), + } + res = self._send_request(url, params=params, payload=payload) + return res.get("data") + + def update_records( + self, + app_token: str, + table_id: str, + table_name: str, + records: str, + user_id_type: str, + ) -> dict: + # 更新多条记录 + url = f"{self.API_BASE_URL}/base/update_records" + params = { + "app_token": app_token, + "table_id": table_id, + "table_name": table_name, + "user_id_type": user_id_type, + } + payload = { + "records": convert_update_records(records), + } + res = self._send_request(url, params=params, payload=payload) + return res.get("data") + + def delete_records( + self, + app_token: str, + table_id: str, + table_name: str, + record_ids: str, + ) -> dict: + # 删除多条记录 + url = f"{self.API_BASE_URL}/base/delete_records" + params = { + "app_token": app_token, + "table_id": table_id, + "table_name": table_name, + } + if not record_ids: + record_id_list = [] + else: + try: + record_id_list = json.loads(record_ids) + except json.JSONDecodeError: + raise ValueError("The input string is not valid JSON") + payload = { + "records": record_id_list, + } + res = self._send_request(url, params=params, payload=payload) + return res.get("data") + + def search_record( + self, + app_token: str, + table_id: str, + table_name: str, + view_id: str, + field_names: str, + sort: str, + filters: str, + page_token: str, + automatic_fields: bool = False, + user_id_type: str = "open_id", + page_size: int = 20, + ) -> dict: + # 查询记录,单次最多查询 500 行记录。 + url = f"{self.API_BASE_URL}/base/search_record" + params = { + "app_token": app_token, + "table_id": table_id, + "table_name": table_name, + "user_id_type": user_id_type, + "page_token": page_token, + "page_size": page_size, + } + + if not field_names: + field_name_list = [] + else: + try: + field_name_list = json.loads(field_names) + except json.JSONDecodeError: + raise ValueError("The input string is not valid JSON") + + if not sort: + sort_list = [] + else: + try: + sort_list = json.loads(sort) + except json.JSONDecodeError: + raise ValueError("The input string is not valid JSON") + + if not filters: + filter_dict = {} + else: + try: + filter_dict = json.loads(filters) + except json.JSONDecodeError: + raise ValueError("The input string is not valid JSON") + + payload = {} + + if view_id: + payload["view_id"] = view_id + if field_names: + payload["field_names"] = field_name_list + if sort: + payload["sort"] = sort_list + if filters: + payload["filter"] = filter_dict + if automatic_fields: + payload["automatic_fields"] = automatic_fields + res = self._send_request(url, params=params, payload=payload) + return res.get("data") + + def get_base_info( + self, + app_token: str, + ) -> dict: + # 获取多维表格元数据 + url = f"{self.API_BASE_URL}/base/get_base_info" + params = { + "app_token": app_token, + } + res = self._send_request(url, method="GET", params=params) + return res.get("data") + + def create_table( + self, + app_token: str, + table_name: str, + default_view_name: str, + fields: str, + ) -> dict: + # 新增一个数据表 + url = f"{self.API_BASE_URL}/base/create_table" + params = { + "app_token": app_token, + } + if not fields: + fields_list = [] + else: + try: + fields_list = json.loads(fields) + except json.JSONDecodeError: + raise ValueError("The input string is not valid JSON") + payload = { + "name": table_name, + "fields": fields_list, + } + if default_view_name: + payload["default_view_name"] = default_view_name + res = self._send_request(url, params=params, payload=payload) + return res.get("data") + + def delete_tables( + self, + app_token: str, + table_ids: str, + table_names: str, + ) -> dict: + # 删除多个数据表 + url = f"{self.API_BASE_URL}/base/delete_tables" + params = { + "app_token": app_token, + } + if not table_ids: + table_id_list = [] + else: + try: + table_id_list = json.loads(table_ids) + except json.JSONDecodeError: + raise ValueError("The input string is not valid JSON") + + if not table_names: + table_name_list = [] + else: + try: + table_name_list = json.loads(table_names) + except json.JSONDecodeError: + raise ValueError("The input string is not valid JSON") + + payload = { + "table_ids": table_id_list, + "table_names": table_name_list, + } + res = self._send_request(url, params=params, payload=payload) + return res.get("data") + + def list_tables( + self, + app_token: str, + page_token: str, + page_size: int = 20, + ) -> dict: + # 列出多维表格下的全部数据表 + url = f"{self.API_BASE_URL}/base/list_tables" + params = { + "app_token": app_token, + "page_token": page_token, + "page_size": page_size, + } + res = self._send_request(url, method="GET", params=params) + return res.get("data") + + def read_records( + self, + app_token: str, + table_id: str, + table_name: str, + record_ids: str, + user_id_type: str = "open_id", + ) -> dict: + url = f"{self.API_BASE_URL}/base/read_records" + params = { + "app_token": app_token, + "table_id": table_id, + "table_name": table_name, + } + if not record_ids: + record_id_list = [] + else: + try: + record_id_list = json.loads(record_ids) + except json.JSONDecodeError: + raise ValueError("The input string is not valid JSON") + payload = { + "record_ids": record_id_list, + "user_id_type": user_id_type, + } + res = self._send_request(url, method="GET", params=params, payload=payload) + return res.get("data") From 0e965b652987b60ca85e5888e595fbf92668c2f9 Mon Sep 17 00:00:00 2001 From: -LAN- <laipz8200@outlook.com> Date: Tue, 22 Oct 2024 21:56:26 +0800 Subject: [PATCH 143/346] chore(models): convert created_by_role to its value for consistency (#9612) --- api/models/model.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/models/model.py b/api/models/model.py index 07c6247e0d..e289423d16 100644 --- a/api/models/model.py +++ b/api/models/model.py @@ -1109,7 +1109,7 @@ class MessageFile(db.Model): self.url = url self.belongs_to = belongs_to self.upload_file_id = upload_file_id - self.created_by_role = created_by_role + self.created_by_role = created_by_role.value self.created_by = created_by id: Mapped[str] = db.Column(StringUUID, server_default=db.text("uuid_generate_v4()")) From a7ee51e5d81dc240d008a02d4c3bc9f8d1628705 Mon Sep 17 00:00:00 2001 From: Kota-Yamaguchi <50980947+Kota-Yamaguchi@users.noreply.github.com> Date: Tue, 22 Oct 2024 22:57:54 +0900 Subject: [PATCH 144/346] feat: add code generator (#9051) Co-authored-by: crazywoola <100913391+crazywoola@users.noreply.github.com> --- api/.env.example | 1 + api/controllers/console/app/generator.py | 35 +++ api/core/llm_generator/llm_generator.py | 50 +++++ api/core/llm_generator/prompts.py | 67 ++++++ .../code-generator/get-code-generator-res.tsx | 200 ++++++++++++++++++ .../components/code-generator-button.tsx | 48 +++++ .../nodes/_base/components/editor/base.tsx | 12 +- .../components/editor/code-editor/index.tsx | 7 +- web/i18n/en-US/app-debug.ts | 14 ++ web/i18n/ja-JP/app-debug.ts | 14 ++ web/i18n/zh-Hans/app-debug.ts | 14 ++ web/service/debug.ts | 10 + 12 files changed, 470 insertions(+), 2 deletions(-) create mode 100644 web/app/components/app/configuration/config/code-generator/get-code-generator-res.tsx create mode 100644 web/app/components/workflow/nodes/_base/components/code-generator-button.tsx diff --git a/api/.env.example b/api/.env.example index 33c58ed691..5a9d21c980 100644 --- a/api/.env.example +++ b/api/.env.example @@ -239,6 +239,7 @@ UPLOAD_AUDIO_FILE_SIZE_LIMIT=50 # Model Configuration MULTIMODAL_SEND_IMAGE_FORMAT=base64 PROMPT_GENERATION_MAX_TOKENS=512 +CODE_GENERATION_MAX_TOKENS=1024 # Mail configuration, support: resend, smtp MAIL_TYPE= diff --git a/api/controllers/console/app/generator.py b/api/controllers/console/app/generator.py index 3d1e6b7a37..7108759b0b 100644 --- a/api/controllers/console/app/generator.py +++ b/api/controllers/console/app/generator.py @@ -52,4 +52,39 @@ class RuleGenerateApi(Resource): return rules +class RuleCodeGenerateApi(Resource): + @setup_required + @login_required + @account_initialization_required + def post(self): + parser = reqparse.RequestParser() + parser.add_argument("instruction", type=str, required=True, nullable=False, location="json") + parser.add_argument("model_config", type=dict, required=True, nullable=False, location="json") + parser.add_argument("no_variable", type=bool, required=True, default=False, location="json") + parser.add_argument("code_language", type=str, required=False, default="javascript", location="json") + args = parser.parse_args() + + account = current_user + CODE_GENERATION_MAX_TOKENS = int(os.getenv("CODE_GENERATION_MAX_TOKENS", "1024")) + try: + code_result = LLMGenerator.generate_code( + tenant_id=account.current_tenant_id, + instruction=args["instruction"], + model_config=args["model_config"], + code_language=args["code_language"], + max_tokens=CODE_GENERATION_MAX_TOKENS, + ) + except ProviderTokenNotInitError as ex: + raise ProviderNotInitializeError(ex.description) + except QuotaExceededError: + raise ProviderQuotaExceededError() + except ModelCurrentlyNotSupportError: + raise ProviderModelCurrentlyNotSupportError() + except InvokeError as e: + raise CompletionRequestError(e.description) + + return code_result + + api.add_resource(RuleGenerateApi, "/rule-generate") +api.add_resource(RuleCodeGenerateApi, "/rule-code-generate") diff --git a/api/core/llm_generator/llm_generator.py b/api/core/llm_generator/llm_generator.py index 39bd6fee69..9cf9ed75c0 100644 --- a/api/core/llm_generator/llm_generator.py +++ b/api/core/llm_generator/llm_generator.py @@ -8,6 +8,8 @@ from core.llm_generator.output_parser.suggested_questions_after_answer import Su from core.llm_generator.prompts import ( CONVERSATION_TITLE_PROMPT, GENERATOR_QA_PROMPT, + JAVASCRIPT_CODE_GENERATOR_PROMPT_TEMPLATE, + PYTHON_CODE_GENERATOR_PROMPT_TEMPLATE, WORKFLOW_RULE_CONFIG_PROMPT_GENERATE_TEMPLATE, ) from core.model_manager import ModelManager @@ -239,6 +241,54 @@ class LLMGenerator: return rule_config + @classmethod + def generate_code( + cls, + tenant_id: str, + instruction: str, + model_config: dict, + code_language: str = "javascript", + max_tokens: int = 1000, + ) -> dict: + if code_language == "python": + prompt_template = PromptTemplateParser(PYTHON_CODE_GENERATOR_PROMPT_TEMPLATE) + else: + prompt_template = PromptTemplateParser(JAVASCRIPT_CODE_GENERATOR_PROMPT_TEMPLATE) + + prompt = prompt_template.format( + inputs={ + "INSTRUCTION": instruction, + "CODE_LANGUAGE": code_language, + }, + remove_template_variables=False, + ) + + model_manager = ModelManager() + model_instance = model_manager.get_model_instance( + tenant_id=tenant_id, + model_type=ModelType.LLM, + provider=model_config.get("provider") if model_config else None, + model=model_config.get("name") if model_config else None, + ) + + prompt_messages = [UserPromptMessage(content=prompt)] + model_parameters = {"max_tokens": max_tokens, "temperature": 0.01} + + try: + response = model_instance.invoke_llm( + prompt_messages=prompt_messages, model_parameters=model_parameters, stream=False + ) + + generated_code = response.message.content + return {"code": generated_code, "language": code_language, "error": ""} + + except InvokeError as e: + error = str(e) + return {"code": "", "language": code_language, "error": f"Failed to generate code. Error: {error}"} + except Exception as e: + logging.exception(e) + return {"code": "", "language": code_language, "error": f"An unexpected error occurred: {str(e)}"} + @classmethod def generate_qa_document(cls, tenant_id: str, query, document_language: str): prompt = GENERATOR_QA_PROMPT.format(language=document_language) diff --git a/api/core/llm_generator/prompts.py b/api/core/llm_generator/prompts.py index e5b6784516..7c0f247052 100644 --- a/api/core/llm_generator/prompts.py +++ b/api/core/llm_generator/prompts.py @@ -61,6 +61,73 @@ User Input: yo, 你今天咋样? User Input: """ # noqa: E501 +PYTHON_CODE_GENERATOR_PROMPT_TEMPLATE = ( + "You are an expert programmer. Generate code based on the following instructions:\n\n" + "Instructions: {{INSTRUCTION}}\n\n" + "Write the code in {{CODE_LANGUAGE}}.\n\n" + "Please ensure that you meet the following requirements:\n" + "1. Define a function named 'main'.\n" + "2. The 'main' function must return a dictionary (dict).\n" + "3. You may modify the arguments of the 'main' function, but include appropriate type hints.\n" + "4. The returned dictionary should contain at least one key-value pair.\n\n" + "5. You may ONLY use the following libraries in your code: \n" + "- json\n" + "- datetime\n" + "- math\n" + "- random\n" + "- re\n" + "- string\n" + "- sys\n" + "- time\n" + "- traceback\n" + "- uuid\n" + "- os\n" + "- base64\n" + "- hashlib\n" + "- hmac\n" + "- binascii\n" + "- collections\n" + "- functools\n" + "- operator\n" + "- itertools\n\n" + "Example:\n" + "def main(arg1: str, arg2: int) -> dict:\n" + " return {\n" + ' "result": arg1 * arg2,\n' + " }\n\n" + "IMPORTANT:\n" + "- Provide ONLY the code without any additional explanations, comments, or markdown formatting.\n" + "- DO NOT use markdown code blocks (``` or ``` python). Return the raw code directly.\n" + "- The code should start immediately after this instruction, without any preceding newlines or spaces.\n" + "- The code should be complete, functional, and follow best practices for {{CODE_LANGUAGE}}.\n\n" + "- Always use the format return {'result': ...} for the output.\n\n" + "Generated Code:\n" +) +JAVASCRIPT_CODE_GENERATOR_PROMPT_TEMPLATE = ( + "You are an expert programmer. Generate code based on the following instructions:\n\n" + "Instructions: {{INSTRUCTION}}\n\n" + "Write the code in {{CODE_LANGUAGE}}.\n\n" + "Please ensure that you meet the following requirements:\n" + "1. Define a function named 'main'.\n" + "2. The 'main' function must return an object.\n" + "3. You may modify the arguments of the 'main' function, but include appropriate JSDoc annotations.\n" + "4. The returned object should contain at least one key-value pair.\n\n" + "5. The returned object should always be in the format: {result: ...}\n\n" + "Example:\n" + "function main(arg1, arg2) {\n" + " return {\n" + " result: arg1 * arg2\n" + " };\n" + "}\n\n" + "IMPORTANT:\n" + "- Provide ONLY the code without any additional explanations, comments, or markdown formatting.\n" + "- DO NOT use markdown code blocks (``` or ``` javascript). Return the raw code directly.\n" + "- The code should start immediately after this instruction, without any preceding newlines or spaces.\n" + "- The code should be complete, functional, and follow best practices for {{CODE_LANGUAGE}}.\n\n" + "Generated Code:\n" +) + + SUGGESTED_QUESTIONS_AFTER_ANSWER_INSTRUCTION_PROMPT = ( "Please help me predict the three most likely questions that human would ask, " "and keeping each question under 20 characters.\n" diff --git a/web/app/components/app/configuration/config/code-generator/get-code-generator-res.tsx b/web/app/components/app/configuration/config/code-generator/get-code-generator-res.tsx new file mode 100644 index 0000000000..b2d45d2733 --- /dev/null +++ b/web/app/components/app/configuration/config/code-generator/get-code-generator-res.tsx @@ -0,0 +1,200 @@ +import type { FC } from 'react' +import React from 'react' +import cn from 'classnames' +import useBoolean from 'ahooks/lib/useBoolean' +import { useTranslation } from 'react-i18next' +import ConfigPrompt from '../../config-prompt' +import { languageMap } from '../../../../workflow/nodes/_base/components/editor/code-editor/index' +import { generateRuleCode } from '@/service/debug' +import type { CodeGenRes } from '@/service/debug' +import { ModelModeType } from '@/types/app' +import type { AppType, Model } from '@/types/app' +import Modal from '@/app/components/base/modal' +import Button from '@/app/components/base/button' +import { Generator } from '@/app/components/base/icons/src/vender/other' +import Toast from '@/app/components/base/toast' +import Loading from '@/app/components/base/loading' +import Confirm from '@/app/components/base/confirm' +import type { CodeLanguage } from '@/app/components/workflow/nodes/code/types' +export type IGetCodeGeneratorResProps = { + mode: AppType + isShow: boolean + codeLanguages: CodeLanguage + onClose: () => void + onFinished: (res: CodeGenRes) => void +} + +export const GetCodeGeneratorResModal: FC<IGetCodeGeneratorResProps> = ( + { + mode, + isShow, + codeLanguages, + onClose, + onFinished, + + }, +) => { + const { t } = useTranslation() + const [instruction, setInstruction] = React.useState<string>('') + const [isLoading, { setTrue: setLoadingTrue, setFalse: setLoadingFalse }] = useBoolean(false) + const [res, setRes] = React.useState<CodeGenRes | null>(null) + const isValid = () => { + if (instruction.trim() === '') { + Toast.notify({ + type: 'error', + message: t('common.errorMsg.fieldRequired', { + field: t('appDebug.code.instruction'), + }), + }) + return false + } + return true + } + const model: Model = { + provider: 'openai', + name: 'gpt-4o-mini', + mode: ModelModeType.chat, + completion_params: { + temperature: 0.7, + max_tokens: 0, + top_p: 0, + echo: false, + stop: [], + presence_penalty: 0, + frequency_penalty: 0, + }, + } + const isInLLMNode = true + const onGenerate = async () => { + if (!isValid()) + return + if (isLoading) + return + setLoadingTrue() + try { + const { error, ...res } = await generateRuleCode({ + instruction, + model_config: model, + no_variable: !!isInLLMNode, + code_language: languageMap[codeLanguages] || 'javascript', + }) + setRes(res) + if (error) { + Toast.notify({ + type: 'error', + message: error, + }) + } + } + finally { + setLoadingFalse() + } + } + const [showConfirmOverwrite, setShowConfirmOverwrite] = React.useState(false) + + const renderLoading = ( + <div className='w-0 grow flex flex-col items-center justify-center h-full space-y-3'> + <Loading /> + <div className='text-[13px] text-gray-400'>{t('appDebug.codegen.loading')}</div> + </div> + ) + + return ( + <Modal + isShow={isShow} + onClose={onClose} + className='!p-0 min-w-[1140px]' + closable + > + <div className='relative flex h-[680px] flex-wrap'> + <div className='w-[570px] shrink-0 p-8 h-full overflow-y-auto border-r border-gray-100'> + <div className='mb-8'> + <div className={'leading-[28px] text-lg font-bold'}>{t('appDebug.codegen.title')}</div> + <div className='mt-1 text-[13px] font-normal text-gray-500'>{t('appDebug.codegen.description')}</div> + </div> + <div className='mt-6'> + <div className='text-[0px]'> + <div className='mb-2 leading-5 text-sm font-medium text-gray-900'>{t('appDebug.codegen.instruction')}</div> + <textarea + className="w-full h-[200px] overflow-y-auto px-3 py-2 text-sm bg-gray-50 rounded-lg" + placeholder={t('appDebug.codegen.instructionPlaceholder') || ''} + value={instruction} + onChange={e => setInstruction(e.target.value)} + /> + </div> + + <div className='mt-5 flex justify-end'> + <Button + className='flex space-x-1' + variant='primary' + onClick={onGenerate} + disabled={isLoading} + > + <Generator className='w-4 h-4 text-white' /> + <span className='text-xs font-semibold text-white'>{t('appDebug.codegen.generate')}</span> + </Button> + </div> + </div> + </div> + {isLoading && renderLoading} + {(!isLoading && res) && ( + <div className='w-0 grow p-6 pb-0 h-full'> + <div className='shrink-0 mb-3 leading-[160%] text-base font-semibold text-gray-800'>{t('appDebug.codegen.resTitle')}</div> + <div className={cn('max-h-[555px] overflow-y-auto', !isInLLMNode && 'pb-2')}> + <ConfigPrompt + mode={mode} + promptTemplate={res?.code || ''} + promptVariables={[]} + readonly + noTitle={isInLLMNode} + gradientBorder + editorHeight={isInLLMNode ? 524 : 0} + noResize={isInLLMNode} + /> + {!isInLLMNode && ( + <> + {res?.code && ( + <div className='mt-4'> + <h3 className='mb-2 text-sm font-medium text-gray-900'>{t('appDebug.codegen.generatedCode')}</h3> + <pre className='p-4 bg-gray-50 rounded-lg overflow-x-auto'> + <code className={`language-${res.language}`}> + {res.code} + </code> + </pre> + </div> + )} + {res?.error && ( + <div className='mt-4 p-4 bg-red-50 rounded-lg'> + <p className='text-sm text-red-600'>{res.error}</p> + </div> + )} + </> + )} + </div> + + <div className='flex justify-end py-4 bg-white'> + <Button onClick={onClose}>{t('common.operation.cancel')}</Button> + <Button variant='primary' className='ml-2' onClick={() => { + setShowConfirmOverwrite(true) + }}>{t('appDebug.codegen.apply')}</Button> + </div> + </div> + )} + </div> + {showConfirmOverwrite && ( + <Confirm + title={t('appDebug.codegen.overwriteConfirmTitle')} + content={t('appDebug.codegen.overwriteConfirmMessage')} + isShow={showConfirmOverwrite} + onConfirm={() => { + setShowConfirmOverwrite(false) + onFinished(res!) + }} + onCancel={() => setShowConfirmOverwrite(false)} + /> + )} + </Modal> + ) +} + +export default React.memo(GetCodeGeneratorResModal) diff --git a/web/app/components/workflow/nodes/_base/components/code-generator-button.tsx b/web/app/components/workflow/nodes/_base/components/code-generator-button.tsx new file mode 100644 index 0000000000..7f3a71dc09 --- /dev/null +++ b/web/app/components/workflow/nodes/_base/components/code-generator-button.tsx @@ -0,0 +1,48 @@ +'use client' +import type { FC } from 'react' +import React, { useCallback } from 'react' +import { useBoolean } from 'ahooks' +import cn from 'classnames' +import type { CodeLanguage } from '../../code/types' +import { Generator } from '@/app/components/base/icons/src/vender/other' +import { ActionButton } from '@/app/components/base/action-button' +import { AppType } from '@/types/app' +import type { CodeGenRes } from '@/service/debug' +import { GetCodeGeneratorResModal } from '@/app/components/app/configuration/config/code-generator/get-code-generator-res' + +type Props = { + className?: string + onGenerated?: (prompt: string) => void + codeLanguages: CodeLanguage +} + +const CodeGenerateBtn: FC<Props> = ({ + className, + codeLanguages, + onGenerated, +}) => { + const [showAutomatic, { setTrue: showAutomaticTrue, setFalse: showAutomaticFalse }] = useBoolean(false) + const handleAutomaticRes = useCallback((res: CodeGenRes) => { + onGenerated?.(res.code) + showAutomaticFalse() + }, [onGenerated, showAutomaticFalse]) + return ( + <div className={cn(className)}> + <ActionButton + className='hover:bg-[#155EFF]/8' + onClick={showAutomaticTrue}> + <Generator className='w-4 h-4 text-primary-600' /> + </ActionButton> + {showAutomatic && ( + <GetCodeGeneratorResModal + mode={AppType.chat} + isShow={showAutomatic} + codeLanguages={codeLanguages} + onClose={showAutomaticFalse} + onFinished={handleAutomaticRes} + /> + )} + </div> + ) +} +export default React.memo(CodeGenerateBtn) diff --git a/web/app/components/workflow/nodes/_base/components/editor/base.tsx b/web/app/components/workflow/nodes/_base/components/editor/base.tsx index e34c84fed8..8799cd0cc7 100644 --- a/web/app/components/workflow/nodes/_base/components/editor/base.tsx +++ b/web/app/components/workflow/nodes/_base/components/editor/base.tsx @@ -2,6 +2,9 @@ import type { FC } from 'react' import React, { useCallback, useRef, useState } from 'react' import copy from 'copy-to-clipboard' +import ToggleExpandBtn from '../toggle-expand-btn' +import CodeGeneratorButton from '../code-generator-button' +import type { CodeLanguage } from '../../../code/types' import Wrap from './wrap' import cn from '@/utils/classnames' import PromptEditorHeightResizeWrap from '@/app/components/app/configuration/config-prompt/prompt-editor-height-resize-wrap' @@ -9,7 +12,6 @@ import { Clipboard, ClipboardCheck, } from '@/app/components/base/icons/src/vender/line/files' -import ToggleExpandBtn from '@/app/components/workflow/nodes/_base/components/toggle-expand-btn' import useToggleExpend from '@/app/components/workflow/nodes/_base/hooks/use-toggle-expend' import type { FileEntity } from '@/app/components/base/file-uploader/types' import FileListInLog from '@/app/components/base/file-uploader/file-list-in-log' @@ -23,6 +25,8 @@ type Props = { value: string isFocus: boolean isInNode?: boolean + onGenerated?: (prompt: string) => void + codeLanguages: CodeLanguage fileList?: FileEntity[] showFileList?: boolean } @@ -36,6 +40,8 @@ const Base: FC<Props> = ({ value, isFocus, isInNode, + onGenerated, + codeLanguages, fileList = [], showFileList, }) => { @@ -70,6 +76,9 @@ const Base: FC<Props> = ({ e.stopPropagation() }}> {headerRight} + <div className='ml-1'> + <CodeGeneratorButton onGenerated={onGenerated} codeLanguages={codeLanguages}/> + </div> {!isCopied ? ( <Clipboard className='mx-1 w-3.5 h-3.5 text-gray-500 cursor-pointer' onClick={handleCopy} /> @@ -78,6 +87,7 @@ const Base: FC<Props> = ({ <ClipboardCheck className='mx-1 w-3.5 h-3.5 text-gray-500' /> ) } + <div className='ml-1'> <ToggleExpandBtn isExpand={isExpand} onExpandChange={setIsExpand} /> </div> diff --git a/web/app/components/workflow/nodes/_base/components/editor/code-editor/index.tsx b/web/app/components/workflow/nodes/_base/components/editor/code-editor/index.tsx index 21e0d142e5..f5be15a5d8 100644 --- a/web/app/components/workflow/nodes/_base/components/editor/code-editor/index.tsx +++ b/web/app/components/workflow/nodes/_base/components/editor/code-editor/index.tsx @@ -33,7 +33,7 @@ export type Props = { showFileList?: boolean } -const languageMap = { +export const languageMap = { [CodeLanguage.javascript]: 'javascript', [CodeLanguage.python3]: 'python', [CodeLanguage.json]: 'json', @@ -149,6 +149,9 @@ const CodeEditor: FC<Props> = ({ return isFocus ? 'focus-theme' : 'blur-theme' })() + const handleGenerated = (code: string) => { + handleEditorChange(code) + } const main = ( <> @@ -200,6 +203,8 @@ const CodeEditor: FC<Props> = ({ isFocus={isFocus && !readOnly} minHeight={minHeight} isInNode={isInNode} + onGenerated={handleGenerated} + codeLanguages={language} fileList={fileList} showFileList={showFileList} > diff --git a/web/i18n/en-US/app-debug.ts b/web/i18n/en-US/app-debug.ts index e9b777835f..c0d0193c7c 100644 --- a/web/i18n/en-US/app-debug.ts +++ b/web/i18n/en-US/app-debug.ts @@ -219,6 +219,20 @@ const translation = { manage: 'Manage', }, }, + codegen: { + title: 'Code Generator', + description: 'The Code Generator uses configured models to generate high-quality code based on your instructions. Please provide clear and detailed instructions.', + instruction: 'Instructions', + instructionPlaceholder: 'Enter detailed description of the code you want to generate.', + generate: 'Generate', + generatedCodeTitle: 'Generated Code', + loading: 'Generating code...', + apply: 'Apply', + applyChanges: 'Apply Changes', + resTitle: 'Generated Code', + overwriteConfirmTitle: 'Overwrite existing code?', + overwriteConfirmMessage: 'This action will overwrite the existing code. Do you want to continue?', + }, generate: { title: 'Prompt Generator', description: 'The Prompt Generator uses the configured model to optimize prompts for higher quality and better structure. Please write clear and detailed instructions.', diff --git a/web/i18n/ja-JP/app-debug.ts b/web/i18n/ja-JP/app-debug.ts index e9ee765435..0ba4c35b0d 100644 --- a/web/i18n/ja-JP/app-debug.ts +++ b/web/i18n/ja-JP/app-debug.ts @@ -199,6 +199,20 @@ const translation = { }, }, }, + codegen: { + title: 'コードジェネレーター', + description: 'コードジェネレーターは、設定されたモデルを使用して指示に基づいて高品質なコードを生成します。明確で詳細な指示を提供してください。', + instruction: '指示', + instructionPlaceholder: '生成したいコードの詳細な説明を入力してください。', + generate: '生成', + generatedCodeTitle: '生成されたコード', + loading: 'コードを生成中...', + apply: '適用', + applyChanges: '変更を適用', + resTitle: '生成されたコード', + overwriteConfirmTitle: '既存のコードを上書きしますか?', + overwriteConfirmMessage: 'この操作は既存のコードを上書きします。続行しますか?', + }, generate: { title: 'プロンプト生成器', description: 'プロンプト生成器は、設定済みのモデルを使って、高品質で構造的に優れたプロンプトを作成するための最適化を行います。具体的で詳細な指示をお書きください。', diff --git a/web/i18n/zh-Hans/app-debug.ts b/web/i18n/zh-Hans/app-debug.ts index b2789b9dcb..ee8ff7bb29 100644 --- a/web/i18n/zh-Hans/app-debug.ts +++ b/web/i18n/zh-Hans/app-debug.ts @@ -219,6 +219,20 @@ const translation = { manage: '管理', }, }, + codegen: { + title: '代码生成器', + description: '代码生成器使用配置的模型根据您的指令生成高质量的代码。请提供清晰详细的说明。', + instruction: '指令', + instructionPlaceholder: '请输入您想要生成的代码的详细描述。', + generate: '生成', + generatedCodeTitle: '生成的代码', + loading: '正在生成代码...', + apply: '应用', + applyChanges: '应用更改', + resTitle: '生成的代码', + overwriteConfirmTitle: '是否覆盖现有代码?', + overwriteConfirmMessage: '此操作将覆盖现有代码。您确定要继续吗?', + }, generate: { title: '提示词生成器', description: '提示词生成器使用配置的模型来优化提示词,以获得更高的质量和更好的结构。请写出清晰详细的说明。', diff --git a/web/service/debug.ts b/web/service/debug.ts index 38068cad6e..3770c4d398 100644 --- a/web/service/debug.ts +++ b/web/service/debug.ts @@ -9,6 +9,11 @@ export type AutomaticRes = { opening_statement: string error?: string } +export type CodeGenRes = { + code: string + language: string[] + error?: string +} export const sendChatMessage = async (appId: string, body: Record<string, any>, { onData, onCompleted, onThought, onFile, onError, getAbortController, onMessageEnd, onMessageReplace }: { onData: IOnData @@ -71,6 +76,11 @@ export const generateRule = (body: Record<string, any>) => { body, }) } +export const generateRuleCode = (body: Record<string, any>) => { + return post<CodeGenRes>('/rule-code-generate', { + body, + }) +} export const fetchModelParams = (providerName: string, modelId: string) => { return get(`workspaces/current/model-providers/${providerName}/models/parameter-rules`, { From 999d3f1539f49ebb9a7e9b7353acfd5988db6be3 Mon Sep 17 00:00:00 2001 From: feiyang_deepnova <736320652@qq.com> Date: Wed, 23 Oct 2024 01:20:02 +0800 Subject: [PATCH 145/346] fix: add downstream nodes of this branch (#9640) --- api/core/workflow/nodes/answer/base_stream_processor.py | 1 + 1 file changed, 1 insertion(+) diff --git a/api/core/workflow/nodes/answer/base_stream_processor.py b/api/core/workflow/nodes/answer/base_stream_processor.py index 36c3fe180a..52d0358c76 100644 --- a/api/core/workflow/nodes/answer/base_stream_processor.py +++ b/api/core/workflow/nodes/answer/base_stream_processor.py @@ -41,6 +41,7 @@ class StreamProcessor(ABC): continue else: unreachable_first_node_ids.append(edge.target_node_id) + unreachable_first_node_ids.extend(self._fetch_node_ids_in_reachable_branch(edge.target_node_id)) for node_id in unreachable_first_node_ids: self._remove_node_ids_in_unreachable_branch(node_id, reachable_node_ids) From 8e7a752b2a38e4c676d0c53d9addf9121e468ee1 Mon Sep 17 00:00:00 2001 From: Zven <userzhangqg@163.com> Date: Wed, 23 Oct 2024 09:16:35 +0800 Subject: [PATCH 146/346] feat: add upstash as a new vector database provider (#9644) --- api/.env.example | 6 +- api/commands.py | 1 + api/configs/middleware/__init__.py | 2 + api/configs/middleware/vdb/upstash_config.py | 20 +++ api/controllers/console/datasets/datasets.py | 2 + .../rag/datasource/vdb/upstash/__init__.py | 0 .../datasource/vdb/upstash/upstash_vector.py | 129 ++++++++++++++++++ api/core/rag/datasource/vdb/vector_factory.py | 4 + api/core/rag/datasource/vdb/vector_type.py | 1 + api/poetry.lock | 60 +++++++- api/pyproject.toml | 1 + .../vdb/__mock/upstashvectordb.py | 75 ++++++++++ .../integration_tests/vdb/upstash/__init__.py | 0 .../vdb/upstash/test_upstash_vector.py | 63 +++++++++ dev/pytest/pytest_vdb.sh | 3 +- docker/docker-compose.yaml | 2 + 16 files changed, 365 insertions(+), 4 deletions(-) create mode 100644 api/configs/middleware/vdb/upstash_config.py create mode 100644 api/core/rag/datasource/vdb/upstash/__init__.py create mode 100644 api/core/rag/datasource/vdb/upstash/upstash_vector.py create mode 100644 api/tests/integration_tests/vdb/__mock/upstashvectordb.py create mode 100644 api/tests/integration_tests/vdb/upstash/__init__.py create mode 100644 api/tests/integration_tests/vdb/upstash/test_upstash_vector.py diff --git a/api/.env.example b/api/.env.example index 5a9d21c980..32cf4293f7 100644 --- a/api/.env.example +++ b/api/.env.example @@ -111,7 +111,7 @@ SUPABASE_URL=your-server-url WEB_API_CORS_ALLOW_ORIGINS=http://127.0.0.1:3000,* CONSOLE_CORS_ALLOW_ORIGINS=http://127.0.0.1:3000,* -# Vector database configuration, support: weaviate, qdrant, milvus, myscale, relyt, pgvecto_rs, pgvector, pgvector, chroma, opensearch, tidb_vector, vikingdb +# Vector database configuration, support: weaviate, qdrant, milvus, myscale, relyt, pgvecto_rs, pgvector, pgvector, chroma, opensearch, tidb_vector, vikingdb, upstash VECTOR_STORE=weaviate # Weaviate configuration @@ -220,6 +220,10 @@ BAIDU_VECTOR_DB_DATABASE=dify BAIDU_VECTOR_DB_SHARD=1 BAIDU_VECTOR_DB_REPLICAS=3 +# Upstash configuration +UPSTASH_VECTOR_URL=your-server-url +UPSTASH_VECTOR_TOKEN=your-access-token + # ViKingDB configuration VIKINGDB_ACCESS_KEY=your-ak VIKINGDB_SECRET_KEY=your-sk diff --git a/api/commands.py b/api/commands.py index f2809be8e7..720a4447da 100644 --- a/api/commands.py +++ b/api/commands.py @@ -277,6 +277,7 @@ def migrate_knowledge_vector_database(): VectorType.TENCENT, VectorType.BAIDU, VectorType.VIKINGDB, + VectorType.UPSTASH, } page = 1 while True: diff --git a/api/configs/middleware/__init__.py b/api/configs/middleware/__init__.py index 84d03e2f45..705e30b7ff 100644 --- a/api/configs/middleware/__init__.py +++ b/api/configs/middleware/__init__.py @@ -28,6 +28,7 @@ from configs.middleware.vdb.qdrant_config import QdrantConfig from configs.middleware.vdb.relyt_config import RelytConfig from configs.middleware.vdb.tencent_vector_config import TencentVectorDBConfig from configs.middleware.vdb.tidb_vector_config import TiDBVectorConfig +from configs.middleware.vdb.upstash_config import UpstashConfig from configs.middleware.vdb.vikingdb_config import VikingDBConfig from configs.middleware.vdb.weaviate_config import WeaviateConfig @@ -246,5 +247,6 @@ class MiddlewareConfig( ElasticsearchConfig, InternalTestConfig, VikingDBConfig, + UpstashConfig, ): pass diff --git a/api/configs/middleware/vdb/upstash_config.py b/api/configs/middleware/vdb/upstash_config.py new file mode 100644 index 0000000000..412c56374a --- /dev/null +++ b/api/configs/middleware/vdb/upstash_config.py @@ -0,0 +1,20 @@ +from typing import Optional + +from pydantic import Field +from pydantic_settings import BaseSettings + + +class UpstashConfig(BaseSettings): + """ + Configuration settings for Upstash vector database + """ + + UPSTASH_VECTOR_URL: Optional[str] = Field( + description="URL of the upstash server (e.g., 'https://vector.upstash.io')", + default=None, + ) + + UPSTASH_VECTOR_TOKEN: Optional[str] = Field( + description="Token for authenticating with the upstash server", + default=None, + ) diff --git a/api/controllers/console/datasets/datasets.py b/api/controllers/console/datasets/datasets.py index 16a77ed880..d735527258 100644 --- a/api/controllers/console/datasets/datasets.py +++ b/api/controllers/console/datasets/datasets.py @@ -630,6 +630,7 @@ class DatasetRetrievalSettingApi(Resource): | VectorType.ORACLE | VectorType.ELASTICSEARCH | VectorType.PGVECTOR + | VectorType.UPSTASH ): return { "retrieval_method": [ @@ -668,6 +669,7 @@ class DatasetRetrievalSettingMockApi(Resource): | VectorType.ORACLE | VectorType.ELASTICSEARCH | VectorType.PGVECTOR + | VectorType.UPSTASH ): return { "retrieval_method": [ diff --git a/api/core/rag/datasource/vdb/upstash/__init__.py b/api/core/rag/datasource/vdb/upstash/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/api/core/rag/datasource/vdb/upstash/upstash_vector.py b/api/core/rag/datasource/vdb/upstash/upstash_vector.py new file mode 100644 index 0000000000..ead7958dc6 --- /dev/null +++ b/api/core/rag/datasource/vdb/upstash/upstash_vector.py @@ -0,0 +1,129 @@ +import json +from typing import Any +from uuid import uuid4 + +from pydantic import BaseModel, model_validator +from upstash_vector import Index, Vector + +from configs import dify_config +from core.rag.datasource.vdb.vector_base import BaseVector +from core.rag.datasource.vdb.vector_factory import AbstractVectorFactory +from core.rag.datasource.vdb.vector_type import VectorType +from core.rag.embedding.embedding_base import Embeddings +from core.rag.models.document import Document +from models.dataset import Dataset + + +class UpstashVectorConfig(BaseModel): + url: str + token: str + + @model_validator(mode="before") + @classmethod + def validate_config(cls, values: dict) -> dict: + if not values["url"]: + raise ValueError("Upstash URL is required") + if not values["token"]: + raise ValueError("Upstash Token is required") + return values + + +class UpstashVector(BaseVector): + def __init__(self, collection_name: str, config: UpstashVectorConfig): + super().__init__(collection_name) + self._table_name = collection_name + self.index = Index(url=config.url, token=config.token) + + def _get_index_dimension(self) -> int: + index_info = self.index.info() + if index_info and index_info.dimension: + return index_info.dimension + else: + return 1536 + + def create(self, texts: list[Document], embeddings: list[list[float]], **kwargs): + self.add_texts(texts, embeddings) + + def add_texts(self, documents: list[Document], embeddings: list[list[float]], **kwargs): + vectors = [ + Vector( + id=str(uuid4()), + vector=embedding, + metadata=doc.metadata, + data=doc.page_content, + ) + for doc, embedding in zip(documents, embeddings) + ] + self.index.upsert(vectors=vectors) + + def text_exists(self, id: str) -> bool: + response = self.get_ids_by_metadata_field("doc_id", id) + return len(response) > 0 + + def delete_by_ids(self, ids: list[str]) -> None: + item_ids = [] + for doc_id in ids: + ids = self.get_ids_by_metadata_field("doc_id", doc_id) + if id: + item_ids += ids + self._delete_by_ids(ids=item_ids) + + def _delete_by_ids(self, ids: list[str]) -> None: + if ids: + self.index.delete(ids=ids) + + def get_ids_by_metadata_field(self, key: str, value: str) -> list[str]: + query_result = self.index.query( + vector=[1.001 * i for i in range(self._get_index_dimension())], + include_metadata=True, + top_k=1000, + filter=f"{key} = '{value}'", + ) + return [result.id for result in query_result] + + def delete_by_metadata_field(self, key: str, value: str) -> None: + ids = self.get_ids_by_metadata_field(key, value) + if ids: + self._delete_by_ids(ids) + + def search_by_vector(self, query_vector: list[float], **kwargs: Any) -> list[Document]: + top_k = kwargs.get("top_k", 4) + result = self.index.query(vector=query_vector, top_k=top_k, include_metadata=True, include_data=True) + docs = [] + score_threshold = float(kwargs.get("score_threshold") or 0.0) + for record in result: + metadata = record.metadata + text = record.data + score = record.score + metadata["score"] = score + if score > score_threshold: + docs.append(Document(page_content=text, metadata=metadata)) + return docs + + def search_by_full_text(self, query: str, **kwargs: Any) -> list[Document]: + return [] + + def delete(self) -> None: + self.index.reset() + + def get_type(self) -> str: + return VectorType.UPSTASH + + +class UpstashVectorFactory(AbstractVectorFactory): + def init_vector(self, dataset: Dataset, attributes: list, embeddings: Embeddings) -> UpstashVector: + if dataset.index_struct_dict: + class_prefix: str = dataset.index_struct_dict["vector_store"]["class_prefix"] + collection_name = class_prefix.lower() + else: + dataset_id = dataset.id + collection_name = Dataset.gen_collection_name_by_id(dataset_id) + dataset.index_struct = json.dumps(self.gen_index_struct_dict(VectorType.UPSTASH, collection_name)) + + return UpstashVector( + collection_name=collection_name, + config=UpstashVectorConfig( + url=dify_config.UPSTASH_VECTOR_URL, + token=dify_config.UPSTASH_VECTOR_TOKEN, + ), + ) diff --git a/api/core/rag/datasource/vdb/vector_factory.py b/api/core/rag/datasource/vdb/vector_factory.py index fb956a16ed..9ea3cf4b6b 100644 --- a/api/core/rag/datasource/vdb/vector_factory.py +++ b/api/core/rag/datasource/vdb/vector_factory.py @@ -111,6 +111,10 @@ class Vector: from core.rag.datasource.vdb.vikingdb.vikingdb_vector import VikingDBVectorFactory return VikingDBVectorFactory + case VectorType.UPSTASH: + from core.rag.datasource.vdb.upstash.upstash_vector import UpstashVectorFactory + + return UpstashVectorFactory case _: raise ValueError(f"Vector store {vector_type} is not supported.") diff --git a/api/core/rag/datasource/vdb/vector_type.py b/api/core/rag/datasource/vdb/vector_type.py index b4d604a080..30aa814553 100644 --- a/api/core/rag/datasource/vdb/vector_type.py +++ b/api/core/rag/datasource/vdb/vector_type.py @@ -18,3 +18,4 @@ class VectorType(str, Enum): ELASTICSEARCH = "elasticsearch" BAIDU = "baidu" VIKINGDB = "vikingdb" + UPSTASH = "upstash" diff --git a/api/poetry.lock b/api/poetry.lock index 384222f2f0..7053afda51 100644 --- a/api/poetry.lock +++ b/api/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand. [[package]] name = "aiohappyeyeballs" @@ -929,6 +929,10 @@ files = [ {file = "Brotli-1.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a37b8f0391212d29b3a91a799c8e4a2855e0576911cdfb2515487e30e322253d"}, {file = "Brotli-1.1.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e84799f09591700a4154154cab9787452925578841a94321d5ee8fb9a9a328f0"}, {file = "Brotli-1.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f66b5337fa213f1da0d9000bc8dc0cb5b896b726eefd9c6046f699b169c41b9e"}, + {file = "Brotli-1.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5dab0844f2cf82be357a0eb11a9087f70c5430b2c241493fc122bb6f2bb0917c"}, + {file = "Brotli-1.1.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e4fe605b917c70283db7dfe5ada75e04561479075761a0b3866c081d035b01c1"}, + {file = "Brotli-1.1.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:1e9a65b5736232e7a7f91ff3d02277f11d339bf34099a56cdab6a8b3410a02b2"}, + {file = "Brotli-1.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:58d4b711689366d4a03ac7957ab8c28890415e267f9b6589969e74b6e42225ec"}, {file = "Brotli-1.1.0-cp310-cp310-win32.whl", hash = "sha256:be36e3d172dc816333f33520154d708a2657ea63762ec16b62ece02ab5e4daf2"}, {file = "Brotli-1.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:0c6244521dda65ea562d5a69b9a26120769b7a9fb3db2fe9545935ed6735b128"}, {file = "Brotli-1.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a3daabb76a78f829cafc365531c972016e4aa8d5b4bf60660ad8ecee19df7ccc"}, @@ -941,8 +945,14 @@ files = [ {file = "Brotli-1.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:19c116e796420b0cee3da1ccec3b764ed2952ccfcc298b55a10e5610ad7885f9"}, {file = "Brotli-1.1.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:510b5b1bfbe20e1a7b3baf5fed9e9451873559a976c1a78eebaa3b86c57b4265"}, {file = "Brotli-1.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a1fd8a29719ccce974d523580987b7f8229aeace506952fa9ce1d53a033873c8"}, + {file = "Brotli-1.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c247dd99d39e0338a604f8c2b3bc7061d5c2e9e2ac7ba9cc1be5a69cb6cd832f"}, + {file = "Brotli-1.1.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1b2c248cd517c222d89e74669a4adfa5577e06ab68771a529060cf5a156e9757"}, + {file = "Brotli-1.1.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:2a24c50840d89ded6c9a8fdc7b6ed3692ed4e86f1c4a4a938e1e92def92933e0"}, + {file = "Brotli-1.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f31859074d57b4639318523d6ffdca586ace54271a73ad23ad021acd807eb14b"}, {file = "Brotli-1.1.0-cp311-cp311-win32.whl", hash = "sha256:39da8adedf6942d76dc3e46653e52df937a3c4d6d18fdc94a7c29d263b1f5b50"}, {file = "Brotli-1.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:aac0411d20e345dc0920bdec5548e438e999ff68d77564d5e9463a7ca9d3e7b1"}, + {file = "Brotli-1.1.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:32d95b80260d79926f5fab3c41701dbb818fde1c9da590e77e571eefd14abe28"}, + {file = "Brotli-1.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b760c65308ff1e462f65d69c12e4ae085cff3b332d894637f6273a12a482d09f"}, {file = "Brotli-1.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:316cc9b17edf613ac76b1f1f305d2a748f1b976b033b049a6ecdfd5612c70409"}, {file = "Brotli-1.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:caf9ee9a5775f3111642d33b86237b05808dafcd6268faa492250e9b78046eb2"}, {file = "Brotli-1.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70051525001750221daa10907c77830bc889cb6d865cc0b813d9db7fefc21451"}, @@ -953,8 +963,24 @@ files = [ {file = "Brotli-1.1.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:4093c631e96fdd49e0377a9c167bfd75b6d0bad2ace734c6eb20b348bc3ea180"}, {file = "Brotli-1.1.0-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:7e4c4629ddad63006efa0ef968c8e4751c5868ff0b1c5c40f76524e894c50248"}, {file = "Brotli-1.1.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:861bf317735688269936f755fa136a99d1ed526883859f86e41a5d43c61d8966"}, + {file = "Brotli-1.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:87a3044c3a35055527ac75e419dfa9f4f3667a1e887ee80360589eb8c90aabb9"}, + {file = "Brotli-1.1.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:c5529b34c1c9d937168297f2c1fde7ebe9ebdd5e121297ff9c043bdb2ae3d6fb"}, + {file = "Brotli-1.1.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:ca63e1890ede90b2e4454f9a65135a4d387a4585ff8282bb72964fab893f2111"}, + {file = "Brotli-1.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e79e6520141d792237c70bcd7a3b122d00f2613769ae0cb61c52e89fd3443839"}, {file = "Brotli-1.1.0-cp312-cp312-win32.whl", hash = "sha256:5f4d5ea15c9382135076d2fb28dde923352fe02951e66935a9efaac8f10e81b0"}, {file = "Brotli-1.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:906bc3a79de8c4ae5b86d3d75a8b77e44404b0f4261714306e3ad248d8ab0951"}, + {file = "Brotli-1.1.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8bf32b98b75c13ec7cf774164172683d6e7891088f6316e54425fde1efc276d5"}, + {file = "Brotli-1.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7bc37c4d6b87fb1017ea28c9508b36bbcb0c3d18b4260fcdf08b200c74a6aee8"}, + {file = "Brotli-1.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c0ef38c7a7014ffac184db9e04debe495d317cc9c6fb10071f7fefd93100a4f"}, + {file = "Brotli-1.1.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91d7cc2a76b5567591d12c01f019dd7afce6ba8cba6571187e21e2fc418ae648"}, + {file = "Brotli-1.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a93dde851926f4f2678e704fadeb39e16c35d8baebd5252c9fd94ce8ce68c4a0"}, + {file = "Brotli-1.1.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f0db75f47be8b8abc8d9e31bc7aad0547ca26f24a54e6fd10231d623f183d089"}, + {file = "Brotli-1.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6967ced6730aed543b8673008b5a391c3b1076d834ca438bbd70635c73775368"}, + {file = "Brotli-1.1.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:7eedaa5d036d9336c95915035fb57422054014ebdeb6f3b42eac809928e40d0c"}, + {file = "Brotli-1.1.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:d487f5432bf35b60ed625d7e1b448e2dc855422e87469e3f450aa5552b0eb284"}, + {file = "Brotli-1.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:832436e59afb93e1836081a20f324cb185836c617659b07b129141a8426973c7"}, + {file = "Brotli-1.1.0-cp313-cp313-win32.whl", hash = "sha256:43395e90523f9c23a3d5bdf004733246fba087f2948f87ab28015f12359ca6a0"}, + {file = "Brotli-1.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:9011560a466d2eb3f5a6e4929cf4a09be405c64154e12df0dd72713f6500e32b"}, {file = "Brotli-1.1.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:a090ca607cbb6a34b0391776f0cb48062081f5f60ddcce5d11838e67a01928d1"}, {file = "Brotli-1.1.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2de9d02f5bda03d27ede52e8cfe7b865b066fa49258cbab568720aa5be80a47d"}, {file = "Brotli-1.1.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2333e30a5e00fe0fe55903c8832e08ee9c3b1382aacf4db26664a16528d51b4b"}, @@ -964,6 +990,10 @@ files = [ {file = "Brotli-1.1.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:fd5f17ff8f14003595ab414e45fce13d073e0762394f957182e69035c9f3d7c2"}, {file = "Brotli-1.1.0-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:069a121ac97412d1fe506da790b3e69f52254b9df4eb665cd42460c837193354"}, {file = "Brotli-1.1.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:e93dfc1a1165e385cc8239fab7c036fb2cd8093728cbd85097b284d7b99249a2"}, + {file = "Brotli-1.1.0-cp36-cp36m-musllinux_1_2_aarch64.whl", hash = "sha256:aea440a510e14e818e67bfc4027880e2fb500c2ccb20ab21c7a7c8b5b4703d75"}, + {file = "Brotli-1.1.0-cp36-cp36m-musllinux_1_2_i686.whl", hash = "sha256:6974f52a02321b36847cd19d1b8e381bf39939c21efd6ee2fc13a28b0d99348c"}, + {file = "Brotli-1.1.0-cp36-cp36m-musllinux_1_2_ppc64le.whl", hash = "sha256:a7e53012d2853a07a4a79c00643832161a910674a893d296c9f1259859a289d2"}, + {file = "Brotli-1.1.0-cp36-cp36m-musllinux_1_2_x86_64.whl", hash = "sha256:d7702622a8b40c49bffb46e1e3ba2e81268d5c04a34f460978c6b5517a34dd52"}, {file = "Brotli-1.1.0-cp36-cp36m-win32.whl", hash = "sha256:a599669fd7c47233438a56936988a2478685e74854088ef5293802123b5b2460"}, {file = "Brotli-1.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:d143fd47fad1db3d7c27a1b1d66162e855b5d50a89666af46e1679c496e8e579"}, {file = "Brotli-1.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:11d00ed0a83fa22d29bc6b64ef636c4552ebafcef57154b4ddd132f5638fbd1c"}, @@ -975,6 +1005,10 @@ files = [ {file = "Brotli-1.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:919e32f147ae93a09fe064d77d5ebf4e35502a8df75c29fb05788528e330fe74"}, {file = "Brotli-1.1.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:23032ae55523cc7bccb4f6a0bf368cd25ad9bcdcc1990b64a647e7bbcce9cb5b"}, {file = "Brotli-1.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:224e57f6eac61cc449f498cc5f0e1725ba2071a3d4f48d5d9dffba42db196438"}, + {file = "Brotli-1.1.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:cb1dac1770878ade83f2ccdf7d25e494f05c9165f5246b46a621cc849341dc01"}, + {file = "Brotli-1.1.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:3ee8a80d67a4334482d9712b8e83ca6b1d9bc7e351931252ebef5d8f7335a547"}, + {file = "Brotli-1.1.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:5e55da2c8724191e5b557f8e18943b1b4839b8efc3ef60d65985bcf6f587dd38"}, + {file = "Brotli-1.1.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:d342778ef319e1026af243ed0a07c97acf3bad33b9f29e7ae6a1f68fd083e90c"}, {file = "Brotli-1.1.0-cp37-cp37m-win32.whl", hash = "sha256:587ca6d3cef6e4e868102672d3bd9dc9698c309ba56d41c2b9c85bbb903cdb95"}, {file = "Brotli-1.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:2954c1c23f81c2eaf0b0717d9380bd348578a94161a65b3a2afc62c86467dd68"}, {file = "Brotli-1.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:efa8b278894b14d6da122a72fefcebc28445f2d3f880ac59d46c90f4c13be9a3"}, @@ -987,6 +1021,10 @@ files = [ {file = "Brotli-1.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ab4fbee0b2d9098c74f3057b2bc055a8bd92ccf02f65944a241b4349229185a"}, {file = "Brotli-1.1.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:141bd4d93984070e097521ed07e2575b46f817d08f9fa42b16b9b5f27b5ac088"}, {file = "Brotli-1.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fce1473f3ccc4187f75b4690cfc922628aed4d3dd013d047f95a9b3919a86596"}, + {file = "Brotli-1.1.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d2b35ca2c7f81d173d2fadc2f4f31e88cc5f7a39ae5b6db5513cf3383b0e0ec7"}, + {file = "Brotli-1.1.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:af6fa6817889314555aede9a919612b23739395ce767fe7fcbea9a80bf140fe5"}, + {file = "Brotli-1.1.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:2feb1d960f760a575dbc5ab3b1c00504b24caaf6986e2dc2b01c09c87866a943"}, + {file = "Brotli-1.1.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:4410f84b33374409552ac9b6903507cdb31cd30d2501fc5ca13d18f73548444a"}, {file = "Brotli-1.1.0-cp38-cp38-win32.whl", hash = "sha256:db85ecf4e609a48f4b29055f1e144231b90edc90af7481aa731ba2d059226b1b"}, {file = "Brotli-1.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:3d7954194c36e304e1523f55d7042c59dc53ec20dd4e9ea9d151f1b62b4415c0"}, {file = "Brotli-1.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5fb2ce4b8045c78ebbc7b8f3c15062e435d47e7393cc57c25115cfd49883747a"}, @@ -999,6 +1037,10 @@ files = [ {file = "Brotli-1.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:949f3b7c29912693cee0afcf09acd6ebc04c57af949d9bf77d6101ebb61e388c"}, {file = "Brotli-1.1.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:89f4988c7203739d48c6f806f1e87a1d96e0806d44f0fba61dba81392c9e474d"}, {file = "Brotli-1.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:de6551e370ef19f8de1807d0a9aa2cdfdce2e85ce88b122fe9f6b2b076837e59"}, + {file = "Brotli-1.1.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0737ddb3068957cf1b054899b0883830bb1fec522ec76b1098f9b6e0f02d9419"}, + {file = "Brotli-1.1.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:4f3607b129417e111e30637af1b56f24f7a49e64763253bbc275c75fa887d4b2"}, + {file = "Brotli-1.1.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:6c6e0c425f22c1c719c42670d561ad682f7bfeeef918edea971a79ac5252437f"}, + {file = "Brotli-1.1.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:494994f807ba0b92092a163a0a283961369a65f6cbe01e8891132b7a320e61eb"}, {file = "Brotli-1.1.0-cp39-cp39-win32.whl", hash = "sha256:f0d8a7a6b5983c2496e364b969f0e526647a06b075d034f3297dc66f3b360c64"}, {file = "Brotli-1.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:cdad5b9014d83ca68c25d2e9444e28e967ef16e80f6b436918c700c117a85467"}, {file = "Brotli-1.1.0.tar.gz", hash = "sha256:81de08ac11bcb85841e440c13611c00b67d3bf82698314928d0b676362546724"}, @@ -9784,6 +9826,20 @@ tsv = ["pandas"] wikipedia = ["wikipedia"] xlsx = ["networkx", "openpyxl", "pandas", "xlrd"] +[[package]] +name = "upstash-vector" +version = "0.6.0" +description = "Serverless Vector SDK from Upstash" +optional = false +python-versions = "<4.0,>=3.8" +files = [ + {file = "upstash_vector-0.6.0-py3-none-any.whl", hash = "sha256:d0bdad7765b8a7f5c205b7a9c81ca4b9a4cee3ee4952afc7d5ea5fb76c3f3c3c"}, + {file = "upstash_vector-0.6.0.tar.gz", hash = "sha256:a716ed4d0251362208518db8b194158a616d37d1ccbb1155f619df690599e39b"}, +] + +[package.dependencies] +httpx = ">=0.23.0,<1" + [[package]] name = "uritemplate" version = "4.1.1" @@ -10796,4 +10852,4 @@ cffi = ["cffi (>=1.11)"] [metadata] lock-version = "2.0" python-versions = ">=3.10,<3.13" -content-hash = "5b102e3bc077ed730e9fb7be9015541111ffe7787888372d50a757aecb1d9eff" +content-hash = "32fd52006f75e42fbc8f787e559a72f4e033383c73225231e4ecadabfec926f7" diff --git a/api/pyproject.toml b/api/pyproject.toml index 1334b37866..e9529a192e 100644 --- a/api/pyproject.toml +++ b/api/pyproject.toml @@ -248,6 +248,7 @@ pymochow = "1.3.1" qdrant-client = "1.7.3" tcvectordb = "1.3.2" tidb-vector = "0.0.9" +upstash-vector = "0.6.0" volcengine-compat = "~1.0.156" weaviate-client = "~3.21.0" diff --git a/api/tests/integration_tests/vdb/__mock/upstashvectordb.py b/api/tests/integration_tests/vdb/__mock/upstashvectordb.py new file mode 100644 index 0000000000..c93292bd8a --- /dev/null +++ b/api/tests/integration_tests/vdb/__mock/upstashvectordb.py @@ -0,0 +1,75 @@ +import os +from typing import Optional + +import pytest +from _pytest.monkeypatch import MonkeyPatch +from upstash_vector import Index + + +# Mocking the Index class from upstash_vector +class MockIndex: + def __init__(self, url="", token=""): + self.url = url + self.token = token + self.vectors = [] + + def upsert(self, vectors): + for vector in vectors: + vector.score = 0.5 + self.vectors.append(vector) + return {"code": 0, "msg": "operation success", "affectedCount": len(vectors)} + + def fetch(self, ids): + return [vector for vector in self.vectors if vector.id in ids] + + def delete(self, ids): + self.vectors = [vector for vector in self.vectors if vector.id not in ids] + return {"code": 0, "msg": "Success"} + + def query( + self, + vector: None, + top_k: int = 10, + include_vectors: bool = False, + include_metadata: bool = False, + filter: str = "", + data: Optional[str] = None, + namespace: str = "", + include_data: bool = False, + ): + # Simple mock query, in real scenario you would calculate similarity + mock_result = [] + for vector_data in self.vectors: + mock_result.append(vector_data) + return mock_result[:top_k] + + def reset(self): + self.vectors = [] + + def info(self): + return AttrDict({"dimension": 1024}) + + +class AttrDict(dict): + def __getattr__(self, item): + return self.get(item) + + +MOCK = os.getenv("MOCK_SWITCH", "false").lower() == "true" + + +@pytest.fixture +def setup_upstashvector_mock(request, monkeypatch: MonkeyPatch): + if MOCK: + monkeypatch.setattr(Index, "__init__", MockIndex.__init__) + monkeypatch.setattr(Index, "upsert", MockIndex.upsert) + monkeypatch.setattr(Index, "fetch", MockIndex.fetch) + monkeypatch.setattr(Index, "delete", MockIndex.delete) + monkeypatch.setattr(Index, "query", MockIndex.query) + monkeypatch.setattr(Index, "reset", MockIndex.reset) + monkeypatch.setattr(Index, "info", MockIndex.info) + + yield + + if MOCK: + monkeypatch.undo() diff --git a/api/tests/integration_tests/vdb/upstash/__init__.py b/api/tests/integration_tests/vdb/upstash/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/api/tests/integration_tests/vdb/upstash/test_upstash_vector.py b/api/tests/integration_tests/vdb/upstash/test_upstash_vector.py new file mode 100644 index 0000000000..c4461e6512 --- /dev/null +++ b/api/tests/integration_tests/vdb/upstash/test_upstash_vector.py @@ -0,0 +1,63 @@ +import time +import uuid + +from core.rag.datasource.vdb.upstash.upstash_vector import UpstashVector, UpstashVectorConfig +from core.rag.models.document import Document +from tests.integration_tests.vdb.__mock.upstashvectordb import setup_upstashvector_mock +from tests.integration_tests.vdb.test_vector_store import AbstractVectorTest + + +def get_example_text() -> str: + return "test_text" + + +def get_example_document(doc_id: str) -> Document: + doc = Document( + page_content=get_example_text(), + metadata={ + "doc_id": doc_id, + "doc_hash": doc_id, + "document_id": doc_id, + "dataset_id": doc_id, + }, + ) + return doc + + +class UpstashVectorTest(AbstractVectorTest): + def __init__(self): + super().__init__() + self.vector = UpstashVector( + collection_name="test_collection", + config=UpstashVectorConfig( + url="your-server-url", + token="your-access-token", + ), + ) + self.example_embedding = [1.001 * i for i in range(self.vector._get_index_dimension())] + + def add_texts(self) -> list[str]: + batch_size = 1 + documents = [get_example_document(doc_id=str(uuid.uuid4())) for _ in range(batch_size)] + embeddings = [self.example_embedding] * batch_size + self.vector.add_texts(documents=documents, embeddings=embeddings) + return [doc.metadata["doc_id"] for doc in documents] + + def get_ids_by_metadata_field(self): + print("doc_id", self.example_doc_id) + ids = self.vector.get_ids_by_metadata_field(key="document_id", value=self.example_doc_id) + assert len(ids) != 0 + + def run_all_tests(self): + self.create_vector() + time.sleep(1) + self.search_by_vector() + self.text_exists() + self.get_ids_by_metadata_field() + added_doc_ids = self.add_texts() + self.delete_by_ids(added_doc_ids + [self.example_doc_id]) + self.delete_vector() + + +def test_upstash_vector(setup_upstashvector_mock): + UpstashVectorTest().run_all_tests() diff --git a/dev/pytest/pytest_vdb.sh b/dev/pytest/pytest_vdb.sh index d6797ed28e..b64435e9a1 100755 --- a/dev/pytest/pytest_vdb.sh +++ b/dev/pytest/pytest_vdb.sh @@ -10,4 +10,5 @@ pytest api/tests/integration_tests/vdb/chroma \ api/tests/integration_tests/vdb/elasticsearch \ api/tests/integration_tests/vdb/vikingdb \ api/tests/integration_tests/vdb/baidu \ - api/tests/integration_tests/vdb/tcvectordb + api/tests/integration_tests/vdb/tcvectordb \ + api/tests/integration_tests/vdb/upstash diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml index 5edcfda5f4..75817949ab 100644 --- a/docker/docker-compose.yaml +++ b/docker/docker-compose.yaml @@ -182,6 +182,8 @@ x-shared-env: &shared-api-worker-env VIKINGDB_REGION: ${VIKINGDB_REGION:-cn-shanghai} VIKINGDB_HOST: ${VIKINGDB_HOST:-api-vikingdb.xxx.volces.com} VIKINGDB_SCHEMA: ${VIKINGDB_SCHEMA:-http} + UPSTASH_VECTOR_URL: ${UPSTASH_VECTOR_URL:-https://xxx-vector.upstash.io} + UPSTASH_VECTOR_TOKEN: ${UPSTASH_VECTOR_TOKEN:-dify} UPLOAD_FILE_SIZE_LIMIT: ${UPLOAD_FILE_SIZE_LIMIT:-15} UPLOAD_FILE_BATCH_LIMIT: ${UPLOAD_FILE_BATCH_LIMIT:-5} ETL_TYPE: ${ETL_TYPE:-dify} From 01a2513812d418eb7fbe8b4d70ba4a0ad60c49cc Mon Sep 17 00:00:00 2001 From: Hash Brown <hi@xzd.me> Date: Wed, 23 Oct 2024 10:19:15 +0800 Subject: [PATCH 147/346] style: chat answer align with new UI (#9658) --- web/app/components/base/chat/chat/answer/basic-content.tsx | 3 +-- web/app/components/base/chat/chat/answer/index.tsx | 4 +--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/web/app/components/base/chat/chat/answer/basic-content.tsx b/web/app/components/base/chat/chat/answer/basic-content.tsx index a9ca3e8630..6c8a44cf52 100644 --- a/web/app/components/base/chat/chat/answer/basic-content.tsx +++ b/web/app/components/base/chat/chat/answer/basic-content.tsx @@ -16,12 +16,11 @@ const BasicContent: FC<BasicContentProps> = ({ } = item if (annotation?.logAnnotation) - return <Markdown content={annotation?.logAnnotation.content || ''} className='px-2 py-1' /> + return <Markdown content={annotation?.logAnnotation.content || ''} /> return ( <Markdown className={cn( - 'px-2 py-1', item.isError && '!text-[#F04438]', )} content={content} diff --git a/web/app/components/base/chat/chat/answer/index.tsx b/web/app/components/base/chat/chat/answer/index.tsx index 16ad8f84c3..50f51f521f 100644 --- a/web/app/components/base/chat/chat/answer/index.tsx +++ b/web/app/components/base/chat/chat/answer/index.tsx @@ -14,7 +14,6 @@ import BasicContent from './basic-content' import SuggestedQuestions from './suggested-questions' import More from './more' import WorkflowProcess from './workflow-process' -import { AnswerTriangle } from '@/app/components/base/icons/src/vender/solid/general' import LoadingAnim from '@/app/components/base/chat/chat/loading-anim' import Citation from '@/app/components/base/chat/chat/citation' import { EditTitle } from '@/app/components/app/annotation/edit-annotation-modal/edit-item' @@ -110,10 +109,9 @@ const Answer: FC<AnswerProps> = ({ </div> <div className='chat-answer-container group grow w-0 ml-4' ref={containerRef}> <div className={cn('group relative pr-10', chatAnswerContainerInner)}> - <AnswerTriangle className='absolute -left-2 top-0 w-2 h-3 text-gray-100' /> <div ref={contentRef} - className={cn('relative inline-block px-4 py-3 max-w-full bg-gray-100 rounded-b-2xl rounded-tr-2xl text-sm text-gray-900', workflowProcess && 'w-full')} + className={cn('relative inline-block px-4 py-3 max-w-full bg-gray-100 rounded-2xl text-sm text-gray-900', workflowProcess && 'w-full')} > { !responding && ( From d5a93a6400bb9df61ed4f9d36b2dfc9ee7c28f51 Mon Sep 17 00:00:00 2001 From: -LAN- <laipz8200@outlook.com> Date: Wed, 23 Oct 2024 10:19:33 +0800 Subject: [PATCH 148/346] fix(variable_pool): handle invalid attributes in variable lookup (#9646) --- api/core/workflow/entities/variable_pool.py | 12 ++++++++---- .../unit_tests/core/workflow/test_variable_pool.py | 4 ++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/api/core/workflow/entities/variable_pool.py b/api/core/workflow/entities/variable_pool.py index f8968990d4..3dc3395da1 100644 --- a/api/core/workflow/entities/variable_pool.py +++ b/api/core/workflow/entities/variable_pool.py @@ -124,11 +124,15 @@ class VariablePool(BaseModel): if value is None: selector, attr = selector[:-1], selector[-1] + # Python support `attr in FileAttribute` after 3.12 + if attr not in {item.value for item in FileAttribute}: + return None value = self.get(selector) - if isinstance(value, FileSegment): - attr = FileAttribute(attr) - attr_value = file_manager.get_attr(file=value.value, attr=attr) - return variable_factory.build_segment(attr_value) + if not isinstance(value, FileSegment): + return None + attr = FileAttribute(attr) + attr_value = file_manager.get_attr(file=value.value, attr=attr) + return variable_factory.build_segment(attr_value) return value diff --git a/api/tests/unit_tests/core/workflow/test_variable_pool.py b/api/tests/unit_tests/core/workflow/test_variable_pool.py index a1e4dda627..9ea6acac17 100644 --- a/api/tests/unit_tests/core/workflow/test_variable_pool.py +++ b/api/tests/unit_tests/core/workflow/test_variable_pool.py @@ -33,8 +33,8 @@ def test_get_file_attribute(pool, file): assert result.value == file.filename # Test getting a non-existent attribute - with pytest.raises(ValueError): - pool.get(("node_1", "file_var", "non_existent_attr")) + result = pool.get(("node_1", "file_var", "non_existent_attr")) + assert result is None def test_use_long_selector(pool): From ceb2c4f3ef9ca03952420a05a97d5fe2ec283d04 Mon Sep 17 00:00:00 2001 From: ice yao <yao3690093@gmail.com> Date: Wed, 23 Oct 2024 10:42:11 +0800 Subject: [PATCH 149/346] chore: reuse existing test functions with upstash vdb (#9679) --- api/controllers/console/datasets/datasets.py | 4 +- .../datasource/vdb/upstash/upstash_vector.py | 2 +- .../vdb/upstash/test_upstash_vector.py | 43 ++----------------- 3 files changed, 7 insertions(+), 42 deletions(-) diff --git a/api/controllers/console/datasets/datasets.py b/api/controllers/console/datasets/datasets.py index d735527258..6e6792936e 100644 --- a/api/controllers/console/datasets/datasets.py +++ b/api/controllers/console/datasets/datasets.py @@ -619,6 +619,7 @@ class DatasetRetrievalSettingApi(Resource): | VectorType.PGVECTO_RS | VectorType.BAIDU | VectorType.VIKINGDB + | VectorType.UPSTASH ): return {"retrieval_method": [RetrievalMethod.SEMANTIC_SEARCH.value]} case ( @@ -630,7 +631,6 @@ class DatasetRetrievalSettingApi(Resource): | VectorType.ORACLE | VectorType.ELASTICSEARCH | VectorType.PGVECTOR - | VectorType.UPSTASH ): return { "retrieval_method": [ @@ -658,6 +658,7 @@ class DatasetRetrievalSettingMockApi(Resource): | VectorType.PGVECTO_RS | VectorType.BAIDU | VectorType.VIKINGDB + | VectorType.UPSTASH ): return {"retrieval_method": [RetrievalMethod.SEMANTIC_SEARCH.value]} case ( @@ -669,7 +670,6 @@ class DatasetRetrievalSettingMockApi(Resource): | VectorType.ORACLE | VectorType.ELASTICSEARCH | VectorType.PGVECTOR - | VectorType.UPSTASH ): return { "retrieval_method": [ diff --git a/api/core/rag/datasource/vdb/upstash/upstash_vector.py b/api/core/rag/datasource/vdb/upstash/upstash_vector.py index ead7958dc6..df1b550b40 100644 --- a/api/core/rag/datasource/vdb/upstash/upstash_vector.py +++ b/api/core/rag/datasource/vdb/upstash/upstash_vector.py @@ -117,7 +117,7 @@ class UpstashVectorFactory(AbstractVectorFactory): collection_name = class_prefix.lower() else: dataset_id = dataset.id - collection_name = Dataset.gen_collection_name_by_id(dataset_id) + collection_name = Dataset.gen_collection_name_by_id(dataset_id).lower() dataset.index_struct = json.dumps(self.gen_index_struct_dict(VectorType.UPSTASH, collection_name)) return UpstashVector( diff --git a/api/tests/integration_tests/vdb/upstash/test_upstash_vector.py b/api/tests/integration_tests/vdb/upstash/test_upstash_vector.py index c4461e6512..23470474ff 100644 --- a/api/tests/integration_tests/vdb/upstash/test_upstash_vector.py +++ b/api/tests/integration_tests/vdb/upstash/test_upstash_vector.py @@ -1,27 +1,7 @@ -import time -import uuid - from core.rag.datasource.vdb.upstash.upstash_vector import UpstashVector, UpstashVectorConfig from core.rag.models.document import Document from tests.integration_tests.vdb.__mock.upstashvectordb import setup_upstashvector_mock -from tests.integration_tests.vdb.test_vector_store import AbstractVectorTest - - -def get_example_text() -> str: - return "test_text" - - -def get_example_document(doc_id: str) -> Document: - doc = Document( - page_content=get_example_text(), - metadata={ - "doc_id": doc_id, - "doc_hash": doc_id, - "document_id": doc_id, - "dataset_id": doc_id, - }, - ) - return doc +from tests.integration_tests.vdb.test_vector_store import AbstractVectorTest, get_example_text class UpstashVectorTest(AbstractVectorTest): @@ -34,29 +14,14 @@ class UpstashVectorTest(AbstractVectorTest): token="your-access-token", ), ) - self.example_embedding = [1.001 * i for i in range(self.vector._get_index_dimension())] - - def add_texts(self) -> list[str]: - batch_size = 1 - documents = [get_example_document(doc_id=str(uuid.uuid4())) for _ in range(batch_size)] - embeddings = [self.example_embedding] * batch_size - self.vector.add_texts(documents=documents, embeddings=embeddings) - return [doc.metadata["doc_id"] for doc in documents] def get_ids_by_metadata_field(self): - print("doc_id", self.example_doc_id) ids = self.vector.get_ids_by_metadata_field(key="document_id", value=self.example_doc_id) assert len(ids) != 0 - def run_all_tests(self): - self.create_vector() - time.sleep(1) - self.search_by_vector() - self.text_exists() - self.get_ids_by_metadata_field() - added_doc_ids = self.add_texts() - self.delete_by_ids(added_doc_ids + [self.example_doc_id]) - self.delete_vector() + def search_by_full_text(self): + hits_by_full_text: list[Document] = self.vector.search_by_full_text(query=get_example_text()) + assert len(hits_by_full_text) == 0 def test_upstash_vector(setup_upstashvector_mock): From 22bdfb7e56019452dcb7e95725ee550b17b7a8df Mon Sep 17 00:00:00 2001 From: Joe <79627742+ZhouhaoJiang@users.noreply.github.com> Date: Wed, 23 Oct 2024 10:59:30 +0800 Subject: [PATCH 150/346] Feat/optimize login (#9642) --- api/controllers/console/auth/oauth.py | 8 +++----- api/services/account_service.py | 12 ++++++------ 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/api/controllers/console/auth/oauth.py b/api/controllers/console/auth/oauth.py index 282e69448e..d27e3353c9 100644 --- a/api/controllers/console/auth/oauth.py +++ b/api/controllers/console/auth/oauth.py @@ -94,17 +94,15 @@ class OAuthCallback(Resource): account = _generate_account(provider, user_info) except AccountNotFoundError: return redirect(f"{dify_config.CONSOLE_WEB_URL}/signin?message=Account not found.") - except WorkSpaceNotFoundError: - return redirect(f"{dify_config.CONSOLE_WEB_URL}/signin?message=Workspace not found.") - except WorkSpaceNotAllowedCreateError: + except (WorkSpaceNotFoundError, WorkSpaceNotAllowedCreateError): return redirect( f"{dify_config.CONSOLE_WEB_URL}/signin" "?message=Workspace not found, please contact system admin to invite you to join in a workspace." ) # Check account status - if account.status in {AccountStatus.BANNED.value, AccountStatus.CLOSED.value}: - return {"error": "Account is banned or closed."}, 403 + if account.status == AccountStatus.BANNED.value: + return redirect(f"{dify_config.CONSOLE_WEB_URL}/signin?message=Account is banned.") if account.status == AccountStatus.PENDING.value: account.status = AccountStatus.ACTIVE.value diff --git a/api/services/account_service.py b/api/services/account_service.py index 529b716773..412685147c 100644 --- a/api/services/account_service.py +++ b/api/services/account_service.py @@ -98,8 +98,8 @@ class AccountService: if not account: return None - if account.status in {AccountStatus.BANNED.value, AccountStatus.CLOSED.value}: - raise Unauthorized("Account is banned or closed.") + if account.status == AccountStatus.BANNED.value: + raise Unauthorized("Account is banned.") current_tenant = TenantAccountJoin.query.filter_by(account_id=account.id, current=True).first() if current_tenant: @@ -143,8 +143,8 @@ class AccountService: if not account: raise AccountNotFoundError() - if account.status in {AccountStatus.BANNED.value, AccountStatus.CLOSED.value}: - raise AccountLoginError("Account is banned or closed.") + if account.status == AccountStatus.BANNED.value: + raise AccountLoginError("Account is banned.") if password and invite_token and account.password is None: # if invite_token is valid, set password and password_salt @@ -408,8 +408,8 @@ class AccountService: if not account: return None - if account.status in {AccountStatus.BANNED.value, AccountStatus.CLOSED.value}: - raise Unauthorized("Account is banned or closed.") + if account.status == AccountStatus.BANNED.value: + raise Unauthorized("Account is banned.") return account From 15acfffd608e0fc646236ee870d5c6b5a98c99ab Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Wed, 23 Oct 2024 11:40:56 +0800 Subject: [PATCH 151/346] chore: some ui and mock data --- web/app/components/plugins/card/card-mock.ts | 28 +++++++++++++++++++ .../install-from-local-package/index.tsx | 7 ++--- .../steps/install.tsx | 6 ++-- .../steps/uploading.tsx | 8 ++---- web/tailwind-common-config.ts | 3 ++ 5 files changed, 41 insertions(+), 11 deletions(-) diff --git a/web/app/components/plugins/card/card-mock.ts b/web/app/components/plugins/card/card-mock.ts index 4679a367f4..2ecd59a12b 100644 --- a/web/app/components/plugins/card/card-mock.ts +++ b/web/app/components/plugins/card/card-mock.ts @@ -1,3 +1,4 @@ +import type { PluginDeclaration } from '../types' import { PluginType } from '../types' export const toolNotion = { @@ -17,6 +18,33 @@ export const toolNotion = { }, } +export const toolNotionManifest: PluginDeclaration = { + version: '1.2.0', + author: 'Notion', + icon: 'https://via.placeholder.com/150', + name: 'notion page search', + category: PluginType.tool, + label: { + 'en-US': 'Notion Page Search', + 'zh-Hans': 'Notion 页面搜索', + }, + description: { + 'en-US': 'Description: Search Notion pages and open visited ones faster. No admin access required.More and more info...More and more info...More and more info...', + 'zh-Hans': '搜索 Notion 页面并更快地打开已访问的页面。无需管理员访问权限。More and more info...More and more info...More and more info...', + }, + created_at: '2022-01-01', + resource: {}, + plugins: {}, + verified: true, + endpoint: { + settings: [], + endpoints: [], + }, + tool: { + } as any, + model: {}, +} + export const extensionDallE = { type: PluginType.extension, org: 'OpenAI', diff --git a/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx b/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx index ab378f3d2d..50478bddb4 100644 --- a/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx +++ b/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx @@ -8,6 +8,7 @@ import Uploading from './steps/uploading' import Install from './steps/install' import Installed from './steps/installed' import { useTranslation } from 'react-i18next' +import { toolNotionManifest } from '../../card/card-mock' const i18nPrefix = 'plugin.installModal' @@ -22,6 +23,7 @@ const InstallFromLocalPackage: React.FC<InstallFromLocalPackageProps> = ({ onClose, }) => { const { t } = useTranslation() + // uploading -> readyToInstall -> installed const [step, setStep] = useState<InstallStep>(InstallStep.uploading) const [uniqueIdentifier, setUniqueIdentifier] = useState<string | null>(null) @@ -31,10 +33,7 @@ const InstallFromLocalPackage: React.FC<InstallFromLocalPackageProps> = ({ return t(`${i18nPrefix}.installedSuccessfully`) return t(`${i18nPrefix}.installPlugin`) }, []) - const [manifest, setManifest] = useState<PluginDeclaration | null>({ - name: 'Notion Sync', - description: 'Sync your Notion notes with Dify', - } as any) + const [manifest, setManifest] = useState<PluginDeclaration | null>(toolNotionManifest) const handleUploaded = useCallback((result: { uniqueIdentifier: string diff --git a/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx b/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx index a20da68447..5067dff908 100644 --- a/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx +++ b/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx @@ -7,6 +7,7 @@ import { pluginManifestToCardPluginProps } from '../../utils' import Button from '@/app/components/base/button' import { sleep } from '@/utils' import { Trans, useTranslation } from 'react-i18next' +import { RiLoader2Line } from '@remixicon/react' const i18nPrefix = 'plugin.installModal' @@ -59,11 +60,12 @@ const Installed: FC<Props> = ({ )} <Button variant='primary' - className='min-w-[72px]' + className='min-w-[72px] flex space-x-0.5' disabled={isInstalling} onClick={handleInstall} > - {t(`${i18nPrefix}.${isInstalling ? 'installing' : 'install'}`)} + {isInstalling && <RiLoader2Line className='w-4 h-4 animate-spin-slow' />} + <span>{t(`${i18nPrefix}.${isInstalling ? 'installing' : 'install'}`)}</span> </Button> </div> </> diff --git a/web/app/components/plugins/install-plugin/install-from-local-package/steps/uploading.tsx b/web/app/components/plugins/install-plugin/install-from-local-package/steps/uploading.tsx index 043897f068..6a8068515d 100644 --- a/web/app/components/plugins/install-plugin/install-from-local-package/steps/uploading.tsx +++ b/web/app/components/plugins/install-plugin/install-from-local-package/steps/uploading.tsx @@ -7,6 +7,7 @@ import type { PluginDeclaration } from '../../../types' import Button from '@/app/components/base/button' import { sleep } from '@/utils' import { useTranslation } from 'react-i18next' +import { toolNotionManifest } from '../../../card/card-mock' const i18nPrefix = 'plugin.installModal' @@ -30,10 +31,7 @@ const Uploading: FC<Props> = ({ await sleep(3000) onUploaded({ uniqueIdentifier: 'yeuoly/neko:0.0.1@5395654da2c0b919b3d9b946a1a0545b737004380765e5f3b8c49976d3276c87', - manifest: { - name: 'Notion Sync', - description: 'Sync your Notion notes with Dify', - } as any, + manifest: toolNotionManifest, }) } @@ -44,7 +42,7 @@ const Uploading: FC<Props> = ({ <> <div className='flex flex-col px-6 py-3 justify-center items-start gap-4 self-stretch'> <div className='flex items-center gap-1 self-stretch'> - <RiLoader2Line className='text-text-accent w-4 h-4' /> + <RiLoader2Line className='text-text-accent w-4 h-4 animate-spin-slow' /> <div className='text-text-secondary system-md-regular'> {t(`${i18nPrefix}.uploadingPackage`, { packageName: fileName, diff --git a/web/tailwind-common-config.ts b/web/tailwind-common-config.ts index 07721b3e48..9e800750a3 100644 --- a/web/tailwind-common-config.ts +++ b/web/tailwind-common-config.ts @@ -83,6 +83,9 @@ const config = { fontSize: { '2xs': '0.625rem', }, + animation: { + 'spin-slow': 'spin 2s linear infinite', + }, }, }, plugins: [ From 8d8d5b523575cdc9406f19d7ebcb9fc1a0816951 Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Wed, 23 Oct 2024 11:45:36 +0800 Subject: [PATCH 152/346] chore: handle verified --- web/app/components/plugins/card/index.tsx | 4 ++-- web/app/components/plugins/install-plugin/utils.ts | 7 ++++--- web/app/components/plugins/types.ts | 1 + 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/web/app/components/plugins/card/index.tsx b/web/app/components/plugins/card/index.tsx index 1ba801eac3..14dffe8f37 100644 --- a/web/app/components/plugins/card/index.tsx +++ b/web/app/components/plugins/card/index.tsx @@ -36,7 +36,7 @@ const Card = ({ }: Props) => { const locale = useGetLanguage() - const { type, name, org, label, brief, icon } = payload + const { type, name, org, label, brief, icon, verified } = payload const getLocalizedText = (obj: Record<string, string> | undefined) => obj?.[locale] || obj?.['en-US'] || '' @@ -60,7 +60,7 @@ const Card = ({ <div className="ml-3 grow"> <div className="flex items-center h-5"> <Title title={getLocalizedText(label)} /> - <RiVerifiedBadgeLine className="shrink-0 ml-0.5 w-4 h-4 text-text-accent" /> + {verified && <RiVerifiedBadgeLine className="shrink-0 ml-0.5 w-4 h-4 text-text-accent" />} {titleLeft} {/* This can be version badge */} </div> <OrgInfo diff --git a/web/app/components/plugins/install-plugin/utils.ts b/web/app/components/plugins/install-plugin/utils.ts index f3d9158d53..bd5453dd8c 100644 --- a/web/app/components/plugins/install-plugin/utils.ts +++ b/web/app/components/plugins/install-plugin/utils.ts @@ -1,4 +1,4 @@ -import type { Plugin, PluginDeclaration } from "../types" +import type { Plugin, PluginDeclaration } from '../types' export const pluginManifestToCardPluginProps = (pluginManifest: PluginDeclaration): Plugin => { return { @@ -11,11 +11,12 @@ export const pluginManifestToCardPluginProps = (pluginManifest: PluginDeclaratio label: pluginManifest.label, brief: pluginManifest.description, icon: pluginManifest.icon, + verified: pluginManifest.verified, introduction: '', repository: '', install_count: 0, endpoint: { - settings: [] - } + settings: [], + }, } } diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts index 654625a6bd..a2c11a8d6c 100644 --- a/web/app/components/plugins/types.ts +++ b/web/app/components/plugins/types.ts @@ -94,6 +94,7 @@ export type Plugin = { version: string latest_version: string icon: string + verified: boolean label: Record<Locale, string> brief: Record<Locale, string> // Repo readme.md content From 67016feb96a57bdb5ca0d359a345a14f2d397b3b Mon Sep 17 00:00:00 2001 From: -LAN- <laipz8200@outlook.com> Date: Wed, 23 Oct 2024 13:12:34 +0800 Subject: [PATCH 153/346] feat(api): enhance file preview handling (#9674) --- api/controllers/files/image_preview.py | 35 ++++++++++++++++++-------- api/services/file_service.py | 9 +++---- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/api/controllers/files/image_preview.py b/api/controllers/files/image_preview.py index 4b2d61e7c3..6b3ac93cdf 100644 --- a/api/controllers/files/image_preview.py +++ b/api/controllers/files/image_preview.py @@ -1,5 +1,5 @@ from flask import Response, request -from flask_restful import Resource +from flask_restful import Resource, reqparse from werkzeug.exceptions import NotFound import services @@ -41,24 +41,39 @@ class FilePreviewApi(Resource): def get(self, file_id): file_id = str(file_id) - timestamp = request.args.get("timestamp") - nonce = request.args.get("nonce") - sign = request.args.get("sign") + parser = reqparse.RequestParser() + parser.add_argument("timestamp", type=str, required=True, location="args") + parser.add_argument("nonce", type=str, required=True, location="args") + parser.add_argument("sign", type=str, required=True, location="args") + parser.add_argument("as_attachment", type=bool, required=False, default=False, location="args") - if not timestamp or not nonce or not sign: + args = parser.parse_args() + + if not args["timestamp"] or not args["nonce"] or not args["sign"]: return {"content": "Invalid request."}, 400 try: - generator, mimetype = FileService.get_signed_file_preview( + generator, upload_file = FileService.get_file_generator_by_file_id( file_id=file_id, - timestamp=timestamp, - nonce=nonce, - sign=sign, + timestamp=args["timestamp"], + nonce=args["nonce"], + sign=args["sign"], ) except services.errors.file.UnsupportedFileTypeError: raise UnsupportedFileTypeError() - return Response(generator, mimetype=mimetype) + response = Response( + generator, + mimetype=upload_file.mime_type, + direct_passthrough=True, + headers={}, + ) + if upload_file.size > 0: + response.headers["Content-Length"] = str(upload_file.size) + if args["as_attachment"]: + response.headers["Content-Disposition"] = f"attachment; filename={upload_file.name}" + + return response class WorkspaceWebappLogoApi(Resource): diff --git a/api/services/file_service.py b/api/services/file_service.py index 22ea923f6b..6193a39669 100644 --- a/api/services/file_service.py +++ b/api/services/file_service.py @@ -1,7 +1,6 @@ import datetime import hashlib import uuid -from collections.abc import Generator from typing import Literal, Union from flask_login import current_user @@ -132,7 +131,7 @@ class FileService: return upload_file @staticmethod - def get_file_preview(file_id: str) -> str: + def get_file_preview(file_id: str): upload_file = db.session.query(UploadFile).filter(UploadFile.id == file_id).first() if not upload_file: @@ -171,7 +170,7 @@ class FileService: return generator, upload_file.mime_type @staticmethod - def get_signed_file_preview(file_id: str, timestamp: str, nonce: str, sign: str): + def get_file_generator_by_file_id(file_id: str, timestamp: str, nonce: str, sign: str): result = file_helpers.verify_file_signature(upload_file_id=file_id, timestamp=timestamp, nonce=nonce, sign=sign) if not result: raise NotFound("File not found or signature is invalid") @@ -183,10 +182,10 @@ class FileService: generator = storage.load(upload_file.key, stream=True) - return generator, upload_file.mime_type + return generator, upload_file @staticmethod - def get_public_image_preview(file_id: str) -> tuple[Generator, str]: + def get_public_image_preview(file_id: str): upload_file = db.session.query(UploadFile).filter(UploadFile.id == file_id).first() if not upload_file: From 9a5bdae07f381d03f3b0b11b77394dbfdc6804c6 Mon Sep 17 00:00:00 2001 From: -LAN- <laipz8200@outlook.com> Date: Wed, 23 Oct 2024 13:25:17 +0800 Subject: [PATCH 154/346] feat(condition): add support for 'exists' and 'not exists' operators (#9687) --- api/core/workflow/utils/condition/entities.py | 3 +++ .../workflow/utils/condition/processor.py | 25 ++++++++++++++++++- .../core/workflow/nodes/test_if_else.py | 1 + 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/api/core/workflow/utils/condition/entities.py b/api/core/workflow/utils/condition/entities.py index 1d96743879..799c735f54 100644 --- a/api/core/workflow/utils/condition/entities.py +++ b/api/core/workflow/utils/condition/entities.py @@ -25,6 +25,9 @@ SupportedComparisonOperator = Literal[ "≤", "null", "not null", + # for file + "exists", + "not exists", ] diff --git a/api/core/workflow/utils/condition/processor.py b/api/core/workflow/utils/condition/processor.py index f4a80fa5e1..19473f39d2 100644 --- a/api/core/workflow/utils/condition/processor.py +++ b/api/core/workflow/utils/condition/processor.py @@ -2,7 +2,7 @@ from collections.abc import Sequence from typing import Any, Literal from core.file import FileAttribute, file_manager -from core.variables.segments import ArrayFileSegment +from core.variables import ArrayFileSegment from core.workflow.entities.variable_pool import VariablePool from .entities import Condition, SubCondition, SupportedComparisonOperator @@ -21,6 +21,8 @@ class ConditionProcessor: for condition in conditions: variable = variable_pool.get(condition.variable_selector) + if variable is None: + raise ValueError(f"Variable {condition.variable_selector} not found") if isinstance(variable, ArrayFileSegment) and condition.comparison_operator in { "contains", @@ -35,6 +37,15 @@ class ConditionProcessor: sub_conditions=condition.sub_variable_condition.conditions, operator=condition.sub_variable_condition.logical_operator, ) + elif condition.comparison_operator in { + "exists", + "not exists", + }: + result = _evaluate_condition( + value=variable.value, + operator=condition.comparison_operator, + expected=None, + ) else: actual_value = variable.value if variable else None expected_value = condition.value @@ -103,6 +114,10 @@ def _evaluate_condition( return _assert_not_in(value=value, expected=expected) case "all of" if isinstance(expected, list): return _assert_all_of(value=value, expected=expected) + case "exists": + return _assert_exists(value=value) + case "not exists": + return _assert_not_exists(value=value) case _: raise ValueError(f"Unsupported operator: {operator}") @@ -338,6 +353,14 @@ def _assert_all_of(*, value: Any, expected: Sequence[str]) -> bool: return True +def _assert_exists(*, value: Any) -> bool: + return value is not None + + +def _assert_not_exists(*, value: Any) -> bool: + return value is None + + def _process_sub_conditions( variable: ArrayFileSegment, sub_conditions: Sequence[SubCondition], diff --git a/api/tests/unit_tests/core/workflow/nodes/test_if_else.py b/api/tests/unit_tests/core/workflow/nodes/test_if_else.py index 8f38d3f280..d964d0e352 100644 --- a/api/tests/unit_tests/core/workflow/nodes/test_if_else.py +++ b/api/tests/unit_tests/core/workflow/nodes/test_if_else.py @@ -55,6 +55,7 @@ def test_execute_if_else_result_true(): pool.add(["start", "less_than"], 21) pool.add(["start", "greater_than_or_equal"], 22) pool.add(["start", "less_than_or_equal"], 21) + pool.add(["start", "null"], None) pool.add(["start", "not_null"], "1212") node = IfElseNode( From 4989d0c9040a710600daaf6deb95e6c231cce898 Mon Sep 17 00:00:00 2001 From: ybalbert001 <120714773+ybalbert001@users.noreply.github.com> Date: Wed, 23 Oct 2024 13:54:21 +0800 Subject: [PATCH 155/346] add bedrock claude 3.5 v2 support (#9685) Co-authored-by: Yuanbo Li <ybalbert@amazon.com> --- .../llm/anthropic.claude-3-sonnet-v2.yaml | 60 +++++++++++++++++++ .../llm/eu.anthropic.claude-3-sonnet-v2.yaml | 60 +++++++++++++++++++ .../llm/us.anthropic.claude-3-sonnet-v2.yaml | 60 +++++++++++++++++++ 3 files changed, 180 insertions(+) create mode 100644 api/core/model_runtime/model_providers/bedrock/llm/anthropic.claude-3-sonnet-v2.yaml create mode 100644 api/core/model_runtime/model_providers/bedrock/llm/eu.anthropic.claude-3-sonnet-v2.yaml create mode 100644 api/core/model_runtime/model_providers/bedrock/llm/us.anthropic.claude-3-sonnet-v2.yaml diff --git a/api/core/model_runtime/model_providers/bedrock/llm/anthropic.claude-3-sonnet-v2.yaml b/api/core/model_runtime/model_providers/bedrock/llm/anthropic.claude-3-sonnet-v2.yaml new file mode 100644 index 0000000000..b1e5698375 --- /dev/null +++ b/api/core/model_runtime/model_providers/bedrock/llm/anthropic.claude-3-sonnet-v2.yaml @@ -0,0 +1,60 @@ +model: anthropic.claude-3-5-sonnet-20241022-v2:0 +label: + en_US: Claude 3.5 Sonnet V2 +model_type: llm +features: + - agent-thought + - vision + - tool-call + - stream-tool-call +model_properties: + mode: chat + context_size: 200000 +# docs: https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-anthropic-claude-messages.html +parameter_rules: + - name: max_tokens + use_template: max_tokens + required: true + type: int + default: 4096 + min: 1 + max: 4096 + help: + zh_Hans: 停止前生成的最大令牌数。请注意,Anthropic Claude 模型可能会在达到 max_tokens 的值之前停止生成令牌。不同的 Anthropic Claude 模型对此参数具有不同的最大值。 + en_US: The maximum number of tokens to generate before stopping. Note that Anthropic Claude models might stop generating tokens before reaching the value of max_tokens. Different Anthropic Claude models have different maximum values for this parameter. + - name: temperature + use_template: temperature + required: false + type: float + default: 1 + min: 0.0 + max: 1.0 + help: + zh_Hans: 生成内容的随机性。 + en_US: The amount of randomness injected into the response. + - name: top_p + required: false + type: float + default: 0.999 + min: 0.000 + max: 1.000 + help: + zh_Hans: 在核采样中,Anthropic Claude 按概率递减顺序计算每个后续标记的所有选项的累积分布,并在达到 top_p 指定的特定概率时将其切断。您应该更改温度或top_p,但不能同时更改两者。 + en_US: In nucleus sampling, Anthropic Claude computes the cumulative distribution over all the options for each subsequent token in decreasing probability order and cuts it off once it reaches a particular probability specified by top_p. You should alter either temperature or top_p, but not both. + - name: top_k + required: false + type: int + default: 0 + min: 0 + # tip docs from aws has error, max value is 500 + max: 500 + help: + zh_Hans: 对于每个后续标记,仅从前 K 个选项中进行采样。使用 top_k 删除长尾低概率响应。 + en_US: Only sample from the top K options for each subsequent token. Use top_k to remove long tail low probability responses. + - name: response_format + use_template: response_format +pricing: + input: '0.003' + output: '0.015' + unit: '0.001' + currency: USD diff --git a/api/core/model_runtime/model_providers/bedrock/llm/eu.anthropic.claude-3-sonnet-v2.yaml b/api/core/model_runtime/model_providers/bedrock/llm/eu.anthropic.claude-3-sonnet-v2.yaml new file mode 100644 index 0000000000..8d831e6fcb --- /dev/null +++ b/api/core/model_runtime/model_providers/bedrock/llm/eu.anthropic.claude-3-sonnet-v2.yaml @@ -0,0 +1,60 @@ +model: eu.anthropic.claude-3-5-sonnet-20241022-v2:0 +label: + en_US: Claude 3.5 Sonnet V2(EU.Cross Region Inference) +model_type: llm +features: + - agent-thought + - vision + - tool-call + - stream-tool-call +model_properties: + mode: chat + context_size: 200000 +# docs: https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-anthropic-claude-messages.html +parameter_rules: + - name: max_tokens + use_template: max_tokens + required: true + type: int + default: 4096 + min: 1 + max: 4096 + help: + zh_Hans: 停止前生成的最大令牌数。请注意,Anthropic Claude 模型可能会在达到 max_tokens 的值之前停止生成令牌。不同的 Anthropic Claude 模型对此参数具有不同的最大值。 + en_US: The maximum number of tokens to generate before stopping. Note that Anthropic Claude models might stop generating tokens before reaching the value of max_tokens. Different Anthropic Claude models have different maximum values for this parameter. + - name: temperature + use_template: temperature + required: false + type: float + default: 1 + min: 0.0 + max: 1.0 + help: + zh_Hans: 生成内容的随机性。 + en_US: The amount of randomness injected into the response. + - name: top_p + required: false + type: float + default: 0.999 + min: 0.000 + max: 1.000 + help: + zh_Hans: 在核采样中,Anthropic Claude 按概率递减顺序计算每个后续标记的所有选项的累积分布,并在达到 top_p 指定的特定概率时将其切断。您应该更改温度或top_p,但不能同时更改两者。 + en_US: In nucleus sampling, Anthropic Claude computes the cumulative distribution over all the options for each subsequent token in decreasing probability order and cuts it off once it reaches a particular probability specified by top_p. You should alter either temperature or top_p, but not both. + - name: top_k + required: false + type: int + default: 0 + min: 0 + # tip docs from aws has error, max value is 500 + max: 500 + help: + zh_Hans: 对于每个后续标记,仅从前 K 个选项中进行采样。使用 top_k 删除长尾低概率响应。 + en_US: Only sample from the top K options for each subsequent token. Use top_k to remove long tail low probability responses. + - name: response_format + use_template: response_format +pricing: + input: '0.003' + output: '0.015' + unit: '0.001' + currency: USD diff --git a/api/core/model_runtime/model_providers/bedrock/llm/us.anthropic.claude-3-sonnet-v2.yaml b/api/core/model_runtime/model_providers/bedrock/llm/us.anthropic.claude-3-sonnet-v2.yaml new file mode 100644 index 0000000000..31a403289b --- /dev/null +++ b/api/core/model_runtime/model_providers/bedrock/llm/us.anthropic.claude-3-sonnet-v2.yaml @@ -0,0 +1,60 @@ +model: us.anthropic.claude-3-5-sonnet-20241022-v2:0 +label: + en_US: Claude 3.5 Sonnet V2(US.Cross Region Inference) +model_type: llm +features: + - agent-thought + - vision + - tool-call + - stream-tool-call +model_properties: + mode: chat + context_size: 200000 +# docs: https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-anthropic-claude-messages.html +parameter_rules: + - name: max_tokens + use_template: max_tokens + required: true + type: int + default: 4096 + min: 1 + max: 4096 + help: + zh_Hans: 停止前生成的最大令牌数。请注意,Anthropic Claude 模型可能会在达到 max_tokens 的值之前停止生成令牌。不同的 Anthropic Claude 模型对此参数具有不同的最大值。 + en_US: The maximum number of tokens to generate before stopping. Note that Anthropic Claude models might stop generating tokens before reaching the value of max_tokens. Different Anthropic Claude models have different maximum values for this parameter. + - name: temperature + use_template: temperature + required: false + type: float + default: 1 + min: 0.0 + max: 1.0 + help: + zh_Hans: 生成内容的随机性。 + en_US: The amount of randomness injected into the response. + - name: top_p + required: false + type: float + default: 0.999 + min: 0.000 + max: 1.000 + help: + zh_Hans: 在核采样中,Anthropic Claude 按概率递减顺序计算每个后续标记的所有选项的累积分布,并在达到 top_p 指定的特定概率时将其切断。您应该更改温度或top_p,但不能同时更改两者。 + en_US: In nucleus sampling, Anthropic Claude computes the cumulative distribution over all the options for each subsequent token in decreasing probability order and cuts it off once it reaches a particular probability specified by top_p. You should alter either temperature or top_p, but not both. + - name: top_k + required: false + type: int + default: 0 + min: 0 + # tip docs from aws has error, max value is 500 + max: 500 + help: + zh_Hans: 对于每个后续标记,仅从前 K 个选项中进行采样。使用 top_k 删除长尾低概率响应。 + en_US: Only sample from the top K options for each subsequent token. Use top_k to remove long tail low probability responses. + - name: response_format + use_template: response_format +pricing: + input: '0.003' + output: '0.015' + unit: '0.001' + currency: USD From ed96a6b6c0081846246c538b5a335968f9f3b0ca Mon Sep 17 00:00:00 2001 From: Joe <79627742+ZhouhaoJiang@users.noreply.github.com> Date: Wed, 23 Oct 2024 14:56:10 +0800 Subject: [PATCH 156/346] fix: remove email code login redirect (#9698) --- api/controllers/console/auth/login.py | 8 ++------ api/controllers/console/error.py | 2 +- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/api/controllers/console/auth/login.py b/api/controllers/console/auth/login.py index 4821c543b7..6c795f95b6 100644 --- a/api/controllers/console/auth/login.py +++ b/api/controllers/console/auth/login.py @@ -1,11 +1,10 @@ from typing import cast import flask_login -from flask import redirect, request +from flask import request from flask_restful import Resource, reqparse import services -from configs import dify_config from constants.languages import languages from controllers.console import api from controllers.console.auth.error import ( @@ -196,10 +195,7 @@ class EmailCodeLoginApi(Resource): email=user_email, name=user_email, interface_language=languages[0] ) except WorkSpaceNotAllowedCreateError: - return redirect( - f"{dify_config.CONSOLE_WEB_URL}/signin" - "?message=Workspace not found, please contact system admin to invite you to join in a workspace." - ) + return NotAllowedCreateWorkspace() token_pair = AccountService.login(account, ip_address=extract_remote_ip(request)) AccountService.reset_login_error_rate_limit(args["email"]) return {"result": "success", "data": token_pair.model_dump()} diff --git a/api/controllers/console/error.py b/api/controllers/console/error.py index a6d4c8e8ec..ed6a99a017 100644 --- a/api/controllers/console/error.py +++ b/api/controllers/console/error.py @@ -41,7 +41,7 @@ class AlreadyActivateError(BaseHTTPException): class NotAllowedCreateWorkspace(BaseHTTPException): - error_code = "unauthorized" + error_code = "not_allowed_create_workspace" description = "Workspace not found, please contact system admin to invite you to join in a workspace." code = 400 From 2cb7b73ee77ede83657b1e33d33b0ae984b5d5ad Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Wed, 23 Oct 2024 15:00:31 +0800 Subject: [PATCH 157/346] feat: handle import from marketplace --- .../components/plugins/plugin-page/index.tsx | 4 +++- .../plugin-page/install-plugin-dropdown.tsx | 17 ++++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/web/app/components/plugins/plugin-page/index.tsx b/web/app/components/plugins/plugin-page/index.tsx index 598c2d7015..7ec7dbfae8 100644 --- a/web/app/components/plugins/plugin-page/index.tsx +++ b/web/app/components/plugins/plugin-page/index.tsx @@ -111,7 +111,9 @@ const PluginPage = ({ </Button> </div> {canManagement && ( - <InstallPluginDropdown /> + <InstallPluginDropdown + onSwitchToMarketplaceTab={() => setActiveTab('discover')} + /> )} { canDebugger && ( diff --git a/web/app/components/plugins/plugin-page/install-plugin-dropdown.tsx b/web/app/components/plugins/plugin-page/install-plugin-dropdown.tsx index cd682f42b7..7a20d5b43e 100644 --- a/web/app/components/plugins/plugin-page/install-plugin-dropdown.tsx +++ b/web/app/components/plugins/plugin-page/install-plugin-dropdown.tsx @@ -6,7 +6,6 @@ import Button from '@/app/components/base/button' import { MagicBox } from '@/app/components/base/icons/src/vender/solid/mediaAndDevices' import { FileZip } from '@/app/components/base/icons/src/vender/solid/files' import { Github } from '@/app/components/base/icons/src/vender/solid/general' -import InstallFromMarketplace from '@/app/components/plugins/install-plugin/install-from-marketplace' import InstallFromGitHub from '@/app/components/plugins/install-plugin/install-from-github' import InstallFromLocalPackage from '@/app/components/plugins/install-plugin/install-from-local-package' import cn from '@/utils/classnames' @@ -17,7 +16,12 @@ import { } from '@/app/components/base/portal-to-follow-elem' import { useSelector as useAppContextSelector } from '@/context/app-context' -const InstallPluginDropdown = () => { +type Props = { + onSwitchToMarketplaceTab: () => void +} +const InstallPluginDropdown = ({ + onSwitchToMarketplaceTab, +}: Props) => { const fileInputRef = useRef<HTMLInputElement>(null) const [isMenuOpen, setIsMenuOpen] = useState(false) const [selectedAction, setSelectedAction] = useState<string | null>(null) @@ -53,7 +57,7 @@ const InstallPluginDropdown = () => { <PortalToFollowElemContent className='z-[1002]'> <div className='flex flex-col p-1 pb-2 items-start w-[200px] bg-components-panel-bg-blur border border-components-panel-border rounded-xl shadows-shadow-lg'> <span className='flex pt-1 pb-0.5 pl-2 pr-3 items-start self-stretch text-text-tertiary system-xs-medium-uppercase'> - Install Form + Install From </span> <input type='file' @@ -65,7 +69,7 @@ const InstallPluginDropdown = () => { <div className='p-1 w-full'> {[ ...( - enable_marketplace + (enable_marketplace || true) ? [{ icon: MagicBox, text: 'Marketplace', action: 'marketplace' }] : [] ), @@ -79,6 +83,10 @@ const InstallPluginDropdown = () => { if (action === 'local') { fileInputRef.current?.click() } + else if (action === 'marketplace') { + onSwitchToMarketplaceTab() + setIsMenuOpen(false) + } else { setSelectedAction(action) setIsMenuOpen(false) @@ -93,7 +101,6 @@ const InstallPluginDropdown = () => { </div> </PortalToFollowElemContent> </div> - {selectedAction === 'marketplace' && <InstallFromMarketplace onClose={() => setSelectedAction(null)} />} {selectedAction === 'github' && <InstallFromGitHub onClose={() => setSelectedAction(null)} />} {selectedAction === 'local' && selectedFile && (<InstallFromLocalPackage From 1b9bf9c62d854571e7753199d518c3ac70f5630e Mon Sep 17 00:00:00 2001 From: -LAN- <laipz8200@outlook.com> Date: Wed, 23 Oct 2024 15:23:30 +0800 Subject: [PATCH 158/346] feat(api): add video and audio file size limits to upload config (#9703) --- api/fields/file_fields.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/api/fields/file_fields.py b/api/fields/file_fields.py index 4ce7644e9d..9ff1111b74 100644 --- a/api/fields/file_fields.py +++ b/api/fields/file_fields.py @@ -6,6 +6,8 @@ upload_config_fields = { "file_size_limit": fields.Integer, "batch_count_limit": fields.Integer, "image_file_size_limit": fields.Integer, + "video_file_size_limit": fields.Integer, + "audio_file_size_limit": fields.Integer, } file_fields = { From c46b5f2fd00a0b689394788bbb7dc8173333ce1d Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Wed, 23 Oct 2024 15:26:31 +0800 Subject: [PATCH 159/346] feat: handle install search params and hide --- .../steps/install.tsx | 74 +++++++++++++++++++ .../steps/installed.tsx | 46 ++++++++++++ .../components/plugins/plugin-page/index.tsx | 42 +++++++++++ 3 files changed, 162 insertions(+) create mode 100644 web/app/components/plugins/install-plugin/install-from-marketplace/steps/install.tsx create mode 100644 web/app/components/plugins/install-plugin/install-from-marketplace/steps/installed.tsx diff --git a/web/app/components/plugins/install-plugin/install-from-marketplace/steps/install.tsx b/web/app/components/plugins/install-plugin/install-from-marketplace/steps/install.tsx new file mode 100644 index 0000000000..5067dff908 --- /dev/null +++ b/web/app/components/plugins/install-plugin/install-from-marketplace/steps/install.tsx @@ -0,0 +1,74 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import type { PluginDeclaration } from '../../../types' +import Card from '../../../card' +import { pluginManifestToCardPluginProps } from '../../utils' +import Button from '@/app/components/base/button' +import { sleep } from '@/utils' +import { Trans, useTranslation } from 'react-i18next' +import { RiLoader2Line } from '@remixicon/react' + +const i18nPrefix = 'plugin.installModal' + +type Props = { + payload: PluginDeclaration + onCancel: () => void + onInstalled: () => void +} + +const Installed: FC<Props> = ({ + payload, + onCancel, + onInstalled, +}) => { + const { t } = useTranslation() + const [isInstalling, setIsInstalling] = React.useState(false) + + const handleInstall = async () => { + if (isInstalling) return + setIsInstalling(true) + await sleep(1500) + onInstalled() + } + + return ( + <> + <div className='flex flex-col px-6 py-3 justify-center items-start gap-4 self-stretch'> + <div className='text-text-secondary system-md-regular'> + <p>{t(`${i18nPrefix}.readyToInstall`)}</p> + <p> + <Trans + i18nKey={`${i18nPrefix}.fromTrustSource`} + components={{ trustSource: <span className='system-md-semibold' /> }} + /> + </p> + </div> + <div className='flex p-2 items-start content-start gap-1 self-stretch flex-wrap rounded-2xl bg-background-section-burn'> + <Card + className='w-full' + payload={pluginManifestToCardPluginProps(payload)} + /> + </div> + </div> + {/* Action Buttons */} + <div className='flex p-6 pt-5 justify-end items-center gap-2 self-stretch'> + {!isInstalling && ( + <Button variant='secondary' className='min-w-[72px]' onClick={onCancel}> + {t('common.operation.cancel')} + </Button> + )} + <Button + variant='primary' + className='min-w-[72px] flex space-x-0.5' + disabled={isInstalling} + onClick={handleInstall} + > + {isInstalling && <RiLoader2Line className='w-4 h-4 animate-spin-slow' />} + <span>{t(`${i18nPrefix}.${isInstalling ? 'installing' : 'install'}`)}</span> + </Button> + </div> + </> + ) +} +export default React.memo(Installed) diff --git a/web/app/components/plugins/install-plugin/install-from-marketplace/steps/installed.tsx b/web/app/components/plugins/install-plugin/install-from-marketplace/steps/installed.tsx new file mode 100644 index 0000000000..34fad51691 --- /dev/null +++ b/web/app/components/plugins/install-plugin/install-from-marketplace/steps/installed.tsx @@ -0,0 +1,46 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import type { PluginDeclaration } from '../../../types' +import Card from '../../../card' +import Button from '@/app/components/base/button' +import { pluginManifestToCardPluginProps } from '../../utils' +import { useTranslation } from 'react-i18next' + +type Props = { + payload: PluginDeclaration + onCancel: () => void + +} + +const Installed: FC<Props> = ({ + payload, + onCancel, +}) => { + const { t } = useTranslation() + return ( + <> + <div className='flex flex-col px-6 py-3 justify-center items-start gap-4 self-stretch'> + <p className='text-text-secondary system-md-regular'>The plugin has been installed successfully.</p> + <div className='flex p-2 items-start content-start gap-1 self-stretch flex-wrap rounded-2xl bg-background-section-burn'> + <Card + className='w-full' + payload={pluginManifestToCardPluginProps(payload)} + installed + /> + </div> + </div> + {/* Action Buttons */} + <div className='flex p-6 pt-5 justify-end items-center gap-2 self-stretch'> + <Button + variant='primary' + className='min-w-[72px]' + onClick={onCancel} + > + {t('common.operation.close')} + </Button> + </div> + </> + ) +} +export default React.memo(Installed) diff --git a/web/app/components/plugins/plugin-page/index.tsx b/web/app/components/plugins/plugin-page/index.tsx index 7ec7dbfae8..6c73f0c6ee 100644 --- a/web/app/components/plugins/plugin-page/index.tsx +++ b/web/app/components/plugins/plugin-page/index.tsx @@ -24,6 +24,13 @@ import Tooltip from '@/app/components/base/tooltip' import cn from '@/utils/classnames' import PermissionSetModal from '@/app/components/plugins/permission-setting-modal/modal' import { useSelector as useAppContextSelector } from '@/context/app-context' +import InstallFromMarketplace from '../install-plugin/install-from-marketplace' +import { + useRouter, + useSearchParams, +} from 'next/navigation' + +const PACKAGE_IDS_KEY = 'package-ids' export type PluginPageProps = { plugins: React.ReactNode @@ -34,6 +41,21 @@ const PluginPage = ({ marketplace, }: PluginPageProps) => { const { t } = useTranslation() + const searchParams = useSearchParams() + const { replace } = useRouter() + + // just support install one package now + const packageId = useMemo(() => { + const idStrings = searchParams.get(PACKAGE_IDS_KEY) + try { + return idStrings ? JSON.parse(idStrings)[0] : '' + } + catch (e) { + return '' + } + }, [searchParams]) + const isInstallPackage = !!packageId + const { canManagement, canDebugger, @@ -72,6 +94,18 @@ const PluginPage = ({ const { dragging, fileUploader, fileChangeHandle, removeFile } = uploaderProps + const [isShowInstallFromMarketplace, { + setTrue: showInstallFromMarketplace, + setFalse: doHideInstallFromMarketplace, + }] = useBoolean(isInstallPackage) + + const hideInstallFromMarketplace = () => { + doHideInstallFromMarketplace() + const url = new URL(window.location.href) + url.searchParams.delete(PACKAGE_IDS_KEY) + replace(url.toString()) + } + return ( <div ref={containerRef} @@ -178,6 +212,14 @@ const PluginPage = ({ onSave={setPermissions} /> )} + + { + isShowInstallFromMarketplace && ( + <InstallFromMarketplace + onClose={hideInstallFromMarketplace} + /> + ) + } </div> ) } From c3473b5b4f50e67213843f5f526a4b4ac7a9eeb6 Mon Sep 17 00:00:00 2001 From: zxhlyh <jasonapring2015@outlook.com> Date: Wed, 23 Oct 2024 15:46:02 +0800 Subject: [PATCH 160/346] fix: workflow [if node] checklist (#9699) --- web/app/components/workflow/nodes/if-else/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/app/components/workflow/nodes/if-else/utils.ts b/web/app/components/workflow/nodes/if-else/utils.ts index e034ce98df..de01498d04 100644 --- a/web/app/components/workflow/nodes/if-else/utils.ts +++ b/web/app/components/workflow/nodes/if-else/utils.ts @@ -3,7 +3,7 @@ import { VarType } from '@/app/components/workflow/types' import type { Branch } from '@/app/components/workflow/types' export const isEmptyRelatedOperator = (operator: ComparisonOperator) => { - return [ComparisonOperator.empty, ComparisonOperator.notEmpty, ComparisonOperator.isNull, ComparisonOperator.isNotNull].includes(operator) + return [ComparisonOperator.empty, ComparisonOperator.notEmpty, ComparisonOperator.isNull, ComparisonOperator.isNotNull, ComparisonOperator.exists, ComparisonOperator.notExists].includes(operator) } const notTranslateKey = [ From b4041759f7c45a35fea3fdac6c05205073f708b0 Mon Sep 17 00:00:00 2001 From: AAEE86 <33052466+AAEE86@users.noreply.github.com> Date: Wed, 23 Oct 2024 15:47:11 +0800 Subject: [PATCH 161/346] Help documentation URL correction (#9704) --- web/app/components/workflow/panel/chat-variable-panel/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/app/components/workflow/panel/chat-variable-panel/index.tsx b/web/app/components/workflow/panel/chat-variable-panel/index.tsx index 8ae17a4db3..2e03f501d3 100644 --- a/web/app/components/workflow/panel/chat-variable-panel/index.tsx +++ b/web/app/components/workflow/panel/chat-variable-panel/index.tsx @@ -139,7 +139,7 @@ const ChatVariablePanel = () => { <div className='inline-block py-[3px] px-[5px] rounded-[5px] border border-divider-deep text-text-tertiary system-2xs-medium-uppercase'>TIPS</div> <div className='mt-1 mb-4 system-sm-regular text-text-secondary'> {t('workflow.chatVariable.panelDescription')} - <a target='_blank' rel='noopener noreferrer' className='text-text-accent' href={locale !== LanguagesSupported[1] ? 'https://docs.dify.ai/guides/workflow/key_concepts#conversation-variables' : `https://docs.dify.ai/v/${locale.toLowerCase()}/guides/workflow/key_concept#hui-hua-bian-liang`}>{t('workflow.chatVariable.docLink')}</a> + <a target='_blank' rel='noopener noreferrer' className='text-text-accent' href={locale !== LanguagesSupported[1] ? 'https://docs.dify.ai/guides/workflow/variables#conversation-variables' : `https://docs.dify.ai/${locale.toLowerCase()}/guides/workflow/variables#hui-hua-bian-liang`}>{t('workflow.chatVariable.docLink')}</a> </div> <div className='flex items-center gap-2'> <div className='flex flex-col p-3 pb-4 bg-workflow-block-bg radius-lg border border-workflow-block-border shadow-md'> From b9afb7bcecf1a12beef29aad6e4add816438a0e5 Mon Sep 17 00:00:00 2001 From: kurokobo <kuro664@gmail.com> Date: Wed, 23 Oct 2024 16:47:50 +0900 Subject: [PATCH 162/346] fix: revert ref usage in handleFormChange to fix IME input issues (#9672) Co-authored-by: StyleZhang <jasonapring2015@outlook.com> --- .../base/chat/chat-with-history/config-panel/form.tsx | 5 +++-- .../base/chat/embedded-chatbot/config-panel/form.tsx | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/web/app/components/base/chat/chat-with-history/config-panel/form.tsx b/web/app/components/base/chat/chat-with-history/config-panel/form.tsx index 2429de36fa..298d8ccd7f 100644 --- a/web/app/components/base/chat/chat-with-history/config-panel/form.tsx +++ b/web/app/components/base/chat/chat-with-history/config-panel/form.tsx @@ -1,3 +1,4 @@ +import { useCallback } from 'react' import { useTranslation } from 'react-i18next' import { useChatWithHistoryContext } from '../context' import Input from './form-input' @@ -15,12 +16,12 @@ const Form = () => { isMobile, } = useChatWithHistoryContext() - const handleFormChange = (variable: string, value: any) => { + const handleFormChange = useCallback((variable: string, value: any) => { handleNewConversationInputsChange({ ...newConversationInputsRef.current, [variable]: value, }) - } + }, [newConversationInputsRef, handleNewConversationInputsChange]) const renderField = (form: any) => { const { diff --git a/web/app/components/base/chat/embedded-chatbot/config-panel/form.tsx b/web/app/components/base/chat/embedded-chatbot/config-panel/form.tsx index da26fdfa24..211907d48b 100644 --- a/web/app/components/base/chat/embedded-chatbot/config-panel/form.tsx +++ b/web/app/components/base/chat/embedded-chatbot/config-panel/form.tsx @@ -1,3 +1,4 @@ +import { useCallback } from 'react' import { useTranslation } from 'react-i18next' import { useEmbeddedChatbotContext } from '../context' import Input from './form-input' @@ -15,12 +16,12 @@ const Form = () => { isMobile, } = useEmbeddedChatbotContext() - const handleFormChange = (variable: string, value: any) => { + const handleFormChange = useCallback((variable: string, value: any) => { handleNewConversationInputsChange({ ...newConversationInputsRef.current, [variable]: value, }) - } + }, [newConversationInputsRef, handleNewConversationInputsChange]) const renderField = (form: any) => { const { From ecc8beef3f0c099777adeed9367b0aaaab9a92a6 Mon Sep 17 00:00:00 2001 From: "Pan, Wen-Ming" <pwm@google.com> Date: Wed, 23 Oct 2024 16:13:51 +0800 Subject: [PATCH 163/346] feat: added claude 3.5 sonnet v2 model to Google Cloud Vertex AI (#9688) --- .../llm/anthropic.claude-3.5-sonnet-v2.yaml | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 api/core/model_runtime/model_providers/vertex_ai/llm/anthropic.claude-3.5-sonnet-v2.yaml diff --git a/api/core/model_runtime/model_providers/vertex_ai/llm/anthropic.claude-3.5-sonnet-v2.yaml b/api/core/model_runtime/model_providers/vertex_ai/llm/anthropic.claude-3.5-sonnet-v2.yaml new file mode 100644 index 0000000000..0be3e26e7a --- /dev/null +++ b/api/core/model_runtime/model_providers/vertex_ai/llm/anthropic.claude-3.5-sonnet-v2.yaml @@ -0,0 +1,55 @@ +model: claude-3-5-sonnet-v2@20241022 +label: + en_US: Claude 3.5 Sonnet v2 +model_type: llm +features: + - agent-thought + - vision +model_properties: + mode: chat + context_size: 200000 +parameter_rules: + - name: max_tokens + use_template: max_tokens + required: true + type: int + default: 4096 + min: 1 + max: 4096 + help: + zh_Hans: 停止前生成的最大令牌数。请注意,Anthropic Claude 模型可能会在达到 max_tokens 的值之前停止生成令牌。不同的 Anthropic Claude 模型对此参数具有不同的最大值。 + en_US: The maximum number of tokens to generate before stopping. Note that Anthropic Claude models might stop generating tokens before reaching the value of max_tokens. Different Anthropic Claude models have different maximum values for this parameter. + - name: temperature + use_template: temperature + required: false + type: float + default: 1 + min: 0.0 + max: 1.0 + help: + zh_Hans: 生成内容的随机性。 + en_US: The amount of randomness injected into the response. + - name: top_p + required: false + type: float + default: 0.999 + min: 0.000 + max: 1.000 + help: + zh_Hans: 在核采样中,Anthropic Claude 按概率递减顺序计算每个后续标记的所有选项的累积分布,并在达到 top_p 指定的特定概率时将其切断。您应该更改温度或top_p,但不能同时更改两者。 + en_US: In nucleus sampling, Anthropic Claude computes the cumulative distribution over all the options for each subsequent token in decreasing probability order and cuts it off once it reaches a particular probability specified by top_p. You should alter either temperature or top_p, but not both. + - name: top_k + required: false + type: int + default: 0 + min: 0 + # tip docs from aws has error, max value is 500 + max: 500 + help: + zh_Hans: 对于每个后续标记,仅从前 K 个选项中进行采样。使用 top_k 删除长尾低概率响应。 + en_US: Only sample from the top K options for each subsequent token. Use top_k to remove long tail low probability responses. +pricing: + input: '0.003' + output: '0.015' + unit: '0.001' + currency: USD From 3e9d271b5264fcda6d791194bd5a2ccbb9b8ce21 Mon Sep 17 00:00:00 2001 From: Jyong <76649700+JohnJyong@users.noreply.github.com> Date: Wed, 23 Oct 2024 16:23:55 +0800 Subject: [PATCH 164/346] nltk security issue and upgrade unstructured (#9558) --- api/constants/__init__.py | 4 +- api/core/rag/extractor/extract_processor.py | 15 +- .../unstructured_eml_extractor.py | 18 +- .../unstructured_epub_extractor.py | 12 +- .../unstructured_markdown_extractor.py | 16 +- .../unstructured_msg_extractor.py | 12 +- .../unstructured_pdf_extractor.py | 47 + .../unstructured_ppt_extractor.py | 9 +- .../unstructured_pptx_extractor.py | 14 +- .../unstructured_xml_extractor.py | 15 +- api/poetry.lock | 2271 +++++++++++------ api/pyproject.toml | 5 +- dev/pytest/pytest_vdb.sh | 7 +- 13 files changed, 1664 insertions(+), 781 deletions(-) create mode 100644 api/core/rag/extractor/unstructured/unstructured_pdf_extractor.py diff --git a/api/constants/__init__.py b/api/constants/__init__.py index 66b9c0b632..05795e11d7 100644 --- a/api/constants/__init__.py +++ b/api/constants/__init__.py @@ -15,7 +15,9 @@ AUDIO_EXTENSIONS.extend([ext.upper() for ext in AUDIO_EXTENSIONS]) if dify_config.ETL_TYPE == "Unstructured": DOCUMENT_EXTENSIONS = ["txt", "markdown", "md", "pdf", "html", "htm", "xlsx", "xls"] - DOCUMENT_EXTENSIONS.extend(("docx", "csv", "eml", "msg", "pptx", "ppt", "xml", "epub")) + DOCUMENT_EXTENSIONS.extend(("docx", "csv", "eml", "msg", "pptx", "xml", "epub")) + if dify_config.UNSTRUCTURED_API_URL: + DOCUMENT_EXTENSIONS.append("ppt") DOCUMENT_EXTENSIONS.extend([ext.upper() for ext in DOCUMENT_EXTENSIONS]) else: DOCUMENT_EXTENSIONS = ["txt", "markdown", "md", "pdf", "html", "htm", "xlsx", "xls", "docx", "csv"] diff --git a/api/core/rag/extractor/extract_processor.py b/api/core/rag/extractor/extract_processor.py index 706a42b735..603f7555dd 100644 --- a/api/core/rag/extractor/extract_processor.py +++ b/api/core/rag/extractor/extract_processor.py @@ -21,6 +21,7 @@ from core.rag.extractor.unstructured.unstructured_eml_extractor import Unstructu from core.rag.extractor.unstructured.unstructured_epub_extractor import UnstructuredEpubExtractor from core.rag.extractor.unstructured.unstructured_markdown_extractor import UnstructuredMarkdownExtractor from core.rag.extractor.unstructured.unstructured_msg_extractor import UnstructuredMsgExtractor +from core.rag.extractor.unstructured.unstructured_pdf_extractor import UnstructuredPDFExtractor from core.rag.extractor.unstructured.unstructured_ppt_extractor import UnstructuredPPTExtractor from core.rag.extractor.unstructured.unstructured_pptx_extractor import UnstructuredPPTXExtractor from core.rag.extractor.unstructured.unstructured_text_extractor import UnstructuredTextExtractor @@ -102,10 +103,10 @@ class ExtractProcessor: if file_extension in {".xlsx", ".xls"}: extractor = ExcelExtractor(file_path) elif file_extension == ".pdf": - extractor = PdfExtractor(file_path) + extractor = UnstructuredPDFExtractor(file_path, unstructured_api_url, unstructured_api_key) elif file_extension in {".md", ".markdown"}: extractor = ( - UnstructuredMarkdownExtractor(file_path, unstructured_api_url) + UnstructuredMarkdownExtractor(file_path, unstructured_api_url, unstructured_api_key) if is_automatic else MarkdownExtractor(file_path, autodetect_encoding=True) ) @@ -116,17 +117,17 @@ class ExtractProcessor: elif file_extension == ".csv": extractor = CSVExtractor(file_path, autodetect_encoding=True) elif file_extension == ".msg": - extractor = UnstructuredMsgExtractor(file_path, unstructured_api_url) + extractor = UnstructuredMsgExtractor(file_path, unstructured_api_url, unstructured_api_key) elif file_extension == ".eml": - extractor = UnstructuredEmailExtractor(file_path, unstructured_api_url) + extractor = UnstructuredEmailExtractor(file_path, unstructured_api_url, unstructured_api_key) elif file_extension == ".ppt": extractor = UnstructuredPPTExtractor(file_path, unstructured_api_url, unstructured_api_key) elif file_extension == ".pptx": - extractor = UnstructuredPPTXExtractor(file_path, unstructured_api_url) + extractor = UnstructuredPPTXExtractor(file_path, unstructured_api_url, unstructured_api_key) elif file_extension == ".xml": - extractor = UnstructuredXmlExtractor(file_path, unstructured_api_url) + extractor = UnstructuredXmlExtractor(file_path, unstructured_api_url, unstructured_api_key) elif file_extension == ".epub": - extractor = UnstructuredEpubExtractor(file_path, unstructured_api_url) + extractor = UnstructuredEpubExtractor(file_path, unstructured_api_url, unstructured_api_key) else: # txt extractor = ( diff --git a/api/core/rag/extractor/unstructured/unstructured_eml_extractor.py b/api/core/rag/extractor/unstructured/unstructured_eml_extractor.py index 34c6811b67..bd669bbad3 100644 --- a/api/core/rag/extractor/unstructured/unstructured_eml_extractor.py +++ b/api/core/rag/extractor/unstructured/unstructured_eml_extractor.py @@ -10,24 +10,26 @@ logger = logging.getLogger(__name__) class UnstructuredEmailExtractor(BaseExtractor): - """Load msg files. + """Load eml files. Args: file_path: Path to the file to load. """ - def __init__( - self, - file_path: str, - api_url: str, - ): + def __init__(self, file_path: str, api_url: str, api_key: str): """Initialize with file path.""" self._file_path = file_path self._api_url = api_url + self._api_key = api_key def extract(self) -> list[Document]: - from unstructured.partition.email import partition_email + if self._api_url: + from unstructured.partition.api import partition_via_api - elements = partition_email(filename=self._file_path) + elements = partition_via_api(filename=self._file_path, api_url=self._api_url, api_key=self._api_key) + else: + from unstructured.partition.email import partition_email + + elements = partition_email(filename=self._file_path) # noinspection PyBroadException try: diff --git a/api/core/rag/extractor/unstructured/unstructured_epub_extractor.py b/api/core/rag/extractor/unstructured/unstructured_epub_extractor.py index a41ed3a558..35220b558a 100644 --- a/api/core/rag/extractor/unstructured/unstructured_epub_extractor.py +++ b/api/core/rag/extractor/unstructured/unstructured_epub_extractor.py @@ -19,15 +19,23 @@ class UnstructuredEpubExtractor(BaseExtractor): self, file_path: str, api_url: Optional[str] = None, + api_key: Optional[str] = None, ): """Initialize with file path.""" self._file_path = file_path self._api_url = api_url + self._api_key = api_key def extract(self) -> list[Document]: - from unstructured.partition.epub import partition_epub + if self._api_url: + from unstructured.partition.api import partition_via_api + + elements = partition_via_api(filename=self._file_path, api_url=self._api_url, api_key=self._api_key) + else: + from unstructured.partition.epub import partition_epub + + elements = partition_epub(filename=self._file_path, xml_keep_tags=True) - elements = partition_epub(filename=self._file_path, xml_keep_tags=True) from unstructured.chunking.title import chunk_by_title chunks = chunk_by_title(elements, max_characters=2000, combine_text_under_n_chars=2000) diff --git a/api/core/rag/extractor/unstructured/unstructured_markdown_extractor.py b/api/core/rag/extractor/unstructured/unstructured_markdown_extractor.py index fc3ff10693..4173d4d122 100644 --- a/api/core/rag/extractor/unstructured/unstructured_markdown_extractor.py +++ b/api/core/rag/extractor/unstructured/unstructured_markdown_extractor.py @@ -24,19 +24,21 @@ class UnstructuredMarkdownExtractor(BaseExtractor): if the specified encoding fails. """ - def __init__( - self, - file_path: str, - api_url: str, - ): + def __init__(self, file_path: str, api_url: str, api_key: str): """Initialize with file path.""" self._file_path = file_path self._api_url = api_url + self._api_key = api_key def extract(self) -> list[Document]: - from unstructured.partition.md import partition_md + if self._api_url: + from unstructured.partition.api import partition_via_api - elements = partition_md(filename=self._file_path) + elements = partition_via_api(filename=self._file_path, api_url=self._api_url, api_key=self._api_key) + else: + from unstructured.partition.md import partition_md + + elements = partition_md(filename=self._file_path) from unstructured.chunking.title import chunk_by_title chunks = chunk_by_title(elements, max_characters=2000, combine_text_under_n_chars=2000) diff --git a/api/core/rag/extractor/unstructured/unstructured_msg_extractor.py b/api/core/rag/extractor/unstructured/unstructured_msg_extractor.py index 8091e83e85..57affb8d36 100644 --- a/api/core/rag/extractor/unstructured/unstructured_msg_extractor.py +++ b/api/core/rag/extractor/unstructured/unstructured_msg_extractor.py @@ -14,15 +14,21 @@ class UnstructuredMsgExtractor(BaseExtractor): file_path: Path to the file to load. """ - def __init__(self, file_path: str, api_url: str): + def __init__(self, file_path: str, api_url: str, api_key: str): """Initialize with file path.""" self._file_path = file_path self._api_url = api_url + self._api_key = api_key def extract(self) -> list[Document]: - from unstructured.partition.msg import partition_msg + if self._api_url: + from unstructured.partition.api import partition_via_api - elements = partition_msg(filename=self._file_path) + elements = partition_via_api(filename=self._file_path, api_url=self._api_url, api_key=self._api_key) + else: + from unstructured.partition.msg import partition_msg + + elements = partition_msg(filename=self._file_path) from unstructured.chunking.title import chunk_by_title chunks = chunk_by_title(elements, max_characters=2000, combine_text_under_n_chars=2000) diff --git a/api/core/rag/extractor/unstructured/unstructured_pdf_extractor.py b/api/core/rag/extractor/unstructured/unstructured_pdf_extractor.py new file mode 100644 index 0000000000..dd8a979e70 --- /dev/null +++ b/api/core/rag/extractor/unstructured/unstructured_pdf_extractor.py @@ -0,0 +1,47 @@ +import logging + +from core.rag.extractor.extractor_base import BaseExtractor +from core.rag.models.document import Document + +logger = logging.getLogger(__name__) + + +class UnstructuredPDFExtractor(BaseExtractor): + """Load pdf files. + + + Args: + file_path: Path to the file to load. + + api_url: Unstructured API URL + + api_key: Unstructured API Key + """ + + def __init__(self, file_path: str, api_url: str, api_key: str): + """Initialize with file path.""" + self._file_path = file_path + self._api_url = api_url + self._api_key = api_key + + def extract(self) -> list[Document]: + if self._api_url: + from unstructured.partition.api import partition_via_api + + elements = partition_via_api( + filename=self._file_path, api_url=self._api_url, api_key=self._api_key, strategy="auto" + ) + else: + from unstructured.partition.pdf import partition_pdf + + elements = partition_pdf(filename=self._file_path, strategy="auto") + + from unstructured.chunking.title import chunk_by_title + + chunks = chunk_by_title(elements, max_characters=2000, combine_text_under_n_chars=2000) + documents = [] + for chunk in chunks: + text = chunk.text.strip() + documents.append(Document(page_content=text)) + + return documents diff --git a/api/core/rag/extractor/unstructured/unstructured_ppt_extractor.py b/api/core/rag/extractor/unstructured/unstructured_ppt_extractor.py index b69394b3b1..0fdcd58b2e 100644 --- a/api/core/rag/extractor/unstructured/unstructured_ppt_extractor.py +++ b/api/core/rag/extractor/unstructured/unstructured_ppt_extractor.py @@ -7,7 +7,7 @@ logger = logging.getLogger(__name__) class UnstructuredPPTExtractor(BaseExtractor): - """Load msg files. + """Load ppt files. Args: @@ -21,9 +21,12 @@ class UnstructuredPPTExtractor(BaseExtractor): self._api_key = api_key def extract(self) -> list[Document]: - from unstructured.partition.api import partition_via_api + if self._api_url: + from unstructured.partition.api import partition_via_api - elements = partition_via_api(filename=self._file_path, api_url=self._api_url, api_key=self._api_key) + elements = partition_via_api(filename=self._file_path, api_url=self._api_url, api_key=self._api_key) + else: + raise NotImplementedError("Unstructured API Url is not configured") text_by_page = {} for element in elements: page = element.metadata.page_number diff --git a/api/core/rag/extractor/unstructured/unstructured_pptx_extractor.py b/api/core/rag/extractor/unstructured/unstructured_pptx_extractor.py index 6ed4a0dfb3..ab41290fbc 100644 --- a/api/core/rag/extractor/unstructured/unstructured_pptx_extractor.py +++ b/api/core/rag/extractor/unstructured/unstructured_pptx_extractor.py @@ -7,22 +7,28 @@ logger = logging.getLogger(__name__) class UnstructuredPPTXExtractor(BaseExtractor): - """Load msg files. + """Load pptx files. Args: file_path: Path to the file to load. """ - def __init__(self, file_path: str, api_url: str): + def __init__(self, file_path: str, api_url: str, api_key: str): """Initialize with file path.""" self._file_path = file_path self._api_url = api_url + self._api_key = api_key def extract(self) -> list[Document]: - from unstructured.partition.pptx import partition_pptx + if self._api_url: + from unstructured.partition.api import partition_via_api - elements = partition_pptx(filename=self._file_path) + elements = partition_via_api(filename=self._file_path, api_url=self._api_url, api_key=self._api_key) + else: + from unstructured.partition.pptx import partition_pptx + + elements = partition_pptx(filename=self._file_path) text_by_page = {} for element in elements: page = element.metadata.page_number diff --git a/api/core/rag/extractor/unstructured/unstructured_xml_extractor.py b/api/core/rag/extractor/unstructured/unstructured_xml_extractor.py index 3bffc01fbf..ef46ab0e70 100644 --- a/api/core/rag/extractor/unstructured/unstructured_xml_extractor.py +++ b/api/core/rag/extractor/unstructured/unstructured_xml_extractor.py @@ -7,22 +7,29 @@ logger = logging.getLogger(__name__) class UnstructuredXmlExtractor(BaseExtractor): - """Load msg files. + """Load xml files. Args: file_path: Path to the file to load. """ - def __init__(self, file_path: str, api_url: str): + def __init__(self, file_path: str, api_url: str, api_key: str): """Initialize with file path.""" self._file_path = file_path self._api_url = api_url + self._api_key = api_key def extract(self) -> list[Document]: - from unstructured.partition.xml import partition_xml + if self._api_url: + from unstructured.partition.api import partition_via_api + + elements = partition_via_api(filename=self._file_path, api_url=self._api_url, api_key=self._api_key) + else: + from unstructured.partition.xml import partition_xml + + elements = partition_xml(filename=self._file_path, xml_keep_tags=True) - elements = partition_xml(filename=self._file_path, xml_keep_tags=True) from unstructured.chunking.title import chunk_by_title chunks = chunk_by_title(elements, max_characters=2000, combine_text_under_n_chars=2000) diff --git a/api/poetry.lock b/api/poetry.lock index 7053afda51..02d57b12fa 100644 --- a/api/poetry.lock +++ b/api/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "aiohappyeyeballs" @@ -453,6 +453,16 @@ typing-extensions = ">=4.7,<5" bedrock = ["boto3 (>=1.28.57)", "botocore (>=1.31.57)"] vertex = ["google-auth (>=2,<3)"] +[[package]] +name = "antlr4-python3-runtime" +version = "4.9.3" +description = "ANTLR 4.9.3 runtime for Python 3.7" +optional = false +python-versions = "*" +files = [ + {file = "antlr4-python3-runtime-4.9.3.tar.gz", hash = "sha256:f224469b4168294902bb1efa80a8bf7855f24c99aef99cbefc1bcd3cce77881b"}, +] + [[package]] name = "anyio" version = "4.6.2.post1" @@ -553,13 +563,13 @@ cryptography = "*" [[package]] name = "azure-ai-inference" -version = "1.0.0b4" +version = "1.0.0b5" description = "Microsoft Azure Ai Inference Client Library for Python" optional = false python-versions = ">=3.8" files = [ - {file = "azure-ai-inference-1.0.0b4.tar.gz", hash = "sha256:5464404bef337338d4af6eefde3af903400ddb8e5c9e6820f902303542fa0f72"}, - {file = "azure_ai_inference-1.0.0b4-py3-none-any.whl", hash = "sha256:e2c949f91845a8cd96cb9a61ffd432b5b0f4ce236b9be8c29d10f38e0a327412"}, + {file = "azure_ai_inference-1.0.0b5-py3-none-any.whl", hash = "sha256:0147653088033f1fd059d5f4bd0fedac82529fdcc7a0d2183d9508b3f80cf549"}, + {file = "azure_ai_inference-1.0.0b5.tar.gz", hash = "sha256:c95b490bcd670ccdeb1048dc2b45e0f8252a4d69a348ca15d4510d327b64dd0d"}, ] [package.dependencies] @@ -567,6 +577,9 @@ azure-core = ">=1.30.0" isodate = ">=0.6.1" typing-extensions = ">=4.6.0" +[package.extras] +opentelemetry = ["azure-core-tracing-opentelemetry"] + [[package]] name = "azure-ai-ml" version = "1.20.0" @@ -844,13 +857,13 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] [[package]] name = "botocore" -version = "1.35.40" +version = "1.35.46" description = "Low-level, data-driven core of boto 3." optional = false python-versions = ">=3.8" files = [ - {file = "botocore-1.35.40-py3-none-any.whl", hash = "sha256:072cc47f29cb1de4fa77ce6632e4f0480af29b70816973ff415fbaa3f50bd1db"}, - {file = "botocore-1.35.40.tar.gz", hash = "sha256:547e0a983856c7d7aeaa30fca2a283873c57c07366cd806d2d639856341b3c31"}, + {file = "botocore-1.35.46-py3-none-any.whl", hash = "sha256:8bbc9a55cae65a8db7f2e33ff087f4dbfc13fce868e8e3c5273ce9af367a555a"}, + {file = "botocore-1.35.46.tar.gz", hash = "sha256:8c0ff5fdd611a28f5752189d171c69690dbc484fa06d74376890bb0543ec3dc1"}, ] [package.dependencies] @@ -863,47 +876,47 @@ crt = ["awscrt (==0.22.0)"] [[package]] name = "bottleneck" -version = "1.4.1" +version = "1.4.2" description = "Fast NumPy array functions written in C" optional = false -python-versions = "*" +python-versions = ">=3.9" files = [ - {file = "Bottleneck-1.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5be5fc34f03216d85f14d01ca12c857ee68f72d7c17dccd22743326200ba3b9f"}, - {file = "Bottleneck-1.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f44cc6ad1a44d3427009fa2c2298ef0b346b7024e30dc7fc9778f5b78f8c10c"}, - {file = "Bottleneck-1.4.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e5babe835350e9f8710b3f8ffb9d5d202b4b13d77bad0e0f9a395af16a55f36"}, - {file = "Bottleneck-1.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:d22a9b4d9cef8bb218df15a13d4aa213042c434c595d5c732d7f4ad287dbe565"}, - {file = "Bottleneck-1.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f47cb74ad6675dc7a54ef9f6fa9e649134e98ba71e6c98b8a34054e48014c941"}, - {file = "Bottleneck-1.4.1-cp310-cp310-win32.whl", hash = "sha256:3a4acf90714de7783f4706eb19d42f4d32ac842082c7b42d6956530ef0884b19"}, - {file = "Bottleneck-1.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:54d60a44bf439c06d35c6c3abdb39aca3de330064c48922a6bad0a96b1f096d5"}, - {file = "Bottleneck-1.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d491dad4757e9bed4204b3b823dfe9996733e11fbd9d3abaec52329a30a02bcc"}, - {file = "Bottleneck-1.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c9186982d57db422641f30a30201fc7b158166887ca803c2af975cab6c9febb7"}, - {file = "Bottleneck-1.4.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59e5bdff742067f10c7fda48e981e4b50ba7c7f39f8627e8c9a1c7224457badd"}, - {file = "Bottleneck-1.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ab6086ced21414288a5b79a00fe359d463a3189f82b5a71adce931655ba93c2"}, - {file = "Bottleneck-1.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:359d3a08e7c1a0938b07d6117cab8b38d4140df6712fbe56491ad44f46878d2f"}, - {file = "Bottleneck-1.4.1-cp311-cp311-win32.whl", hash = "sha256:bb642a652e656a20ea239d241aa2c39e0e3d3882aacea7d3f8412d9ec7a5f185"}, - {file = "Bottleneck-1.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:bd89930c0375799aaf381a2a2924ca53a17ef84734d9e1a5763da7eb4499e53d"}, - {file = "Bottleneck-1.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:32a0e516a66a0d048e993bc926aa878208e8db549d30e39bef7b933a81dcad26"}, - {file = "Bottleneck-1.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1be7a1589a553ce6575d77a0ae3404b4a0a69c647e1cda85e41f388a61c1210d"}, - {file = "Bottleneck-1.4.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:845e2975704c1e40cd27a3d1d3eb45af031e7f25edf826577dbedab33bf1674e"}, - {file = "Bottleneck-1.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:fea946c0fed796b62ddd812ea6533d2733d7a070383236a0d9ba585e66619c30"}, - {file = "Bottleneck-1.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:23e16efc311df996321fde53537815acca26dca731395d9e6da36e743fc0d27f"}, - {file = "Bottleneck-1.4.1-cp312-cp312-win32.whl", hash = "sha256:75ab6c9daed8528f9f0f37efb9f15d0b9759b8902325abcfd38cb79126c76db4"}, - {file = "Bottleneck-1.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:7ce544479354ef3893c04b8f135b454c126cc236907879f552422855de5df35d"}, - {file = "Bottleneck-1.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:681e8889170d349bed1a7c30a4b32ba25f6988e1432217a91967fd7a5a963d7d"}, - {file = "Bottleneck-1.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d774d69ed3ba968b9b2e5271b14d013f85b820612ec4dbd8f0a32f23a07c6d77"}, - {file = "Bottleneck-1.4.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d0a0be22fa01c2698ff746a4e1e27238acd18409a353e2c7172b0e50b2f04a9"}, - {file = "Bottleneck-1.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:eb39b78f99304f174338c486a015d490707374a0c349167ba6ade7b6d3484304"}, - {file = "Bottleneck-1.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:052fcc86f5713a3192f3ce0a4f950c2ff451df8c43c9d0291e7c4bd624ae1292"}, - {file = "Bottleneck-1.4.1-cp313-cp313-win32.whl", hash = "sha256:cbcc5e36ba50a50d5d8084e2772008b33b9507d06c2c1642c8e2299709439881"}, - {file = "Bottleneck-1.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:3e36a7ab42bc0f1e2508f1c33308fb08c8454edc4694164ee8fdd46918adea03"}, - {file = "Bottleneck-1.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f12ab7f52881065323ac4ac1f8fd424cf5ecde0d9c0746945fb6e8b1a5cbfcac"}, - {file = "Bottleneck-1.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a76155466718066fcfb77329b29be71d1bce679b1a7daf693a7a08fbf42577b8"}, - {file = "Bottleneck-1.4.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cde4981d889f41f175a054ad5c3434b81ee8749f31b6e7b9ec92776ec4f7292f"}, - {file = "Bottleneck-1.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:351ddfedc51c2575c90d43a03e350bdc00020e219dfa877480df2b69dbc31eab"}, - {file = "Bottleneck-1.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:98032a0efb2a4f46223645600f53cb9f7c50dbec8c146e2869585dc9f81fa0ea"}, - {file = "Bottleneck-1.4.1-cp39-cp39-win32.whl", hash = "sha256:ddc2218dc8e8b626d1645e57596bc353559facb99c362c9ba5eb6d5b4a12d5fc"}, - {file = "Bottleneck-1.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:d6f275a727a59c27897e3e29dabde4d8af299fcfc667f13a9b00fd2a1ab72178"}, - {file = "bottleneck-1.4.1.tar.gz", hash = "sha256:58c66619db62291c9ca3b497b05f40f7b1ff9ac010b88bff1925f3101dae2c89"}, + {file = "Bottleneck-1.4.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:125436df93751a226eab1732783aa8f6125e88e779587aa61be071fb66e41f9d"}, + {file = "Bottleneck-1.4.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c6df9a60ec6ab88fec934ca864266ba95edd89c490af71dc9cd8afb2a54ebd9"}, + {file = "Bottleneck-1.4.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e2fe327dc2d0564e295a5857a252755103f8c6e05b07d3ff80a69afaa9f5065"}, + {file = "Bottleneck-1.4.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:6b7790ca8658cd69e3cc0d0e4ff0e9829d60849bf7945fbd7344fbce05b2bbb8"}, + {file = "Bottleneck-1.4.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:6282fa925ac3768f66e3547f89a512376d3f9de7ef53bdd37aa29232fd864054"}, + {file = "Bottleneck-1.4.2-cp310-cp310-win32.whl", hash = "sha256:e56a206fbf48e3b8054a964398bf1ed843e9625d3c6bdbeb7898cb48bf97441b"}, + {file = "Bottleneck-1.4.2-cp310-cp310-win_amd64.whl", hash = "sha256:eb0c611d15b0fd8f511d288e8964e4725b4b3b0d9d310880cf0ff6b8dd03c859"}, + {file = "Bottleneck-1.4.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b6902ebf3e85315b481bc084f10c5770f8240275ad1e039ac69c7c8d2013b040"}, + {file = "Bottleneck-1.4.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c2fd34b9b490204f95288f0dd35d37042486a95029617246c88c0f94a0ab49fe"}, + {file = "Bottleneck-1.4.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:122845e3106c85465551d4a9a3777841347cfedfbebb3aa985cca110e07030b1"}, + {file = "Bottleneck-1.4.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1f61658ebdf5a178298544336b65020730bf86cc092dab5f6579a99a86bd888b"}, + {file = "Bottleneck-1.4.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7c7d29c044a3511b36fd744503c3e697e279c273a8477a6d91a2831d04fd19e0"}, + {file = "Bottleneck-1.4.2-cp311-cp311-win32.whl", hash = "sha256:c663cbba8f52011fd82ee08c6a85c93b34b19e0e7ebba322d2d67809f34e0597"}, + {file = "Bottleneck-1.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:89651ef18c06616850203bf8875c958c5d316ea48d8ba60d9b450199d39ae391"}, + {file = "Bottleneck-1.4.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a74ddd0417f42eeaba37375f0fc065b28451e0fba45cb2f99e88880b10b3fa43"}, + {file = "Bottleneck-1.4.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:070d22f2f62ab81297380a89492cca931e4d9443fa4b84c2baeb52db09c3b1b4"}, + {file = "Bottleneck-1.4.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1fc4e7645bd425c05e05acd5541e9e09cb4179e71164e862f082561bf4509eac"}, + {file = "Bottleneck-1.4.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:037315c56605128a39f77d19af6a6019dc8c21a63694a4bfef3c026ed963be2e"}, + {file = "Bottleneck-1.4.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:99778329331d5fae8df19772a019e8b73ba4d9d1650f110cd995ab7657114db0"}, + {file = "Bottleneck-1.4.2-cp312-cp312-win32.whl", hash = "sha256:7363b3c8ce6ca433779cd7e96bcb94c0e516dcacadff0011adcbf0b3ac86bc9d"}, + {file = "Bottleneck-1.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:48c6b9d9287c4102b803fcb01ae66ae7ef6b310b711b4b7b7e23bf952894dc05"}, + {file = "Bottleneck-1.4.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c1c885ad02a6a8fa1f7ee9099f29b9d4c03eb1da2c7ab25839482d5cce739021"}, + {file = "Bottleneck-1.4.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7a1b023de1de3d84b18826462718fba548fed41870df44354f9ab6a414ea82f"}, + {file = "Bottleneck-1.4.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c9dbaf737b605b30c81611f2c1d197c2fd2e46c33f605876c1d332d3360c4fc"}, + {file = "Bottleneck-1.4.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:7ebbcbe5d4062e37507b9a81e2aacdb1fcccc6193f7feff124ef2b5a6a5eb740"}, + {file = "Bottleneck-1.4.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:964f6ac4118ddab3bbbac79d4f726b093459be751baba73ee0aa364666e8068e"}, + {file = "Bottleneck-1.4.2-cp313-cp313-win32.whl", hash = "sha256:2db287f6ecdbb1c998085eca9b717fec2bfc48a4ab6ae070a9820ba8ab59c90b"}, + {file = "Bottleneck-1.4.2-cp313-cp313-win_amd64.whl", hash = "sha256:26b5f0531f7044befaad95c20365dd666372e66bdacbfaf009ff65d60285534d"}, + {file = "Bottleneck-1.4.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:72d6aa95cdd782833d2589f81434fd865ba004b8938e07920b6ef02796ce8918"}, + {file = "Bottleneck-1.4.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b33e83665e7daf7f513fe1f7b04b13944d44b6635c45d5a9c89c9e5ed11811b6"}, + {file = "Bottleneck-1.4.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:52248f3e0fead78c17912fb086a585c86f567019247d21c69e87645241b97b02"}, + {file = "Bottleneck-1.4.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:dce1a3c5ff89a56fb2678c9bda17b89f60f710d6002ab7cd72b7661bc3fae64d"}, + {file = "Bottleneck-1.4.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:48d2e101d99a9d72aa86da1a048d2094f4e1db0cf77519d1c33239f9d62da162"}, + {file = "Bottleneck-1.4.2-cp39-cp39-win32.whl", hash = "sha256:9d7b12936516f944e3d981a64038f99acb21f0e99f92fad16d9a468248c2b231"}, + {file = "Bottleneck-1.4.2-cp39-cp39-win_amd64.whl", hash = "sha256:7b459d08f1f3e2da85db0a9e2d3e6e3541105f5866e9026dbca32dafc5106f2b"}, + {file = "bottleneck-1.4.2.tar.gz", hash = "sha256:fa8e8e1799dea5483ce6669462660f9d9a95649f6f98a80d315b84ec89f449f4"}, ] [package.dependencies] @@ -929,10 +942,6 @@ files = [ {file = "Brotli-1.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a37b8f0391212d29b3a91a799c8e4a2855e0576911cdfb2515487e30e322253d"}, {file = "Brotli-1.1.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e84799f09591700a4154154cab9787452925578841a94321d5ee8fb9a9a328f0"}, {file = "Brotli-1.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f66b5337fa213f1da0d9000bc8dc0cb5b896b726eefd9c6046f699b169c41b9e"}, - {file = "Brotli-1.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5dab0844f2cf82be357a0eb11a9087f70c5430b2c241493fc122bb6f2bb0917c"}, - {file = "Brotli-1.1.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e4fe605b917c70283db7dfe5ada75e04561479075761a0b3866c081d035b01c1"}, - {file = "Brotli-1.1.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:1e9a65b5736232e7a7f91ff3d02277f11d339bf34099a56cdab6a8b3410a02b2"}, - {file = "Brotli-1.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:58d4b711689366d4a03ac7957ab8c28890415e267f9b6589969e74b6e42225ec"}, {file = "Brotli-1.1.0-cp310-cp310-win32.whl", hash = "sha256:be36e3d172dc816333f33520154d708a2657ea63762ec16b62ece02ab5e4daf2"}, {file = "Brotli-1.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:0c6244521dda65ea562d5a69b9a26120769b7a9fb3db2fe9545935ed6735b128"}, {file = "Brotli-1.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a3daabb76a78f829cafc365531c972016e4aa8d5b4bf60660ad8ecee19df7ccc"}, @@ -945,14 +954,8 @@ files = [ {file = "Brotli-1.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:19c116e796420b0cee3da1ccec3b764ed2952ccfcc298b55a10e5610ad7885f9"}, {file = "Brotli-1.1.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:510b5b1bfbe20e1a7b3baf5fed9e9451873559a976c1a78eebaa3b86c57b4265"}, {file = "Brotli-1.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a1fd8a29719ccce974d523580987b7f8229aeace506952fa9ce1d53a033873c8"}, - {file = "Brotli-1.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c247dd99d39e0338a604f8c2b3bc7061d5c2e9e2ac7ba9cc1be5a69cb6cd832f"}, - {file = "Brotli-1.1.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1b2c248cd517c222d89e74669a4adfa5577e06ab68771a529060cf5a156e9757"}, - {file = "Brotli-1.1.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:2a24c50840d89ded6c9a8fdc7b6ed3692ed4e86f1c4a4a938e1e92def92933e0"}, - {file = "Brotli-1.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f31859074d57b4639318523d6ffdca586ace54271a73ad23ad021acd807eb14b"}, {file = "Brotli-1.1.0-cp311-cp311-win32.whl", hash = "sha256:39da8adedf6942d76dc3e46653e52df937a3c4d6d18fdc94a7c29d263b1f5b50"}, {file = "Brotli-1.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:aac0411d20e345dc0920bdec5548e438e999ff68d77564d5e9463a7ca9d3e7b1"}, - {file = "Brotli-1.1.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:32d95b80260d79926f5fab3c41701dbb818fde1c9da590e77e571eefd14abe28"}, - {file = "Brotli-1.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b760c65308ff1e462f65d69c12e4ae085cff3b332d894637f6273a12a482d09f"}, {file = "Brotli-1.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:316cc9b17edf613ac76b1f1f305d2a748f1b976b033b049a6ecdfd5612c70409"}, {file = "Brotli-1.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:caf9ee9a5775f3111642d33b86237b05808dafcd6268faa492250e9b78046eb2"}, {file = "Brotli-1.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70051525001750221daa10907c77830bc889cb6d865cc0b813d9db7fefc21451"}, @@ -963,24 +966,8 @@ files = [ {file = "Brotli-1.1.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:4093c631e96fdd49e0377a9c167bfd75b6d0bad2ace734c6eb20b348bc3ea180"}, {file = "Brotli-1.1.0-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:7e4c4629ddad63006efa0ef968c8e4751c5868ff0b1c5c40f76524e894c50248"}, {file = "Brotli-1.1.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:861bf317735688269936f755fa136a99d1ed526883859f86e41a5d43c61d8966"}, - {file = "Brotli-1.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:87a3044c3a35055527ac75e419dfa9f4f3667a1e887ee80360589eb8c90aabb9"}, - {file = "Brotli-1.1.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:c5529b34c1c9d937168297f2c1fde7ebe9ebdd5e121297ff9c043bdb2ae3d6fb"}, - {file = "Brotli-1.1.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:ca63e1890ede90b2e4454f9a65135a4d387a4585ff8282bb72964fab893f2111"}, - {file = "Brotli-1.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e79e6520141d792237c70bcd7a3b122d00f2613769ae0cb61c52e89fd3443839"}, {file = "Brotli-1.1.0-cp312-cp312-win32.whl", hash = "sha256:5f4d5ea15c9382135076d2fb28dde923352fe02951e66935a9efaac8f10e81b0"}, {file = "Brotli-1.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:906bc3a79de8c4ae5b86d3d75a8b77e44404b0f4261714306e3ad248d8ab0951"}, - {file = "Brotli-1.1.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8bf32b98b75c13ec7cf774164172683d6e7891088f6316e54425fde1efc276d5"}, - {file = "Brotli-1.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7bc37c4d6b87fb1017ea28c9508b36bbcb0c3d18b4260fcdf08b200c74a6aee8"}, - {file = "Brotli-1.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c0ef38c7a7014ffac184db9e04debe495d317cc9c6fb10071f7fefd93100a4f"}, - {file = "Brotli-1.1.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91d7cc2a76b5567591d12c01f019dd7afce6ba8cba6571187e21e2fc418ae648"}, - {file = "Brotli-1.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a93dde851926f4f2678e704fadeb39e16c35d8baebd5252c9fd94ce8ce68c4a0"}, - {file = "Brotli-1.1.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f0db75f47be8b8abc8d9e31bc7aad0547ca26f24a54e6fd10231d623f183d089"}, - {file = "Brotli-1.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6967ced6730aed543b8673008b5a391c3b1076d834ca438bbd70635c73775368"}, - {file = "Brotli-1.1.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:7eedaa5d036d9336c95915035fb57422054014ebdeb6f3b42eac809928e40d0c"}, - {file = "Brotli-1.1.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:d487f5432bf35b60ed625d7e1b448e2dc855422e87469e3f450aa5552b0eb284"}, - {file = "Brotli-1.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:832436e59afb93e1836081a20f324cb185836c617659b07b129141a8426973c7"}, - {file = "Brotli-1.1.0-cp313-cp313-win32.whl", hash = "sha256:43395e90523f9c23a3d5bdf004733246fba087f2948f87ab28015f12359ca6a0"}, - {file = "Brotli-1.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:9011560a466d2eb3f5a6e4929cf4a09be405c64154e12df0dd72713f6500e32b"}, {file = "Brotli-1.1.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:a090ca607cbb6a34b0391776f0cb48062081f5f60ddcce5d11838e67a01928d1"}, {file = "Brotli-1.1.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2de9d02f5bda03d27ede52e8cfe7b865b066fa49258cbab568720aa5be80a47d"}, {file = "Brotli-1.1.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2333e30a5e00fe0fe55903c8832e08ee9c3b1382aacf4db26664a16528d51b4b"}, @@ -990,10 +977,6 @@ files = [ {file = "Brotli-1.1.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:fd5f17ff8f14003595ab414e45fce13d073e0762394f957182e69035c9f3d7c2"}, {file = "Brotli-1.1.0-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:069a121ac97412d1fe506da790b3e69f52254b9df4eb665cd42460c837193354"}, {file = "Brotli-1.1.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:e93dfc1a1165e385cc8239fab7c036fb2cd8093728cbd85097b284d7b99249a2"}, - {file = "Brotli-1.1.0-cp36-cp36m-musllinux_1_2_aarch64.whl", hash = "sha256:aea440a510e14e818e67bfc4027880e2fb500c2ccb20ab21c7a7c8b5b4703d75"}, - {file = "Brotli-1.1.0-cp36-cp36m-musllinux_1_2_i686.whl", hash = "sha256:6974f52a02321b36847cd19d1b8e381bf39939c21efd6ee2fc13a28b0d99348c"}, - {file = "Brotli-1.1.0-cp36-cp36m-musllinux_1_2_ppc64le.whl", hash = "sha256:a7e53012d2853a07a4a79c00643832161a910674a893d296c9f1259859a289d2"}, - {file = "Brotli-1.1.0-cp36-cp36m-musllinux_1_2_x86_64.whl", hash = "sha256:d7702622a8b40c49bffb46e1e3ba2e81268d5c04a34f460978c6b5517a34dd52"}, {file = "Brotli-1.1.0-cp36-cp36m-win32.whl", hash = "sha256:a599669fd7c47233438a56936988a2478685e74854088ef5293802123b5b2460"}, {file = "Brotli-1.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:d143fd47fad1db3d7c27a1b1d66162e855b5d50a89666af46e1679c496e8e579"}, {file = "Brotli-1.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:11d00ed0a83fa22d29bc6b64ef636c4552ebafcef57154b4ddd132f5638fbd1c"}, @@ -1005,10 +988,6 @@ files = [ {file = "Brotli-1.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:919e32f147ae93a09fe064d77d5ebf4e35502a8df75c29fb05788528e330fe74"}, {file = "Brotli-1.1.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:23032ae55523cc7bccb4f6a0bf368cd25ad9bcdcc1990b64a647e7bbcce9cb5b"}, {file = "Brotli-1.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:224e57f6eac61cc449f498cc5f0e1725ba2071a3d4f48d5d9dffba42db196438"}, - {file = "Brotli-1.1.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:cb1dac1770878ade83f2ccdf7d25e494f05c9165f5246b46a621cc849341dc01"}, - {file = "Brotli-1.1.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:3ee8a80d67a4334482d9712b8e83ca6b1d9bc7e351931252ebef5d8f7335a547"}, - {file = "Brotli-1.1.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:5e55da2c8724191e5b557f8e18943b1b4839b8efc3ef60d65985bcf6f587dd38"}, - {file = "Brotli-1.1.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:d342778ef319e1026af243ed0a07c97acf3bad33b9f29e7ae6a1f68fd083e90c"}, {file = "Brotli-1.1.0-cp37-cp37m-win32.whl", hash = "sha256:587ca6d3cef6e4e868102672d3bd9dc9698c309ba56d41c2b9c85bbb903cdb95"}, {file = "Brotli-1.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:2954c1c23f81c2eaf0b0717d9380bd348578a94161a65b3a2afc62c86467dd68"}, {file = "Brotli-1.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:efa8b278894b14d6da122a72fefcebc28445f2d3f880ac59d46c90f4c13be9a3"}, @@ -1021,10 +1000,6 @@ files = [ {file = "Brotli-1.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ab4fbee0b2d9098c74f3057b2bc055a8bd92ccf02f65944a241b4349229185a"}, {file = "Brotli-1.1.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:141bd4d93984070e097521ed07e2575b46f817d08f9fa42b16b9b5f27b5ac088"}, {file = "Brotli-1.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fce1473f3ccc4187f75b4690cfc922628aed4d3dd013d047f95a9b3919a86596"}, - {file = "Brotli-1.1.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d2b35ca2c7f81d173d2fadc2f4f31e88cc5f7a39ae5b6db5513cf3383b0e0ec7"}, - {file = "Brotli-1.1.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:af6fa6817889314555aede9a919612b23739395ce767fe7fcbea9a80bf140fe5"}, - {file = "Brotli-1.1.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:2feb1d960f760a575dbc5ab3b1c00504b24caaf6986e2dc2b01c09c87866a943"}, - {file = "Brotli-1.1.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:4410f84b33374409552ac9b6903507cdb31cd30d2501fc5ca13d18f73548444a"}, {file = "Brotli-1.1.0-cp38-cp38-win32.whl", hash = "sha256:db85ecf4e609a48f4b29055f1e144231b90edc90af7481aa731ba2d059226b1b"}, {file = "Brotli-1.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:3d7954194c36e304e1523f55d7042c59dc53ec20dd4e9ea9d151f1b62b4415c0"}, {file = "Brotli-1.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5fb2ce4b8045c78ebbc7b8f3c15062e435d47e7393cc57c25115cfd49883747a"}, @@ -1037,10 +1012,6 @@ files = [ {file = "Brotli-1.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:949f3b7c29912693cee0afcf09acd6ebc04c57af949d9bf77d6101ebb61e388c"}, {file = "Brotli-1.1.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:89f4988c7203739d48c6f806f1e87a1d96e0806d44f0fba61dba81392c9e474d"}, {file = "Brotli-1.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:de6551e370ef19f8de1807d0a9aa2cdfdce2e85ce88b122fe9f6b2b076837e59"}, - {file = "Brotli-1.1.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0737ddb3068957cf1b054899b0883830bb1fec522ec76b1098f9b6e0f02d9419"}, - {file = "Brotli-1.1.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:4f3607b129417e111e30637af1b56f24f7a49e64763253bbc275c75fa887d4b2"}, - {file = "Brotli-1.1.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:6c6e0c425f22c1c719c42670d561ad682f7bfeeef918edea971a79ac5252437f"}, - {file = "Brotli-1.1.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:494994f807ba0b92092a163a0a283961369a65f6cbe01e8891132b7a320e61eb"}, {file = "Brotli-1.1.0-cp39-cp39-win32.whl", hash = "sha256:f0d8a7a6b5983c2496e364b969f0e526647a06b075d034f3297dc66f3b360c64"}, {file = "Brotli-1.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:cdad5b9014d83ca68c25d2e9444e28e967ef16e80f6b436918c700c117a85467"}, {file = "Brotli-1.1.0.tar.gz", hash = "sha256:81de08ac11bcb85841e440c13611c00b67d3bf82698314928d0b676362546724"}, @@ -1924,38 +1895,38 @@ files = [ [[package]] name = "cryptography" -version = "43.0.1" +version = "43.0.3" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." optional = false python-versions = ">=3.7" files = [ - {file = "cryptography-43.0.1-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:8385d98f6a3bf8bb2d65a73e17ed87a3ba84f6991c155691c51112075f9ffc5d"}, - {file = "cryptography-43.0.1-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27e613d7077ac613e399270253259d9d53872aaf657471473ebfc9a52935c062"}, - {file = "cryptography-43.0.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68aaecc4178e90719e95298515979814bda0cbada1256a4485414860bd7ab962"}, - {file = "cryptography-43.0.1-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:de41fd81a41e53267cb020bb3a7212861da53a7d39f863585d13ea11049cf277"}, - {file = "cryptography-43.0.1-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f98bf604c82c416bc829e490c700ca1553eafdf2912a91e23a79d97d9801372a"}, - {file = "cryptography-43.0.1-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:61ec41068b7b74268fa86e3e9e12b9f0c21fcf65434571dbb13d954bceb08042"}, - {file = "cryptography-43.0.1-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:014f58110f53237ace6a408b5beb6c427b64e084eb451ef25a28308270086494"}, - {file = "cryptography-43.0.1-cp37-abi3-win32.whl", hash = "sha256:2bd51274dcd59f09dd952afb696bf9c61a7a49dfc764c04dd33ef7a6b502a1e2"}, - {file = "cryptography-43.0.1-cp37-abi3-win_amd64.whl", hash = "sha256:666ae11966643886c2987b3b721899d250855718d6d9ce41b521252a17985f4d"}, - {file = "cryptography-43.0.1-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:ac119bb76b9faa00f48128b7f5679e1d8d437365c5d26f1c2c3f0da4ce1b553d"}, - {file = "cryptography-43.0.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bbcce1a551e262dfbafb6e6252f1ae36a248e615ca44ba302df077a846a8806"}, - {file = "cryptography-43.0.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58d4e9129985185a06d849aa6df265bdd5a74ca6e1b736a77959b498e0505b85"}, - {file = "cryptography-43.0.1-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:d03a475165f3134f773d1388aeb19c2d25ba88b6a9733c5c590b9ff7bbfa2e0c"}, - {file = "cryptography-43.0.1-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:511f4273808ab590912a93ddb4e3914dfd8a388fed883361b02dea3791f292e1"}, - {file = "cryptography-43.0.1-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:80eda8b3e173f0f247f711eef62be51b599b5d425c429b5d4ca6a05e9e856baa"}, - {file = "cryptography-43.0.1-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:38926c50cff6f533f8a2dae3d7f19541432610d114a70808f0926d5aaa7121e4"}, - {file = "cryptography-43.0.1-cp39-abi3-win32.whl", hash = "sha256:a575913fb06e05e6b4b814d7f7468c2c660e8bb16d8d5a1faf9b33ccc569dd47"}, - {file = "cryptography-43.0.1-cp39-abi3-win_amd64.whl", hash = "sha256:d75601ad10b059ec832e78823b348bfa1a59f6b8d545db3a24fd44362a1564cb"}, - {file = "cryptography-43.0.1-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ea25acb556320250756e53f9e20a4177515f012c9eaea17eb7587a8c4d8ae034"}, - {file = "cryptography-43.0.1-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c1332724be35d23a854994ff0b66530119500b6053d0bd3363265f7e5e77288d"}, - {file = "cryptography-43.0.1-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:fba1007b3ef89946dbbb515aeeb41e30203b004f0b4b00e5e16078b518563289"}, - {file = "cryptography-43.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:5b43d1ea6b378b54a1dc99dd8a2b5be47658fe9a7ce0a58ff0b55f4b43ef2b84"}, - {file = "cryptography-43.0.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:88cce104c36870d70c49c7c8fd22885875d950d9ee6ab54df2745f83ba0dc365"}, - {file = "cryptography-43.0.1-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:9d3cdb25fa98afdd3d0892d132b8d7139e2c087da1712041f6b762e4f807cc96"}, - {file = "cryptography-43.0.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e710bf40870f4db63c3d7d929aa9e09e4e7ee219e703f949ec4073b4294f6172"}, - {file = "cryptography-43.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7c05650fe8023c5ed0d46793d4b7d7e6cd9c04e68eabe5b0aeea836e37bdcec2"}, - {file = "cryptography-43.0.1.tar.gz", hash = "sha256:203e92a75716d8cfb491dc47c79e17d0d9207ccffcbcb35f598fbe463ae3444d"}, + {file = "cryptography-43.0.3-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:bf7a1932ac4176486eab36a19ed4c0492da5d97123f1406cf15e41b05e787d2e"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63efa177ff54aec6e1c0aefaa1a241232dcd37413835a9b674b6e3f0ae2bfd3e"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e1ce50266f4f70bf41a2c6dc4358afadae90e2a1e5342d3c08883df1675374f"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:443c4a81bb10daed9a8f334365fe52542771f25aedaf889fd323a853ce7377d6"}, + {file = "cryptography-43.0.3-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:74f57f24754fe349223792466a709f8e0c093205ff0dca557af51072ff47ab18"}, + {file = "cryptography-43.0.3-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9762ea51a8fc2a88b70cf2995e5675b38d93bf36bd67d91721c309df184f49bd"}, + {file = "cryptography-43.0.3-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:81ef806b1fef6b06dcebad789f988d3b37ccaee225695cf3e07648eee0fc6b73"}, + {file = "cryptography-43.0.3-cp37-abi3-win32.whl", hash = "sha256:cbeb489927bd7af4aa98d4b261af9a5bc025bd87f0e3547e11584be9e9427be2"}, + {file = "cryptography-43.0.3-cp37-abi3-win_amd64.whl", hash = "sha256:f46304d6f0c6ab8e52770addfa2fc41e6629495548862279641972b6215451cd"}, + {file = "cryptography-43.0.3-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:8ac43ae87929a5982f5948ceda07001ee5e83227fd69cf55b109144938d96984"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:846da004a5804145a5f441b8530b4bf35afbf7da70f82409f151695b127213d5"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f996e7268af62598f2fc1204afa98a3b5712313a55c4c9d434aef49cadc91d4"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f7b178f11ed3664fd0e995a47ed2b5ff0a12d893e41dd0494f406d1cf555cab7"}, + {file = "cryptography-43.0.3-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405"}, + {file = "cryptography-43.0.3-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e1be4655c7ef6e1bbe6b5d0403526601323420bcf414598955968c9ef3eb7d16"}, + {file = "cryptography-43.0.3-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:df6b6c6d742395dd77a23ea3728ab62f98379eff8fb61be2744d4679ab678f73"}, + {file = "cryptography-43.0.3-cp39-abi3-win32.whl", hash = "sha256:d56e96520b1020449bbace2b78b603442e7e378a9b3bd68de65c782db1507995"}, + {file = "cryptography-43.0.3-cp39-abi3-win_amd64.whl", hash = "sha256:0c580952eef9bf68c4747774cde7ec1d85a6e61de97281f2dba83c7d2c806362"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d03b5621a135bffecad2c73e9f4deb1a0f977b9a8ffe6f8e002bf6c9d07b918c"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:a2a431ee15799d6db9fe80c82b055bae5a752bef645bba795e8e52687c69efe3"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:281c945d0e28c92ca5e5930664c1cefd85efe80e5c0d2bc58dd63383fda29f83"}, + {file = "cryptography-43.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:f18c716be16bc1fea8e95def49edf46b82fccaa88587a45f8dc0ff6ab5d8e0a7"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:4a02ded6cd4f0a5562a8887df8b3bd14e822a90f97ac5e544c162899bc467664"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:53a583b6637ab4c4e3591a15bc9db855b8d9dee9a669b550f311480acab6eb08"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1ec0bcf7e17c0c5669d881b1cd38c4972fade441b27bda1051665faaa89bdcaa"}, + {file = "cryptography-43.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2ce6fae5bdad59577b44e4dfed356944fbf1d925269114c28be377692643b4ff"}, + {file = "cryptography-43.0.3.tar.gz", hash = "sha256:315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805"}, ] [package.dependencies] @@ -1968,7 +1939,7 @@ nox = ["nox"] pep8test = ["check-sdist", "click", "mypy", "ruff"] sdist = ["build"] ssh = ["bcrypt (>=3.1.5)"] -test = ["certifi", "cryptography-vectors (==43.0.1)", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] +test = ["certifi", "cryptography-vectors (==43.0.3)", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] test-randomorder = ["pytest-randomly"] [[package]] @@ -2256,18 +2227,18 @@ files = [ [[package]] name = "duckduckgo-search" -version = "6.3.0" +version = "6.3.2" description = "Search for words, documents, images, news, maps and text translation using the DuckDuckGo.com search engine." optional = false python-versions = ">=3.8" files = [ - {file = "duckduckgo_search-6.3.0-py3-none-any.whl", hash = "sha256:9a231a7b325226811cf7d35a240f3f501e718ae10a1aa0a638cabc80e129dfe7"}, - {file = "duckduckgo_search-6.3.0.tar.gz", hash = "sha256:e9f56955569325a7d9cacda2488ca78bf6629a459e74415892bee560b664f5eb"}, + {file = "duckduckgo_search-6.3.2-py3-none-any.whl", hash = "sha256:cd631275292460d590d1d496995d002bf2fe6db9752713fab17b9e95924ced98"}, + {file = "duckduckgo_search-6.3.2.tar.gz", hash = "sha256:53dbf45f8749bfc67483eb9f281f2e722a5fe644d61c54ed9e551d26cb6bcbf2"}, ] [package.dependencies] click = ">=8.1.7" -primp = ">=0.6.3" +primp = ">=0.6.4" [package.extras] dev = ["mypy (>=1.11.1)", "pytest (>=8.3.1)", "pytest-asyncio (>=0.23.8)", "ruff (>=0.6.1)"] @@ -2284,6 +2255,24 @@ files = [ {file = "durationpy-0.9.tar.gz", hash = "sha256:fd3feb0a69a0057d582ef643c355c40d2fa1c942191f914d12203b1a01ac722a"}, ] +[[package]] +name = "effdet" +version = "0.4.1" +description = "EfficientDet for PyTorch" +optional = false +python-versions = ">=3.7" +files = [ + {file = "effdet-0.4.1-py3-none-any.whl", hash = "sha256:10889a226228d515c948e3fcf811e64c0d78d7aa94823a300045653b9c284cb7"}, + {file = "effdet-0.4.1.tar.gz", hash = "sha256:ac5589fd304a5650c201986b2ef5f8e10c111093a71b1c49fa6b8817710812b5"}, +] + +[package.dependencies] +omegaconf = ">=2.0" +pycocotools = ">=2.0.2" +timm = ">=0.9.2" +torch = ">=1.12.1" +torchvision = "*" + [[package]] name = "elastic-transport" version = "8.15.1" @@ -2381,6 +2370,20 @@ files = [ {file = "et_xmlfile-1.1.0.tar.gz", hash = "sha256:8eb9e2bc2f8c97e37a2dc85a09ecdcdec9d8a396530a6d5a33b30b9a92da0c5c"}, ] +[[package]] +name = "eval-type-backport" +version = "0.2.0" +description = "Like `typing._eval_type`, but lets older Python versions use newer typing features." +optional = false +python-versions = ">=3.8" +files = [ + {file = "eval_type_backport-0.2.0-py3-none-any.whl", hash = "sha256:ac2f73d30d40c5a30a80b8739a789d6bb5e49fdffa66d7912667e2015d9c9933"}, + {file = "eval_type_backport-0.2.0.tar.gz", hash = "sha256:68796cfbc7371ebf923f03bdf7bef415f3ec098aeced24e054b253a0e78f7b37"}, +] + +[package.extras] +tests = ["pytest"] + [[package]] name = "exceptiongroup" version = "1.2.2" @@ -2397,18 +2400,18 @@ test = ["pytest (>=6)"] [[package]] name = "fastapi" -version = "0.115.2" +version = "0.115.3" description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" optional = false python-versions = ">=3.8" files = [ - {file = "fastapi-0.115.2-py3-none-any.whl", hash = "sha256:61704c71286579cc5a598763905928f24ee98bfcc07aabe84cfefb98812bbc86"}, - {file = "fastapi-0.115.2.tar.gz", hash = "sha256:3995739e0b09fa12f984bce8fa9ae197b35d433750d3d312422d846e283697ee"}, + {file = "fastapi-0.115.3-py3-none-any.whl", hash = "sha256:8035e8f9a2b0aa89cea03b6c77721178ed5358e1aea4cd8570d9466895c0638c"}, + {file = "fastapi-0.115.3.tar.gz", hash = "sha256:c091c6a35599c036d676fa24bd4a6e19fa30058d93d950216cdc672881f6f7db"}, ] [package.dependencies] pydantic = ">=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0 || >2.0.0,<2.0.1 || >2.0.1,<2.1.0 || >2.1.0,<3.0.0" -starlette = ">=0.37.2,<0.41.0" +starlette = ">=0.40.0,<0.42.0" typing-extensions = ">=4.8.0" [package.extras] @@ -2889,13 +2892,13 @@ files = [ [[package]] name = "fsspec" -version = "2024.9.0" +version = "2024.10.0" description = "File-system specification" optional = false python-versions = ">=3.8" files = [ - {file = "fsspec-2024.9.0-py3-none-any.whl", hash = "sha256:a0947d552d8a6efa72cc2c730b12c41d043509156966cca4fb157b0f2a0c574b"}, - {file = "fsspec-2024.9.0.tar.gz", hash = "sha256:4b0afb90c2f21832df142f292649035d80b421f60a9e1c027802e5a0da2b04e8"}, + {file = "fsspec-2024.10.0-py3-none-any.whl", hash = "sha256:03b9a6785766a4de40368b88906366755e2819e758b83705c88cd7cb5fe81871"}, + {file = "fsspec-2024.10.0.tar.gz", hash = "sha256:eda2d8a4116d4f2429db8550f2457da57279247dd930bb12f821b58391359493"}, ] [package.extras] @@ -3318,6 +3321,23 @@ requests = ">=2.18.0,<3.0.0dev" [package.extras] protobuf = ["protobuf (<5.0.0dev)"] +[[package]] +name = "google-cloud-vision" +version = "3.7.4" +description = "Google Cloud Vision API client library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "google_cloud_vision-3.7.4-py2.py3-none-any.whl", hash = "sha256:0b956480002545ab8f13d2b4b8f316e9332cdeb6f65f92c0a20d72e9e0df3ad6"}, + {file = "google_cloud_vision-3.7.4.tar.gz", hash = "sha256:80b67f0a2dc587a31d7482d3d2692a773f25fbd09468fd9de45d00b671aad999"}, +] + +[package.dependencies] +google-api-core = {version = ">=1.34.1,<2.0.dev0 || >=2.11.dev0,<3.0.0dev", extras = ["grpc"]} +google-auth = ">=2.14.1,<2.24.0 || >2.24.0,<2.25.0 || >2.25.0,<3.0.0dev" +proto-plus = ">=1.22.3,<2.0.0dev" +protobuf = ">=3.20.2,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<6.0.0dev" + [[package]] name = "google-crc32c" version = "1.6.0" @@ -3433,13 +3453,13 @@ grpc = ["grpcio (>=1.44.0,<2.0.0.dev0)"] [[package]] name = "gotrue" -version = "2.9.2" +version = "2.9.3" description = "Python Client Library for Supabase Auth" optional = false -python-versions = "<4.0,>=3.8" +python-versions = "<4.0,>=3.9" files = [ - {file = "gotrue-2.9.2-py3-none-any.whl", hash = "sha256:fcd5279e8f1cc630f3ac35af5485fe39f8030b23906776920d2c32a4e308cff4"}, - {file = "gotrue-2.9.2.tar.gz", hash = "sha256:57b3245e916c5efbf19a21b1181011a903c1276bb1df2d847558f2f24f29abb2"}, + {file = "gotrue-2.9.3-py3-none-any.whl", hash = "sha256:9d2e9c74405d879f4828e0a7b94daf167a6e109c10ae6e5c59a0e21446f6e423"}, + {file = "gotrue-2.9.3.tar.gz", hash = "sha256:051551d80e642bdd2ab42cac78207745d89a2a08f429a1512d82624e675d8255"}, ] [package.dependencies] @@ -3550,70 +3570,70 @@ protobuf = ">=3.20.2,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4 [[package]] name = "grpcio" -version = "1.66.2" +version = "1.67.0" description = "HTTP/2-based RPC framework" optional = false python-versions = ">=3.8" files = [ - {file = "grpcio-1.66.2-cp310-cp310-linux_armv7l.whl", hash = "sha256:fe96281713168a3270878255983d2cb1a97e034325c8c2c25169a69289d3ecfa"}, - {file = "grpcio-1.66.2-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:73fc8f8b9b5c4a03e802b3cd0c18b2b06b410d3c1dcbef989fdeb943bd44aff7"}, - {file = "grpcio-1.66.2-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:03b0b307ba26fae695e067b94cbb014e27390f8bc5ac7a3a39b7723fed085604"}, - {file = "grpcio-1.66.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d69ce1f324dc2d71e40c9261d3fdbe7d4c9d60f332069ff9b2a4d8a257c7b2b"}, - {file = "grpcio-1.66.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05bc2ceadc2529ab0b227b1310d249d95d9001cd106aa4d31e8871ad3c428d73"}, - {file = "grpcio-1.66.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:8ac475e8da31484efa25abb774674d837b343afb78bb3bcdef10f81a93e3d6bf"}, - {file = "grpcio-1.66.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0be4e0490c28da5377283861bed2941d1d20ec017ca397a5df4394d1c31a9b50"}, - {file = "grpcio-1.66.2-cp310-cp310-win32.whl", hash = "sha256:4e504572433f4e72b12394977679161d495c4c9581ba34a88d843eaf0f2fbd39"}, - {file = "grpcio-1.66.2-cp310-cp310-win_amd64.whl", hash = "sha256:2018b053aa15782db2541ca01a7edb56a0bf18c77efed975392583725974b249"}, - {file = "grpcio-1.66.2-cp311-cp311-linux_armv7l.whl", hash = "sha256:2335c58560a9e92ac58ff2bc5649952f9b37d0735608242973c7a8b94a6437d8"}, - {file = "grpcio-1.66.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:45a3d462826f4868b442a6b8fdbe8b87b45eb4f5b5308168c156b21eca43f61c"}, - {file = "grpcio-1.66.2-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:a9539f01cb04950fd4b5ab458e64a15f84c2acc273670072abe49a3f29bbad54"}, - {file = "grpcio-1.66.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ce89f5876662f146d4c1f695dda29d4433a5d01c8681fbd2539afff535da14d4"}, - {file = "grpcio-1.66.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d25a14af966438cddf498b2e338f88d1c9706f3493b1d73b93f695c99c5f0e2a"}, - {file = "grpcio-1.66.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6001e575b8bbd89eee11960bb640b6da6ae110cf08113a075f1e2051cc596cae"}, - {file = "grpcio-1.66.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4ea1d062c9230278793820146c95d038dc0f468cbdd172eec3363e42ff1c7d01"}, - {file = "grpcio-1.66.2-cp311-cp311-win32.whl", hash = "sha256:38b68498ff579a3b1ee8f93a05eb48dc2595795f2f62716e797dc24774c1aaa8"}, - {file = "grpcio-1.66.2-cp311-cp311-win_amd64.whl", hash = "sha256:6851de821249340bdb100df5eacfecfc4e6075fa85c6df7ee0eb213170ec8e5d"}, - {file = "grpcio-1.66.2-cp312-cp312-linux_armv7l.whl", hash = "sha256:802d84fd3d50614170649853d121baaaa305de7b65b3e01759247e768d691ddf"}, - {file = "grpcio-1.66.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:80fd702ba7e432994df208f27514280b4b5c6843e12a48759c9255679ad38db8"}, - {file = "grpcio-1.66.2-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:12fda97ffae55e6526825daf25ad0fa37483685952b5d0f910d6405c87e3adb6"}, - {file = "grpcio-1.66.2-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:950da58d7d80abd0ea68757769c9db0a95b31163e53e5bb60438d263f4bed7b7"}, - {file = "grpcio-1.66.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e636ce23273683b00410f1971d209bf3689238cf5538d960adc3cdfe80dd0dbd"}, - {file = "grpcio-1.66.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:a917d26e0fe980b0ac7bfcc1a3c4ad6a9a4612c911d33efb55ed7833c749b0ee"}, - {file = "grpcio-1.66.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:49f0ca7ae850f59f828a723a9064cadbed90f1ece179d375966546499b8a2c9c"}, - {file = "grpcio-1.66.2-cp312-cp312-win32.whl", hash = "sha256:31fd163105464797a72d901a06472860845ac157389e10f12631025b3e4d0453"}, - {file = "grpcio-1.66.2-cp312-cp312-win_amd64.whl", hash = "sha256:ff1f7882e56c40b0d33c4922c15dfa30612f05fb785074a012f7cda74d1c3679"}, - {file = "grpcio-1.66.2-cp313-cp313-linux_armv7l.whl", hash = "sha256:3b00efc473b20d8bf83e0e1ae661b98951ca56111feb9b9611df8efc4fe5d55d"}, - {file = "grpcio-1.66.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:1caa38fb22a8578ab8393da99d4b8641e3a80abc8fd52646f1ecc92bcb8dee34"}, - {file = "grpcio-1.66.2-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:c408f5ef75cfffa113cacd8b0c0e3611cbfd47701ca3cdc090594109b9fcbaed"}, - {file = "grpcio-1.66.2-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c806852deaedee9ce8280fe98955c9103f62912a5b2d5ee7e3eaa284a6d8d8e7"}, - {file = "grpcio-1.66.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f145cc21836c332c67baa6fc81099d1d27e266401565bf481948010d6ea32d46"}, - {file = "grpcio-1.66.2-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:73e3b425c1e155730273f73e419de3074aa5c5e936771ee0e4af0814631fb30a"}, - {file = "grpcio-1.66.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:9c509a4f78114cbc5f0740eb3d7a74985fd2eff022971bc9bc31f8bc93e66a3b"}, - {file = "grpcio-1.66.2-cp313-cp313-win32.whl", hash = "sha256:20657d6b8cfed7db5e11b62ff7dfe2e12064ea78e93f1434d61888834bc86d75"}, - {file = "grpcio-1.66.2-cp313-cp313-win_amd64.whl", hash = "sha256:fb70487c95786e345af5e854ffec8cb8cc781bcc5df7930c4fbb7feaa72e1cdf"}, - {file = "grpcio-1.66.2-cp38-cp38-linux_armv7l.whl", hash = "sha256:a18e20d8321c6400185b4263e27982488cb5cdd62da69147087a76a24ef4e7e3"}, - {file = "grpcio-1.66.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:02697eb4a5cbe5a9639f57323b4c37bcb3ab2d48cec5da3dc2f13334d72790dd"}, - {file = "grpcio-1.66.2-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:99a641995a6bc4287a6315989ee591ff58507aa1cbe4c2e70d88411c4dcc0839"}, - {file = "grpcio-1.66.2-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3ed71e81782966ffead60268bbda31ea3f725ebf8aa73634d5dda44f2cf3fb9c"}, - {file = "grpcio-1.66.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbd27c24a4cc5e195a7f56cfd9312e366d5d61b86e36d46bbe538457ea6eb8dd"}, - {file = "grpcio-1.66.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:d9a9724a156c8ec6a379869b23ba3323b7ea3600851c91489b871e375f710bc8"}, - {file = "grpcio-1.66.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d8d4732cc5052e92cea2f78b233c2e2a52998ac40cd651f40e398893ad0d06ec"}, - {file = "grpcio-1.66.2-cp38-cp38-win32.whl", hash = "sha256:7b2c86457145ce14c38e5bf6bdc19ef88e66c5fee2c3d83285c5aef026ba93b3"}, - {file = "grpcio-1.66.2-cp38-cp38-win_amd64.whl", hash = "sha256:e88264caad6d8d00e7913996030bac8ad5f26b7411495848cc218bd3a9040b6c"}, - {file = "grpcio-1.66.2-cp39-cp39-linux_armv7l.whl", hash = "sha256:c400ba5675b67025c8a9f48aa846f12a39cf0c44df5cd060e23fda5b30e9359d"}, - {file = "grpcio-1.66.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:66a0cd8ba6512b401d7ed46bb03f4ee455839957f28b8d61e7708056a806ba6a"}, - {file = "grpcio-1.66.2-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:06de8ec0bd71be123eec15b0e0d457474931c2c407869b6c349bd9bed4adbac3"}, - {file = "grpcio-1.66.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fb57870449dfcfac428afbb5a877829fcb0d6db9d9baa1148705739e9083880e"}, - {file = "grpcio-1.66.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b672abf90a964bfde2d0ecbce30f2329a47498ba75ce6f4da35a2f4532b7acbc"}, - {file = "grpcio-1.66.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ad2efdbe90c73b0434cbe64ed372e12414ad03c06262279b104a029d1889d13e"}, - {file = "grpcio-1.66.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9c3a99c519f4638e700e9e3f83952e27e2ea10873eecd7935823dab0c1c9250e"}, - {file = "grpcio-1.66.2-cp39-cp39-win32.whl", hash = "sha256:78fa51ebc2d9242c0fc5db0feecc57a9943303b46664ad89921f5079e2e4ada7"}, - {file = "grpcio-1.66.2-cp39-cp39-win_amd64.whl", hash = "sha256:728bdf36a186e7f51da73be7f8d09457a03061be848718d0edf000e709418987"}, - {file = "grpcio-1.66.2.tar.gz", hash = "sha256:563588c587b75c34b928bc428548e5b00ea38c46972181a4d8b75ba7e3f24231"}, + {file = "grpcio-1.67.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:bd79929b3bb96b54df1296cd3bf4d2b770bd1df6c2bdf549b49bab286b925cdc"}, + {file = "grpcio-1.67.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:16724ffc956ea42967f5758c2f043faef43cb7e48a51948ab593570570d1e68b"}, + {file = "grpcio-1.67.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:2b7183c80b602b0ad816315d66f2fb7887614ead950416d60913a9a71c12560d"}, + {file = "grpcio-1.67.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:efe32b45dd6d118f5ea2e5deaed417d8a14976325c93812dd831908522b402c9"}, + {file = "grpcio-1.67.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe89295219b9c9e47780a0f1c75ca44211e706d1c598242249fe717af3385ec8"}, + {file = "grpcio-1.67.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa8d025fae1595a207b4e47c2e087cb88d47008494db258ac561c00877d4c8f8"}, + {file = "grpcio-1.67.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f95e15db43e75a534420e04822df91f645664bf4ad21dfaad7d51773c80e6bb4"}, + {file = "grpcio-1.67.0-cp310-cp310-win32.whl", hash = "sha256:a6b9a5c18863fd4b6624a42e2712103fb0f57799a3b29651c0e5b8119a519d65"}, + {file = "grpcio-1.67.0-cp310-cp310-win_amd64.whl", hash = "sha256:b6eb68493a05d38b426604e1dc93bfc0137c4157f7ab4fac5771fd9a104bbaa6"}, + {file = "grpcio-1.67.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:e91d154689639932305b6ea6f45c6e46bb51ecc8ea77c10ef25aa77f75443ad4"}, + {file = "grpcio-1.67.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:cb204a742997277da678611a809a8409657b1398aaeebf73b3d9563b7d154c13"}, + {file = "grpcio-1.67.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:ae6de510f670137e755eb2a74b04d1041e7210af2444103c8c95f193340d17ee"}, + {file = "grpcio-1.67.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:74b900566bdf68241118f2918d312d3bf554b2ce0b12b90178091ea7d0a17b3d"}, + {file = "grpcio-1.67.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a4e95e43447a02aa603abcc6b5e727d093d161a869c83b073f50b9390ecf0fa8"}, + {file = "grpcio-1.67.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0bb94e66cd8f0baf29bd3184b6aa09aeb1a660f9ec3d85da615c5003154bc2bf"}, + {file = "grpcio-1.67.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:82e5bd4b67b17c8c597273663794a6a46a45e44165b960517fe6d8a2f7f16d23"}, + {file = "grpcio-1.67.0-cp311-cp311-win32.whl", hash = "sha256:7fc1d2b9fd549264ae585026b266ac2db53735510a207381be509c315b4af4e8"}, + {file = "grpcio-1.67.0-cp311-cp311-win_amd64.whl", hash = "sha256:ac11ecb34a86b831239cc38245403a8de25037b448464f95c3315819e7519772"}, + {file = "grpcio-1.67.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:227316b5631260e0bef8a3ce04fa7db4cc81756fea1258b007950b6efc90c05d"}, + {file = "grpcio-1.67.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:d90cfdafcf4b45a7a076e3e2a58e7bc3d59c698c4f6470b0bb13a4d869cf2273"}, + {file = "grpcio-1.67.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:77196216d5dd6f99af1c51e235af2dd339159f657280e65ce7e12c1a8feffd1d"}, + {file = "grpcio-1.67.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15c05a26a0f7047f720da41dc49406b395c1470eef44ff7e2c506a47ac2c0591"}, + {file = "grpcio-1.67.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3840994689cc8cbb73d60485c594424ad8adb56c71a30d8948d6453083624b52"}, + {file = "grpcio-1.67.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:5a1e03c3102b6451028d5dc9f8591131d6ab3c8a0e023d94c28cb930ed4b5f81"}, + {file = "grpcio-1.67.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:682968427a63d898759474e3b3178d42546e878fdce034fd7474ef75143b64e3"}, + {file = "grpcio-1.67.0-cp312-cp312-win32.whl", hash = "sha256:d01793653248f49cf47e5695e0a79805b1d9d4eacef85b310118ba1dfcd1b955"}, + {file = "grpcio-1.67.0-cp312-cp312-win_amd64.whl", hash = "sha256:985b2686f786f3e20326c4367eebdaed3e7aa65848260ff0c6644f817042cb15"}, + {file = "grpcio-1.67.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:8c9a35b8bc50db35ab8e3e02a4f2a35cfba46c8705c3911c34ce343bd777813a"}, + {file = "grpcio-1.67.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:42199e704095b62688998c2d84c89e59a26a7d5d32eed86d43dc90e7a3bd04aa"}, + {file = "grpcio-1.67.0-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:c4c425f440fb81f8d0237c07b9322fc0fb6ee2b29fbef5f62a322ff8fcce240d"}, + {file = "grpcio-1.67.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:323741b6699cd2b04a71cb38f502db98f90532e8a40cb675393d248126a268af"}, + {file = "grpcio-1.67.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:662c8e105c5e5cee0317d500eb186ed7a93229586e431c1bf0c9236c2407352c"}, + {file = "grpcio-1.67.0-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:f6bd2ab135c64a4d1e9e44679a616c9bc944547357c830fafea5c3caa3de5153"}, + {file = "grpcio-1.67.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:2f55c1e0e2ae9bdd23b3c63459ee4c06d223b68aeb1961d83c48fb63dc29bc03"}, + {file = "grpcio-1.67.0-cp313-cp313-win32.whl", hash = "sha256:fd6bc27861e460fe28e94226e3673d46e294ca4673d46b224428d197c5935e69"}, + {file = "grpcio-1.67.0-cp313-cp313-win_amd64.whl", hash = "sha256:cf51d28063338608cd8d3cd64677e922134837902b70ce00dad7f116e3998210"}, + {file = "grpcio-1.67.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:7f200aca719c1c5dc72ab68be3479b9dafccdf03df530d137632c534bb6f1ee3"}, + {file = "grpcio-1.67.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:0892dd200ece4822d72dd0952f7112c542a487fc48fe77568deaaa399c1e717d"}, + {file = "grpcio-1.67.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:f4d613fbf868b2e2444f490d18af472ccb47660ea3df52f068c9c8801e1f3e85"}, + {file = "grpcio-1.67.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c69bf11894cad9da00047f46584d5758d6ebc9b5950c0dc96fec7e0bce5cde9"}, + {file = "grpcio-1.67.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b9bca3ca0c5e74dea44bf57d27e15a3a3996ce7e5780d61b7c72386356d231db"}, + {file = "grpcio-1.67.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:014dfc020e28a0d9be7e93a91f85ff9f4a87158b7df9952fe23cc42d29d31e1e"}, + {file = "grpcio-1.67.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d4ea4509d42c6797539e9ec7496c15473177ce9abc89bc5c71e7abe50fc25737"}, + {file = "grpcio-1.67.0-cp38-cp38-win32.whl", hash = "sha256:9d75641a2fca9ae1ae86454fd25d4c298ea8cc195dbc962852234d54a07060ad"}, + {file = "grpcio-1.67.0-cp38-cp38-win_amd64.whl", hash = "sha256:cff8e54d6a463883cda2fab94d2062aad2f5edd7f06ae3ed030f2a74756db365"}, + {file = "grpcio-1.67.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:62492bd534979e6d7127b8a6b29093161a742dee3875873e01964049d5250a74"}, + {file = "grpcio-1.67.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eef1dce9d1a46119fd09f9a992cf6ab9d9178b696382439446ca5f399d7b96fe"}, + {file = "grpcio-1.67.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:f623c57a5321461c84498a99dddf9d13dac0e40ee056d884d6ec4ebcab647a78"}, + {file = "grpcio-1.67.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54d16383044e681f8beb50f905249e4e7261dd169d4aaf6e52eab67b01cbbbe2"}, + {file = "grpcio-1.67.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2a44e572fb762c668e4812156b81835f7aba8a721b027e2d4bb29fb50ff4d33"}, + {file = "grpcio-1.67.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:391df8b0faac84d42f5b8dfc65f5152c48ed914e13c522fd05f2aca211f8bfad"}, + {file = "grpcio-1.67.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:cfd9306511fdfc623a1ba1dc3bc07fbd24e6cfbe3c28b4d1e05177baa2f99617"}, + {file = "grpcio-1.67.0-cp39-cp39-win32.whl", hash = "sha256:30d47dbacfd20cbd0c8be9bfa52fdb833b395d4ec32fe5cff7220afc05d08571"}, + {file = "grpcio-1.67.0-cp39-cp39-win_amd64.whl", hash = "sha256:f55f077685f61f0fbd06ea355142b71e47e4a26d2d678b3ba27248abfe67163a"}, + {file = "grpcio-1.67.0.tar.gz", hash = "sha256:e090b2553e0da1c875449c8e75073dd4415dd71c9bde6a406240fdf4c0ee467c"}, ] [package.extras] -protobuf = ["grpcio-tools (>=1.66.2)"] +protobuf = ["grpcio-tools (>=1.67.0)"] [[package]] name = "grpcio-status" @@ -3912,54 +3932,54 @@ pyparsing = {version = ">=2.4.2,<3.0.0 || >3.0.0,<3.0.1 || >3.0.1,<3.0.2 || >3.0 [[package]] name = "httptools" -version = "0.6.2" +version = "0.6.4" description = "A collection of framework independent HTTP protocol utils." optional = false python-versions = ">=3.8.0" files = [ - {file = "httptools-0.6.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0238f07780782c018e9801d8f5f5aea3a4680a1af132034b444f677718c6fe88"}, - {file = "httptools-0.6.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:10d28e5597d4349390c640232c9366ddc15568114f56724fe30a53de9686b6ab"}, - {file = "httptools-0.6.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9ddaf99e362ae4169f6a8b3508f3487264e0a1b1e58c0b07b86407bc9ecee831"}, - {file = "httptools-0.6.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efc9d039b6b8a36b182bc60774bb5d456b8ff9ec44cf97719f2f38bb1dcdd546"}, - {file = "httptools-0.6.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b57cb8a4a8a8ffdaf0395326ef3b9c1aba36e58a421438fc04c002a1f511db63"}, - {file = "httptools-0.6.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b73cda1326738eab5d60640ca0b87ac4e4db09a099423c41b59a5681917e8d1d"}, - {file = "httptools-0.6.2-cp310-cp310-win_amd64.whl", hash = "sha256:352a496244360deb1c1d108391d76cd6f3dd9f53ccf975a082e74c6761af30c9"}, - {file = "httptools-0.6.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2e9d225b178a6cc700c23cf2f5daf85a10f93f1db7c34e9ee4ee0bbc29ad458a"}, - {file = "httptools-0.6.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d49b14fcc9b12a52da8667587efa124a18e1a3eb63bbbcabf9882f4008d171d6"}, - {file = "httptools-0.6.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d5c33d98b2311ddbe06e92b12b14de334dcfbe64ebcbb2c7a34b5c6036db512"}, - {file = "httptools-0.6.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53cd2d776700bf0ed0e6fb203d716b041712ea4906479031cc5ac5421ecaa7d2"}, - {file = "httptools-0.6.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7da016a0dab1fcced89dfff8537033c5dc200015e14023368f3f4a69e39b8716"}, - {file = "httptools-0.6.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4d6e0ba155a1b3159551ac6b4551eb20028617e2e4bb71f2c61efed0756e6825"}, - {file = "httptools-0.6.2-cp311-cp311-win_amd64.whl", hash = "sha256:ad44569b0f508e046ffe85b4a547d5b68d1548fd90767df69449cc28021ee709"}, - {file = "httptools-0.6.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:c92d2b7c1a914ab2f66454961eeaf904f4fe7529b93ff537619d22c18b82d070"}, - {file = "httptools-0.6.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:78f920a75c1dbcb5a48a495f384d73ceb41e437a966c318eb7e56f1c1ad1df3e"}, - {file = "httptools-0.6.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56bcd9ba0adf16edb4e3e45b8b9346f5b3b2372402e953d54c84b345d0f691e0"}, - {file = "httptools-0.6.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e350a887adb38ac65c93c2f395b60cf482baca61fd396ed8d6fd313dbcce6fac"}, - {file = "httptools-0.6.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ddc328c2a2daf2cf4bdc7bbc8a458dc4c840637223d4b8e01bce2168cc79fd23"}, - {file = "httptools-0.6.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ddaf38943dbb32333a182c894b6092a68b56c5e36d0c54ba3761d28119b15447"}, - {file = "httptools-0.6.2-cp312-cp312-win_amd64.whl", hash = "sha256:052f7f50e4a38f069478143878371ed17937f268349bcd68f6f7a9de9fcfce21"}, - {file = "httptools-0.6.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:406f7dc5d9db68cd9ac638d14c74d077085f76b45f704d3ec38d43b842b3cb44"}, - {file = "httptools-0.6.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:77e22c33123ce11231ff2773d8905e20b45d77a69459def7481283b72a583955"}, - {file = "httptools-0.6.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41965586b02715c3d83dd9153001f654e5b621de0c5255f5ef0635485212d0c0"}, - {file = "httptools-0.6.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93b1839d54b80a06a51a31b90d024a1770e250d00de57e7ae069bafba932f398"}, - {file = "httptools-0.6.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:8fdb4634040d1dbde7e0b373e19668cdb61c0ee8690d3b4064ac748d85365bca"}, - {file = "httptools-0.6.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c30902f9b9da0d74668b6f71d7b57081a4879d9a5ea93d5922dbe15b15b3b24a"}, - {file = "httptools-0.6.2-cp313-cp313-win_amd64.whl", hash = "sha256:cf61238811a75335751b4b17f8b221a35f93f2d57489296742adf98412d2a568"}, - {file = "httptools-0.6.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8d80878cb40ebf88a48839ff7206ceb62e4b54327e0c2f9f15ee12edbd8b907e"}, - {file = "httptools-0.6.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5141ccc9dbd8cdc59d1e93e318d405477a940dc6ebadcb8d9f8da17d2812d353"}, - {file = "httptools-0.6.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bb67d47f045f56e9a5da4deccf710bdde21212e4b1f4776b7a542449f6a7682"}, - {file = "httptools-0.6.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76dcb8f5c866f1537ccbaad01ebb3611890d281ef8d25e050d1cc3d90fba6b3d"}, - {file = "httptools-0.6.2-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:1b7bc59362143dc2d02896dde94004ef54ff1989ceedf4b389ad3b530f312364"}, - {file = "httptools-0.6.2-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:c7a5715b1f46e9852442f496c0df2f8c393cc8f293f5396d2c8d95cac852fb51"}, - {file = "httptools-0.6.2-cp38-cp38-win_amd64.whl", hash = "sha256:3f0246ca7f78fa8e3902ddb985b9f55509d417a862f4634a8fa63a7a496266c8"}, - {file = "httptools-0.6.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:1099f73952e18c718ccaaf7a97ae58c94a91839c3d247c6184326f85a2eda7b4"}, - {file = "httptools-0.6.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c3e45d004531330030f7d07abe4865bc17963b9989bc1941cebbf7224010fb82"}, - {file = "httptools-0.6.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4f2fea370361a90cb9330610a95303587eda9d1e69930dbbee9978eac1d5946"}, - {file = "httptools-0.6.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0481154c91725f7e7b729a535190388be6c7cbae3bbf0e793343ca386282312"}, - {file = "httptools-0.6.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d25f8fdbc6cc6561353c7a384d76295e6a85a4945115b8bc347855db150e8c77"}, - {file = "httptools-0.6.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:054bdee08e4f7c15c186f6e7dbc8f0cf974b8dd1832b5f17f988faf8b12815c9"}, - {file = "httptools-0.6.2-cp39-cp39-win_amd64.whl", hash = "sha256:4502620722b453c2c6306fad392c515dcb804dfa9c6d3b90d8926a07a7a01109"}, - {file = "httptools-0.6.2.tar.gz", hash = "sha256:ae694efefcb61317c79b2fa1caebc122060992408e389bb00889567e463a47f1"}, + {file = "httptools-0.6.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3c73ce323711a6ffb0d247dcd5a550b8babf0f757e86a52558fe5b86d6fefcc0"}, + {file = "httptools-0.6.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:345c288418f0944a6fe67be8e6afa9262b18c7626c3ef3c28adc5eabc06a68da"}, + {file = "httptools-0.6.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:deee0e3343f98ee8047e9f4c5bc7cedbf69f5734454a94c38ee829fb2d5fa3c1"}, + {file = "httptools-0.6.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca80b7485c76f768a3bc83ea58373f8db7b015551117375e4918e2aa77ea9b50"}, + {file = "httptools-0.6.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:90d96a385fa941283ebd231464045187a31ad932ebfa541be8edf5b3c2328959"}, + {file = "httptools-0.6.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:59e724f8b332319e2875efd360e61ac07f33b492889284a3e05e6d13746876f4"}, + {file = "httptools-0.6.4-cp310-cp310-win_amd64.whl", hash = "sha256:c26f313951f6e26147833fc923f78f95604bbec812a43e5ee37f26dc9e5a686c"}, + {file = "httptools-0.6.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f47f8ed67cc0ff862b84a1189831d1d33c963fb3ce1ee0c65d3b0cbe7b711069"}, + {file = "httptools-0.6.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0614154d5454c21b6410fdf5262b4a3ddb0f53f1e1721cfd59d55f32138c578a"}, + {file = "httptools-0.6.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8787367fbdfccae38e35abf7641dafc5310310a5987b689f4c32cc8cc3ee975"}, + {file = "httptools-0.6.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40b0f7fe4fd38e6a507bdb751db0379df1e99120c65fbdc8ee6c1d044897a636"}, + {file = "httptools-0.6.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:40a5ec98d3f49904b9fe36827dcf1aadfef3b89e2bd05b0e35e94f97c2b14721"}, + {file = "httptools-0.6.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:dacdd3d10ea1b4ca9df97a0a303cbacafc04b5cd375fa98732678151643d4988"}, + {file = "httptools-0.6.4-cp311-cp311-win_amd64.whl", hash = "sha256:288cd628406cc53f9a541cfaf06041b4c71d751856bab45e3702191f931ccd17"}, + {file = "httptools-0.6.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:df017d6c780287d5c80601dafa31f17bddb170232d85c066604d8558683711a2"}, + {file = "httptools-0.6.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:85071a1e8c2d051b507161f6c3e26155b5c790e4e28d7f236422dbacc2a9cc44"}, + {file = "httptools-0.6.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69422b7f458c5af875922cdb5bd586cc1f1033295aa9ff63ee196a87519ac8e1"}, + {file = "httptools-0.6.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:16e603a3bff50db08cd578d54f07032ca1631450ceb972c2f834c2b860c28ea2"}, + {file = "httptools-0.6.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ec4f178901fa1834d4a060320d2f3abc5c9e39766953d038f1458cb885f47e81"}, + {file = "httptools-0.6.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f9eb89ecf8b290f2e293325c646a211ff1c2493222798bb80a530c5e7502494f"}, + {file = "httptools-0.6.4-cp312-cp312-win_amd64.whl", hash = "sha256:db78cb9ca56b59b016e64b6031eda5653be0589dba2b1b43453f6e8b405a0970"}, + {file = "httptools-0.6.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ade273d7e767d5fae13fa637f4d53b6e961fb7fd93c7797562663f0171c26660"}, + {file = "httptools-0.6.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:856f4bc0478ae143bad54a4242fccb1f3f86a6e1be5548fecfd4102061b3a083"}, + {file = "httptools-0.6.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:322d20ea9cdd1fa98bd6a74b77e2ec5b818abdc3d36695ab402a0de8ef2865a3"}, + {file = "httptools-0.6.4-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4d87b29bd4486c0093fc64dea80231f7c7f7eb4dc70ae394d70a495ab8436071"}, + {file = "httptools-0.6.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:342dd6946aa6bda4b8f18c734576106b8a31f2fe31492881a9a160ec84ff4bd5"}, + {file = "httptools-0.6.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b36913ba52008249223042dca46e69967985fb4051951f94357ea681e1f5dc0"}, + {file = "httptools-0.6.4-cp313-cp313-win_amd64.whl", hash = "sha256:28908df1b9bb8187393d5b5db91435ccc9c8e891657f9cbb42a2541b44c82fc8"}, + {file = "httptools-0.6.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:d3f0d369e7ffbe59c4b6116a44d6a8eb4783aae027f2c0b366cf0aa964185dba"}, + {file = "httptools-0.6.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:94978a49b8f4569ad607cd4946b759d90b285e39c0d4640c6b36ca7a3ddf2efc"}, + {file = "httptools-0.6.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40dc6a8e399e15ea525305a2ddba998b0af5caa2566bcd79dcbe8948181eeaff"}, + {file = "httptools-0.6.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab9ba8dcf59de5181f6be44a77458e45a578fc99c31510b8c65b7d5acc3cf490"}, + {file = "httptools-0.6.4-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:fc411e1c0a7dcd2f902c7c48cf079947a7e65b5485dea9decb82b9105ca71a43"}, + {file = "httptools-0.6.4-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:d54efd20338ac52ba31e7da78e4a72570cf729fac82bc31ff9199bedf1dc7440"}, + {file = "httptools-0.6.4-cp38-cp38-win_amd64.whl", hash = "sha256:df959752a0c2748a65ab5387d08287abf6779ae9165916fe053e68ae1fbdc47f"}, + {file = "httptools-0.6.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:85797e37e8eeaa5439d33e556662cc370e474445d5fab24dcadc65a8ffb04003"}, + {file = "httptools-0.6.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:db353d22843cf1028f43c3651581e4bb49374d85692a85f95f7b9a130e1b2cab"}, + {file = "httptools-0.6.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1ffd262a73d7c28424252381a5b854c19d9de5f56f075445d33919a637e3547"}, + {file = "httptools-0.6.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:703c346571fa50d2e9856a37d7cd9435a25e7fd15e236c397bf224afaa355fe9"}, + {file = "httptools-0.6.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:aafe0f1918ed07b67c1e838f950b1c1fabc683030477e60b335649b8020e1076"}, + {file = "httptools-0.6.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0e563e54979e97b6d13f1bbc05a96109923e76b901f786a5eae36e99c01237bd"}, + {file = "httptools-0.6.4-cp39-cp39-win_amd64.whl", hash = "sha256:b799de31416ecc589ad79dd85a0b2657a8fe39327944998dea368c1d4c9e55e6"}, + {file = "httptools-0.6.4.tar.gz", hash = "sha256:4e93eee4add6493b59a5c514da98c939b244fce4a0d8879cd3f466562f4b7d5c"}, ] [package.extras] @@ -4112,6 +4132,24 @@ files = [ {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, ] +[[package]] +name = "iopath" +version = "0.1.10" +description = "A library for providing I/O abstraction." +optional = false +python-versions = ">=3.6" +files = [ + {file = "iopath-0.1.10.tar.gz", hash = "sha256:3311c16a4d9137223e20f141655759933e1eda24f8bff166af834af3c645ef01"}, +] + +[package.dependencies] +portalocker = "*" +tqdm = "*" +typing_extensions = "*" + +[package.extras] +aws = ["boto3"] + [[package]] name = "isodate" version = "0.7.2" @@ -4303,6 +4341,17 @@ files = [ [package.dependencies] ply = "*" +[[package]] +name = "jsonpath-python" +version = "1.0.6" +description = "A more powerful JSONPath implementation in modern python" +optional = false +python-versions = ">=3.6" +files = [ + {file = "jsonpath-python-1.0.6.tar.gz", hash = "sha256:dd5be4a72d8a2995c3f583cf82bf3cd1a9544cfdabf2d22595b67aff07349666"}, + {file = "jsonpath_python-1.0.6-py3-none-any.whl", hash = "sha256:1e3b78df579f5efc23565293612decee04214609208a2335884b3ee3f786b575"}, +] + [[package]] name = "jsonschema" version = "4.23.0" @@ -4577,13 +4626,13 @@ openai = ["openai (>=0.27.8)"] [[package]] name = "langsmith" -version = "0.1.135" +version = "0.1.137" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.135-py3-none-any.whl", hash = "sha256:b1d1ca3bad483a4239745c57e9b9157b4d099fbf3149be21e3d112c94ede06ac"}, - {file = "langsmith-0.1.135.tar.gz", hash = "sha256:7abed7e141386af99a2177f0b3600b124ae3ad1b482879ba0724ce92ef998a11"}, + {file = "langsmith-0.1.137-py3-none-any.whl", hash = "sha256:4256d5c61133749890f7b5c88321dbb133ce0f440c621ea28e76513285859b81"}, + {file = "langsmith-0.1.137.tar.gz", hash = "sha256:56cdfcc6c74cb20a3f437d5bd144feb5bf93f54c5a2918d1e568cbd084a372d4"}, ] [package.dependencies] @@ -4596,6 +4645,36 @@ pydantic = [ requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" +[[package]] +name = "layoutparser" +version = "0.3.4" +description = "A unified toolkit for Deep Learning Based Document Image Analysis" +optional = false +python-versions = ">=3.6" +files = [ + {file = "layoutparser-0.3.4-py3-none-any.whl", hash = "sha256:269aedfab8a0caa50aef8d0fa62740fbee1f2964880daae3a0e6a0415363126a"}, + {file = "layoutparser-0.3.4.tar.gz", hash = "sha256:0dfb2194c36a5ad1075b8310f3cbc280c00306d1758cef127d20283f7ce085ea"}, +] + +[package.dependencies] +iopath = "*" +numpy = "*" +opencv-python = "*" +pandas = "*" +pdf2image = "*" +pdfplumber = "*" +pillow = "*" +pyyaml = ">=5.1" +scipy = "*" + +[package.extras] +effdet = ["effdet", "torch", "torchvision"] +gcv = ["google-cloud-vision (==1)"] +layoutmodels = ["effdet", "torch", "torchvision"] +ocr = ["google-cloud-vision (==1)", "pytesseract"] +paddledetection = ["paddlepaddle (==2.1.0)"] +tesseract = ["pytesseract"] + [[package]] name = "llvmlite" version = "0.43.0" @@ -4867,13 +4946,13 @@ urllib3 = ">=1.23" [[package]] name = "mako" -version = "1.3.5" +version = "1.3.6" description = "A super-fast templating language that borrows the best ideas from the existing templating languages." optional = false python-versions = ">=3.8" files = [ - {file = "Mako-1.3.5-py3-none-any.whl", hash = "sha256:260f1dbc3a519453a9c856dedfe4beb4e50bd5a26d96386cb6c80856556bb91a"}, - {file = "Mako-1.3.5.tar.gz", hash = "sha256:48dbc20568c1d276a2698b36d968fa76161bf127194907ea6fc594fa81f943bc"}, + {file = "Mako-1.3.6-py3-none-any.whl", hash = "sha256:a91198468092a2f1a0de86ca92690fb0cfc43ca90ee17e15d93662b4c04b241a"}, + {file = "mako-1.3.6.tar.gz", hash = "sha256:9ec3a1583713479fae654f83ed9fa8c9a4c16b7bb0daba0e6bbebff50c0d983d"}, ] [package.dependencies] @@ -4925,92 +5004,92 @@ testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] [[package]] name = "markupsafe" -version = "3.0.1" +version = "3.0.2" description = "Safely add untrusted strings to HTML/XML markup." optional = false python-versions = ">=3.9" files = [ - {file = "MarkupSafe-3.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:db842712984e91707437461930e6011e60b39136c7331e971952bb30465bc1a1"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3ffb4a8e7d46ed96ae48805746755fadd0909fea2306f93d5d8233ba23dda12a"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67c519635a4f64e495c50e3107d9b4075aec33634272b5db1cde839e07367589"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48488d999ed50ba8d38c581d67e496f955821dc183883550a6fbc7f1aefdc170"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f31ae06f1328595d762c9a2bf29dafd8621c7d3adc130cbb46278079758779ca"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:80fcbf3add8790caddfab6764bde258b5d09aefbe9169c183f88a7410f0f6dea"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3341c043c37d78cc5ae6e3e305e988532b072329639007fd408a476642a89fd6"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cb53e2a99df28eee3b5f4fea166020d3ef9116fdc5764bc5117486e6d1211b25"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-win32.whl", hash = "sha256:db15ce28e1e127a0013dfb8ac243a8e392db8c61eae113337536edb28bdc1f97"}, - {file = "MarkupSafe-3.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:4ffaaac913c3f7345579db4f33b0020db693f302ca5137f106060316761beea9"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:26627785a54a947f6d7336ce5963569b5d75614619e75193bdb4e06e21d447ad"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b954093679d5750495725ea6f88409946d69cfb25ea7b4c846eef5044194f583"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:973a371a55ce9ed333a3a0f8e0bcfae9e0d637711534bcb11e130af2ab9334e7"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:244dbe463d5fb6d7ce161301a03a6fe744dac9072328ba9fc82289238582697b"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d98e66a24497637dd31ccab090b34392dddb1f2f811c4b4cd80c230205c074a3"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ad91738f14eb8da0ff82f2acd0098b6257621410dcbd4df20aaa5b4233d75a50"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7044312a928a66a4c2a22644147bc61a199c1709712069a344a3fb5cfcf16915"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a4792d3b3a6dfafefdf8e937f14906a51bd27025a36f4b188728a73382231d91"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-win32.whl", hash = "sha256:fa7d686ed9883f3d664d39d5a8e74d3c5f63e603c2e3ff0abcba23eac6542635"}, - {file = "MarkupSafe-3.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:9ba25a71ebf05b9bb0e2ae99f8bc08a07ee8e98c612175087112656ca0f5c8bf"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8ae369e84466aa70f3154ee23c1451fda10a8ee1b63923ce76667e3077f2b0c4"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40f1e10d51c92859765522cbd79c5c8989f40f0419614bcdc5015e7b6bf97fc5"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a4cb365cb49b750bdb60b846b0c0bc49ed62e59a76635095a179d440540c346"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee3941769bd2522fe39222206f6dd97ae83c442a94c90f2b7a25d847d40f4729"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62fada2c942702ef8952754abfc1a9f7658a4d5460fabe95ac7ec2cbe0d02abc"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4c2d64fdba74ad16138300815cfdc6ab2f4647e23ced81f59e940d7d4a1469d9"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:fb532dd9900381d2e8f48172ddc5a59db4c445a11b9fab40b3b786da40d3b56b"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0f84af7e813784feb4d5e4ff7db633aba6c8ca64a833f61d8e4eade234ef0c38"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-win32.whl", hash = "sha256:cbf445eb5628981a80f54087f9acdbf84f9b7d862756110d172993b9a5ae81aa"}, - {file = "MarkupSafe-3.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:a10860e00ded1dd0a65b83e717af28845bb7bd16d8ace40fe5531491de76b79f"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e81c52638315ff4ac1b533d427f50bc0afc746deb949210bc85f05d4f15fd772"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:312387403cd40699ab91d50735ea7a507b788091c416dd007eac54434aee51da"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ae99f31f47d849758a687102afdd05bd3d3ff7dbab0a8f1587981b58a76152a"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c97ff7fedf56d86bae92fa0a646ce1a0ec7509a7578e1ed238731ba13aabcd1c"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7420ceda262dbb4b8d839a4ec63d61c261e4e77677ed7c66c99f4e7cb5030dd"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:45d42d132cff577c92bfba536aefcfea7e26efb975bd455db4e6602f5c9f45e7"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4c8817557d0de9349109acb38b9dd570b03cc5014e8aabf1cbddc6e81005becd"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a54c43d3ec4cf2a39f4387ad044221c66a376e58c0d0e971d47c475ba79c6b5"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-win32.whl", hash = "sha256:c91b394f7601438ff79a4b93d16be92f216adb57d813a78be4446fe0f6bc2d8c"}, - {file = "MarkupSafe-3.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:fe32482b37b4b00c7a52a07211b479653b7fe4f22b2e481b9a9b099d8a430f2f"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:17b2aea42a7280db02ac644db1d634ad47dcc96faf38ab304fe26ba2680d359a"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:852dc840f6d7c985603e60b5deaae1d89c56cb038b577f6b5b8c808c97580f1d"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0778de17cff1acaeccc3ff30cd99a3fd5c50fc58ad3d6c0e0c4c58092b859396"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:800100d45176652ded796134277ecb13640c1a537cad3b8b53da45aa96330453"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d06b24c686a34c86c8c1fba923181eae6b10565e4d80bdd7bc1c8e2f11247aa4"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:33d1c36b90e570ba7785dacd1faaf091203d9942bc036118fab8110a401eb1a8"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:beeebf760a9c1f4c07ef6a53465e8cfa776ea6a2021eda0d0417ec41043fe984"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:bbde71a705f8e9e4c3e9e33db69341d040c827c7afa6789b14c6e16776074f5a"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-win32.whl", hash = "sha256:82b5dba6eb1bcc29cc305a18a3c5365d2af06ee71b123216416f7e20d2a84e5b"}, - {file = "MarkupSafe-3.0.1-cp313-cp313t-win_amd64.whl", hash = "sha256:730d86af59e0e43ce277bb83970530dd223bf7f2a838e086b50affa6ec5f9295"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:4935dd7883f1d50e2ffecca0aa33dc1946a94c8f3fdafb8df5c330e48f71b132"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e9393357f19954248b00bed7c56f29a25c930593a77630c719653d51e7669c2a"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40621d60d0e58aa573b68ac5e2d6b20d44392878e0bfc159012a5787c4e35bc8"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f94190df587738280d544971500b9cafc9b950d32efcb1fba9ac10d84e6aa4e6"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b6a387d61fe41cdf7ea95b38e9af11cfb1a63499af2759444b99185c4ab33f5b"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:8ad4ad1429cd4f315f32ef263c1342166695fad76c100c5d979c45d5570ed58b"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e24bfe89c6ac4c31792793ad9f861b8f6dc4546ac6dc8f1c9083c7c4f2b335cd"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2a4b34a8d14649315c4bc26bbfa352663eb51d146e35eef231dd739d54a5430a"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-win32.whl", hash = "sha256:242d6860f1fd9191aef5fae22b51c5c19767f93fb9ead4d21924e0bcb17619d8"}, - {file = "MarkupSafe-3.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:93e8248d650e7e9d49e8251f883eed60ecbc0e8ffd6349e18550925e31bd029b"}, - {file = "markupsafe-3.0.1.tar.gz", hash = "sha256:3e683ee4f5d0fa2dde4db77ed8dd8a876686e3fc417655c2ece9a90576905344"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, + {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, ] [[package]] name = "marshmallow" -version = "3.22.0" +version = "3.23.0" description = "A lightweight library for converting complex datatypes to and from native Python datatypes." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "marshmallow-3.22.0-py3-none-any.whl", hash = "sha256:71a2dce49ef901c3f97ed296ae5051135fd3febd2bf43afe0ae9a82143a494d9"}, - {file = "marshmallow-3.22.0.tar.gz", hash = "sha256:4972f529104a220bb8637d595aa4c9762afbe7f7a77d82dc58c1615d70c5823e"}, + {file = "marshmallow-3.23.0-py3-none-any.whl", hash = "sha256:82f20a2397834fe6d9611b241f2f7e7b680ed89c49f84728a1ad937be6b4bdf4"}, + {file = "marshmallow-3.23.0.tar.gz", hash = "sha256:98d8827a9f10c03d44ead298d2e99c6aea8197df18ccfad360dae7f89a50da2e"}, ] [package.dependencies] packaging = ">=17.0" [package.extras] -dev = ["marshmallow[tests]", "pre-commit (>=3.5,<4.0)", "tox"] -docs = ["alabaster (==1.0.0)", "autodocsumm (==0.2.13)", "sphinx (==8.0.2)", "sphinx-issues (==4.1.0)", "sphinx-version-warning (==1.1.2)"] -tests = ["pytest", "pytz", "simplejson"] +dev = ["marshmallow[tests]", "pre-commit (>=3.5,<5.0)", "tox"] +docs = ["alabaster (==1.0.0)", "autodocsumm (==0.2.13)", "sphinx (==8.1.3)", "sphinx-issues (==5.0.0)", "sphinx-version-warning (==1.1.2)"] +tests = ["pytest", "simplejson"] [[package]] name = "matplotlib" @@ -5289,23 +5368,6 @@ files = [ msal = ">=1.29,<2" portalocker = ">=1.4,<3" -[[package]] -name = "msg-parser" -version = "1.2.0" -description = "This module enables reading, parsing and converting Microsoft Outlook MSG E-Mail files." -optional = false -python-versions = ">=3.4" -files = [ - {file = "msg_parser-1.2.0-py2.py3-none-any.whl", hash = "sha256:d47a2f0b2a359cb189fad83cc991b63ea781ecc70d91410324273fbf93e95375"}, - {file = "msg_parser-1.2.0.tar.gz", hash = "sha256:0de858d4fcebb6c8f6f028da83a17a20fe01cdce67c490779cf43b3b0162aa66"}, -] - -[package.dependencies] -olefile = ">=0.46" - -[package.extras] -rtf = ["compressed-rtf (>=1.0.5)"] - [[package]] name = "msrest" version = "0.7.1" @@ -5481,6 +5543,36 @@ files = [ {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, ] +[[package]] +name = "nest-asyncio" +version = "1.6.0" +description = "Patch asyncio to allow nested event loops" +optional = false +python-versions = ">=3.5" +files = [ + {file = "nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c"}, + {file = "nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe"}, +] + +[[package]] +name = "networkx" +version = "3.4.2" +description = "Python package for creating and manipulating graphs and networks" +optional = false +python-versions = ">=3.10" +files = [ + {file = "networkx-3.4.2-py3-none-any.whl", hash = "sha256:df5d4365b724cf81b8c6a7312509d0c22386097011ad1abe274afd5e9d3bbc5f"}, + {file = "networkx-3.4.2.tar.gz", hash = "sha256:307c3669428c5362aab27c8a1260aa8f47c4e91d3891f48be0141738d8d053e1"}, +] + +[package.extras] +default = ["matplotlib (>=3.7)", "numpy (>=1.24)", "pandas (>=2.0)", "scipy (>=1.10,!=1.11.0,!=1.11.1)"] +developer = ["changelist (==0.5)", "mypy (>=1.1)", "pre-commit (>=3.2)", "rtoml"] +doc = ["intersphinx-registry", "myst-nb (>=1.1)", "numpydoc (>=1.8.0)", "pillow (>=9.4)", "pydata-sphinx-theme (>=0.15)", "sphinx (>=7.3)", "sphinx-gallery (>=0.16)", "texext (>=0.6.7)"] +example = ["cairocffi (>=1.7)", "contextily (>=1.6)", "igraph (>=0.11)", "momepy (>=0.7.2)", "osmnx (>=1.9)", "scikit-learn (>=1.5)", "seaborn (>=0.13)"] +extra = ["lxml (>=4.6)", "pydot (>=3.0.1)", "pygraphviz (>=1.14)", "sympy (>=1.10)"] +test = ["pytest (>=7.2)", "pytest-cov (>=4.0)"] + [[package]] name = "newspaper3k" version = "0.2.8" @@ -5509,13 +5601,13 @@ tldextract = ">=2.0.1" [[package]] name = "nltk" -version = "3.8.1" +version = "3.9.1" description = "Natural Language Toolkit" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "nltk-3.8.1-py3-none-any.whl", hash = "sha256:fd5c9109f976fa86bcadba8f91e47f5e9293bd034474752e92a520f81c93dda5"}, - {file = "nltk-3.8.1.zip", hash = "sha256:1834da3d0682cba4f2cede2f9aad6b0fafb6461ba451db0efb6f9c39798d64d3"}, + {file = "nltk-3.9.1-py3-none-any.whl", hash = "sha256:4fa26829c5b00715afe3061398a8989dc643b92ce7dd93fb4585a70930d168a1"}, + {file = "nltk-3.9.1.tar.gz", hash = "sha256:87d127bd3de4bd89a4f81265e5fa59cb1b199b27440175370f7417d2bc7ae868"}, ] [package.dependencies] @@ -5698,6 +5790,150 @@ files = [ {file = "numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010"}, ] +[[package]] +name = "nvidia-cublas-cu12" +version = "12.1.3.1" +description = "CUBLAS native runtime libraries" +optional = false +python-versions = ">=3" +files = [ + {file = "nvidia_cublas_cu12-12.1.3.1-py3-none-manylinux1_x86_64.whl", hash = "sha256:ee53ccca76a6fc08fb9701aa95b6ceb242cdaab118c3bb152af4e579af792728"}, + {file = "nvidia_cublas_cu12-12.1.3.1-py3-none-win_amd64.whl", hash = "sha256:2b964d60e8cf11b5e1073d179d85fa340c120e99b3067558f3cf98dd69d02906"}, +] + +[[package]] +name = "nvidia-cuda-cupti-cu12" +version = "12.1.105" +description = "CUDA profiling tools runtime libs." +optional = false +python-versions = ">=3" +files = [ + {file = "nvidia_cuda_cupti_cu12-12.1.105-py3-none-manylinux1_x86_64.whl", hash = "sha256:e54fde3983165c624cb79254ae9818a456eb6e87a7fd4d56a2352c24ee542d7e"}, + {file = "nvidia_cuda_cupti_cu12-12.1.105-py3-none-win_amd64.whl", hash = "sha256:bea8236d13a0ac7190bd2919c3e8e6ce1e402104276e6f9694479e48bb0eb2a4"}, +] + +[[package]] +name = "nvidia-cuda-nvrtc-cu12" +version = "12.1.105" +description = "NVRTC native runtime libraries" +optional = false +python-versions = ">=3" +files = [ + {file = "nvidia_cuda_nvrtc_cu12-12.1.105-py3-none-manylinux1_x86_64.whl", hash = "sha256:339b385f50c309763ca65456ec75e17bbefcbbf2893f462cb8b90584cd27a1c2"}, + {file = "nvidia_cuda_nvrtc_cu12-12.1.105-py3-none-win_amd64.whl", hash = "sha256:0a98a522d9ff138b96c010a65e145dc1b4850e9ecb75a0172371793752fd46ed"}, +] + +[[package]] +name = "nvidia-cuda-runtime-cu12" +version = "12.1.105" +description = "CUDA Runtime native Libraries" +optional = false +python-versions = ">=3" +files = [ + {file = "nvidia_cuda_runtime_cu12-12.1.105-py3-none-manylinux1_x86_64.whl", hash = "sha256:6e258468ddf5796e25f1dc591a31029fa317d97a0a94ed93468fc86301d61e40"}, + {file = "nvidia_cuda_runtime_cu12-12.1.105-py3-none-win_amd64.whl", hash = "sha256:dfb46ef84d73fababab44cf03e3b83f80700d27ca300e537f85f636fac474344"}, +] + +[[package]] +name = "nvidia-cudnn-cu12" +version = "9.1.0.70" +description = "cuDNN runtime libraries" +optional = false +python-versions = ">=3" +files = [ + {file = "nvidia_cudnn_cu12-9.1.0.70-py3-none-manylinux2014_x86_64.whl", hash = "sha256:165764f44ef8c61fcdfdfdbe769d687e06374059fbb388b6c89ecb0e28793a6f"}, + {file = "nvidia_cudnn_cu12-9.1.0.70-py3-none-win_amd64.whl", hash = "sha256:6278562929433d68365a07a4a1546c237ba2849852c0d4b2262a486e805b977a"}, +] + +[package.dependencies] +nvidia-cublas-cu12 = "*" + +[[package]] +name = "nvidia-cufft-cu12" +version = "11.0.2.54" +description = "CUFFT native runtime libraries" +optional = false +python-versions = ">=3" +files = [ + {file = "nvidia_cufft_cu12-11.0.2.54-py3-none-manylinux1_x86_64.whl", hash = "sha256:794e3948a1aa71fd817c3775866943936774d1c14e7628c74f6f7417224cdf56"}, + {file = "nvidia_cufft_cu12-11.0.2.54-py3-none-win_amd64.whl", hash = "sha256:d9ac353f78ff89951da4af698f80870b1534ed69993f10a4cf1d96f21357e253"}, +] + +[[package]] +name = "nvidia-curand-cu12" +version = "10.3.2.106" +description = "CURAND native runtime libraries" +optional = false +python-versions = ">=3" +files = [ + {file = "nvidia_curand_cu12-10.3.2.106-py3-none-manylinux1_x86_64.whl", hash = "sha256:9d264c5036dde4e64f1de8c50ae753237c12e0b1348738169cd0f8a536c0e1e0"}, + {file = "nvidia_curand_cu12-10.3.2.106-py3-none-win_amd64.whl", hash = "sha256:75b6b0c574c0037839121317e17fd01f8a69fd2ef8e25853d826fec30bdba74a"}, +] + +[[package]] +name = "nvidia-cusolver-cu12" +version = "11.4.5.107" +description = "CUDA solver native runtime libraries" +optional = false +python-versions = ">=3" +files = [ + {file = "nvidia_cusolver_cu12-11.4.5.107-py3-none-manylinux1_x86_64.whl", hash = "sha256:8a7ec542f0412294b15072fa7dab71d31334014a69f953004ea7a118206fe0dd"}, + {file = "nvidia_cusolver_cu12-11.4.5.107-py3-none-win_amd64.whl", hash = "sha256:74e0c3a24c78612192a74fcd90dd117f1cf21dea4822e66d89e8ea80e3cd2da5"}, +] + +[package.dependencies] +nvidia-cublas-cu12 = "*" +nvidia-cusparse-cu12 = "*" +nvidia-nvjitlink-cu12 = "*" + +[[package]] +name = "nvidia-cusparse-cu12" +version = "12.1.0.106" +description = "CUSPARSE native runtime libraries" +optional = false +python-versions = ">=3" +files = [ + {file = "nvidia_cusparse_cu12-12.1.0.106-py3-none-manylinux1_x86_64.whl", hash = "sha256:f3b50f42cf363f86ab21f720998517a659a48131e8d538dc02f8768237bd884c"}, + {file = "nvidia_cusparse_cu12-12.1.0.106-py3-none-win_amd64.whl", hash = "sha256:b798237e81b9719373e8fae8d4f091b70a0cf09d9d85c95a557e11df2d8e9a5a"}, +] + +[package.dependencies] +nvidia-nvjitlink-cu12 = "*" + +[[package]] +name = "nvidia-nccl-cu12" +version = "2.20.5" +description = "NVIDIA Collective Communication Library (NCCL) Runtime" +optional = false +python-versions = ">=3" +files = [ + {file = "nvidia_nccl_cu12-2.20.5-py3-none-manylinux2014_aarch64.whl", hash = "sha256:1fc150d5c3250b170b29410ba682384b14581db722b2531b0d8d33c595f33d01"}, + {file = "nvidia_nccl_cu12-2.20.5-py3-none-manylinux2014_x86_64.whl", hash = "sha256:057f6bf9685f75215d0c53bf3ac4a10b3e6578351de307abad9e18a99182af56"}, +] + +[[package]] +name = "nvidia-nvjitlink-cu12" +version = "12.6.77" +description = "Nvidia JIT LTO Library" +optional = false +python-versions = ">=3" +files = [ + {file = "nvidia_nvjitlink_cu12-12.6.77-py3-none-manylinux2014_aarch64.whl", hash = "sha256:3bf10d85bb1801e9c894c6e197e44dd137d2a0a9e43f8450e9ad13f2df0dd52d"}, + {file = "nvidia_nvjitlink_cu12-12.6.77-py3-none-manylinux2014_x86_64.whl", hash = "sha256:9ae346d16203ae4ea513be416495167a0101d33d2d14935aa9c1829a3fb45142"}, + {file = "nvidia_nvjitlink_cu12-12.6.77-py3-none-win_amd64.whl", hash = "sha256:410718cd44962bed862a31dd0318620f6f9a8b28a6291967bcfcb446a6516771"}, +] + +[[package]] +name = "nvidia-nvtx-cu12" +version = "12.1.105" +description = "NVIDIA Tools Extension" +optional = false +python-versions = ">=3" +files = [ + {file = "nvidia_nvtx_cu12-12.1.105-py3-none-manylinux1_x86_64.whl", hash = "sha256:dc21cf308ca5691e7c04d962e213f8a4aa9bbfa23d95412f452254c2caeb09e5"}, + {file = "nvidia_nvtx_cu12-12.1.105-py3-none-win_amd64.whl", hash = "sha256:65f4d98982b31b60026e0e6de73fbdfc09d08a96f4656dd3665ca616a11e1e82"}, +] + [[package]] name = "oauthlib" version = "3.2.2" @@ -5760,6 +5996,63 @@ files = [ [package.extras] tests = ["pytest", "pytest-cov"] +[[package]] +name = "omegaconf" +version = "2.3.0" +description = "A flexible configuration library" +optional = false +python-versions = ">=3.6" +files = [ + {file = "omegaconf-2.3.0-py3-none-any.whl", hash = "sha256:7b4df175cdb08ba400f45cae3bdcae7ba8365db4d165fc65fd04b050ab63b46b"}, + {file = "omegaconf-2.3.0.tar.gz", hash = "sha256:d5d4b6d29955cc50ad50c46dc269bcd92c6e00f5f90d23ab5fee7bfca4ba4cc7"}, +] + +[package.dependencies] +antlr4-python3-runtime = "==4.9.*" +PyYAML = ">=5.1.0" + +[[package]] +name = "onnx" +version = "1.17.0" +description = "Open Neural Network Exchange" +optional = false +python-versions = ">=3.8" +files = [ + {file = "onnx-1.17.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:38b5df0eb22012198cdcee527cc5f917f09cce1f88a69248aaca22bd78a7f023"}, + {file = "onnx-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d545335cb49d4d8c47cc803d3a805deb7ad5d9094dc67657d66e568610a36d7d"}, + {file = "onnx-1.17.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3193a3672fc60f1a18c0f4c93ac81b761bc72fd8a6c2035fa79ff5969f07713e"}, + {file = "onnx-1.17.0-cp310-cp310-win32.whl", hash = "sha256:0141c2ce806c474b667b7e4499164227ef594584da432fd5613ec17c1855e311"}, + {file = "onnx-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:dfd777d95c158437fda6b34758f0877d15b89cbe9ff45affbedc519b35345cf9"}, + {file = "onnx-1.17.0-cp311-cp311-macosx_12_0_universal2.whl", hash = "sha256:d6fc3a03fc0129b8b6ac03f03bc894431ffd77c7d79ec023d0afd667b4d35869"}, + {file = "onnx-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f01a4b63d4e1d8ec3e2f069e7b798b2955810aa434f7361f01bc8ca08d69cce4"}, + {file = "onnx-1.17.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a183c6178be001bf398260e5ac2c927dc43e7746e8638d6c05c20e321f8c949"}, + {file = "onnx-1.17.0-cp311-cp311-win32.whl", hash = "sha256:081ec43a8b950171767d99075b6b92553901fa429d4bc5eb3ad66b36ef5dbe3a"}, + {file = "onnx-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:95c03e38671785036bb704c30cd2e150825f6ab4763df3a4f1d249da48525957"}, + {file = "onnx-1.17.0-cp312-cp312-macosx_12_0_universal2.whl", hash = "sha256:0e906e6a83437de05f8139ea7eaf366bf287f44ae5cc44b2850a30e296421f2f"}, + {file = "onnx-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d955ba2939878a520a97614bcf2e79c1df71b29203e8ced478fa78c9a9c63c2"}, + {file = "onnx-1.17.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f3fb5cc4e2898ac5312a7dc03a65133dd2abf9a5e520e69afb880a7251ec97a"}, + {file = "onnx-1.17.0-cp312-cp312-win32.whl", hash = "sha256:317870fca3349d19325a4b7d1b5628f6de3811e9710b1e3665c68b073d0e68d7"}, + {file = "onnx-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:659b8232d627a5460d74fd3c96947ae83db6d03f035ac633e20cd69cfa029227"}, + {file = "onnx-1.17.0-cp38-cp38-macosx_12_0_universal2.whl", hash = "sha256:23b8d56a9df492cdba0eb07b60beea027d32ff5e4e5fe271804eda635bed384f"}, + {file = "onnx-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ecf2b617fd9a39b831abea2df795e17bac705992a35a98e1f0363f005c4a5247"}, + {file = "onnx-1.17.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea5023a8dcdadbb23fd0ed0179ce64c1f6b05f5b5c34f2909b4e927589ebd0e4"}, + {file = "onnx-1.17.0-cp38-cp38-win32.whl", hash = "sha256:f0e437f8f2f0c36f629e9743d28cf266312baa90be6a899f405f78f2d4cb2e1d"}, + {file = "onnx-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:e4673276b558b5b572b960b7f9ef9214dce9305673683eb289bb97a7df379a4b"}, + {file = "onnx-1.17.0-cp39-cp39-macosx_12_0_universal2.whl", hash = "sha256:67e1c59034d89fff43b5301b6178222e54156eadd6ab4cd78ddc34b2f6274a66"}, + {file = "onnx-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e19fd064b297f7773b4c1150f9ce6213e6d7d041d7a9201c0d348041009cdcd"}, + {file = "onnx-1.17.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8167295f576055158a966161f8ef327cb491c06ede96cc23392be6022071b6ed"}, + {file = "onnx-1.17.0-cp39-cp39-win32.whl", hash = "sha256:76884fe3e0258c911c749d7d09667fb173365fd27ee66fcedaf9fa039210fd13"}, + {file = "onnx-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:5ca7a0894a86d028d509cdcf99ed1864e19bfe5727b44322c11691d834a1c546"}, + {file = "onnx-1.17.0.tar.gz", hash = "sha256:48ca1a91ff73c1d5e3ea2eef20ae5d0e709bb8a2355ed798ffc2169753013fd3"}, +] + +[package.dependencies] +numpy = ">=1.20" +protobuf = ">=3.20.2" + +[package.extras] +reference = ["Pillow", "google-re2"] + [[package]] name = "onnxruntime" version = "1.19.2" @@ -5804,13 +6097,13 @@ sympy = "*" [[package]] name = "openai" -version = "1.52.0" +version = "1.52.1" description = "The official Python library for the openai API" optional = false python-versions = ">=3.7.1" files = [ - {file = "openai-1.52.0-py3-none-any.whl", hash = "sha256:0c249f20920183b0a2ca4f7dba7b0452df3ecd0fa7985eb1d91ad884bc3ced9c"}, - {file = "openai-1.52.0.tar.gz", hash = "sha256:95c65a5f77559641ab8f3e4c3a050804f7b51d278870e2ec1f7444080bfe565a"}, + {file = "openai-1.52.1-py3-none-any.whl", hash = "sha256:f23e83df5ba04ee0e82c8562571e8cb596cd88f9a84ab783e6c6259e5ffbfb4a"}, + {file = "openai-1.52.1.tar.gz", hash = "sha256:383b96c7e937cbec23cad5bf5718085381e4313ca33c5c5896b54f8e1b19d144"}, ] [package.dependencies] @@ -5885,6 +6178,30 @@ files = [ [package.dependencies] opencensus = ">=0.8.0,<1.0.0" +[[package]] +name = "opencv-python" +version = "4.10.0.84" +description = "Wrapper package for OpenCV python bindings." +optional = false +python-versions = ">=3.6" +files = [ + {file = "opencv-python-4.10.0.84.tar.gz", hash = "sha256:72d234e4582e9658ffea8e9cae5b63d488ad06994ef12d81dc303b17472f3526"}, + {file = "opencv_python-4.10.0.84-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:fc182f8f4cda51b45f01c64e4cbedfc2f00aff799debebc305d8d0210c43f251"}, + {file = "opencv_python-4.10.0.84-cp37-abi3-macosx_12_0_x86_64.whl", hash = "sha256:71e575744f1d23f79741450254660442785f45a0797212852ee5199ef12eed98"}, + {file = "opencv_python-4.10.0.84-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09a332b50488e2dda866a6c5573ee192fe3583239fb26ff2f7f9ceb0bc119ea6"}, + {file = "opencv_python-4.10.0.84-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ace140fc6d647fbe1c692bcb2abce768973491222c067c131d80957c595b71f"}, + {file = "opencv_python-4.10.0.84-cp37-abi3-win32.whl", hash = "sha256:2db02bb7e50b703f0a2d50c50ced72e95c574e1e5a0bb35a8a86d0b35c98c236"}, + {file = "opencv_python-4.10.0.84-cp37-abi3-win_amd64.whl", hash = "sha256:32dbbd94c26f611dc5cc6979e6b7aa1f55a64d6b463cc1dcd3c95505a63e48fe"}, +] + +[package.dependencies] +numpy = [ + {version = ">=1.21.4", markers = "python_version >= \"3.10\" and platform_system == \"Darwin\" and python_version < \"3.11\""}, + {version = ">=1.21.2", markers = "platform_system != \"Darwin\" and python_version >= \"3.10\" and python_version < \"3.11\""}, + {version = ">=1.23.5", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, + {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, +] + [[package]] name = "openpyxl" version = "3.1.5" @@ -6131,68 +6448,69 @@ cryptography = ">=3.2.1" [[package]] name = "orjson" -version = "3.10.7" +version = "3.10.10" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.7-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:74f4544f5a6405b90da8ea724d15ac9c36da4d72a738c64685003337401f5c12"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34a566f22c28222b08875b18b0dfbf8a947e69df21a9ed5c51a6bf91cfb944ac"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bf6ba8ebc8ef5792e2337fb0419f8009729335bb400ece005606336b7fd7bab7"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac7cf6222b29fbda9e3a472b41e6a5538b48f2c8f99261eecd60aafbdb60690c"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de817e2f5fc75a9e7dd350c4b0f54617b280e26d1631811a43e7e968fa71e3e9"}, - {file = "orjson-3.10.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:348bdd16b32556cf8d7257b17cf2bdb7ab7976af4af41ebe79f9796c218f7e91"}, - {file = "orjson-3.10.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:479fd0844ddc3ca77e0fd99644c7fe2de8e8be1efcd57705b5c92e5186e8a250"}, - {file = "orjson-3.10.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:fdf5197a21dd660cf19dfd2a3ce79574588f8f5e2dbf21bda9ee2d2b46924d84"}, - {file = "orjson-3.10.7-cp310-none-win32.whl", hash = "sha256:d374d36726746c81a49f3ff8daa2898dccab6596864ebe43d50733275c629175"}, - {file = "orjson-3.10.7-cp310-none-win_amd64.whl", hash = "sha256:cb61938aec8b0ffb6eef484d480188a1777e67b05d58e41b435c74b9d84e0b9c"}, - {file = "orjson-3.10.7-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:7db8539039698ddfb9a524b4dd19508256107568cdad24f3682d5773e60504a2"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:480f455222cb7a1dea35c57a67578848537d2602b46c464472c995297117fa09"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8a9c9b168b3a19e37fe2778c0003359f07822c90fdff8f98d9d2a91b3144d8e0"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8de062de550f63185e4c1c54151bdddfc5625e37daf0aa1e75d2a1293e3b7d9a"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6b0dd04483499d1de9c8f6203f8975caf17a6000b9c0c54630cef02e44ee624e"}, - {file = "orjson-3.10.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b58d3795dafa334fc8fd46f7c5dc013e6ad06fd5b9a4cc98cb1456e7d3558bd6"}, - {file = "orjson-3.10.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:33cfb96c24034a878d83d1a9415799a73dc77480e6c40417e5dda0710d559ee6"}, - {file = "orjson-3.10.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e724cebe1fadc2b23c6f7415bad5ee6239e00a69f30ee423f319c6af70e2a5c0"}, - {file = "orjson-3.10.7-cp311-none-win32.whl", hash = "sha256:82763b46053727a7168d29c772ed5c870fdae2f61aa8a25994c7984a19b1021f"}, - {file = "orjson-3.10.7-cp311-none-win_amd64.whl", hash = "sha256:eb8d384a24778abf29afb8e41d68fdd9a156cf6e5390c04cc07bbc24b89e98b5"}, - {file = "orjson-3.10.7-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44a96f2d4c3af51bfac6bc4ef7b182aa33f2f054fd7f34cc0ee9a320d051d41f"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76ac14cd57df0572453543f8f2575e2d01ae9e790c21f57627803f5e79b0d3c3"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bdbb61dcc365dd9be94e8f7df91975edc9364d6a78c8f7adb69c1cdff318ec93"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b48b3db6bb6e0a08fa8c83b47bc169623f801e5cc4f24442ab2b6617da3b5313"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23820a1563a1d386414fef15c249040042b8e5d07b40ab3fe3efbfbbcbcb8864"}, - {file = "orjson-3.10.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0c6a008e91d10a2564edbb6ee5069a9e66df3fbe11c9a005cb411f441fd2c09"}, - {file = "orjson-3.10.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d352ee8ac1926d6193f602cbe36b1643bbd1bbcb25e3c1a657a4390f3000c9a5"}, - {file = "orjson-3.10.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d2d9f990623f15c0ae7ac608103c33dfe1486d2ed974ac3f40b693bad1a22a7b"}, - {file = "orjson-3.10.7-cp312-none-win32.whl", hash = "sha256:7c4c17f8157bd520cdb7195f75ddbd31671997cbe10aee559c2d613592e7d7eb"}, - {file = "orjson-3.10.7-cp312-none-win_amd64.whl", hash = "sha256:1d9c0e733e02ada3ed6098a10a8ee0052dd55774de3d9110d29868d24b17faa1"}, - {file = "orjson-3.10.7-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:77d325ed866876c0fa6492598ec01fe30e803272a6e8b10e992288b009cbe149"}, - {file = "orjson-3.10.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ea2c232deedcb605e853ae1db2cc94f7390ac776743b699b50b071b02bea6fe"}, - {file = "orjson-3.10.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3dcfbede6737fdbef3ce9c37af3fb6142e8e1ebc10336daa05872bfb1d87839c"}, - {file = "orjson-3.10.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:11748c135f281203f4ee695b7f80bb1358a82a63905f9f0b794769483ea854ad"}, - {file = "orjson-3.10.7-cp313-none-win32.whl", hash = "sha256:a7e19150d215c7a13f39eb787d84db274298d3f83d85463e61d277bbd7f401d2"}, - {file = "orjson-3.10.7-cp313-none-win_amd64.whl", hash = "sha256:eef44224729e9525d5261cc8d28d6b11cafc90e6bd0be2157bde69a52ec83024"}, - {file = "orjson-3.10.7-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:6ea2b2258eff652c82652d5e0f02bd5e0463a6a52abb78e49ac288827aaa1469"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:430ee4d85841e1483d487e7b81401785a5dfd69db5de01314538f31f8fbf7ee1"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4b6146e439af4c2472c56f8540d799a67a81226e11992008cb47e1267a9b3225"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:084e537806b458911137f76097e53ce7bf5806dda33ddf6aaa66a028f8d43a23"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4829cf2195838e3f93b70fd3b4292156fc5e097aac3739859ac0dcc722b27ac0"}, - {file = "orjson-3.10.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1193b2416cbad1a769f868b1749535d5da47626ac29445803dae7cc64b3f5c98"}, - {file = "orjson-3.10.7-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:4e6c3da13e5a57e4b3dca2de059f243ebec705857522f188f0180ae88badd354"}, - {file = "orjson-3.10.7-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:c31008598424dfbe52ce8c5b47e0752dca918a4fdc4a2a32004efd9fab41d866"}, - {file = "orjson-3.10.7-cp38-none-win32.whl", hash = "sha256:7122a99831f9e7fe977dc45784d3b2edc821c172d545e6420c375e5a935f5a1c"}, - {file = "orjson-3.10.7-cp38-none-win_amd64.whl", hash = "sha256:a763bc0e58504cc803739e7df040685816145a6f3c8a589787084b54ebc9f16e"}, - {file = "orjson-3.10.7-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e76be12658a6fa376fcd331b1ea4e58f5a06fd0220653450f0d415b8fd0fbe20"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed350d6978d28b92939bfeb1a0570c523f6170efc3f0a0ef1f1df287cd4f4960"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:144888c76f8520e39bfa121b31fd637e18d4cc2f115727865fdf9fa325b10412"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09b2d92fd95ad2402188cf51573acde57eb269eddabaa60f69ea0d733e789fe9"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5b24a579123fa884f3a3caadaed7b75eb5715ee2b17ab5c66ac97d29b18fe57f"}, - {file = "orjson-3.10.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e72591bcfe7512353bd609875ab38050efe3d55e18934e2f18950c108334b4ff"}, - {file = "orjson-3.10.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f4db56635b58cd1a200b0a23744ff44206ee6aa428185e2b6c4a65b3197abdcd"}, - {file = "orjson-3.10.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0fa5886854673222618638c6df7718ea7fe2f3f2384c452c9ccedc70b4a510a5"}, - {file = "orjson-3.10.7-cp39-none-win32.whl", hash = "sha256:8272527d08450ab16eb405f47e0f4ef0e5ff5981c3d82afe0efd25dcbef2bcd2"}, - {file = "orjson-3.10.7-cp39-none-win_amd64.whl", hash = "sha256:974683d4618c0c7dbf4f69c95a979734bf183d0658611760017f6e70a145af58"}, - {file = "orjson-3.10.7.tar.gz", hash = "sha256:75ef0640403f945f3a1f9f6400686560dbfb0fb5b16589ad62cd477043c4eee3"}, + {file = "orjson-3.10.10-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b788a579b113acf1c57e0a68e558be71d5d09aa67f62ca1f68e01117e550a998"}, + {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:804b18e2b88022c8905bb79bd2cbe59c0cd014b9328f43da8d3b28441995cda4"}, + {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9972572a1d042ec9ee421b6da69f7cc823da5962237563fa548ab17f152f0b9b"}, + {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc6993ab1c2ae7dd0711161e303f1db69062955ac2668181bfdf2dd410e65258"}, + {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d78e4cacced5781b01d9bc0f0cd8b70b906a0e109825cb41c1b03f9c41e4ce86"}, + {file = "orjson-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6eb2598df518281ba0cbc30d24c5b06124ccf7e19169e883c14e0831217a0bc"}, + {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:23776265c5215ec532de6238a52707048401a568f0fa0d938008e92a147fe2c7"}, + {file = "orjson-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8cc2a654c08755cef90b468ff17c102e2def0edd62898b2486767204a7f5cc9c"}, + {file = "orjson-3.10.10-cp310-none-win32.whl", hash = "sha256:081b3fc6a86d72efeb67c13d0ea7c030017bd95f9868b1e329a376edc456153b"}, + {file = "orjson-3.10.10-cp310-none-win_amd64.whl", hash = "sha256:ff38c5fb749347768a603be1fb8a31856458af839f31f064c5aa74aca5be9efe"}, + {file = "orjson-3.10.10-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:879e99486c0fbb256266c7c6a67ff84f46035e4f8749ac6317cc83dacd7f993a"}, + {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:019481fa9ea5ff13b5d5d95e6fd5ab25ded0810c80b150c2c7b1cc8660b662a7"}, + {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0dd57eff09894938b4c86d4b871a479260f9e156fa7f12f8cad4b39ea8028bb5"}, + {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dbde6d70cd95ab4d11ea8ac5e738e30764e510fc54d777336eec09bb93b8576c"}, + {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2625cb37b8fb42e2147404e5ff7ef08712099197a9cd38895006d7053e69d6"}, + {file = "orjson-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbf3c20c6a7db69df58672a0d5815647ecf78c8e62a4d9bd284e8621c1fe5ccb"}, + {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:75c38f5647e02d423807d252ce4528bf6a95bd776af999cb1fb48867ed01d1f6"}, + {file = "orjson-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:23458d31fa50ec18e0ec4b0b4343730928296b11111df5f547c75913714116b2"}, + {file = "orjson-3.10.10-cp311-none-win32.whl", hash = "sha256:2787cd9dedc591c989f3facd7e3e86508eafdc9536a26ec277699c0aa63c685b"}, + {file = "orjson-3.10.10-cp311-none-win_amd64.whl", hash = "sha256:6514449d2c202a75183f807bc755167713297c69f1db57a89a1ef4a0170ee269"}, + {file = "orjson-3.10.10-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8564f48f3620861f5ef1e080ce7cd122ee89d7d6dacf25fcae675ff63b4d6e05"}, + {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5bf161a32b479034098c5b81f2608f09167ad2fa1c06abd4e527ea6bf4837a9"}, + {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68b65c93617bcafa7f04b74ae8bc2cc214bd5cb45168a953256ff83015c6747d"}, + {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8e28406f97fc2ea0c6150f4c1b6e8261453318930b334abc419214c82314f85"}, + {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4d0d9fe174cc7a5bdce2e6c378bcdb4c49b2bf522a8f996aa586020e1b96cee"}, + {file = "orjson-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3be81c42f1242cbed03cbb3973501fcaa2675a0af638f8be494eaf37143d999"}, + {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:65f9886d3bae65be026219c0a5f32dbbe91a9e6272f56d092ab22561ad0ea33b"}, + {file = "orjson-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:730ed5350147db7beb23ddaf072f490329e90a1d059711d364b49fe352ec987b"}, + {file = "orjson-3.10.10-cp312-none-win32.whl", hash = "sha256:a8f4bf5f1c85bea2170800020d53a8877812892697f9c2de73d576c9307a8a5f"}, + {file = "orjson-3.10.10-cp312-none-win_amd64.whl", hash = "sha256:384cd13579a1b4cd689d218e329f459eb9ddc504fa48c5a83ef4889db7fd7a4f"}, + {file = "orjson-3.10.10-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:44bffae68c291f94ff5a9b4149fe9d1bdd4cd0ff0fb575bcea8351d48db629a1"}, + {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e27b4c6437315df3024f0835887127dac2a0a3ff643500ec27088d2588fa5ae1"}, + {file = "orjson-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca84df16d6b49325a4084fd8b2fe2229cb415e15c46c529f868c3387bb1339d"}, + {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c14ce70e8f39bd71f9f80423801b5d10bf93d1dceffdecd04df0f64d2c69bc01"}, + {file = "orjson-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:24ac62336da9bda1bd93c0491eff0613003b48d3cb5d01470842e7b52a40d5b4"}, + {file = "orjson-3.10.10-cp313-none-win32.whl", hash = "sha256:eb0a42831372ec2b05acc9ee45af77bcaccbd91257345f93780a8e654efc75db"}, + {file = "orjson-3.10.10-cp313-none-win_amd64.whl", hash = "sha256:f0c4f37f8bf3f1075c6cc8dd8a9f843689a4b618628f8812d0a71e6968b95ffd"}, + {file = "orjson-3.10.10-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:829700cc18503efc0cf502d630f612884258020d98a317679cd2054af0259568"}, + {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0ceb5e0e8c4f010ac787d29ae6299846935044686509e2f0f06ed441c1ca949"}, + {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c25908eb86968613216f3db4d3003f1c45d78eb9046b71056ca327ff92bdbd4"}, + {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:218cb0bc03340144b6328a9ff78f0932e642199ac184dd74b01ad691f42f93ff"}, + {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2277ec2cea3775640dc81ab5195bb5b2ada2fe0ea6eee4677474edc75ea6785"}, + {file = "orjson-3.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:848ea3b55ab5ccc9d7bbd420d69432628b691fba3ca8ae3148c35156cbd282aa"}, + {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:e3e67b537ac0c835b25b5f7d40d83816abd2d3f4c0b0866ee981a045287a54f3"}, + {file = "orjson-3.10.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7948cfb909353fce2135dcdbe4521a5e7e1159484e0bb024c1722f272488f2b8"}, + {file = "orjson-3.10.10-cp38-none-win32.whl", hash = "sha256:78bee66a988f1a333dc0b6257503d63553b1957889c17b2c4ed72385cd1b96ae"}, + {file = "orjson-3.10.10-cp38-none-win_amd64.whl", hash = "sha256:f1d647ca8d62afeb774340a343c7fc023efacfd3a39f70c798991063f0c681dd"}, + {file = "orjson-3.10.10-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5a059afddbaa6dd733b5a2d76a90dbc8af790b993b1b5cb97a1176ca713b5df8"}, + {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f9b5c59f7e2a1a410f971c5ebc68f1995822837cd10905ee255f96074537ee6"}, + {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d5ef198bafdef4aa9d49a4165ba53ffdc0a9e1c7b6f76178572ab33118afea25"}, + {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf29ce0bb5d3320824ec3d1508652421000ba466abd63bdd52c64bcce9eb1fa"}, + {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dddd5516bcc93e723d029c1633ae79c4417477b4f57dad9bfeeb6bc0315e654a"}, + {file = "orjson-3.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a12f2003695b10817f0fa8b8fca982ed7f5761dcb0d93cff4f2f9f6709903fd7"}, + {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:672f9874a8a8fb9bb1b771331d31ba27f57702c8106cdbadad8bda5d10bc1019"}, + {file = "orjson-3.10.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1dcbb0ca5fafb2b378b2c74419480ab2486326974826bbf6588f4dc62137570a"}, + {file = "orjson-3.10.10-cp39-none-win32.whl", hash = "sha256:d9bbd3a4b92256875cb058c3381b782649b9a3c68a4aa9a2fff020c2f9cfc1be"}, + {file = "orjson-3.10.10-cp39-none-win_amd64.whl", hash = "sha256:766f21487a53aee8524b97ca9582d5c6541b03ab6210fbaf10142ae2f3ced2aa"}, + {file = "orjson-3.10.10.tar.gz", hash = "sha256:37949383c4df7b4337ce82ee35b6d7471e55195efa7dcb45ab8226ceadb0fe3b"}, ] [[package]] @@ -6347,14 +6665,64 @@ multiprocess = ">=0.70.17" pox = ">=0.3.5" ppft = ">=1.7.6.9" +[[package]] +name = "pdf2image" +version = "1.17.0" +description = "A wrapper around the pdftoppm and pdftocairo command line tools to convert PDF to a PIL Image list." +optional = false +python-versions = "*" +files = [ + {file = "pdf2image-1.17.0-py3-none-any.whl", hash = "sha256:ecdd58d7afb810dffe21ef2b1bbc057ef434dabbac6c33778a38a3f7744a27e2"}, + {file = "pdf2image-1.17.0.tar.gz", hash = "sha256:eaa959bc116b420dd7ec415fcae49b98100dda3dd18cd2fdfa86d09f112f6d57"}, +] + +[package.dependencies] +pillow = "*" + +[[package]] +name = "pdfminer-six" +version = "20221105" +description = "PDF parser and analyzer" +optional = false +python-versions = ">=3.6" +files = [ + {file = "pdfminer.six-20221105-py3-none-any.whl", hash = "sha256:1eaddd712d5b2732f8ac8486824533514f8ba12a0787b3d5fe1e686cd826532d"}, + {file = "pdfminer.six-20221105.tar.gz", hash = "sha256:8448ab7b939d18b64820478ecac5394f482d7a79f5f7eaa7703c6c959c175e1d"}, +] + +[package.dependencies] +charset-normalizer = ">=2.0.0" +cryptography = ">=36.0.0" + +[package.extras] +dev = ["black", "mypy (==0.931)", "nox", "pytest"] +docs = ["sphinx", "sphinx-argparse"] +image = ["Pillow"] + +[[package]] +name = "pdfplumber" +version = "0.9.0" +description = "Plumb a PDF for detailed information about each char, rectangle, and line." +optional = false +python-versions = ">=3.7" +files = [ + {file = "pdfplumber-0.9.0-py3-none-any.whl", hash = "sha256:b396f2919670eb863124f649a907dc846c8653bbb6ba8024fe274952de121077"}, + {file = "pdfplumber-0.9.0.tar.gz", hash = "sha256:a43a213e125ed72b2358c0d3428f9b72f83939109ec33b77ef9325eeab9846f0"}, +] + +[package.dependencies] +"pdfminer.six" = "20221105" +Pillow = ">=9.1" +Wand = ">=0.6.10" + [[package]] name = "peewee" -version = "3.17.6" +version = "3.17.7" description = "a little orm" optional = false python-versions = "*" files = [ - {file = "peewee-3.17.6.tar.gz", hash = "sha256:cea5592c6f4da1592b7cff8eaf655be6648a1f5857469e30037bf920c03fb8fb"}, + {file = "peewee-3.17.7.tar.gz", hash = "sha256:6aefc700bd530fc6ac23fa19c9c5b47041751d92985b799169c8e318e97eabaa"}, ] [[package]] @@ -6392,97 +6760,215 @@ files = [ [package.dependencies] numpy = "*" +[[package]] +name = "pi-heif" +version = "0.20.0" +description = "Python interface for libheif library" +optional = false +python-versions = ">=3.9" +files = [ + {file = "pi_heif-0.20.0-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:1371a3a34bffdc98b5bacf48b01c8bba0fd49183fd425a6f152390fda792e8da"}, + {file = "pi_heif-0.20.0-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:397e7839682771a21e7756a4822b4bc45251805d3188bb6275eb51fd63e6c1b2"}, + {file = "pi_heif-0.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee28de31da7d1a8cc08e4fa1b5a1c095b3e1c8be5edd5cf26c8ac4c365b806b3"}, + {file = "pi_heif-0.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33cf72ec7d344ae681046455ab7b2d3210e8369ed46f921038fd980ba1b5b27f"}, + {file = "pi_heif-0.20.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:393868800055271ae7ad876055e7b3f2eae5ab2fe1980ebe28a5761725c2c189"}, + {file = "pi_heif-0.20.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e81e28f0c7330133b5b1ce7e1ad118663eb9eac4cad6638bfca07c0eb761129a"}, + {file = "pi_heif-0.20.0-cp310-cp310-win_amd64.whl", hash = "sha256:b6bfcc917d3b11f6bcf80db8c64f721ce1ab7335459c0f109e933ca92e6dfb1a"}, + {file = "pi_heif-0.20.0-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:89c8e89b7615a0aa717f366169c4be31451af72a937314104cc88cbe40e1da11"}, + {file = "pi_heif-0.20.0-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:2484c8b5f447bc0018d9045faea9880e177c818c89eb333239aa02b9ed4a9ffb"}, + {file = "pi_heif-0.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9050f675bdc43333c1ac6aab734e253a3ba92a0efc8014d3431953add906ead5"}, + {file = "pi_heif-0.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:834b188f4963ac29b2ea92153e7d437993d8dd9e5adbff1640695563832f2157"}, + {file = "pi_heif-0.20.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:18b8c3269d1e07f85d146217616b117f5f2c8142328c6669a46d8d762699aadb"}, + {file = "pi_heif-0.20.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:eadcc3cec45d3c021e4c41c5a85e56f4c2b8b8942fa9a1720d9376b29c2e39cb"}, + {file = "pi_heif-0.20.0-cp311-cp311-win_amd64.whl", hash = "sha256:b23d891b4b788a00fb8e0c170e4744d86708bc682b3bf095143b10074bdd694c"}, + {file = "pi_heif-0.20.0-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:52436771e1e9198145a3db25885ec9fda4eda11f5753e1317ae9459b190cd6a4"}, + {file = "pi_heif-0.20.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:1f482ac86090c0d8adf65bd3a6b97f485ceaa0876123225913e3e2ac687e5bfe"}, + {file = "pi_heif-0.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6a4d350ac12fb5f45bc83eb35747156a4faa12d001dcdd9525a3912ae5b4d7a"}, + {file = "pi_heif-0.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8cd2a83ee8cc597ddf7e13d2adec60b7206357ff55649c4aea2f4c76bdb11c2"}, + {file = "pi_heif-0.20.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6edf3cf270838d26329e1f0d93a3a85963e4f811de8e80173e18a2f137020deb"}, + {file = "pi_heif-0.20.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:05b938736a4712fbc1224d4207ceb226670568f7db329b61895876c1ae7fe241"}, + {file = "pi_heif-0.20.0-cp312-cp312-win_amd64.whl", hash = "sha256:f082f12fb3954ac0140e9eead2d3a2be4aa60aa834a3998665175fde67f50793"}, + {file = "pi_heif-0.20.0-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:81e0f769d62f7af250518a99c75c3cc357147ab78ad673b5c0e96b3c1e3ef21b"}, + {file = "pi_heif-0.20.0-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:137af16fc31f8862775a82287e0c1ea0627fb0e9ffa53fccf84cacd1f4e0a90a"}, + {file = "pi_heif-0.20.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:030df62463a03053d68af01fb3fafb3dae3bc578b8da24280f0787469c22bdd0"}, + {file = "pi_heif-0.20.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b71571e792389151a679f4cb477a54ee1f3834d4b21c2f9e272068a4166964a"}, + {file = "pi_heif-0.20.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5ca9ccfda3b114229c92b5470f8fe451b5d07f4c8677edc3525403ef379b53ba"}, + {file = "pi_heif-0.20.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d57f48a08b0cdc492e17fe33312b47356a17fcf6a93c508a9e503e497e03ef4f"}, + {file = "pi_heif-0.20.0-cp313-cp313-win_amd64.whl", hash = "sha256:086d101461f0580b621de1cf24e6cf9c136015e6ff9408fec7f254c2c4f49243"}, + {file = "pi_heif-0.20.0-cp39-cp39-macosx_12_0_x86_64.whl", hash = "sha256:2a38a50b33cec5261037e625c35270656ec16c2febdcbbb529a9a96857b16a5b"}, + {file = "pi_heif-0.20.0-cp39-cp39-macosx_14_0_arm64.whl", hash = "sha256:ff50c2c090c2af6347e9caa8f2e3998c29f9ff8d4fac625bd48e0072f2133464"}, + {file = "pi_heif-0.20.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:627cc28de13eab9eabef9931c0ae260bdeb61200f6ce3d2cb8444a6979053ef9"}, + {file = "pi_heif-0.20.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f4b94f5ea91cfe180ead680528a197da8f77ff27b339aceb169bd7e2a51b53b1"}, + {file = "pi_heif-0.20.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:3e00bab005d97e6a60b2a52e9fc14fb8d50d9a7ff290d52b0e6491848e853550"}, + {file = "pi_heif-0.20.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0305ea6e108979eee370fed0486df8b90ff25c619db9d9d539b00603e139626f"}, + {file = "pi_heif-0.20.0-cp39-cp39-win_amd64.whl", hash = "sha256:13146a8d4873198cf614c70ea344b69932637c28fb506427caffe9b951cc5694"}, + {file = "pi_heif-0.20.0-pp310-pypy310_pp73-macosx_12_0_x86_64.whl", hash = "sha256:f3f1e59b802d96c0dcf1b91ed2cc7d196a94b9e3d985ef80a86700e16e45bb28"}, + {file = "pi_heif-0.20.0-pp310-pypy310_pp73-macosx_14_0_arm64.whl", hash = "sha256:d002ca0b10e39b3f034385f1d453f4effd94bf83bbb4464ee72a386dcdbb1c4c"}, + {file = "pi_heif-0.20.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:33ab67a27bcbe24840bb26bf71a097e66c1ac63e1c5c155456913b8f933c9582"}, + {file = "pi_heif-0.20.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:323b7d1ed4a702fe7b8ca2f959f01f33879e38c413542408d522383b65857492"}, + {file = "pi_heif-0.20.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d7866ea2735d8cbc7501a98735a940ea22098303e340f2218caad3427f261abb"}, + {file = "pi_heif-0.20.0-pp39-pypy39_pp73-macosx_12_0_x86_64.whl", hash = "sha256:3bc6d86cdc42c22fe0821db2771eefa7e9651922668dd008c1cf8d786c1b13cc"}, + {file = "pi_heif-0.20.0-pp39-pypy39_pp73-macosx_14_0_arm64.whl", hash = "sha256:849d6ff186128d563b494cd463abc156a73ad4598b38dcaed0d52c0e78ec8cc4"}, + {file = "pi_heif-0.20.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:90e1e4ccd08e7256d1a19519b546efd7d5baf75337d522cbaa813fd6155675ec"}, + {file = "pi_heif-0.20.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4908b6e6be10062bf06dd5512184b1ad495291b73aa8f0b82f0fc9d66f2bcc1b"}, + {file = "pi_heif-0.20.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:695417ff1050cf79bca5c47bead807d7eb30fcf76fd64457f686a6342712284f"}, + {file = "pi_heif-0.20.0.tar.gz", hash = "sha256:f63b5ab190697c91dec482112bfa90751e48070899f4888317e943075dccf0be"}, +] + +[package.dependencies] +pillow = ">=10.1.0" + +[package.extras] +tests = ["defusedxml", "numpy", "packaging", "pympler", "pytest"] +tests-min = ["defusedxml", "packaging", "pytest"] + +[[package]] +name = "pikepdf" +version = "9.3.0" +description = "Read and write PDFs with Python, powered by qpdf" +optional = false +python-versions = ">=3.9" +files = [ + {file = "pikepdf-9.3.0-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:f54ad2d6d3e4c564bf1f9c33e4165b4c36aea62c49654f356a5570f99b89c647"}, + {file = "pikepdf-9.3.0-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:a09688758168a86585bb0baeae0a704349285ef40a02da8739be4ad8f4b1aee7"}, + {file = "pikepdf-9.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8422a3944187a8d24626812044b6b09c865426e2bf8d0b2ead80f56f609b3345"}, + {file = "pikepdf-9.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40724cb905ce682c97f048e4eb3a728eade6dd1bc64425f3b7bb9872688964ea"}, + {file = "pikepdf-9.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:663ddb129d823f9e1d1e5b4118906c508b801bf1d86fd8583938f96588bf8dda"}, + {file = "pikepdf-9.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:dbe7d9930789ea56e8b38b3b6b2b0b4e1090509825ceb572b906a1d23dea0282"}, + {file = "pikepdf-9.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:d0d6b11da16d280f83c5406ae0db03521e613c7758212b9104bad3dbf9bf2098"}, + {file = "pikepdf-9.3.0-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:180e7423f3b517688cf14d6c5537e97a1a9b047421915bb28d3198f881b46f14"}, + {file = "pikepdf-9.3.0-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:7a9feafdb688e64e4017b4596c3cf90793cd658b53e915e6c5a2668d1b3eb0c9"}, + {file = "pikepdf-9.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f74ba40a3c6f450d19b0958df5c92f84965f4160fd973d4a00f00492093f01c"}, + {file = "pikepdf-9.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7dd4166bb14db7d0711f2a32b21cf479217e34828af435b7ece0fab6ea02664d"}, + {file = "pikepdf-9.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7ac65c0ace97d995dc7263d2912208ac5310c2f84f42f1fdf043b47d77c01852"}, + {file = "pikepdf-9.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:287206055d2543ee768f85c24146e267c2465c1b2024e37ccf80b5a16674d2a2"}, + {file = "pikepdf-9.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:689fcd1e89857ddc31191d4cc7a1fab2dbb5ce88c347f4de0db41abb176a11fb"}, + {file = "pikepdf-9.3.0-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:5eef37caae6ad7a4baa4a6cdb35690945ee1a83bc0da5bbbf0023bc27d113f9c"}, + {file = "pikepdf-9.3.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:d96804a7e26e2ff37a9c2d796042754b7cae0668ed118a9185169fe1fc3b18d6"}, + {file = "pikepdf-9.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38b3f882351d17f65d38d43d24772cfe471b63dc8c09dad52434c4fe02693e33"}, + {file = "pikepdf-9.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08d0c72ba70cbe9f45772168e0c922b8d7625899cbfbcbd0dfd1316acff90258"}, + {file = "pikepdf-9.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98e546120b0d5707836a5ced43b09c086f5866f6eed93cfe4a0555c987fcba6f"}, + {file = "pikepdf-9.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0da5ebba4a31e257ca86a93657a4d47afffeda2ee48cde25227ce43d6dabae13"}, + {file = "pikepdf-9.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:cd796a039cbaddb6106127f210d5f2160654c0e629c1b663f2d9e6f67bba96b8"}, + {file = "pikepdf-9.3.0-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:7a9a738186b07a1177369713e8003371d0393808e5a62b2af86751dad6684a92"}, + {file = "pikepdf-9.3.0-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:8dbab43c6a6fa2737df6cfccd049bbe5b762c39809a0b14484d0154f403be4fb"}, + {file = "pikepdf-9.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e5bb5e40394d6a15c494469be5026c063676918cbabf48345c7fdf8b2f776f5"}, + {file = "pikepdf-9.3.0-cp39-cp39-macosx_12_0_x86_64.whl", hash = "sha256:344602b23ae6852180587c8e3280719ac31c78a4ca6cf08d8a51467d5f1741ba"}, + {file = "pikepdf-9.3.0-cp39-cp39-macosx_14_0_arm64.whl", hash = "sha256:363d01aa89f871c12fdc3d08c677456d693028cfb865e314cebe679273a7ebcb"}, + {file = "pikepdf-9.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8022a925cb2c67a1de3736c19de5d280d43241e1b118f1188b94df07e84c8b8f"}, + {file = "pikepdf-9.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53202d816838e87ee80c28af695b554e3cbfd5cb3598d7bcfba533f9dbd411e9"}, + {file = "pikepdf-9.3.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:84555d4039ea10935fa2d0084577de5b81b508b9716ce482163e2dc65db1b180"}, + {file = "pikepdf-9.3.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:6b905b05fc32c4e279aceb1578d7d917ed9a4e70a8a8e8d1b40ee8afff9d6bfc"}, + {file = "pikepdf-9.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:3afa0ea7b57a125a7744313b08062e59ecca15b2b3b31d13431244ec99b4d683"}, + {file = "pikepdf-9.3.0-pp310-pypy310_pp73-macosx_12_0_x86_64.whl", hash = "sha256:58e256aec46ee13256e264bae949e23a98707833fc27a3e3c7172c034d0ab870"}, + {file = "pikepdf-9.3.0-pp310-pypy310_pp73-macosx_14_0_arm64.whl", hash = "sha256:18e48cc0359f29b5083bad94237b53d928d8491f7ba5d4a389ca5c366226d766"}, + {file = "pikepdf-9.3.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a56b7ccf13817689adb977ba92efa8d567d42a307154acff156179ddb76668b"}, + {file = "pikepdf-9.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:3ffc14ad4172f7acd7c1c7eb22eeac66f92c93c83941c63a3b56961602af67d7"}, + {file = "pikepdf-9.3.0-pp39-pypy39_pp73-macosx_12_0_x86_64.whl", hash = "sha256:e6bb3466f92b7a741a58fe348285d7bec69ea6102bbe3b2a3f49af0e6f2f3327"}, + {file = "pikepdf-9.3.0-pp39-pypy39_pp73-macosx_14_0_arm64.whl", hash = "sha256:ecb8ab93305f07f806399101858ab9ff350c3e1de819d6043b5d54220cf81e71"}, + {file = "pikepdf-9.3.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f1153d3f7be818ba0f9f0875f37ed5203c3d500c33a4058a4d2d0f978d3ce29"}, + {file = "pikepdf-9.3.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:80630a897d4203be10861e4e7fca8774cf1a85a1abcc41f978984564fb729ef6"}, + {file = "pikepdf-9.3.0.tar.gz", hash = "sha256:906d8afc1aa4f2f7409381a58e158207170f3aeba8ad2aec40072a648e8a2914"}, +] + +[package.dependencies] +Deprecated = "*" +lxml = ">=4.8" +packaging = "*" +Pillow = ">=10.0.1" + +[package.extras] +dev = ["pre-commit", "typer"] +docs = ["Sphinx (>=3)", "sphinx-autoapi", "sphinx-design", "sphinx-issues", "sphinx-rtd-theme", "tomli"] +mypy = ["lxml-stubs", "types-Pillow", "types-requests", "types-setuptools"] +test = ["attrs (>=20.2.0)", "coverage[toml]", "hypothesis (>=6.36)", "numpy (>=1.21.0)", "psutil (>=5.9)", "pybind11", "pytest (>=6.2.5)", "pytest-cov (>=3.0.0)", "pytest-timeout (>=2.1.0)", "pytest-xdist (>=2.5.0)", "python-dateutil (>=2.8.1)", "python-xmp-toolkit (>=2.0.1)", "tomli"] + [[package]] name = "pillow" -version = "10.4.0" +version = "11.0.0" description = "Python Imaging Library (Fork)" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "pillow-10.4.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:4d9667937cfa347525b319ae34375c37b9ee6b525440f3ef48542fcf66f2731e"}, - {file = "pillow-10.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:543f3dc61c18dafb755773efc89aae60d06b6596a63914107f75459cf984164d"}, - {file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7928ecbf1ece13956b95d9cbcfc77137652b02763ba384d9ab508099a2eca856"}, - {file = "pillow-10.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4d49b85c4348ea0b31ea63bc75a9f3857869174e2bf17e7aba02945cd218e6f"}, - {file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:6c762a5b0997f5659a5ef2266abc1d8851ad7749ad9a6a5506eb23d314e4f46b"}, - {file = "pillow-10.4.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a985e028fc183bf12a77a8bbf36318db4238a3ded7fa9df1b9a133f1cb79f8fc"}, - {file = "pillow-10.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:812f7342b0eee081eaec84d91423d1b4650bb9828eb53d8511bcef8ce5aecf1e"}, - {file = "pillow-10.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ac1452d2fbe4978c2eec89fb5a23b8387aba707ac72810d9490118817d9c0b46"}, - {file = "pillow-10.4.0-cp310-cp310-win32.whl", hash = "sha256:bcd5e41a859bf2e84fdc42f4edb7d9aba0a13d29a2abadccafad99de3feff984"}, - {file = "pillow-10.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:ecd85a8d3e79cd7158dec1c9e5808e821feea088e2f69a974db5edf84dc53141"}, - {file = "pillow-10.4.0-cp310-cp310-win_arm64.whl", hash = "sha256:ff337c552345e95702c5fde3158acb0625111017d0e5f24bf3acdb9cc16b90d1"}, - {file = "pillow-10.4.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:0a9ec697746f268507404647e531e92889890a087e03681a3606d9b920fbee3c"}, - {file = "pillow-10.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfe91cb65544a1321e631e696759491ae04a2ea11d36715eca01ce07284738be"}, - {file = "pillow-10.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dc6761a6efc781e6a1544206f22c80c3af4c8cf461206d46a1e6006e4429ff3"}, - {file = "pillow-10.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e84b6cc6a4a3d76c153a6b19270b3526a5a8ed6b09501d3af891daa2a9de7d6"}, - {file = "pillow-10.4.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:bbc527b519bd3aa9d7f429d152fea69f9ad37c95f0b02aebddff592688998abe"}, - {file = "pillow-10.4.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:76a911dfe51a36041f2e756b00f96ed84677cdeb75d25c767f296c1c1eda1319"}, - {file = "pillow-10.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:59291fb29317122398786c2d44427bbd1a6d7ff54017075b22be9d21aa59bd8d"}, - {file = "pillow-10.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:416d3a5d0e8cfe4f27f574362435bc9bae57f679a7158e0096ad2beb427b8696"}, - {file = "pillow-10.4.0-cp311-cp311-win32.whl", hash = "sha256:7086cc1d5eebb91ad24ded9f58bec6c688e9f0ed7eb3dbbf1e4800280a896496"}, - {file = "pillow-10.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cbed61494057c0f83b83eb3a310f0bf774b09513307c434d4366ed64f4128a91"}, - {file = "pillow-10.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:f5f0c3e969c8f12dd2bb7e0b15d5c468b51e5017e01e2e867335c81903046a22"}, - {file = "pillow-10.4.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:673655af3eadf4df6b5457033f086e90299fdd7a47983a13827acf7459c15d94"}, - {file = "pillow-10.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:866b6942a92f56300012f5fbac71f2d610312ee65e22f1aa2609e491284e5597"}, - {file = "pillow-10.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29dbdc4207642ea6aad70fbde1a9338753d33fb23ed6956e706936706f52dd80"}, - {file = "pillow-10.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf2342ac639c4cf38799a44950bbc2dfcb685f052b9e262f446482afaf4bffca"}, - {file = "pillow-10.4.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:f5b92f4d70791b4a67157321c4e8225d60b119c5cc9aee8ecf153aace4aad4ef"}, - {file = "pillow-10.4.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:86dcb5a1eb778d8b25659d5e4341269e8590ad6b4e8b44d9f4b07f8d136c414a"}, - {file = "pillow-10.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:780c072c2e11c9b2c7ca37f9a2ee8ba66f44367ac3e5c7832afcfe5104fd6d1b"}, - {file = "pillow-10.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:37fb69d905be665f68f28a8bba3c6d3223c8efe1edf14cc4cfa06c241f8c81d9"}, - {file = "pillow-10.4.0-cp312-cp312-win32.whl", hash = "sha256:7dfecdbad5c301d7b5bde160150b4db4c659cee2b69589705b6f8a0c509d9f42"}, - {file = "pillow-10.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:1d846aea995ad352d4bdcc847535bd56e0fd88d36829d2c90be880ef1ee4668a"}, - {file = "pillow-10.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:e553cad5179a66ba15bb18b353a19020e73a7921296a7979c4a2b7f6a5cd57f9"}, - {file = "pillow-10.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8bc1a764ed8c957a2e9cacf97c8b2b053b70307cf2996aafd70e91a082e70df3"}, - {file = "pillow-10.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6209bb41dc692ddfee4942517c19ee81b86c864b626dbfca272ec0f7cff5d9fb"}, - {file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bee197b30783295d2eb680b311af15a20a8b24024a19c3a26431ff83eb8d1f70"}, - {file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ef61f5dd14c300786318482456481463b9d6b91ebe5ef12f405afbba77ed0be"}, - {file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:297e388da6e248c98bc4a02e018966af0c5f92dfacf5a5ca22fa01cb3179bca0"}, - {file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:e4db64794ccdf6cb83a59d73405f63adbe2a1887012e308828596100a0b2f6cc"}, - {file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bd2880a07482090a3bcb01f4265f1936a903d70bc740bfcb1fd4e8a2ffe5cf5a"}, - {file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b35b21b819ac1dbd1233317adeecd63495f6babf21b7b2512d244ff6c6ce309"}, - {file = "pillow-10.4.0-cp313-cp313-win32.whl", hash = "sha256:551d3fd6e9dc15e4c1eb6fc4ba2b39c0c7933fa113b220057a34f4bb3268a060"}, - {file = "pillow-10.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:030abdbe43ee02e0de642aee345efa443740aa4d828bfe8e2eb11922ea6a21ea"}, - {file = "pillow-10.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:5b001114dd152cfd6b23befeb28d7aee43553e2402c9f159807bf55f33af8a8d"}, - {file = "pillow-10.4.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:8d4d5063501b6dd4024b8ac2f04962d661222d120381272deea52e3fc52d3736"}, - {file = "pillow-10.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7c1ee6f42250df403c5f103cbd2768a28fe1a0ea1f0f03fe151c8741e1469c8b"}, - {file = "pillow-10.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b15e02e9bb4c21e39876698abf233c8c579127986f8207200bc8a8f6bb27acf2"}, - {file = "pillow-10.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a8d4bade9952ea9a77d0c3e49cbd8b2890a399422258a77f357b9cc9be8d680"}, - {file = "pillow-10.4.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:43efea75eb06b95d1631cb784aa40156177bf9dd5b4b03ff38979e048258bc6b"}, - {file = "pillow-10.4.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:950be4d8ba92aca4b2bb0741285a46bfae3ca699ef913ec8416c1b78eadd64cd"}, - {file = "pillow-10.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d7480af14364494365e89d6fddc510a13e5a2c3584cb19ef65415ca57252fb84"}, - {file = "pillow-10.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:73664fe514b34c8f02452ffb73b7a92c6774e39a647087f83d67f010eb9a0cf0"}, - {file = "pillow-10.4.0-cp38-cp38-win32.whl", hash = "sha256:e88d5e6ad0d026fba7bdab8c3f225a69f063f116462c49892b0149e21b6c0a0e"}, - {file = "pillow-10.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:5161eef006d335e46895297f642341111945e2c1c899eb406882a6c61a4357ab"}, - {file = "pillow-10.4.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:0ae24a547e8b711ccaaf99c9ae3cd975470e1a30caa80a6aaee9a2f19c05701d"}, - {file = "pillow-10.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:298478fe4f77a4408895605f3482b6cc6222c018b2ce565c2b6b9c354ac3229b"}, - {file = "pillow-10.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:134ace6dc392116566980ee7436477d844520a26a4b1bd4053f6f47d096997fd"}, - {file = "pillow-10.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:930044bb7679ab003b14023138b50181899da3f25de50e9dbee23b61b4de2126"}, - {file = "pillow-10.4.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:c76e5786951e72ed3686e122d14c5d7012f16c8303a674d18cdcd6d89557fc5b"}, - {file = "pillow-10.4.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:b2724fdb354a868ddf9a880cb84d102da914e99119211ef7ecbdc613b8c96b3c"}, - {file = "pillow-10.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:dbc6ae66518ab3c5847659e9988c3b60dc94ffb48ef9168656e0019a93dbf8a1"}, - {file = "pillow-10.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:06b2f7898047ae93fad74467ec3d28fe84f7831370e3c258afa533f81ef7f3df"}, - {file = "pillow-10.4.0-cp39-cp39-win32.whl", hash = "sha256:7970285ab628a3779aecc35823296a7869f889b8329c16ad5a71e4901a3dc4ef"}, - {file = "pillow-10.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:961a7293b2457b405967af9c77dcaa43cc1a8cd50d23c532e62d48ab6cdd56f5"}, - {file = "pillow-10.4.0-cp39-cp39-win_arm64.whl", hash = "sha256:32cda9e3d601a52baccb2856b8ea1fc213c90b340c542dcef77140dfa3278a9e"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5b4815f2e65b30f5fbae9dfffa8636d992d49705723fe86a3661806e069352d4"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8f0aef4ef59694b12cadee839e2ba6afeab89c0f39a3adc02ed51d109117b8da"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f4727572e2918acaa9077c919cbbeb73bd2b3ebcfe033b72f858fc9fbef0026"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ff25afb18123cea58a591ea0244b92eb1e61a1fd497bf6d6384f09bc3262ec3e"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dc3e2db6ba09ffd7d02ae9141cfa0ae23393ee7687248d46a7507b75d610f4f5"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:02a2be69f9c9b8c1e97cf2713e789d4e398c751ecfd9967c18d0ce304efbf885"}, - {file = "pillow-10.4.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:0755ffd4a0c6f267cccbae2e9903d95477ca2f77c4fcf3a3a09570001856c8a5"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:a02364621fe369e06200d4a16558e056fe2805d3468350df3aef21e00d26214b"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:1b5dea9831a90e9d0721ec417a80d4cbd7022093ac38a568db2dd78363b00908"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b885f89040bb8c4a1573566bbb2f44f5c505ef6e74cec7ab9068c900047f04b"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87dd88ded2e6d74d31e1e0a99a726a6765cda32d00ba72dc37f0651f306daaa8"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:2db98790afc70118bd0255c2eeb465e9767ecf1f3c25f9a1abb8ffc8cfd1fe0a"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f7baece4ce06bade126fb84b8af1c33439a76d8a6fd818970215e0560ca28c27"}, - {file = "pillow-10.4.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:cfdd747216947628af7b259d274771d84db2268ca062dd5faf373639d00113a3"}, - {file = "pillow-10.4.0.tar.gz", hash = "sha256:166c1cd4d24309b30d61f79f4a9114b7b2313d7450912277855ff5dfd7cd4a06"}, + {file = "pillow-11.0.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:6619654954dc4936fcff82db8eb6401d3159ec6be81e33c6000dfd76ae189947"}, + {file = "pillow-11.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b3c5ac4bed7519088103d9450a1107f76308ecf91d6dabc8a33a2fcfb18d0fba"}, + {file = "pillow-11.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a65149d8ada1055029fcb665452b2814fe7d7082fcb0c5bed6db851cb69b2086"}, + {file = "pillow-11.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88a58d8ac0cc0e7f3a014509f0455248a76629ca9b604eca7dc5927cc593c5e9"}, + {file = "pillow-11.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:c26845094b1af3c91852745ae78e3ea47abf3dbcd1cf962f16b9a5fbe3ee8488"}, + {file = "pillow-11.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:1a61b54f87ab5786b8479f81c4b11f4d61702830354520837f8cc791ebba0f5f"}, + {file = "pillow-11.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:674629ff60030d144b7bca2b8330225a9b11c482ed408813924619c6f302fdbb"}, + {file = "pillow-11.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:598b4e238f13276e0008299bd2482003f48158e2b11826862b1eb2ad7c768b97"}, + {file = "pillow-11.0.0-cp310-cp310-win32.whl", hash = "sha256:9a0f748eaa434a41fccf8e1ee7a3eed68af1b690e75328fd7a60af123c193b50"}, + {file = "pillow-11.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:a5629742881bcbc1f42e840af185fd4d83a5edeb96475a575f4da50d6ede337c"}, + {file = "pillow-11.0.0-cp310-cp310-win_arm64.whl", hash = "sha256:ee217c198f2e41f184f3869f3e485557296d505b5195c513b2bfe0062dc537f1"}, + {file = "pillow-11.0.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:1c1d72714f429a521d8d2d018badc42414c3077eb187a59579f28e4270b4b0fc"}, + {file = "pillow-11.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:499c3a1b0d6fc8213519e193796eb1a86a1be4b1877d678b30f83fd979811d1a"}, + {file = "pillow-11.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c8b2351c85d855293a299038e1f89db92a2f35e8d2f783489c6f0b2b5f3fe8a3"}, + {file = "pillow-11.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f4dba50cfa56f910241eb7f883c20f1e7b1d8f7d91c750cd0b318bad443f4d5"}, + {file = "pillow-11.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:5ddbfd761ee00c12ee1be86c9c0683ecf5bb14c9772ddbd782085779a63dd55b"}, + {file = "pillow-11.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:45c566eb10b8967d71bf1ab8e4a525e5a93519e29ea071459ce517f6b903d7fa"}, + {file = "pillow-11.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b4fd7bd29610a83a8c9b564d457cf5bd92b4e11e79a4ee4716a63c959699b306"}, + {file = "pillow-11.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:cb929ca942d0ec4fac404cbf520ee6cac37bf35be479b970c4ffadf2b6a1cad9"}, + {file = "pillow-11.0.0-cp311-cp311-win32.whl", hash = "sha256:006bcdd307cc47ba43e924099a038cbf9591062e6c50e570819743f5607404f5"}, + {file = "pillow-11.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:52a2d8323a465f84faaba5236567d212c3668f2ab53e1c74c15583cf507a0291"}, + {file = "pillow-11.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:16095692a253047fe3ec028e951fa4221a1f3ed3d80c397e83541a3037ff67c9"}, + {file = "pillow-11.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d2c0a187a92a1cb5ef2c8ed5412dd8d4334272617f532d4ad4de31e0495bd923"}, + {file = "pillow-11.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:084a07ef0821cfe4858fe86652fffac8e187b6ae677e9906e192aafcc1b69903"}, + {file = "pillow-11.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8069c5179902dcdce0be9bfc8235347fdbac249d23bd90514b7a47a72d9fecf4"}, + {file = "pillow-11.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f02541ef64077f22bf4924f225c0fd1248c168f86e4b7abdedd87d6ebaceab0f"}, + {file = "pillow-11.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:fcb4621042ac4b7865c179bb972ed0da0218a076dc1820ffc48b1d74c1e37fe9"}, + {file = "pillow-11.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:00177a63030d612148e659b55ba99527803288cea7c75fb05766ab7981a8c1b7"}, + {file = "pillow-11.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8853a3bf12afddfdf15f57c4b02d7ded92c7a75a5d7331d19f4f9572a89c17e6"}, + {file = "pillow-11.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3107c66e43bda25359d5ef446f59c497de2b5ed4c7fdba0894f8d6cf3822dafc"}, + {file = "pillow-11.0.0-cp312-cp312-win32.whl", hash = "sha256:86510e3f5eca0ab87429dd77fafc04693195eec7fd6a137c389c3eeb4cfb77c6"}, + {file = "pillow-11.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:8ec4a89295cd6cd4d1058a5e6aec6bf51e0eaaf9714774e1bfac7cfc9051db47"}, + {file = "pillow-11.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:27a7860107500d813fcd203b4ea19b04babe79448268403172782754870dac25"}, + {file = "pillow-11.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:bcd1fb5bb7b07f64c15618c89efcc2cfa3e95f0e3bcdbaf4642509de1942a699"}, + {file = "pillow-11.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0e038b0745997c7dcaae350d35859c9715c71e92ffb7e0f4a8e8a16732150f38"}, + {file = "pillow-11.0.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ae08bd8ffc41aebf578c2af2f9d8749d91f448b3bfd41d7d9ff573d74f2a6b2"}, + {file = "pillow-11.0.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d69bfd8ec3219ae71bcde1f942b728903cad25fafe3100ba2258b973bd2bc1b2"}, + {file = "pillow-11.0.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:61b887f9ddba63ddf62fd02a3ba7add935d053b6dd7d58998c630e6dbade8527"}, + {file = "pillow-11.0.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:c6a660307ca9d4867caa8d9ca2c2658ab685de83792d1876274991adec7b93fa"}, + {file = "pillow-11.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:73e3a0200cdda995c7e43dd47436c1548f87a30bb27fb871f352a22ab8dcf45f"}, + {file = "pillow-11.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fba162b8872d30fea8c52b258a542c5dfd7b235fb5cb352240c8d63b414013eb"}, + {file = "pillow-11.0.0-cp313-cp313-win32.whl", hash = "sha256:f1b82c27e89fffc6da125d5eb0ca6e68017faf5efc078128cfaa42cf5cb38798"}, + {file = "pillow-11.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:8ba470552b48e5835f1d23ecb936bb7f71d206f9dfeee64245f30c3270b994de"}, + {file = "pillow-11.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:846e193e103b41e984ac921b335df59195356ce3f71dcfd155aa79c603873b84"}, + {file = "pillow-11.0.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4ad70c4214f67d7466bea6a08061eba35c01b1b89eaa098040a35272a8efb22b"}, + {file = "pillow-11.0.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:6ec0d5af64f2e3d64a165f490d96368bb5dea8b8f9ad04487f9ab60dc4bb6003"}, + {file = "pillow-11.0.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c809a70e43c7977c4a42aefd62f0131823ebf7dd73556fa5d5950f5b354087e2"}, + {file = "pillow-11.0.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:4b60c9520f7207aaf2e1d94de026682fc227806c6e1f55bba7606d1c94dd623a"}, + {file = "pillow-11.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:1e2688958a840c822279fda0086fec1fdab2f95bf2b717b66871c4ad9859d7e8"}, + {file = "pillow-11.0.0-cp313-cp313t-win32.whl", hash = "sha256:607bbe123c74e272e381a8d1957083a9463401f7bd01287f50521ecb05a313f8"}, + {file = "pillow-11.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5c39ed17edea3bc69c743a8dd3e9853b7509625c2462532e62baa0732163a904"}, + {file = "pillow-11.0.0-cp313-cp313t-win_arm64.whl", hash = "sha256:75acbbeb05b86bc53cbe7b7e6fe00fbcf82ad7c684b3ad82e3d711da9ba287d3"}, + {file = "pillow-11.0.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:2e46773dc9f35a1dd28bd6981332fd7f27bec001a918a72a79b4133cf5291dba"}, + {file = "pillow-11.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2679d2258b7f1192b378e2893a8a0a0ca472234d4c2c0e6bdd3380e8dfa21b6a"}, + {file = "pillow-11.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eda2616eb2313cbb3eebbe51f19362eb434b18e3bb599466a1ffa76a033fb916"}, + {file = "pillow-11.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20ec184af98a121fb2da42642dea8a29ec80fc3efbaefb86d8fdd2606619045d"}, + {file = "pillow-11.0.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:8594f42df584e5b4bb9281799698403f7af489fba84c34d53d1c4bfb71b7c4e7"}, + {file = "pillow-11.0.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:c12b5ae868897c7338519c03049a806af85b9b8c237b7d675b8c5e089e4a618e"}, + {file = "pillow-11.0.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:70fbbdacd1d271b77b7721fe3cdd2d537bbbd75d29e6300c672ec6bb38d9672f"}, + {file = "pillow-11.0.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5178952973e588b3f1360868847334e9e3bf49d19e169bbbdfaf8398002419ae"}, + {file = "pillow-11.0.0-cp39-cp39-win32.whl", hash = "sha256:8c676b587da5673d3c75bd67dd2a8cdfeb282ca38a30f37950511766b26858c4"}, + {file = "pillow-11.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:94f3e1780abb45062287b4614a5bc0874519c86a777d4a7ad34978e86428b8dd"}, + {file = "pillow-11.0.0-cp39-cp39-win_arm64.whl", hash = "sha256:290f2cc809f9da7d6d622550bbf4c1e57518212da51b6a30fe8e0a270a5b78bd"}, + {file = "pillow-11.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:1187739620f2b365de756ce086fdb3604573337cc28a0d3ac4a01ab6b2d2a6d2"}, + {file = "pillow-11.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:fbbcb7b57dc9c794843e3d1258c0fbf0f48656d46ffe9e09b63bbd6e8cd5d0a2"}, + {file = "pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d203af30149ae339ad1b4f710d9844ed8796e97fda23ffbc4cc472968a47d0b"}, + {file = "pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21a0d3b115009ebb8ac3d2ebec5c2982cc693da935f4ab7bb5c8ebe2f47d36f2"}, + {file = "pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:73853108f56df97baf2bb8b522f3578221e56f646ba345a372c78326710d3830"}, + {file = "pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e58876c91f97b0952eb766123bfef372792ab3f4e3e1f1a2267834c2ab131734"}, + {file = "pillow-11.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:224aaa38177597bb179f3ec87eeefcce8e4f85e608025e9cfac60de237ba6316"}, + {file = "pillow-11.0.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:5bd2d3bdb846d757055910f0a59792d33b555800813c3b39ada1829c372ccb06"}, + {file = "pillow-11.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:375b8dd15a1f5d2feafff536d47e22f69625c1aa92f12b339ec0b2ca40263273"}, + {file = "pillow-11.0.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:daffdf51ee5db69a82dd127eabecce20729e21f7a3680cf7cbb23f0829189790"}, + {file = "pillow-11.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7326a1787e3c7b0429659e0a944725e1b03eeaa10edd945a86dead1913383944"}, + {file = "pillow-11.0.0.tar.gz", hash = "sha256:72bacbaf24ac003fea9bff9837d1eedb6088758d41e100c1552930151f677739"}, ] [package.extras] -docs = ["furo", "olefile", "sphinx (>=7.3)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"] +docs = ["furo", "olefile", "sphinx (>=8.1)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"] fpx = ["olefile"] mic = ["olefile"] tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] @@ -6567,20 +7053,20 @@ tests = ["pytest (>=5.4.1)", "pytest-cov (>=2.8.1)", "pytest-mypy (>=0.8.0)", "p [[package]] name = "postgrest" -version = "0.17.1" +version = "0.17.2" description = "PostgREST client for Python. This library provides an ORM interface to PostgREST." optional = false -python-versions = "<4.0,>=3.8" +python-versions = "<4.0,>=3.9" files = [ - {file = "postgrest-0.17.1-py3-none-any.whl", hash = "sha256:ec1d00dc8532fe5ffb342cfc7c4e610a1e0e2272eb14f78f9b2b61094f9be510"}, - {file = "postgrest-0.17.1.tar.gz", hash = "sha256:e31d9977dbb80dc5f9fdd4d444014686606692dc4ddb9adc85639e56c6d54c92"}, + {file = "postgrest-0.17.2-py3-none-any.whl", hash = "sha256:f7c4f448e5a5e2d4c1dcf192edae9d1007c4261e9a6fb5116783a0046846ece2"}, + {file = "postgrest-0.17.2.tar.gz", hash = "sha256:445cd4e4a191e279492549df0c4e827d32f9d01d0852599bb8a6efb0f07fcf78"}, ] [package.dependencies] deprecation = ">=2.1.0,<3.0.0" httpx = {version = ">=0.26,<0.28", extras = ["http2"]} pydantic = ">=1.9,<3.0" -strenum = ">=0.4.9,<0.5.0" +strenum = {version = ">=0.4.9,<0.5.0", markers = "python_version < \"3.11\""} [[package]] name = "posthog" @@ -6632,19 +7118,19 @@ dill = ["dill (>=0.3.9)"] [[package]] name = "primp" -version = "0.6.3" +version = "0.6.4" description = "HTTP client that can impersonate web browsers, mimicking their headers and `TLS/JA3/JA4/HTTP2` fingerprints" optional = false python-versions = ">=3.8" files = [ - {file = "primp-0.6.3-cp38-abi3-macosx_10_12_x86_64.whl", hash = "sha256:bdbe6a7cdaaf5c9ed863432a941f4a75bd4c6ff626cbc8d32fc232793c70ba06"}, - {file = "primp-0.6.3-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:eeb53eb987bdcbcd85740633470255cab887d921df713ffa12a36a13366c9cdb"}, - {file = "primp-0.6.3-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78da53d3c92a8e3f05bd3286ac76c291f1b6fe5e08ea63b7ba92b0f9141800bb"}, - {file = "primp-0.6.3-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:86337b44deecdac752bd8112909987fc9fa9b894f30191c80a164dc8f895da53"}, - {file = "primp-0.6.3-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:d3cd9a22b97f3eae42b2a5fb99f00480daf4cd6d9b139e05b0ffb03f7cc037f3"}, - {file = "primp-0.6.3-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:7732bec917e2d3c48a31cdb92e1250f4ad6203a1aa4f802bd9abd84f2286a1e0"}, - {file = "primp-0.6.3-cp38-abi3-win_amd64.whl", hash = "sha256:1e4113c34b86c676ae321af185f03a372caef3ee009f1682c2d62e30ec87348c"}, - {file = "primp-0.6.3.tar.gz", hash = "sha256:17d30ebe26864defad5232dbbe1372e80483940012356e1f68846bb182282039"}, + {file = "primp-0.6.4-cp38-abi3-macosx_10_12_x86_64.whl", hash = "sha256:e627330c1f2b723b523dc2e47caacbc5b5d0cd51ca11583b42fb8cde4da60d7d"}, + {file = "primp-0.6.4-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:e0cb7c05dd56c8b9741042fd568c0983fc19b0f3aa209a3940ecc04b4fd60314"}, + {file = "primp-0.6.4-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a4adc200ccb39e130c478d8b1a94f43a5b359068c6cb65b7c848812f96d96992"}, + {file = "primp-0.6.4-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:0ebae2d3aa36b04028e4accf2609d31d2e6981659e8e2effb09ee8ba960192e1"}, + {file = "primp-0.6.4-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:77f5fa5b34eaf251815622258419a484a2a9179dcbae2a1e702a254d91f613f1"}, + {file = "primp-0.6.4-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:14cddf535cd2c4987412e90ca3ca35ae52cddbee6e0f0953d26b33a652a95692"}, + {file = "primp-0.6.4-cp38-abi3-win_amd64.whl", hash = "sha256:96177ec2dadc47eaecbf0b22d2e93aeaf964a1be9a71e6e318d2ffb9e4242743"}, + {file = "primp-0.6.4.tar.gz", hash = "sha256:0a3de63e46a50664bcdc76e7aaf7060bf8443698efa902864669c5fca0d1abdd"}, ] [package.extras] @@ -6703,112 +7189,108 @@ files = [ [[package]] name = "psutil" -version = "6.0.0" +version = "6.1.0" description = "Cross-platform lib for process and system monitoring in Python." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ - {file = "psutil-6.0.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a021da3e881cd935e64a3d0a20983bda0bb4cf80e4f74fa9bfcb1bc5785360c6"}, - {file = "psutil-6.0.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:1287c2b95f1c0a364d23bc6f2ea2365a8d4d9b726a3be7294296ff7ba97c17f0"}, - {file = "psutil-6.0.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:a9a3dbfb4de4f18174528d87cc352d1f788b7496991cca33c6996f40c9e3c92c"}, - {file = "psutil-6.0.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:6ec7588fb3ddaec7344a825afe298db83fe01bfaaab39155fa84cf1c0d6b13c3"}, - {file = "psutil-6.0.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:1e7c870afcb7d91fdea2b37c24aeb08f98b6d67257a5cb0a8bc3ac68d0f1a68c"}, - {file = "psutil-6.0.0-cp27-none-win32.whl", hash = "sha256:02b69001f44cc73c1c5279d02b30a817e339ceb258ad75997325e0e6169d8b35"}, - {file = "psutil-6.0.0-cp27-none-win_amd64.whl", hash = "sha256:21f1fb635deccd510f69f485b87433460a603919b45e2a324ad65b0cc74f8fb1"}, - {file = "psutil-6.0.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c588a7e9b1173b6e866756dde596fd4cad94f9399daf99ad8c3258b3cb2b47a0"}, - {file = "psutil-6.0.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ed2440ada7ef7d0d608f20ad89a04ec47d2d3ab7190896cd62ca5fc4fe08bf0"}, - {file = "psutil-6.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fd9a97c8e94059b0ef54a7d4baf13b405011176c3b6ff257c247cae0d560ecd"}, - {file = "psutil-6.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2e8d0054fc88153ca0544f5c4d554d42e33df2e009c4ff42284ac9ebdef4132"}, - {file = "psutil-6.0.0-cp36-cp36m-win32.whl", hash = "sha256:fc8c9510cde0146432bbdb433322861ee8c3efbf8589865c8bf8d21cb30c4d14"}, - {file = "psutil-6.0.0-cp36-cp36m-win_amd64.whl", hash = "sha256:34859b8d8f423b86e4385ff3665d3f4d94be3cdf48221fbe476e883514fdb71c"}, - {file = "psutil-6.0.0-cp37-abi3-win32.whl", hash = "sha256:a495580d6bae27291324fe60cea0b5a7c23fa36a7cd35035a16d93bdcf076b9d"}, - {file = "psutil-6.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:33ea5e1c975250a720b3a6609c490db40dae5d83a4eb315170c4fe0d8b1f34b3"}, - {file = "psutil-6.0.0-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:ffe7fc9b6b36beadc8c322f84e1caff51e8703b88eee1da46d1e3a6ae11b4fd0"}, - {file = "psutil-6.0.0.tar.gz", hash = "sha256:8faae4f310b6d969fa26ca0545338b21f73c6b15db7c4a8d934a5482faa818f2"}, + {file = "psutil-6.1.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ff34df86226c0227c52f38b919213157588a678d049688eded74c76c8ba4a5d0"}, + {file = "psutil-6.1.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:c0e0c00aa18ca2d3b2b991643b799a15fc8f0563d2ebb6040f64ce8dc027b942"}, + {file = "psutil-6.1.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:000d1d1ebd634b4efb383f4034437384e44a6d455260aaee2eca1e9c1b55f047"}, + {file = "psutil-6.1.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:5cd2bcdc75b452ba2e10f0e8ecc0b57b827dd5d7aaffbc6821b2a9a242823a76"}, + {file = "psutil-6.1.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:045f00a43c737f960d273a83973b2511430d61f283a44c96bf13a6e829ba8fdc"}, + {file = "psutil-6.1.0-cp27-none-win32.whl", hash = "sha256:9118f27452b70bb1d9ab3198c1f626c2499384935aaf55388211ad982611407e"}, + {file = "psutil-6.1.0-cp27-none-win_amd64.whl", hash = "sha256:a8506f6119cff7015678e2bce904a4da21025cc70ad283a53b099e7620061d85"}, + {file = "psutil-6.1.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6e2dcd475ce8b80522e51d923d10c7871e45f20918e027ab682f94f1c6351688"}, + {file = "psutil-6.1.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:0895b8414afafc526712c498bd9de2b063deaac4021a3b3c34566283464aff8e"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9dcbfce5d89f1d1f2546a2090f4fcf87c7f669d1d90aacb7d7582addece9fb38"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:498c6979f9c6637ebc3a73b3f87f9eb1ec24e1ce53a7c5173b8508981614a90b"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d905186d647b16755a800e7263d43df08b790d709d575105d419f8b6ef65423a"}, + {file = "psutil-6.1.0-cp36-cp36m-win32.whl", hash = "sha256:6d3fbbc8d23fcdcb500d2c9f94e07b1342df8ed71b948a2649b5cb060a7c94ca"}, + {file = "psutil-6.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:1209036fbd0421afde505a4879dee3b2fd7b1e14fee81c0069807adcbbcca747"}, + {file = "psutil-6.1.0-cp37-abi3-win32.whl", hash = "sha256:1ad45a1f5d0b608253b11508f80940985d1d0c8f6111b5cb637533a0e6ddc13e"}, + {file = "psutil-6.1.0-cp37-abi3-win_amd64.whl", hash = "sha256:a8fb3752b491d246034fa4d279ff076501588ce8cbcdbb62c32fd7a377d996be"}, + {file = "psutil-6.1.0.tar.gz", hash = "sha256:353815f59a7f64cdaca1c0307ee13558a0512f6db064e92fe833784f08539c7a"}, ] [package.extras] -test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] +dev = ["black", "check-manifest", "coverage", "packaging", "pylint", "pyperf", "pypinfo", "pytest-cov", "requests", "rstcheck", "ruff", "sphinx", "sphinx_rtd_theme", "toml-sort", "twine", "virtualenv", "wheel"] +test = ["pytest", "pytest-xdist", "setuptools"] [[package]] name = "psycopg2-binary" -version = "2.9.9" +version = "2.9.10" description = "psycopg2 - Python-PostgreSQL Database Adapter" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "psycopg2-binary-2.9.9.tar.gz", hash = "sha256:7f01846810177d829c7692f1f5ada8096762d9172af1b1a28d4ab5b77c923c1c"}, - {file = "psycopg2_binary-2.9.9-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c2470da5418b76232f02a2fcd2229537bb2d5a7096674ce61859c3229f2eb202"}, - {file = "psycopg2_binary-2.9.9-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c6af2a6d4b7ee9615cbb162b0738f6e1fd1f5c3eda7e5da17861eacf4c717ea7"}, - {file = "psycopg2_binary-2.9.9-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:75723c3c0fbbf34350b46a3199eb50638ab22a0228f93fb472ef4d9becc2382b"}, - {file = "psycopg2_binary-2.9.9-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83791a65b51ad6ee6cf0845634859d69a038ea9b03d7b26e703f94c7e93dbcf9"}, - {file = "psycopg2_binary-2.9.9-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0ef4854e82c09e84cc63084a9e4ccd6d9b154f1dbdd283efb92ecd0b5e2b8c84"}, - {file = "psycopg2_binary-2.9.9-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed1184ab8f113e8d660ce49a56390ca181f2981066acc27cf637d5c1e10ce46e"}, - {file = "psycopg2_binary-2.9.9-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d2997c458c690ec2bc6b0b7ecbafd02b029b7b4283078d3b32a852a7ce3ddd98"}, - {file = "psycopg2_binary-2.9.9-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:b58b4710c7f4161b5e9dcbe73bb7c62d65670a87df7bcce9e1faaad43e715245"}, - {file = "psycopg2_binary-2.9.9-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:0c009475ee389757e6e34611d75f6e4f05f0cf5ebb76c6037508318e1a1e0d7e"}, - {file = "psycopg2_binary-2.9.9-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8dbf6d1bc73f1d04ec1734bae3b4fb0ee3cb2a493d35ede9badbeb901fb40f6f"}, - {file = "psycopg2_binary-2.9.9-cp310-cp310-win32.whl", hash = "sha256:3f78fd71c4f43a13d342be74ebbc0666fe1f555b8837eb113cb7416856c79682"}, - {file = "psycopg2_binary-2.9.9-cp310-cp310-win_amd64.whl", hash = "sha256:876801744b0dee379e4e3c38b76fc89f88834bb15bf92ee07d94acd06ec890a0"}, - {file = "psycopg2_binary-2.9.9-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ee825e70b1a209475622f7f7b776785bd68f34af6e7a46e2e42f27b659b5bc26"}, - {file = "psycopg2_binary-2.9.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1ea665f8ce695bcc37a90ee52de7a7980be5161375d42a0b6c6abedbf0d81f0f"}, - {file = "psycopg2_binary-2.9.9-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:143072318f793f53819048fdfe30c321890af0c3ec7cb1dfc9cc87aa88241de2"}, - {file = "psycopg2_binary-2.9.9-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c332c8d69fb64979ebf76613c66b985414927a40f8defa16cf1bc028b7b0a7b0"}, - {file = "psycopg2_binary-2.9.9-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7fc5a5acafb7d6ccca13bfa8c90f8c51f13d8fb87d95656d3950f0158d3ce53"}, - {file = "psycopg2_binary-2.9.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:977646e05232579d2e7b9c59e21dbe5261f403a88417f6a6512e70d3f8a046be"}, - {file = "psycopg2_binary-2.9.9-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b6356793b84728d9d50ead16ab43c187673831e9d4019013f1402c41b1db9b27"}, - {file = "psycopg2_binary-2.9.9-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:bc7bb56d04601d443f24094e9e31ae6deec9ccb23581f75343feebaf30423359"}, - {file = "psycopg2_binary-2.9.9-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:77853062a2c45be16fd6b8d6de2a99278ee1d985a7bd8b103e97e41c034006d2"}, - {file = "psycopg2_binary-2.9.9-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:78151aa3ec21dccd5cdef6c74c3e73386dcdfaf19bced944169697d7ac7482fc"}, - {file = "psycopg2_binary-2.9.9-cp311-cp311-win32.whl", hash = "sha256:dc4926288b2a3e9fd7b50dc6a1909a13bbdadfc67d93f3374d984e56f885579d"}, - {file = "psycopg2_binary-2.9.9-cp311-cp311-win_amd64.whl", hash = "sha256:b76bedd166805480ab069612119ea636f5ab8f8771e640ae103e05a4aae3e417"}, - {file = "psycopg2_binary-2.9.9-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:8532fd6e6e2dc57bcb3bc90b079c60de896d2128c5d9d6f24a63875a95a088cf"}, - {file = "psycopg2_binary-2.9.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b0605eaed3eb239e87df0d5e3c6489daae3f7388d455d0c0b4df899519c6a38d"}, - {file = "psycopg2_binary-2.9.9-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f8544b092a29a6ddd72f3556a9fcf249ec412e10ad28be6a0c0d948924f2212"}, - {file = "psycopg2_binary-2.9.9-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2d423c8d8a3c82d08fe8af900ad5b613ce3632a1249fd6a223941d0735fce493"}, - {file = "psycopg2_binary-2.9.9-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e5afae772c00980525f6d6ecf7cbca55676296b580c0e6abb407f15f3706996"}, - {file = "psycopg2_binary-2.9.9-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e6f98446430fdf41bd36d4faa6cb409f5140c1c2cf58ce0bbdaf16af7d3f119"}, - {file = "psycopg2_binary-2.9.9-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c77e3d1862452565875eb31bdb45ac62502feabbd53429fdc39a1cc341d681ba"}, - {file = "psycopg2_binary-2.9.9-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:cb16c65dcb648d0a43a2521f2f0a2300f40639f6f8c1ecbc662141e4e3e1ee07"}, - {file = "psycopg2_binary-2.9.9-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:911dda9c487075abd54e644ccdf5e5c16773470a6a5d3826fda76699410066fb"}, - {file = "psycopg2_binary-2.9.9-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:57fede879f08d23c85140a360c6a77709113efd1c993923c59fde17aa27599fe"}, - {file = "psycopg2_binary-2.9.9-cp312-cp312-win32.whl", hash = "sha256:64cf30263844fa208851ebb13b0732ce674d8ec6a0c86a4e160495d299ba3c93"}, - {file = "psycopg2_binary-2.9.9-cp312-cp312-win_amd64.whl", hash = "sha256:81ff62668af011f9a48787564ab7eded4e9fb17a4a6a74af5ffa6a457400d2ab"}, - {file = "psycopg2_binary-2.9.9-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2293b001e319ab0d869d660a704942c9e2cce19745262a8aba2115ef41a0a42a"}, - {file = "psycopg2_binary-2.9.9-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:03ef7df18daf2c4c07e2695e8cfd5ee7f748a1d54d802330985a78d2a5a6dca9"}, - {file = "psycopg2_binary-2.9.9-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a602ea5aff39bb9fac6308e9c9d82b9a35c2bf288e184a816002c9fae930b77"}, - {file = "psycopg2_binary-2.9.9-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8359bf4791968c5a78c56103702000105501adb557f3cf772b2c207284273984"}, - {file = "psycopg2_binary-2.9.9-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:275ff571376626195ab95a746e6a04c7df8ea34638b99fc11160de91f2fef503"}, - {file = "psycopg2_binary-2.9.9-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:f9b5571d33660d5009a8b3c25dc1db560206e2d2f89d3df1cb32d72c0d117d52"}, - {file = "psycopg2_binary-2.9.9-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:420f9bbf47a02616e8554e825208cb947969451978dceb77f95ad09c37791dae"}, - {file = "psycopg2_binary-2.9.9-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:4154ad09dac630a0f13f37b583eae260c6aa885d67dfbccb5b02c33f31a6d420"}, - {file = "psycopg2_binary-2.9.9-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a148c5d507bb9b4f2030a2025c545fccb0e1ef317393eaba42e7eabd28eb6041"}, - {file = "psycopg2_binary-2.9.9-cp37-cp37m-win32.whl", hash = "sha256:68fc1f1ba168724771e38bee37d940d2865cb0f562380a1fb1ffb428b75cb692"}, - {file = "psycopg2_binary-2.9.9-cp37-cp37m-win_amd64.whl", hash = "sha256:281309265596e388ef483250db3640e5f414168c5a67e9c665cafce9492eda2f"}, - {file = "psycopg2_binary-2.9.9-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:60989127da422b74a04345096c10d416c2b41bd7bf2a380eb541059e4e999980"}, - {file = "psycopg2_binary-2.9.9-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:246b123cc54bb5361588acc54218c8c9fb73068bf227a4a531d8ed56fa3ca7d6"}, - {file = "psycopg2_binary-2.9.9-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34eccd14566f8fe14b2b95bb13b11572f7c7d5c36da61caf414d23b91fcc5d94"}, - {file = "psycopg2_binary-2.9.9-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18d0ef97766055fec15b5de2c06dd8e7654705ce3e5e5eed3b6651a1d2a9a152"}, - {file = "psycopg2_binary-2.9.9-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d3f82c171b4ccd83bbaf35aa05e44e690113bd4f3b7b6cc54d2219b132f3ae55"}, - {file = "psycopg2_binary-2.9.9-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ead20f7913a9c1e894aebe47cccf9dc834e1618b7aa96155d2091a626e59c972"}, - {file = "psycopg2_binary-2.9.9-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ca49a8119c6cbd77375ae303b0cfd8c11f011abbbd64601167ecca18a87e7cdd"}, - {file = "psycopg2_binary-2.9.9-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:323ba25b92454adb36fa425dc5cf6f8f19f78948cbad2e7bc6cdf7b0d7982e59"}, - {file = "psycopg2_binary-2.9.9-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:1236ed0952fbd919c100bc839eaa4a39ebc397ed1c08a97fc45fee2a595aa1b3"}, - {file = "psycopg2_binary-2.9.9-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:729177eaf0aefca0994ce4cffe96ad3c75e377c7b6f4efa59ebf003b6d398716"}, - {file = "psycopg2_binary-2.9.9-cp38-cp38-win32.whl", hash = "sha256:804d99b24ad523a1fe18cc707bf741670332f7c7412e9d49cb5eab67e886b9b5"}, - {file = "psycopg2_binary-2.9.9-cp38-cp38-win_amd64.whl", hash = "sha256:a6cdcc3ede532f4a4b96000b6362099591ab4a3e913d70bcbac2b56c872446f7"}, - {file = "psycopg2_binary-2.9.9-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:72dffbd8b4194858d0941062a9766f8297e8868e1dd07a7b36212aaa90f49472"}, - {file = "psycopg2_binary-2.9.9-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:30dcc86377618a4c8f3b72418df92e77be4254d8f89f14b8e8f57d6d43603c0f"}, - {file = "psycopg2_binary-2.9.9-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:31a34c508c003a4347d389a9e6fcc2307cc2150eb516462a7a17512130de109e"}, - {file = "psycopg2_binary-2.9.9-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15208be1c50b99203fe88d15695f22a5bed95ab3f84354c494bcb1d08557df67"}, - {file = "psycopg2_binary-2.9.9-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1873aade94b74715be2246321c8650cabf5a0d098a95bab81145ffffa4c13876"}, - {file = "psycopg2_binary-2.9.9-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a58c98a7e9c021f357348867f537017057c2ed7f77337fd914d0bedb35dace7"}, - {file = "psycopg2_binary-2.9.9-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4686818798f9194d03c9129a4d9a702d9e113a89cb03bffe08c6cf799e053291"}, - {file = "psycopg2_binary-2.9.9-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ebdc36bea43063116f0486869652cb2ed7032dbc59fbcb4445c4862b5c1ecf7f"}, - {file = "psycopg2_binary-2.9.9-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:ca08decd2697fdea0aea364b370b1249d47336aec935f87b8bbfd7da5b2ee9c1"}, - {file = "psycopg2_binary-2.9.9-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ac05fb791acf5e1a3e39402641827780fe44d27e72567a000412c648a85ba860"}, - {file = "psycopg2_binary-2.9.9-cp39-cp39-win32.whl", hash = "sha256:9dba73be7305b399924709b91682299794887cbbd88e38226ed9f6712eabee90"}, - {file = "psycopg2_binary-2.9.9-cp39-cp39-win_amd64.whl", hash = "sha256:f7ae5d65ccfbebdfa761585228eb4d0df3a8b15cfb53bd953e713e09fbb12957"}, + {file = "psycopg2-binary-2.9.10.tar.gz", hash = "sha256:4b3df0e6990aa98acda57d983942eff13d824135fe2250e6522edaa782a06de2"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:0ea8e3d0ae83564f2fc554955d327fa081d065c8ca5cc6d2abb643e2c9c1200f"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:3e9c76f0ac6f92ecfc79516a8034a544926430f7b080ec5a0537bca389ee0906"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ad26b467a405c798aaa1458ba09d7e2b6e5f96b1ce0ac15d82fd9f95dc38a92"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:270934a475a0e4b6925b5f804e3809dd5f90f8613621d062848dd82f9cd62007"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:48b338f08d93e7be4ab2b5f1dbe69dc5e9ef07170fe1f86514422076d9c010d0"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f4152f8f76d2023aac16285576a9ecd2b11a9895373a1f10fd9db54b3ff06b4"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:32581b3020c72d7a421009ee1c6bf4a131ef5f0a968fab2e2de0c9d2bb4577f1"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:2ce3e21dc3437b1d960521eca599d57408a695a0d3c26797ea0f72e834c7ffe5"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e984839e75e0b60cfe75e351db53d6db750b00de45644c5d1f7ee5d1f34a1ce5"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3c4745a90b78e51d9ba06e2088a2fe0c693ae19cc8cb051ccda44e8df8a6eb53"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-win32.whl", hash = "sha256:e5720a5d25e3b99cd0dc5c8a440570469ff82659bb09431c1439b92caf184d3b"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-win_amd64.whl", hash = "sha256:3c18f74eb4386bf35e92ab2354a12c17e5eb4d9798e4c0ad3a00783eae7cd9f1"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:04392983d0bb89a8717772a193cfaac58871321e3ec69514e1c4e0d4957b5aff"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:1a6784f0ce3fec4edc64e985865c17778514325074adf5ad8f80636cd029ef7c"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5f86c56eeb91dc3135b3fd8a95dc7ae14c538a2f3ad77a19645cf55bab1799c"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b3d2491d4d78b6b14f76881905c7a8a8abcf974aad4a8a0b065273a0ed7a2cb"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2286791ececda3a723d1910441c793be44625d86d1a4e79942751197f4d30341"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:512d29bb12608891e349af6a0cccedce51677725a921c07dba6342beaf576f9a"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5a507320c58903967ef7384355a4da7ff3f28132d679aeb23572753cbf2ec10b"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:6d4fa1079cab9018f4d0bd2db307beaa612b0d13ba73b5c6304b9fe2fb441ff7"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:851485a42dbb0bdc1edcdabdb8557c09c9655dfa2ca0460ff210522e073e319e"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:35958ec9e46432d9076286dda67942ed6d968b9c3a6a2fd62b48939d1d78bf68"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-win32.whl", hash = "sha256:ecced182e935529727401b24d76634a357c71c9275b356efafd8a2a91ec07392"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-win_amd64.whl", hash = "sha256:ee0e8c683a7ff25d23b55b11161c2663d4b099770f6085ff0a20d4505778d6b4"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:880845dfe1f85d9d5f7c412efea7a08946a46894537e4e5d091732eb1d34d9a0"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:9440fa522a79356aaa482aa4ba500b65f28e5d0e63b801abf6aa152a29bd842a"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3923c1d9870c49a2d44f795df0c889a22380d36ef92440ff618ec315757e539"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b2c956c028ea5de47ff3a8d6b3cc3330ab45cf0b7c3da35a2d6ff8420896526"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f758ed67cab30b9a8d2833609513ce4d3bd027641673d4ebc9c067e4d208eec1"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cd9b4f2cfab88ed4a9106192de509464b75a906462fb846b936eabe45c2063e"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6dc08420625b5a20b53551c50deae6e231e6371194fa0651dbe0fb206452ae1f"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:d7cd730dfa7c36dbe8724426bf5612798734bff2d3c3857f36f2733f5bfc7c00"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:155e69561d54d02b3c3209545fb08938e27889ff5a10c19de8d23eb5a41be8a5"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c3cc28a6fd5a4a26224007712e79b81dbaee2ffb90ff406256158ec4d7b52b47"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-win32.whl", hash = "sha256:ec8a77f521a17506a24a5f626cb2aee7850f9b69a0afe704586f63a464f3cd64"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-win_amd64.whl", hash = "sha256:18c5ee682b9c6dd3696dad6e54cc7ff3a1a9020df6a5c0f861ef8bfd338c3ca0"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:26540d4a9a4e2b096f1ff9cce51253d0504dca5a85872c7f7be23be5a53eb18d"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:e217ce4d37667df0bc1c397fdcd8de5e81018ef305aed9415c3b093faaeb10fb"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:245159e7ab20a71d989da00f280ca57da7641fa2cdcf71749c193cea540a74f7"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c4ded1a24b20021ebe677b7b08ad10bf09aac197d6943bfe6fec70ac4e4690d"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3abb691ff9e57d4a93355f60d4f4c1dd2d68326c968e7db17ea96df3c023ef73"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8608c078134f0b3cbd9f89b34bd60a943b23fd33cc5f065e8d5f840061bd0673"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:230eeae2d71594103cd5b93fd29d1ace6420d0b86f4778739cb1a5a32f607d1f"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:bb89f0a835bcfc1d42ccd5f41f04870c1b936d8507c6df12b7737febc40f0909"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f0c2d907a1e102526dd2986df638343388b94c33860ff3bbe1384130828714b1"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f8157bed2f51db683f31306aa497311b560f2265998122abe1dce6428bd86567"}, + {file = "psycopg2_binary-2.9.10-cp38-cp38-macosx_12_0_x86_64.whl", hash = "sha256:eb09aa7f9cecb45027683bb55aebaaf45a0df8bf6de68801a6afdc7947bb09d4"}, + {file = "psycopg2_binary-2.9.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b73d6d7f0ccdad7bc43e6d34273f70d587ef62f824d7261c4ae9b8b1b6af90e8"}, + {file = "psycopg2_binary-2.9.10-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ce5ab4bf46a211a8e924d307c1b1fcda82368586a19d0a24f8ae166f5c784864"}, + {file = "psycopg2_binary-2.9.10-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:056470c3dc57904bbf63d6f534988bafc4e970ffd50f6271fc4ee7daad9498a5"}, + {file = "psycopg2_binary-2.9.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:73aa0e31fa4bb82578f3a6c74a73c273367727de397a7a0f07bd83cbea696baa"}, + {file = "psycopg2_binary-2.9.10-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8de718c0e1c4b982a54b41779667242bc630b2197948405b7bd8ce16bcecac92"}, + {file = "psycopg2_binary-2.9.10-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:5c370b1e4975df846b0277b4deba86419ca77dbc25047f535b0bb03d1a544d44"}, + {file = "psycopg2_binary-2.9.10-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:ffe8ed017e4ed70f68b7b371d84b7d4a790368db9203dfc2d222febd3a9c8863"}, + {file = "psycopg2_binary-2.9.10-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:8aecc5e80c63f7459a1a2ab2c64df952051df196294d9f739933a9f6687e86b3"}, + {file = "psycopg2_binary-2.9.10-cp39-cp39-macosx_12_0_x86_64.whl", hash = "sha256:7a813c8bdbaaaab1f078014b9b0b13f5de757e2b5d9be6403639b298a04d218b"}, + {file = "psycopg2_binary-2.9.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d00924255d7fc916ef66e4bf22f354a940c67179ad3fd7067d7a0a9c84d2fbfc"}, + {file = "psycopg2_binary-2.9.10-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7559bce4b505762d737172556a4e6ea8a9998ecac1e39b5233465093e8cee697"}, + {file = "psycopg2_binary-2.9.10-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8b58f0a96e7a1e341fc894f62c1177a7c83febebb5ff9123b579418fdc8a481"}, + {file = "psycopg2_binary-2.9.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b269105e59ac96aba877c1707c600ae55711d9dcd3fc4b5012e4af68e30c648"}, + {file = "psycopg2_binary-2.9.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:79625966e176dc97ddabc142351e0409e28acf4660b88d1cf6adb876d20c490d"}, + {file = "psycopg2_binary-2.9.10-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:8aabf1c1a04584c168984ac678a668094d831f152859d06e055288fa515e4d30"}, + {file = "psycopg2_binary-2.9.10-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:19721ac03892001ee8fdd11507e6a2e01f4e37014def96379411ca99d78aeb2c"}, + {file = "psycopg2_binary-2.9.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7f5d859928e635fa3ce3477704acee0f667b3a3d3e4bb109f2b18d4005f38287"}, + {file = "psycopg2_binary-2.9.10-cp39-cp39-win32.whl", hash = "sha256:3216ccf953b3f267691c90c6fe742e45d890d8272326b4a8b20850a03d05b7b8"}, + {file = "psycopg2_binary-2.9.10-cp39-cp39-win_amd64.whl", hash = "sha256:30e34c4e97964805f715206c7b789d54a78b70f3ff19fbe590104b71c45600e5"}, ] [[package]] @@ -6863,19 +7345,6 @@ files = [ {file = "pyarrow-17.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:392bc9feabc647338e6c89267635e111d71edad5fcffba204425a7c8d13610d7"}, {file = "pyarrow-17.0.0-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:af5ff82a04b2171415f1410cff7ebb79861afc5dae50be73ce06d6e870615204"}, {file = "pyarrow-17.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:edca18eaca89cd6382dfbcff3dd2d87633433043650c07375d095cd3517561d8"}, - {file = "pyarrow-17.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7c7916bff914ac5d4a8fe25b7a25e432ff921e72f6f2b7547d1e325c1ad9d155"}, - {file = "pyarrow-17.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f553ca691b9e94b202ff741bdd40f6ccb70cdd5fbf65c187af132f1317de6145"}, - {file = "pyarrow-17.0.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:0cdb0e627c86c373205a2f94a510ac4376fdc523f8bb36beab2e7f204416163c"}, - {file = "pyarrow-17.0.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:d7d192305d9d8bc9082d10f361fc70a73590a4c65cf31c3e6926cd72b76bc35c"}, - {file = "pyarrow-17.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:02dae06ce212d8b3244dd3e7d12d9c4d3046945a5933d28026598e9dbbda1fca"}, - {file = "pyarrow-17.0.0-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:13d7a460b412f31e4c0efa1148e1d29bdf18ad1411eb6757d38f8fbdcc8645fb"}, - {file = "pyarrow-17.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9b564a51fbccfab5a04a80453e5ac6c9954a9c5ef2890d1bcf63741909c3f8df"}, - {file = "pyarrow-17.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32503827abbc5aadedfa235f5ece8c4f8f8b0a3cf01066bc8d29de7539532687"}, - {file = "pyarrow-17.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a155acc7f154b9ffcc85497509bcd0d43efb80d6f733b0dc3bb14e281f131c8b"}, - {file = "pyarrow-17.0.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:dec8d129254d0188a49f8a1fc99e0560dc1b85f60af729f47de4046015f9b0a5"}, - {file = "pyarrow-17.0.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:a48ddf5c3c6a6c505904545c25a4ae13646ae1f8ba703c4df4a1bfe4f4006bda"}, - {file = "pyarrow-17.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:42bf93249a083aca230ba7e2786c5f673507fa97bbd9725a1e2754715151a204"}, - {file = "pyarrow-17.0.0.tar.gz", hash = "sha256:4beca9521ed2c0921c1023e68d097d0299b62c362639ea315572a58f3f50fd28"}, ] [package.dependencies] @@ -6909,6 +7378,48 @@ files = [ [package.dependencies] pyasn1 = ">=0.4.6,<0.7.0" +[[package]] +name = "pycocotools" +version = "2.0.8" +description = "Official APIs for the MS-COCO dataset" +optional = false +python-versions = ">=3.9" +files = [ + {file = "pycocotools-2.0.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:9a66886f45b04cee1ff0492e9f5e25d430d8aa3eb63e63c4ebc620945caa11b9"}, + {file = "pycocotools-2.0.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:257130b65b7b0f122ce1ed62942867ca9789e56a68109682796cc85c9770c74a"}, + {file = "pycocotools-2.0.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:663c14cd471913aabecb17ddb52b3b254a65dcaba26ccfea408c52c75cc3862c"}, + {file = "pycocotools-2.0.8-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:35a6ef931448632efe1c83eb2ac3c37c53b3c080a5432bc6ff1858944a603a2d"}, + {file = "pycocotools-2.0.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e7b4ee8b15539d6f789857faefe7d3eef81755f7b17f60903798524e4f321a5c"}, + {file = "pycocotools-2.0.8-cp310-cp310-win_amd64.whl", hash = "sha256:889edd2dbf61f4d2fe77c2e8e5608476903d1911d2ed00f9911354eff23f2423"}, + {file = "pycocotools-2.0.8-cp310-cp310-win_arm64.whl", hash = "sha256:52e06a833fad735485cad5c1f8fe40e2b586261b2856806b5d6923b0b5a3c971"}, + {file = "pycocotools-2.0.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:92bf788e6936fc52b57ccaaa78ecdaeac81872eebbfc45b6fe16ae18b85709bd"}, + {file = "pycocotools-2.0.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a07f57f991e379959c0f4a1b9ea35d875876433b7f45c6d8fe6b718e58834bc"}, + {file = "pycocotools-2.0.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5968a1e5421719af9eb7ccee4c540bfb18b1fc95d30d9a48571d0aaeb159a1ae"}, + {file = "pycocotools-2.0.8-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:59eb7b1839f269262456347b6fe2bb88a8be56b32d87fab946483746e1f18a07"}, + {file = "pycocotools-2.0.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:05480f731fcd7c5d05389081f84198f3b8117f4560227185bc462cccb5c79181"}, + {file = "pycocotools-2.0.8-cp311-cp311-win_amd64.whl", hash = "sha256:e680e27e58b840c105fa09a3bb1d91706038c5c8d7b7bf09c2e5ecbd1b05ad7f"}, + {file = "pycocotools-2.0.8-cp311-cp311-win_arm64.whl", hash = "sha256:16c5a1d2c8726149b5a0e6fe95095ffc172d4012ece5dee9b5beeef708fc0284"}, + {file = "pycocotools-2.0.8-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:dd4616621d062882db677de5c64b1b0f6efbcaed9fd284b61e7ba4b16ab24d7a"}, + {file = "pycocotools-2.0.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5683ba2612c39094a2e8453d40349768a3da6673376786651481d6f553ff7b50"}, + {file = "pycocotools-2.0.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b89f399eb851d18f68dfa7f126380394ec0820915c7b3831dd37563bc58daa95"}, + {file = "pycocotools-2.0.8-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:e6d528c4f35580347ee3cd57f92cf0926e9b6a688d0904b2ea8a814ae2e57a47"}, + {file = "pycocotools-2.0.8-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:56bbe8be608def61da0b4430562b8d5ff14525f509631a667cfd8405325193da"}, + {file = "pycocotools-2.0.8-cp312-cp312-win_amd64.whl", hash = "sha256:d004033e760a172b2ccbdf4a62d20d2bcf0c9b40dc3c0d1d724045b0a6944862"}, + {file = "pycocotools-2.0.8-cp312-cp312-win_arm64.whl", hash = "sha256:87853ca11e9b130e461d6b5284ea475efe35429060a915844e1998d206ba028e"}, + {file = "pycocotools-2.0.8-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2b432353a20ce9dd44d85d093c4520fa941cd6cd8a5346443f2056eb0cbdae2b"}, + {file = "pycocotools-2.0.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b53d36452ec0f1069d94a311aea051a36e8c7f8f63411db372e0ac89e826149"}, + {file = "pycocotools-2.0.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7aba650cc2e0472cc773a994f196c24937c8da1be87e02e72c180c8144aea11f"}, + {file = "pycocotools-2.0.8-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a7029806ceea48379ee2f33cc33d79bbaf64b627df444641f123a00f70e8609a"}, + {file = "pycocotools-2.0.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:fa750afead393671f6c6e40e22d8fd197157f9fa5ee1fa4aba325bbe86c0de1b"}, + {file = "pycocotools-2.0.8-cp39-cp39-win_amd64.whl", hash = "sha256:5ecb969dd07390b593893dbc45fc361d9b1f2cb3abd5dc7ff68afb0803f71b29"}, + {file = "pycocotools-2.0.8-cp39-cp39-win_arm64.whl", hash = "sha256:26b329c27e42e092f412faa5ff5bf6e1c4286a8e1709e474b640d356d1d0ae07"}, + {file = "pycocotools-2.0.8.tar.gz", hash = "sha256:8f2bcedb786ba26c367a3680f9c4eb5b2ad9dccb2b34eaeb205e0a021e1dfb8d"}, +] + +[package.dependencies] +matplotlib = ">=2.1.0" +numpy = "*" + [[package]] name = "pycparser" version = "2.22" @@ -7285,6 +7796,27 @@ files = [ [package.extras] diagrams = ["jinja2", "railroad-diagrams"] +[[package]] +name = "pypdf" +version = "5.0.1" +description = "A pure-python PDF library capable of splitting, merging, cropping, and transforming PDF files" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pypdf-5.0.1-py3-none-any.whl", hash = "sha256:ff8a32da6c7a63fea9c32fa4dd837cdd0db7966adf6c14f043e3f12592e992db"}, + {file = "pypdf-5.0.1.tar.gz", hash = "sha256:a361c3c372b4a659f9c8dd438d5ce29a753c79c620dc6e1fd66977651f5547ea"}, +] + +[package.dependencies] +typing_extensions = {version = ">=4.0", markers = "python_version < \"3.11\""} + +[package.extras] +crypto = ["PyCryptodome", "cryptography"] +dev = ["black", "flit", "pip-tools", "pre-commit (<2.18.0)", "pytest-cov", "pytest-socket", "pytest-timeout", "pytest-xdist", "wheel"] +docs = ["myst_parser", "sphinx", "sphinx_rtd_theme"] +full = ["Pillow (>=8.0.0)", "PyCryptodome", "cryptography"] +image = ["Pillow (>=8.0.0)"] + [[package]] name = "pypdfium2" version = "4.17.0" @@ -7540,13 +8072,13 @@ files = [ [[package]] name = "python-dateutil" -version = "2.9.0.post0" +version = "2.8.2" description = "Extensions to the standard Python datetime module" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, - {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, + {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, + {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, ] [package.dependencies] @@ -7583,17 +8115,17 @@ cli = ["click (>=5.0)"] [[package]] name = "python-iso639" -version = "2024.4.27" +version = "2024.10.22" description = "ISO 639 language codes, names, and other associated information" optional = false python-versions = ">=3.8" files = [ - {file = "python_iso639-2024.4.27-py3-none-any.whl", hash = "sha256:27526a84cebc4c4d53fea9d1ebbc7209c8d279bebaa343e6765a1fc8780565ab"}, - {file = "python_iso639-2024.4.27.tar.gz", hash = "sha256:97e63b5603e085c6a56a12a95740010e75d9134e0aab767e0978b53fd8824f13"}, + {file = "python_iso639-2024.10.22-py3-none-any.whl", hash = "sha256:02d3ce2e01c6896b30b9cbbd3e1c8ee0d7221250b5d63ea9803e0d2a81fd1047"}, + {file = "python_iso639-2024.10.22.tar.gz", hash = "sha256:750f21b6a0bc6baa24253a3d8aae92b582bf93aa40988361cd96852c2c6d9a52"}, ] [package.extras] -dev = ["black (==24.4.2)", "build (==1.2.1)", "flake8 (==7.0.0)", "pytest (==8.1.2)", "requests (==2.31.0)", "twine (==5.0.0)"] +dev = ["black (==24.10.0)", "build (==1.2.1)", "flake8 (==7.1.1)", "pytest (==8.3.3)", "requests (==2.32.3)", "twine (==5.1.1)"] [[package]] name = "python-magic" @@ -7607,19 +8139,47 @@ files = [ ] [[package]] -name = "python-pptx" -version = "0.6.23" -description = "Generate and manipulate Open XML PowerPoint (.pptx) files" +name = "python-multipart" +version = "0.0.12" +description = "A streaming multipart parser for Python" optional = false -python-versions = "*" +python-versions = ">=3.8" files = [ - {file = "python-pptx-0.6.23.tar.gz", hash = "sha256:587497ff28e779ab18dbb074f6d4052893c85dedc95ed75df319364f331fedee"}, - {file = "python_pptx-0.6.23-py3-none-any.whl", hash = "sha256:dd0527194627a2b7cc05f3ba23ecaa2d9a0d5ac9b6193a28ed1b7a716f4217d4"}, + {file = "python_multipart-0.0.12-py3-none-any.whl", hash = "sha256:43dcf96cf65888a9cd3423544dd0d75ac10f7aa0c3c28a175bbcd00c9ce1aebf"}, + {file = "python_multipart-0.0.12.tar.gz", hash = "sha256:045e1f98d719c1ce085ed7f7e1ef9d8ccc8c02ba02b5566d5f7521410ced58cb"}, +] + +[[package]] +name = "python-oxmsg" +version = "0.0.1" +description = "Extract attachments from Outlook .msg files." +optional = false +python-versions = ">=3.9" +files = [ + {file = "python_oxmsg-0.0.1-py3-none-any.whl", hash = "sha256:8ea7d5dda1bc161a413213da9e18ed152927c1fda2feaf5d1f02192d8ad45eea"}, + {file = "python_oxmsg-0.0.1.tar.gz", hash = "sha256:b65c1f93d688b85a9410afa824192a1ddc39da359b04a0bd2cbd3874e84d4994"}, +] + +[package.dependencies] +click = "*" +olefile = "*" +typing-extensions = ">=4.9.0" + +[[package]] +name = "python-pptx" +version = "1.0.2" +description = "Create, read, and update PowerPoint 2007+ (.pptx) files." +optional = false +python-versions = ">=3.8" +files = [ + {file = "python_pptx-1.0.2-py3-none-any.whl", hash = "sha256:160838e0b8565a8b1f67947675886e9fea18aa5e795db7ae531606d68e785cba"}, + {file = "python_pptx-1.0.2.tar.gz", hash = "sha256:479a8af0eaf0f0d76b6f00b0887732874ad2e3188230315290cd1f9dd9cc7095"}, ] [package.dependencies] lxml = ">=3.1.0" Pillow = ">=3.3.2" +typing-extensions = ">=4.9.0" XlsxWriter = ">=0.5.7" [[package]] @@ -8193,13 +8753,13 @@ py = ">=1.4.26,<2.0.0" [[package]] name = "rich" -version = "13.9.2" +version = "13.9.3" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" optional = false python-versions = ">=3.8.0" files = [ - {file = "rich-13.9.2-py3-none-any.whl", hash = "sha256:8c82a3d3f8dcfe9e734771313e606b39d8247bb6b826e196f4914b333b743cf1"}, - {file = "rich-13.9.2.tar.gz", hash = "sha256:51a2c62057461aaf7152b4d611168f93a9fc73068f8ded2790f29fe2b5366d0c"}, + {file = "rich-13.9.3-py3-none-any.whl", hash = "sha256:9836f5096eb2172c9e77df411c1b009bace4193d6a481d534fea75ebba758283"}, + {file = "rich-13.9.3.tar.gz", hash = "sha256:bc1e01b899537598cf02579d2b9f4a415104d3fc439313a7a2c165d76557a08e"}, ] [package.dependencies] @@ -8612,11 +9172,6 @@ files = [ {file = "scikit_learn-1.5.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f60021ec1574e56632be2a36b946f8143bf4e5e6af4a06d85281adc22938e0dd"}, {file = "scikit_learn-1.5.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:394397841449853c2290a32050382edaec3da89e35b3e03d6cc966aebc6a8ae6"}, {file = "scikit_learn-1.5.2-cp312-cp312-win_amd64.whl", hash = "sha256:57cc1786cfd6bd118220a92ede80270132aa353647684efa385a74244a41e3b1"}, - {file = "scikit_learn-1.5.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9a702e2de732bbb20d3bad29ebd77fc05a6b427dc49964300340e4c9328b3f5"}, - {file = "scikit_learn-1.5.2-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:b0768ad641981f5d3a198430a1d31c3e044ed2e8a6f22166b4d546a5116d7908"}, - {file = "scikit_learn-1.5.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:178ddd0a5cb0044464fc1bfc4cca5b1833bfc7bb022d70b05db8530da4bb3dd3"}, - {file = "scikit_learn-1.5.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7284ade780084d94505632241bf78c44ab3b6f1e8ccab3d2af58e0e950f9c12"}, - {file = "scikit_learn-1.5.2-cp313-cp313-win_amd64.whl", hash = "sha256:b7b0f9a0b1040830d38c39b91b3a44e1b643f4b36e36567b80b7c6bd2202a27f"}, {file = "scikit_learn-1.5.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:757c7d514ddb00ae249832fe87100d9c73c6ea91423802872d9e74970a0e40b9"}, {file = "scikit_learn-1.5.2-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:52788f48b5d8bca5c0736c175fa6bdaab2ef00a8f536cda698db61bd89c551c1"}, {file = "scikit_learn-1.5.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:643964678f4b5fbdc95cbf8aec638acc7aa70f5f79ee2cdad1eec3df4ba6ead8"}, @@ -8742,13 +9297,13 @@ tornado = ["tornado (>=5)"] [[package]] name = "setuptools" -version = "75.1.0" +version = "75.2.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-75.1.0-py3-none-any.whl", hash = "sha256:35ab7fd3bcd95e6b7fd704e4a1539513edad446c097797f2985e0e4b960772f2"}, - {file = "setuptools-75.1.0.tar.gz", hash = "sha256:d59a21b17a275fb872a9c3dae73963160ae079f1049ed956880cd7c09b120538"}, + {file = "setuptools-75.2.0-py3-none-any.whl", hash = "sha256:a7fcb66f68b4d9e8e66b42f9876150a3371558f98fa32222ffaa5bced76406f8"}, + {file = "setuptools-75.2.0.tar.gz", hash = "sha256:753bb6ebf1f465a1912e19ed1d41f403a79173a9acf66a42e7e6aec45c3c16ec"}, ] [package.extras] @@ -8914,60 +9469,68 @@ files = [ [[package]] name = "sqlalchemy" -version = "2.0.35" +version = "2.0.36" description = "Database Abstraction Library" optional = false python-versions = ">=3.7" files = [ - {file = "SQLAlchemy-2.0.35-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:67219632be22f14750f0d1c70e62f204ba69d28f62fd6432ba05ab295853de9b"}, - {file = "SQLAlchemy-2.0.35-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4668bd8faf7e5b71c0319407b608f278f279668f358857dbfd10ef1954ac9f90"}, - {file = "SQLAlchemy-2.0.35-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb8bea573863762bbf45d1e13f87c2d2fd32cee2dbd50d050f83f87429c9e1ea"}, - {file = "SQLAlchemy-2.0.35-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f552023710d4b93d8fb29a91fadf97de89c5926c6bd758897875435f2a939f33"}, - {file = "SQLAlchemy-2.0.35-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:016b2e665f778f13d3c438651dd4de244214b527a275e0acf1d44c05bc6026a9"}, - {file = "SQLAlchemy-2.0.35-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7befc148de64b6060937231cbff8d01ccf0bfd75aa26383ffdf8d82b12ec04ff"}, - {file = "SQLAlchemy-2.0.35-cp310-cp310-win32.whl", hash = "sha256:22b83aed390e3099584b839b93f80a0f4a95ee7f48270c97c90acd40ee646f0b"}, - {file = "SQLAlchemy-2.0.35-cp310-cp310-win_amd64.whl", hash = "sha256:a29762cd3d116585278ffb2e5b8cc311fb095ea278b96feef28d0b423154858e"}, - {file = "SQLAlchemy-2.0.35-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e21f66748ab725ade40fa7af8ec8b5019c68ab00b929f6643e1b1af461eddb60"}, - {file = "SQLAlchemy-2.0.35-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8a6219108a15fc6d24de499d0d515c7235c617b2540d97116b663dade1a54d62"}, - {file = "SQLAlchemy-2.0.35-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:042622a5306c23b972192283f4e22372da3b8ddf5f7aac1cc5d9c9b222ab3ff6"}, - {file = "SQLAlchemy-2.0.35-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:627dee0c280eea91aed87b20a1f849e9ae2fe719d52cbf847c0e0ea34464b3f7"}, - {file = "SQLAlchemy-2.0.35-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4fdcd72a789c1c31ed242fd8c1bcd9ea186a98ee8e5408a50e610edfef980d71"}, - {file = "SQLAlchemy-2.0.35-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:89b64cd8898a3a6f642db4eb7b26d1b28a497d4022eccd7717ca066823e9fb01"}, - {file = "SQLAlchemy-2.0.35-cp311-cp311-win32.whl", hash = "sha256:6a93c5a0dfe8d34951e8a6f499a9479ffb9258123551fa007fc708ae2ac2bc5e"}, - {file = "SQLAlchemy-2.0.35-cp311-cp311-win_amd64.whl", hash = "sha256:c68fe3fcde03920c46697585620135b4ecfdfc1ed23e75cc2c2ae9f8502c10b8"}, - {file = "SQLAlchemy-2.0.35-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:eb60b026d8ad0c97917cb81d3662d0b39b8ff1335e3fabb24984c6acd0c900a2"}, - {file = "SQLAlchemy-2.0.35-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6921ee01caf375363be5e9ae70d08ce7ca9d7e0e8983183080211a062d299468"}, - {file = "SQLAlchemy-2.0.35-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8cdf1a0dbe5ced887a9b127da4ffd7354e9c1a3b9bb330dce84df6b70ccb3a8d"}, - {file = "SQLAlchemy-2.0.35-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93a71c8601e823236ac0e5d087e4f397874a421017b3318fd92c0b14acf2b6db"}, - {file = "SQLAlchemy-2.0.35-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e04b622bb8a88f10e439084486f2f6349bf4d50605ac3e445869c7ea5cf0fa8c"}, - {file = "SQLAlchemy-2.0.35-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1b56961e2d31389aaadf4906d453859f35302b4eb818d34a26fab72596076bb8"}, - {file = "SQLAlchemy-2.0.35-cp312-cp312-win32.whl", hash = "sha256:0f9f3f9a3763b9c4deb8c5d09c4cc52ffe49f9876af41cc1b2ad0138878453cf"}, - {file = "SQLAlchemy-2.0.35-cp312-cp312-win_amd64.whl", hash = "sha256:25b0f63e7fcc2a6290cb5f7f5b4fc4047843504983a28856ce9b35d8f7de03cc"}, - {file = "SQLAlchemy-2.0.35-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:f021d334f2ca692523aaf7bbf7592ceff70c8594fad853416a81d66b35e3abf9"}, - {file = "SQLAlchemy-2.0.35-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05c3f58cf91683102f2f0265c0db3bd3892e9eedabe059720492dbaa4f922da1"}, - {file = "SQLAlchemy-2.0.35-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:032d979ce77a6c2432653322ba4cbeabf5a6837f704d16fa38b5a05d8e21fa00"}, - {file = "SQLAlchemy-2.0.35-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:2e795c2f7d7249b75bb5f479b432a51b59041580d20599d4e112b5f2046437a3"}, - {file = "SQLAlchemy-2.0.35-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:cc32b2990fc34380ec2f6195f33a76b6cdaa9eecf09f0c9404b74fc120aef36f"}, - {file = "SQLAlchemy-2.0.35-cp37-cp37m-win32.whl", hash = "sha256:9509c4123491d0e63fb5e16199e09f8e262066e58903e84615c301dde8fa2e87"}, - {file = "SQLAlchemy-2.0.35-cp37-cp37m-win_amd64.whl", hash = "sha256:3655af10ebcc0f1e4e06c5900bb33e080d6a1fa4228f502121f28a3b1753cde5"}, - {file = "SQLAlchemy-2.0.35-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4c31943b61ed8fdd63dfd12ccc919f2bf95eefca133767db6fbbd15da62078ec"}, - {file = "SQLAlchemy-2.0.35-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a62dd5d7cc8626a3634208df458c5fe4f21200d96a74d122c83bc2015b333bc1"}, - {file = "SQLAlchemy-2.0.35-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0630774b0977804fba4b6bbea6852ab56c14965a2b0c7fc7282c5f7d90a1ae72"}, - {file = "SQLAlchemy-2.0.35-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d625eddf7efeba2abfd9c014a22c0f6b3796e0ffb48f5d5ab106568ef01ff5a"}, - {file = "SQLAlchemy-2.0.35-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:ada603db10bb865bbe591939de854faf2c60f43c9b763e90f653224138f910d9"}, - {file = "SQLAlchemy-2.0.35-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:c41411e192f8d3ea39ea70e0fae48762cd11a2244e03751a98bd3c0ca9a4e936"}, - {file = "SQLAlchemy-2.0.35-cp38-cp38-win32.whl", hash = "sha256:d299797d75cd747e7797b1b41817111406b8b10a4f88b6e8fe5b5e59598b43b0"}, - {file = "SQLAlchemy-2.0.35-cp38-cp38-win_amd64.whl", hash = "sha256:0375a141e1c0878103eb3d719eb6d5aa444b490c96f3fedab8471c7f6ffe70ee"}, - {file = "SQLAlchemy-2.0.35-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ccae5de2a0140d8be6838c331604f91d6fafd0735dbdcee1ac78fc8fbaba76b4"}, - {file = "SQLAlchemy-2.0.35-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2a275a806f73e849e1c309ac11108ea1a14cd7058577aba962cd7190e27c9e3c"}, - {file = "SQLAlchemy-2.0.35-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:732e026240cdd1c1b2e3ac515c7a23820430ed94292ce33806a95869c46bd139"}, - {file = "SQLAlchemy-2.0.35-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:890da8cd1941fa3dab28c5bac3b9da8502e7e366f895b3b8e500896f12f94d11"}, - {file = "SQLAlchemy-2.0.35-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:c0d8326269dbf944b9201911b0d9f3dc524d64779a07518199a58384c3d37a44"}, - {file = "SQLAlchemy-2.0.35-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b76d63495b0508ab9fc23f8152bac63205d2a704cd009a2b0722f4c8e0cba8e0"}, - {file = "SQLAlchemy-2.0.35-cp39-cp39-win32.whl", hash = "sha256:69683e02e8a9de37f17985905a5eca18ad651bf592314b4d3d799029797d0eb3"}, - {file = "SQLAlchemy-2.0.35-cp39-cp39-win_amd64.whl", hash = "sha256:aee110e4ef3c528f3abbc3c2018c121e708938adeeff9006428dd7c8555e9b3f"}, - {file = "SQLAlchemy-2.0.35-py3-none-any.whl", hash = "sha256:2ab3f0336c0387662ce6221ad30ab3a5e6499aab01b9790879b6578fd9b8faa1"}, - {file = "sqlalchemy-2.0.35.tar.gz", hash = "sha256:e11d7ea4d24f0a262bccf9a7cd6284c976c5369dac21db237cff59586045ab9f"}, + {file = "SQLAlchemy-2.0.36-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:59b8f3adb3971929a3e660337f5dacc5942c2cdb760afcabb2614ffbda9f9f72"}, + {file = "SQLAlchemy-2.0.36-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:37350015056a553e442ff672c2d20e6f4b6d0b2495691fa239d8aa18bb3bc908"}, + {file = "SQLAlchemy-2.0.36-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8318f4776c85abc3f40ab185e388bee7a6ea99e7fa3a30686580b209eaa35c08"}, + {file = "SQLAlchemy-2.0.36-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c245b1fbade9c35e5bd3b64270ab49ce990369018289ecfde3f9c318411aaa07"}, + {file = "SQLAlchemy-2.0.36-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:69f93723edbca7342624d09f6704e7126b152eaed3cdbb634cb657a54332a3c5"}, + {file = "SQLAlchemy-2.0.36-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f9511d8dd4a6e9271d07d150fb2f81874a3c8c95e11ff9af3a2dfc35fe42ee44"}, + {file = "SQLAlchemy-2.0.36-cp310-cp310-win32.whl", hash = "sha256:c3f3631693003d8e585d4200730616b78fafd5a01ef8b698f6967da5c605b3fa"}, + {file = "SQLAlchemy-2.0.36-cp310-cp310-win_amd64.whl", hash = "sha256:a86bfab2ef46d63300c0f06936bd6e6c0105faa11d509083ba8f2f9d237fb5b5"}, + {file = "SQLAlchemy-2.0.36-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fd3a55deef00f689ce931d4d1b23fa9f04c880a48ee97af488fd215cf24e2a6c"}, + {file = "SQLAlchemy-2.0.36-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4f5e9cd989b45b73bd359f693b935364f7e1f79486e29015813c338450aa5a71"}, + {file = "SQLAlchemy-2.0.36-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0ddd9db6e59c44875211bc4c7953a9f6638b937b0a88ae6d09eb46cced54eff"}, + {file = "SQLAlchemy-2.0.36-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2519f3a5d0517fc159afab1015e54bb81b4406c278749779be57a569d8d1bb0d"}, + {file = "SQLAlchemy-2.0.36-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:59b1ee96617135f6e1d6f275bbe988f419c5178016f3d41d3c0abb0c819f75bb"}, + {file = "SQLAlchemy-2.0.36-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:39769a115f730d683b0eb7b694db9789267bcd027326cccc3125e862eb03bfd8"}, + {file = "SQLAlchemy-2.0.36-cp311-cp311-win32.whl", hash = "sha256:66bffbad8d6271bb1cc2f9a4ea4f86f80fe5e2e3e501a5ae2a3dc6a76e604e6f"}, + {file = "SQLAlchemy-2.0.36-cp311-cp311-win_amd64.whl", hash = "sha256:23623166bfefe1487d81b698c423f8678e80df8b54614c2bf4b4cfcd7c711959"}, + {file = "SQLAlchemy-2.0.36-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f7b64e6ec3f02c35647be6b4851008b26cff592a95ecb13b6788a54ef80bbdd4"}, + {file = "SQLAlchemy-2.0.36-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:46331b00096a6db1fdc052d55b101dbbfc99155a548e20a0e4a8e5e4d1362855"}, + {file = "SQLAlchemy-2.0.36-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdf3386a801ea5aba17c6410dd1dc8d39cf454ca2565541b5ac42a84e1e28f53"}, + {file = "SQLAlchemy-2.0.36-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac9dfa18ff2a67b09b372d5db8743c27966abf0e5344c555d86cc7199f7ad83a"}, + {file = "SQLAlchemy-2.0.36-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:90812a8933df713fdf748b355527e3af257a11e415b613dd794512461eb8a686"}, + {file = "SQLAlchemy-2.0.36-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1bc330d9d29c7f06f003ab10e1eaced295e87940405afe1b110f2eb93a233588"}, + {file = "SQLAlchemy-2.0.36-cp312-cp312-win32.whl", hash = "sha256:79d2e78abc26d871875b419e1fd3c0bca31a1cb0043277d0d850014599626c2e"}, + {file = "SQLAlchemy-2.0.36-cp312-cp312-win_amd64.whl", hash = "sha256:b544ad1935a8541d177cb402948b94e871067656b3a0b9e91dbec136b06a2ff5"}, + {file = "SQLAlchemy-2.0.36-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b5cc79df7f4bc3d11e4b542596c03826063092611e481fcf1c9dfee3c94355ef"}, + {file = "SQLAlchemy-2.0.36-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3c01117dd36800f2ecaa238c65365b7b16497adc1522bf84906e5710ee9ba0e8"}, + {file = "SQLAlchemy-2.0.36-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9bc633f4ee4b4c46e7adcb3a9b5ec083bf1d9a97c1d3854b92749d935de40b9b"}, + {file = "SQLAlchemy-2.0.36-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e46ed38affdfc95d2c958de328d037d87801cfcbea6d421000859e9789e61c2"}, + {file = "SQLAlchemy-2.0.36-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b2985c0b06e989c043f1dc09d4fe89e1616aadd35392aea2844f0458a989eacf"}, + {file = "SQLAlchemy-2.0.36-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4a121d62ebe7d26fec9155f83f8be5189ef1405f5973ea4874a26fab9f1e262c"}, + {file = "SQLAlchemy-2.0.36-cp313-cp313-win32.whl", hash = "sha256:0572f4bd6f94752167adfd7c1bed84f4b240ee6203a95e05d1e208d488d0d436"}, + {file = "SQLAlchemy-2.0.36-cp313-cp313-win_amd64.whl", hash = "sha256:8c78ac40bde930c60e0f78b3cd184c580f89456dd87fc08f9e3ee3ce8765ce88"}, + {file = "SQLAlchemy-2.0.36-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:be9812b766cad94a25bc63bec11f88c4ad3629a0cec1cd5d4ba48dc23860486b"}, + {file = "SQLAlchemy-2.0.36-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50aae840ebbd6cdd41af1c14590e5741665e5272d2fee999306673a1bb1fdb4d"}, + {file = "SQLAlchemy-2.0.36-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4557e1f11c5f653ebfdd924f3f9d5ebfc718283b0b9beebaa5dd6b77ec290971"}, + {file = "SQLAlchemy-2.0.36-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:07b441f7d03b9a66299ce7ccf3ef2900abc81c0db434f42a5694a37bd73870f2"}, + {file = "SQLAlchemy-2.0.36-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:28120ef39c92c2dd60f2721af9328479516844c6b550b077ca450c7d7dc68575"}, + {file = "SQLAlchemy-2.0.36-cp37-cp37m-win32.whl", hash = "sha256:b81ee3d84803fd42d0b154cb6892ae57ea6b7c55d8359a02379965706c7efe6c"}, + {file = "SQLAlchemy-2.0.36-cp37-cp37m-win_amd64.whl", hash = "sha256:f942a799516184c855e1a32fbc7b29d7e571b52612647866d4ec1c3242578fcb"}, + {file = "SQLAlchemy-2.0.36-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3d6718667da04294d7df1670d70eeddd414f313738d20a6f1d1f379e3139a545"}, + {file = "SQLAlchemy-2.0.36-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:72c28b84b174ce8af8504ca28ae9347d317f9dba3999e5981a3cd441f3712e24"}, + {file = "SQLAlchemy-2.0.36-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b11d0cfdd2b095e7b0686cf5fabeb9c67fae5b06d265d8180715b8cfa86522e3"}, + {file = "SQLAlchemy-2.0.36-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e32092c47011d113dc01ab3e1d3ce9f006a47223b18422c5c0d150af13a00687"}, + {file = "SQLAlchemy-2.0.36-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:6a440293d802d3011028e14e4226da1434b373cbaf4a4bbb63f845761a708346"}, + {file = "SQLAlchemy-2.0.36-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:c54a1e53a0c308a8e8a7dffb59097bff7facda27c70c286f005327f21b2bd6b1"}, + {file = "SQLAlchemy-2.0.36-cp38-cp38-win32.whl", hash = "sha256:1e0d612a17581b6616ff03c8e3d5eff7452f34655c901f75d62bd86449d9750e"}, + {file = "SQLAlchemy-2.0.36-cp38-cp38-win_amd64.whl", hash = "sha256:8958b10490125124463095bbdadda5aa22ec799f91958e410438ad6c97a7b793"}, + {file = "SQLAlchemy-2.0.36-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:dc022184d3e5cacc9579e41805a681187650e170eb2fd70e28b86192a479dcaa"}, + {file = "SQLAlchemy-2.0.36-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b817d41d692bf286abc181f8af476c4fbef3fd05e798777492618378448ee689"}, + {file = "SQLAlchemy-2.0.36-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4e46a888b54be23d03a89be510f24a7652fe6ff660787b96cd0e57a4ebcb46d"}, + {file = "SQLAlchemy-2.0.36-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4ae3005ed83f5967f961fd091f2f8c5329161f69ce8480aa8168b2d7fe37f06"}, + {file = "SQLAlchemy-2.0.36-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:03e08af7a5f9386a43919eda9de33ffda16b44eb11f3b313e6822243770e9763"}, + {file = "SQLAlchemy-2.0.36-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:3dbb986bad3ed5ceaf090200eba750b5245150bd97d3e67343a3cfed06feecf7"}, + {file = "SQLAlchemy-2.0.36-cp39-cp39-win32.whl", hash = "sha256:9fe53b404f24789b5ea9003fc25b9a3988feddebd7e7b369c8fac27ad6f52f28"}, + {file = "SQLAlchemy-2.0.36-cp39-cp39-win_amd64.whl", hash = "sha256:af148a33ff0349f53512a049c6406923e4e02bf2f26c5fb285f143faf4f0e46a"}, + {file = "SQLAlchemy-2.0.36-py3-none-any.whl", hash = "sha256:fddbe92b4760c6f5d48162aef14824add991aeda8ddadb3c31d56eb15ca69f8e"}, + {file = "sqlalchemy-2.0.36.tar.gz", hash = "sha256:7f2767680b6d2398aea7082e45a774b2b0767b5c8d8ffb9c8b683088ea9b29c5"}, ] [package.dependencies] @@ -8980,7 +9543,7 @@ aioodbc = ["aioodbc", "greenlet (!=0.4.17)"] aiosqlite = ["aiosqlite", "greenlet (!=0.4.17)", "typing_extensions (!=3.10.0.1)"] asyncio = ["greenlet (!=0.4.17)"] asyncmy = ["asyncmy (>=0.2.3,!=0.2.4,!=0.2.6)", "greenlet (!=0.4.17)"] -mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2,!=1.1.5)"] +mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2,!=1.1.5,!=1.1.10)"] mssql = ["pyodbc"] mssql-pymssql = ["pymssql"] mssql-pyodbc = ["pyodbc"] @@ -9016,13 +9579,13 @@ doc = ["sphinx"] [[package]] name = "starlette" -version = "0.39.2" +version = "0.41.0" description = "The little ASGI library that shines." optional = false python-versions = ">=3.8" files = [ - {file = "starlette-0.39.2-py3-none-any.whl", hash = "sha256:134dd6deb655a9775991d352312d53f1879775e5cc8a481f966e83416a2c3f71"}, - {file = "starlette-0.39.2.tar.gz", hash = "sha256:caaa3b87ef8518ef913dac4f073dea44e85f73343ad2bdc17941931835b2a26a"}, + {file = "starlette-0.41.0-py3-none-any.whl", hash = "sha256:a0193a3c413ebc9c78bff1c3546a45bb8c8bcb4a84cae8747d650a65bd37210a"}, + {file = "starlette-0.41.0.tar.gz", hash = "sha256:39cbd8768b107d68bfe1ff1672b38a2c38b49777de46d2a592841d58e3bf7c2a"}, ] [package.dependencies] @@ -9033,13 +9596,13 @@ full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.7 [[package]] name = "storage3" -version = "0.8.1" +version = "0.8.2" description = "Supabase Storage client for Python." optional = false -python-versions = "<4.0,>=3.8" +python-versions = "<4.0,>=3.9" files = [ - {file = "storage3-0.8.1-py3-none-any.whl", hash = "sha256:0b21205f43eaf0d1dd33bde6c6d0612f88524b7865f017d2ae9827e3f63d9cdc"}, - {file = "storage3-0.8.1.tar.gz", hash = "sha256:ea60b68b2221b3868ccc1a7f1294d57d0d9c51642cdc639d8115fe5d0adc8892"}, + {file = "storage3-0.8.2-py3-none-any.whl", hash = "sha256:f2e995b18c77a2a9265d1a33047d43e4d6abb11eb3ca5067959f68281c305de3"}, + {file = "storage3-0.8.2.tar.gz", hash = "sha256:db05d3fe8fb73bd30c814c4c4749664f37a5dfc78b629e8c058ef558c2b89f5a"}, ] [package.dependencies] @@ -9099,13 +9662,13 @@ typing-extensions = ">=4.12.2,<5.0.0" [[package]] name = "supafunc" -version = "0.6.1" +version = "0.6.2" description = "Library for Supabase Functions" optional = false -python-versions = "<4.0,>=3.8" +python-versions = "<4.0,>=3.9" files = [ - {file = "supafunc-0.6.1-py3-none-any.whl", hash = "sha256:01aeeeb4bf429977664454a32c86418345140faf6d2e6eb0636d52e4547c5fbb"}, - {file = "supafunc-0.6.1.tar.gz", hash = "sha256:3c8761e3999336ccdb7550498a395fd08afc8469382f55ea56f7f640e5a909aa"}, + {file = "supafunc-0.6.2-py3-none-any.whl", hash = "sha256:101b30616b0a1ce8cf938eca1df362fa4cf1deacb0271f53ebbd674190fb0da5"}, + {file = "supafunc-0.6.2.tar.gz", hash = "sha256:c7dfa20db7182f7fe4ae436e94e05c06cd7ed98d697fed75d68c7b9792822adc"}, ] [package.dependencies] @@ -9185,13 +9748,13 @@ test = ["pytest", "tornado (>=4.5)", "typeguard"] [[package]] name = "tencentcloud-sdk-python-common" -version = "3.0.1250" +version = "3.0.1256" description = "Tencent Cloud Common SDK for Python" optional = false python-versions = "*" files = [ - {file = "tencentcloud-sdk-python-common-3.0.1250.tar.gz", hash = "sha256:97c15c3f2ffbde60550656eab3e9337d9e0ec8958a533f223c5d5caa2762b6e9"}, - {file = "tencentcloud_sdk_python_common-3.0.1250-py2.py3-none-any.whl", hash = "sha256:e369dee2d920ee365a8e2d314d563d243f2e73f5bc6bd2886f96534c9d00c3a7"}, + {file = "tencentcloud-sdk-python-common-3.0.1256.tar.gz", hash = "sha256:83c7b4154f502d67741486cbeae99e734aaf0bfe7eb2cdc9e77916cce9017f17"}, + {file = "tencentcloud_sdk_python_common-3.0.1256-py2.py3-none-any.whl", hash = "sha256:2639f3510743003add35f97c7717680ff357b5324ce3bd67466c19dafe4e7f0b"}, ] [package.dependencies] @@ -9199,17 +9762,17 @@ requests = ">=2.16.0" [[package]] name = "tencentcloud-sdk-python-hunyuan" -version = "3.0.1250" +version = "3.0.1256" description = "Tencent Cloud Hunyuan SDK for Python" optional = false python-versions = "*" files = [ - {file = "tencentcloud-sdk-python-hunyuan-3.0.1250.tar.gz", hash = "sha256:ac95085edee2a95c69326b2fd6a0f61116fc5d214d5c8cf14a1b42bbb262dba8"}, - {file = "tencentcloud_sdk_python_hunyuan-3.0.1250-py2.py3-none-any.whl", hash = "sha256:caac95c47348639452a78d39cdcb87257f97cec3b52398e3be97a5b8c4c5e496"}, + {file = "tencentcloud-sdk-python-hunyuan-3.0.1256.tar.gz", hash = "sha256:bbc72cd4ef8aacde6ff186521be9ba62eb795eab673fa8e87a4e51e91d33cb95"}, + {file = "tencentcloud_sdk_python_hunyuan-3.0.1256-py2.py3-none-any.whl", hash = "sha256:fbc2e66aac8a9279c560e041a843c2a6884c9145846e6215cde59fa0a127e7e1"}, ] [package.dependencies] -tencentcloud-sdk-python-common = "3.0.1250" +tencentcloud-sdk-python-common = "3.0.1256" [[package]] name = "threadpoolctl" @@ -9286,6 +9849,24 @@ requests = ">=2.26.0" [package.extras] blobfile = ["blobfile (>=2)"] +[[package]] +name = "timm" +version = "1.0.11" +description = "PyTorch Image Models" +optional = false +python-versions = ">=3.8" +files = [ + {file = "timm-1.0.11-py3-none-any.whl", hash = "sha256:52a6f895e2cbec35a87d0846870419c2c0aa40de9b205bcda917f38278bf3044"}, + {file = "timm-1.0.11.tar.gz", hash = "sha256:a005f72b87e67ed30cdbf405a9ffd4e723360c780a43b1cefe266af8ecc9d151"}, +] + +[package.dependencies] +huggingface_hub = "*" +pyyaml = "*" +safetensors = "*" +torch = "*" +torchvision = "*" + [[package]] name = "tinysegmenter" version = "0.3" @@ -9466,14 +10047,106 @@ files = [ {file = "tomli-2.0.2.tar.gz", hash = "sha256:d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed"}, ] +[[package]] +name = "torch" +version = "2.4.1" +description = "Tensors and Dynamic neural networks in Python with strong GPU acceleration" +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "torch-2.4.1-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:362f82e23a4cd46341daabb76fba08f04cd646df9bfaf5da50af97cb60ca4971"}, + {file = "torch-2.4.1-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:e8ac1985c3ff0f60d85b991954cfc2cc25f79c84545aead422763148ed2759e3"}, + {file = "torch-2.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:91e326e2ccfb1496e3bee58f70ef605aeb27bd26be07ba64f37dcaac3d070ada"}, + {file = "torch-2.4.1-cp310-none-macosx_11_0_arm64.whl", hash = "sha256:d36a8ef100f5bff3e9c3cea934b9e0d7ea277cb8210c7152d34a9a6c5830eadd"}, + {file = "torch-2.4.1-cp311-cp311-manylinux1_x86_64.whl", hash = "sha256:0b5f88afdfa05a335d80351e3cea57d38e578c8689f751d35e0ff36bce872113"}, + {file = "torch-2.4.1-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:ef503165f2341942bfdf2bd520152f19540d0c0e34961232f134dc59ad435be8"}, + {file = "torch-2.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:092e7c2280c860eff762ac08c4bdcd53d701677851670695e0c22d6d345b269c"}, + {file = "torch-2.4.1-cp311-none-macosx_11_0_arm64.whl", hash = "sha256:ddddbd8b066e743934a4200b3d54267a46db02106876d21cf31f7da7a96f98ea"}, + {file = "torch-2.4.1-cp312-cp312-manylinux1_x86_64.whl", hash = "sha256:fdc4fe11db3eb93c1115d3e973a27ac7c1a8318af8934ffa36b0370efe28e042"}, + {file = "torch-2.4.1-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:18835374f599207a9e82c262153c20ddf42ea49bc76b6eadad8e5f49729f6e4d"}, + {file = "torch-2.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:ebea70ff30544fc021d441ce6b219a88b67524f01170b1c538d7d3ebb5e7f56c"}, + {file = "torch-2.4.1-cp312-none-macosx_11_0_arm64.whl", hash = "sha256:72b484d5b6cec1a735bf3fa5a1c4883d01748698c5e9cfdbeb4ffab7c7987e0d"}, + {file = "torch-2.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:c99e1db4bf0c5347107845d715b4aa1097e601bdc36343d758963055e9599d93"}, + {file = "torch-2.4.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:b57f07e92858db78c5b72857b4f0b33a65b00dc5d68e7948a8494b0314efb880"}, + {file = "torch-2.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:f18197f3f7c15cde2115892b64f17c80dbf01ed72b008020e7da339902742cf6"}, + {file = "torch-2.4.1-cp38-none-macosx_11_0_arm64.whl", hash = "sha256:5fc1d4d7ed265ef853579caf272686d1ed87cebdcd04f2a498f800ffc53dab71"}, + {file = "torch-2.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:40f6d3fe3bae74efcf08cb7f8295eaddd8a838ce89e9d26929d4edd6d5e4329d"}, + {file = "torch-2.4.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:c9299c16c9743001ecef515536ac45900247f4338ecdf70746f2461f9e4831db"}, + {file = "torch-2.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:6bce130f2cd2d52ba4e2c6ada461808de7e5eccbac692525337cfb4c19421846"}, + {file = "torch-2.4.1-cp39-none-macosx_11_0_arm64.whl", hash = "sha256:a38de2803ee6050309aac032676536c3d3b6a9804248537e38e098d0e14817ec"}, +] + +[package.dependencies] +filelock = "*" +fsspec = "*" +jinja2 = "*" +networkx = "*" +nvidia-cublas-cu12 = {version = "12.1.3.1", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +nvidia-cuda-cupti-cu12 = {version = "12.1.105", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +nvidia-cuda-nvrtc-cu12 = {version = "12.1.105", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +nvidia-cuda-runtime-cu12 = {version = "12.1.105", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +nvidia-cudnn-cu12 = {version = "9.1.0.70", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +nvidia-cufft-cu12 = {version = "11.0.2.54", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +nvidia-curand-cu12 = {version = "10.3.2.106", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +nvidia-cusolver-cu12 = {version = "11.4.5.107", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +nvidia-cusparse-cu12 = {version = "12.1.0.106", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +nvidia-nccl-cu12 = {version = "2.20.5", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +nvidia-nvtx-cu12 = {version = "12.1.105", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} +setuptools = "*" +sympy = "*" +triton = {version = "3.0.0", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\" and python_version < \"3.13\""} +typing-extensions = ">=4.8.0" + +[package.extras] +opt-einsum = ["opt-einsum (>=3.3)"] +optree = ["optree (>=0.11.0)"] + +[[package]] +name = "torchvision" +version = "0.19.1" +description = "image and video datasets and models for torch deep learning" +optional = false +python-versions = ">=3.8" +files = [ + {file = "torchvision-0.19.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:54e8513099e6f586356c70f809d34f391af71ad182fe071cc328a28af2c40608"}, + {file = "torchvision-0.19.1-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:20a1f5e02bfdad7714e55fa3fa698347c11d829fa65e11e5a84df07d93350eed"}, + {file = "torchvision-0.19.1-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:7b063116164be52fc6deb4762de7f8c90bfa3a65f8d5caf17f8e2d5aadc75a04"}, + {file = "torchvision-0.19.1-cp310-cp310-win_amd64.whl", hash = "sha256:f40b6acabfa886da1bc3768f47679c61feee6bde90deb979d9f300df8c8a0145"}, + {file = "torchvision-0.19.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:40514282b4896d62765b8e26d7091c32e17c35817d00ec4be2362ea3ba3d1787"}, + {file = "torchvision-0.19.1-cp311-cp311-manylinux1_x86_64.whl", hash = "sha256:5a91be061ae5d6d5b95e833b93e57ca4d3c56c5a57444dd15da2e3e7fba96050"}, + {file = "torchvision-0.19.1-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:d71a6a6fe3a5281ca3487d4c56ad4aad20ff70f82f1d7c79bcb6e7b0c2af00c8"}, + {file = "torchvision-0.19.1-cp311-cp311-win_amd64.whl", hash = "sha256:70dea324174f5e9981b68e4b7cd524512c106ba64aedef560a86a0bbf2fbf62c"}, + {file = "torchvision-0.19.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:27ece277ff0f6cdc7fed0627279c632dcb2e58187da771eca24b0fbcf3f8590d"}, + {file = "torchvision-0.19.1-cp312-cp312-manylinux1_x86_64.whl", hash = "sha256:c659ff92a61f188a1a7baef2850f3c0b6c85685447453c03d0e645ba8f1dcc1c"}, + {file = "torchvision-0.19.1-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:c07bf43c2a145d792ecd9d0503d6c73577147ece508d45600d8aac77e4cdfcf9"}, + {file = "torchvision-0.19.1-cp312-cp312-win_amd64.whl", hash = "sha256:b4283d283675556bb0eae31d29996f53861b17cbdcdf3509e6bc050414ac9289"}, + {file = "torchvision-0.19.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4c4e4f5b24ea6b087b02ed492ab1e21bba3352c4577e2def14248cfc60732338"}, + {file = "torchvision-0.19.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:9281d63ead929bb19143731154cd1d8bf0b5e9873dff8578a40e90a6bec3c6fa"}, + {file = "torchvision-0.19.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:4d10bc9083c4d5fadd7edd7b729700a7be48dab4f62278df3bc73fa48e48a155"}, + {file = "torchvision-0.19.1-cp38-cp38-win_amd64.whl", hash = "sha256:ccf085ef1824fb9e16f1901285bf89c298c62dfd93267a39e8ee42c71255242f"}, + {file = "torchvision-0.19.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:731f434d91586769e255b5d70ed1a4457e0a1394a95f4aacf0e1e7e21f80c098"}, + {file = "torchvision-0.19.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:febe4f14d4afcb47cc861d8be7760ab6a123cd0817f97faf5771488cb6aa90f4"}, + {file = "torchvision-0.19.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:e328309b8670a2e889b2fe76a1c2744a099c11c984da9a822357bd9debd699a5"}, + {file = "torchvision-0.19.1-cp39-cp39-win_amd64.whl", hash = "sha256:6616f12e00a22e7f3fedbd0fccb0804c05e8fe22871668f10eae65cf3f283614"}, +] + +[package.dependencies] +numpy = "*" +pillow = ">=5.3.0,<8.3.dev0 || >=8.4.dev0" +torch = "2.4.1" + +[package.extras] +gdown = ["gdown (>=4.7.3)"] +scipy = ["scipy"] + [[package]] name = "tos" -version = "2.7.1" +version = "2.7.2" description = "Volc TOS (Tinder Object Storage) SDK" optional = false python-versions = "*" files = [ - {file = "tos-2.7.1.tar.gz", hash = "sha256:4bccdbff3cfd63eb44648bb44862903708c4b3e790f0dd55c96305baaeece805"}, + {file = "tos-2.7.2.tar.gz", hash = "sha256:3c31257716785bca7b2cac51474ff32543cda94075a7b7aff70d769c15c7b7ed"}, ] [package.dependencies] @@ -9571,6 +10244,28 @@ torchhub = ["filelock", "huggingface-hub (>=0.16.4,<1.0)", "importlib-metadata", video = ["av (==9.2.0)", "decord (==0.6.0)"] vision = ["Pillow (<10.0.0)"] +[[package]] +name = "triton" +version = "3.0.0" +description = "A language and compiler for custom Deep Learning operations" +optional = false +python-versions = "*" +files = [ + {file = "triton-3.0.0-1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e1efef76935b2febc365bfadf74bcb65a6f959a9872e5bddf44cc9e0adce1e1a"}, + {file = "triton-3.0.0-1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5ce8520437c602fb633f1324cc3871c47bee3b67acf9756c1a66309b60e3216c"}, + {file = "triton-3.0.0-1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:34e509deb77f1c067d8640725ef00c5cbfcb2052a1a3cb6a6d343841f92624eb"}, + {file = "triton-3.0.0-1-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:bcbf3b1c48af6a28011a5c40a5b3b9b5330530c3827716b5fbf6d7adcc1e53e9"}, + {file = "triton-3.0.0-1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6e5727202f7078c56f91ff13ad0c1abab14a0e7f2c87e91b12b6f64f3e8ae609"}, +] + +[package.dependencies] +filelock = "*" + +[package.extras] +build = ["cmake (>=3.20)", "lit"] +tests = ["autopep8", "flake8", "isort", "llnl-hatchet", "numpy", "pytest", "scipy (>=1.7.1)"] +tutorials = ["matplotlib", "pandas", "tabulate"] + [[package]] name = "twilio" version = "9.0.5" @@ -9607,13 +10302,13 @@ typing-extensions = ">=3.7.4.3" [[package]] name = "types-requests" -version = "2.32.0.20240914" +version = "2.32.0.20241016" description = "Typing stubs for requests" optional = false python-versions = ">=3.8" files = [ - {file = "types-requests-2.32.0.20240914.tar.gz", hash = "sha256:2850e178db3919d9bf809e434eef65ba49d0e7e33ac92d588f4a5e295fffd405"}, - {file = "types_requests-2.32.0.20240914-py3-none-any.whl", hash = "sha256:59c2f673eb55f32a99b2894faf6020e1a9f4a402ad0f192bfee0b64469054310"}, + {file = "types-requests-2.32.0.20241016.tar.gz", hash = "sha256:0d9cad2f27515d0e3e3da7134a1b6f28fb97129d86b867f24d9c726452634d95"}, + {file = "types_requests-2.32.0.20241016-py3-none-any.whl", hash = "sha256:4195d62d6d3e043a4eaaf08ff8a62184584d2e8684e9d2aa178c7915a7da3747"}, ] [package.dependencies] @@ -9745,13 +10440,13 @@ files = [ [[package]] name = "unstructured" -version = "0.10.30" +version = "0.15.14" description = "A library that prepares raw documents for downstream ML tasks." optional = false -python-versions = ">=3.7.0" +python-versions = "<3.13,>=3.9.0" files = [ - {file = "unstructured-0.10.30-py3-none-any.whl", hash = "sha256:0615f14daa37450e9c0fcf3c3fd178c3a06b6b8d006a36d1a5e54dbe487aa6b6"}, - {file = "unstructured-0.10.30.tar.gz", hash = "sha256:a86c3d15c572a28322d83cb5ecf0ac7a24f1c36864fb7c68df096de8a1acc106"}, + {file = "unstructured-0.15.14-py3-none-any.whl", hash = "sha256:502903cbcc60844c82f5351a0bc2e77f00f16a144cb884ac44d2f175470a1df8"}, + {file = "unstructured-0.15.14.tar.gz", hash = "sha256:876546c308c257314865996ce15745139c9fd4f79c7b4f09ad9d719d466b5b55"}, ] [package.dependencies] @@ -9759,73 +10454,166 @@ backoff = "*" beautifulsoup4 = "*" chardet = "*" dataclasses-json = "*" +effdet = {version = "*", optional = true, markers = "extra == \"pdf\""} emoji = "*" filetype = "*" +google-cloud-vision = {version = "*", optional = true, markers = "extra == \"pdf\""} langdetect = "*" lxml = "*" markdown = {version = "*", optional = true, markers = "extra == \"md\""} -msg-parser = {version = "*", optional = true, markers = "extra == \"msg\""} nltk = "*" -numpy = "*" +numpy = "<2" +onnx = {version = "*", optional = true, markers = "extra == \"pdf\""} +pdf2image = {version = "*", optional = true, markers = "extra == \"pdf\""} +"pdfminer.six" = {version = "*", optional = true, markers = "extra == \"pdf\""} +pi-heif = {version = "*", optional = true, markers = "extra == \"pdf\""} +pikepdf = {version = "*", optional = true, markers = "extra == \"pdf\""} +psutil = "*" pypandoc = {version = "*", optional = true, markers = "extra == \"epub\""} -python-docx = {version = ">=1.1.0", optional = true, markers = "extra == \"docx\""} +pypdf = {version = "*", optional = true, markers = "extra == \"pdf\""} +python-docx = {version = ">=1.1.2", optional = true, markers = "extra == \"docx\""} python-iso639 = "*" python-magic = "*" -python-pptx = {version = "<=0.6.23", optional = true, markers = "extra == \"ppt\" or extra == \"pptx\""} +python-oxmsg = "*" +python-pptx = {version = ">=1.0.1", optional = true, markers = "extra == \"ppt\" or extra == \"pptx\""} rapidfuzz = "*" requests = "*" tabulate = "*" +tqdm = "*" typing-extensions = "*" +unstructured-client = "*" +unstructured-inference = {version = "0.7.36", optional = true, markers = "extra == \"pdf\""} +"unstructured.pytesseract" = {version = ">=0.3.12", optional = true, markers = "extra == \"pdf\""} +wrapt = "*" [package.extras] airtable = ["pyairtable"] -all-docs = ["markdown", "msg-parser", "networkx", "onnx", "openpyxl", "pandas", "pdf2image", "pdfminer.six", "pypandoc", "python-docx (>=1.1.0)", "python-pptx (<=0.6.23)", "unstructured-inference (==0.7.11)", "unstructured.pytesseract (>=0.3.12)", "xlrd"] -azure = ["adlfs", "fsspec (==2023.9.1)"] +all-docs = ["effdet", "google-cloud-vision", "markdown", "networkx", "onnx", "openpyxl", "pandas", "pdf2image", "pdfminer.six", "pi-heif", "pikepdf", "pypandoc", "pypdf", "python-docx (>=1.1.2)", "python-pptx (>=1.0.1)", "unstructured-inference (==0.7.36)", "unstructured.pytesseract (>=0.3.12)", "xlrd"] +astradb = ["astrapy"] +azure = ["adlfs", "fsspec"] azure-cognitive-search = ["azure-search-documents"] -bedrock = ["boto3", "langchain"] +bedrock = ["boto3", "langchain-community"] biomed = ["bs4"] -box = ["boxfs", "fsspec (==2023.9.1)"] +box = ["boxfs", "fsspec"] +chroma = ["chromadb (>0.4.14)", "importlib-metadata (>=8.2.0)", "tenacity (==8.5.0)", "typer (<=0.9.0)"] +clarifai = ["clarifai"] confluence = ["atlassian-python-api"] csv = ["pandas"] -delta-table = ["deltalake", "fsspec (==2023.9.1)"] +databricks-volumes = ["databricks-sdk"] +delta-table = ["deltalake (<=0.19.1)", "fsspec"] discord = ["discord-py"] -doc = ["python-docx (>=1.1.0)"] -docx = ["python-docx (>=1.1.0)"] -dropbox = ["dropboxdrivefs", "fsspec (==2023.9.1)"] -elasticsearch = ["elasticsearch", "jq"] -embed-huggingface = ["huggingface", "langchain", "sentence-transformers"] +doc = ["python-docx (>=1.1.2)"] +docx = ["python-docx (>=1.1.2)"] +dropbox = ["dropboxdrivefs", "fsspec"] +elasticsearch = ["elasticsearch[async]"] +embed-huggingface = ["langchain-huggingface"] +embed-mixedbreadai = ["mixedbread-ai"] +embed-octoai = ["openai", "tiktoken"] +embed-vertexai = ["langchain", "langchain-community", "langchain-google-vertexai"] +embed-voyageai = ["langchain", "langchain-voyageai"] epub = ["pypandoc"] -gcs = ["bs4", "fsspec (==2023.9.1)", "gcsfs"] +gcs = ["bs4", "fsspec", "gcsfs"] github = ["pygithub (>1.58.0)"] gitlab = ["python-gitlab"] google-drive = ["google-api-python-client"] +hubspot = ["hubspot-api-client", "urllib3"] huggingface = ["langdetect", "sacremoses", "sentencepiece", "torch", "transformers"] -image = ["onnx", "pdf2image", "pdfminer.six", "unstructured-inference (==0.7.11)", "unstructured.pytesseract (>=0.3.12)"] +image = ["effdet", "google-cloud-vision", "onnx", "pdf2image", "pdfminer.six", "pi-heif", "pikepdf", "pypdf", "unstructured-inference (==0.7.36)", "unstructured.pytesseract (>=0.3.12)"] jira = ["atlassian-python-api"] -local-inference = ["markdown", "msg-parser", "networkx", "onnx", "openpyxl", "pandas", "pdf2image", "pdfminer.six", "pypandoc", "python-docx (>=1.1.0)", "python-pptx (<=0.6.23)", "unstructured-inference (==0.7.11)", "unstructured.pytesseract (>=0.3.12)", "xlrd"] +kafka = ["confluent-kafka"] +local-inference = ["effdet", "google-cloud-vision", "markdown", "networkx", "onnx", "openpyxl", "pandas", "pdf2image", "pdfminer.six", "pi-heif", "pikepdf", "pypandoc", "pypdf", "python-docx (>=1.1.2)", "python-pptx (>=1.0.1)", "unstructured-inference (==0.7.36)", "unstructured.pytesseract (>=0.3.12)", "xlrd"] md = ["markdown"] -msg = ["msg-parser"] +mongodb = ["pymongo"] notion = ["htmlBuilder", "notion-client"] -odt = ["pypandoc", "python-docx (>=1.1.0)"] -onedrive = ["Office365-REST-Python-Client (<2.4.3)", "bs4", "msal"] -openai = ["langchain", "openai", "tiktoken"] +odt = ["pypandoc", "python-docx (>=1.1.2)"] +onedrive = ["Office365-REST-Python-Client", "bs4", "msal"] +openai = ["langchain-openai"] +opensearch = ["opensearch-py"] org = ["pypandoc"] -outlook = ["Office365-REST-Python-Client (<2.4.3)", "msal"] -paddleocr = ["unstructured.paddleocr (==2.6.1.3)"] -pdf = ["onnx", "pdf2image", "pdfminer.six", "unstructured-inference (==0.7.11)", "unstructured.pytesseract (>=0.3.12)"] -ppt = ["python-pptx (<=0.6.23)"] -pptx = ["python-pptx (<=0.6.23)"] +outlook = ["Office365-REST-Python-Client", "msal"] +paddleocr = ["paddlepaddle (==3.0.0b1)", "unstructured.paddleocr (==2.8.1.0)"] +pdf = ["effdet", "google-cloud-vision", "onnx", "pdf2image", "pdfminer.six", "pi-heif", "pikepdf", "pypdf", "unstructured-inference (==0.7.36)", "unstructured.pytesseract (>=0.3.12)"] +pinecone = ["pinecone-client (>=3.7.1)"] +postgres = ["psycopg2-binary"] +ppt = ["python-pptx (>=1.0.1)"] +pptx = ["python-pptx (>=1.0.1)"] +qdrant = ["qdrant-client"] reddit = ["praw"] rst = ["pypandoc"] rtf = ["pypandoc"] -s3 = ["fsspec (==2023.9.1)", "s3fs"] +s3 = ["fsspec", "s3fs"] salesforce = ["simple-salesforce"] -sharepoint = ["Office365-REST-Python-Client (<2.4.3)", "msal"] +sftp = ["fsspec", "paramiko"] +sharepoint = ["Office365-REST-Python-Client", "msal"] +singlestore = ["singlestoredb"] slack = ["slack-sdk"] tsv = ["pandas"] +weaviate = ["weaviate-client"] wikipedia = ["wikipedia"] xlsx = ["networkx", "openpyxl", "pandas", "xlrd"] +[[package]] +name = "unstructured-client" +version = "0.26.1" +description = "Python Client SDK for Unstructured API" +optional = false +python-versions = "<4.0,>=3.8" +files = [ + {file = "unstructured_client-0.26.1-py3-none-any.whl", hash = "sha256:b8b839d477122bab3f37242cbe44b39f7eb7b564b07b53500321f953710119b6"}, + {file = "unstructured_client-0.26.1.tar.gz", hash = "sha256:907cceb470529b45b0fddb2d0f1bbf4d6568f347c757ab68639a7bb620ec2484"}, +] + +[package.dependencies] +cryptography = ">=3.1" +eval-type-backport = ">=0.2.0,<0.3.0" +httpx = ">=0.27.0" +jsonpath-python = ">=1.0.6,<2.0.0" +nest-asyncio = ">=1.6.0" +pydantic = ">=2.9.0,<2.10.0" +pypdf = ">=4.0" +python-dateutil = "2.8.2" +requests-toolbelt = ">=1.0.0" +typing-inspect = ">=0.9.0,<0.10.0" + +[[package]] +name = "unstructured-inference" +version = "0.7.36" +description = "A library for performing inference using trained models." +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "unstructured_inference-0.7.36-py3-none-any.whl", hash = "sha256:6e59c2226c0d049d8e78e102d95bba1a126e14ede4d40494a72ef82ecf7fb64f"}, + {file = "unstructured_inference-0.7.36.tar.gz", hash = "sha256:0b998b311c6156df021d309147b724de4f88f80ef17d8328dfc37eedab67d82a"}, +] + +[package.dependencies] +huggingface-hub = "*" +layoutparser = "*" +matplotlib = "*" +onnx = "*" +onnxruntime = ">=1.17.0" +opencv-python = "!=4.7.0.68" +python-multipart = "*" +rapidfuzz = "*" +timm = "*" +torch = "*" +transformers = ">=4.25.1" + +[[package]] +name = "unstructured-pytesseract" +version = "0.3.13" +description = "Python-tesseract is a python wrapper for Google's Tesseract-OCR" +optional = false +python-versions = ">=3.8" +files = [ + {file = "unstructured.pytesseract-0.3.13-py3-none-any.whl", hash = "sha256:8001bc860470d56185176eb3ceb4623e888eba058ca3b30af79003784bc40e19"}, + {file = "unstructured.pytesseract-0.3.13.tar.gz", hash = "sha256:ff2e6391496e457dbf4b4e327f4a4577cce18921ea6570dc74bd64381b10e963"}, +] + +[package.dependencies] +packaging = ">=21.3" +Pillow = ">=8.0.0" + [[package]] name = "upstash-vector" version = "0.6.0" @@ -9870,13 +10658,13 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "uvicorn" -version = "0.31.1" +version = "0.32.0" description = "The lightning-fast ASGI server." optional = false python-versions = ">=3.8" files = [ - {file = "uvicorn-0.31.1-py3-none-any.whl", hash = "sha256:adc42d9cac80cf3e51af97c1851648066841e7cfb6993a4ca8de29ac1548ed41"}, - {file = "uvicorn-0.31.1.tar.gz", hash = "sha256:f5167919867b161b7bcaf32646c6a94cdbd4c3aa2eb5c17d36bb9aa5cfd8c493"}, + {file = "uvicorn-0.32.0-py3-none-any.whl", hash = "sha256:60b8f3a5ac027dcd31448f411ced12b5ef452c646f76f02f8cc3f25d8d26fd82"}, + {file = "uvicorn-0.32.0.tar.gz", hash = "sha256:f78b36b143c16f54ccdb8190d0a26b5f1901fe5a3c777e1ab29f26391af8551e"}, ] [package.dependencies] @@ -10066,6 +10854,21 @@ urllib3 = ">=1.23" [package.extras] ark = ["anyio (>=3.5.0,<5)", "cached-property", "httpx (>=0.23.0,<1)", "pydantic (>=1.9.0,<3)"] +[[package]] +name = "wand" +version = "0.6.13" +description = "Ctypes-based simple MagickWand API binding for Python" +optional = false +python-versions = "*" +files = [ + {file = "Wand-0.6.13-py2.py3-none-any.whl", hash = "sha256:e5dda0ac2204a40c29ef5c4cb310770c95d3d05c37b1379e69c94ea79d7d19c0"}, + {file = "Wand-0.6.13.tar.gz", hash = "sha256:f5013484eaf7a20eb22d1821aaefe60b50cc329722372b5f8565d46d4aaafcca"}, +] + +[package.extras] +doc = ["Sphinx (>=5.3.0)"] +test = ["pytest (>=7.2.0)"] + [[package]] name = "watchfiles" version = "0.24.0" @@ -10486,13 +11289,13 @@ files = [ [[package]] name = "xmltodict" -version = "0.14.1" +version = "0.14.2" description = "Makes working with XML feel like you are working with JSON" optional = false python-versions = ">=3.6" files = [ - {file = "xmltodict-0.14.1-py2.py3-none-any.whl", hash = "sha256:3ef4a7b71c08f19047fcbea572e1d7f4207ab269da1565b5d40e9823d3894e63"}, - {file = "xmltodict-0.14.1.tar.gz", hash = "sha256:338c8431e4fc554517651972d62f06958718f6262b04316917008e8fd677a6b0"}, + {file = "xmltodict-0.14.2-py2.py3-none-any.whl", hash = "sha256:20cc7d723ed729276e808f26fb6b3599f786cbc37e06c65e192ba77c40f20aac"}, + {file = "xmltodict-0.14.2.tar.gz", hash = "sha256:201e7c28bb210e374999d1dde6382923ab0ed1a8a5faeece48ab525b7810a553"}, ] [[package]] @@ -10602,13 +11405,13 @@ multidict = ">=4.0" [[package]] name = "yfinance" -version = "0.2.44" +version = "0.2.46" description = "Download market data from Yahoo! Finance API" optional = false python-versions = "*" files = [ - {file = "yfinance-0.2.44-py2.py3-none-any.whl", hash = "sha256:fdc18791662f286539f7a08dccd7e8191b1ca509814f7b0faac264623bebe8a8"}, - {file = "yfinance-0.2.44.tar.gz", hash = "sha256:532ad1644ee9cf4024ec0d9cade0cc073664ec0d140cc6c22a0cce8a9118b523"}, + {file = "yfinance-0.2.46-py2.py3-none-any.whl", hash = "sha256:371860d532cae76605195678a540e29382bfd0607f8aa61695f753e714916ffc"}, + {file = "yfinance-0.2.46.tar.gz", hash = "sha256:a6e2a128915532a54b8f6614cfdb7a8c242d2386e05f95c89b15865b5d9c0352"}, ] [package.dependencies] @@ -10852,4 +11655,4 @@ cffi = ["cffi (>=1.11)"] [metadata] lock-version = "2.0" python-versions = ">=3.10,<3.13" -content-hash = "32fd52006f75e42fbc8f787e559a72f4e033383c73225231e4ecadabfec926f7" +content-hash = "54eec8f3991658d8b718afa317ad48bd440d618d751c6a45e88a55f35fe2841f" diff --git a/api/pyproject.toml b/api/pyproject.toml index e9529a192e..4f75fc3c89 100644 --- a/api/pyproject.toml +++ b/api/pyproject.toml @@ -172,11 +172,12 @@ sagemaker = "2.231.0" scikit-learn = "~1.5.1" sentry-sdk = { version = "~1.44.1", extras = ["flask"] } sqlalchemy = "~2.0.29" +starlette = "0.41.0" tencentcloud-sdk-python-hunyuan = "~3.0.1158" tiktoken = "~0.8.0" tokenizers = "~0.15.0" transformers = "~4.35.0" -unstructured = { version = "~0.10.27", extras = ["docx", "epub", "md", "msg", "ppt", "pptx"] } +unstructured = { version = "~0.15.7", extras = ["docx", "epub", "md", "msg", "ppt", "pptx", "pdf"] } validators = "0.21.0" volcengine-python-sdk = {extras = ["ark"], version = "~1.0.98"} websocket-client = "~1.7.0" @@ -206,7 +207,7 @@ duckduckgo-search = "~6.3.0" jsonpath-ng = "1.6.1" matplotlib = "~3.8.2" newspaper3k = "0.2.8" -nltk = "3.8.1" +nltk = "3.9.1" numexpr = "~2.9.0" pydub = "~0.25.1" qrcode = "~7.4.2" diff --git a/dev/pytest/pytest_vdb.sh b/dev/pytest/pytest_vdb.sh index b64435e9a1..47122b537f 100755 --- a/dev/pytest/pytest_vdb.sh +++ b/dev/pytest/pytest_vdb.sh @@ -6,9 +6,4 @@ pytest api/tests/integration_tests/vdb/chroma \ api/tests/integration_tests/vdb/pgvecto_rs \ api/tests/integration_tests/vdb/pgvector \ api/tests/integration_tests/vdb/qdrant \ - api/tests/integration_tests/vdb/weaviate \ - api/tests/integration_tests/vdb/elasticsearch \ - api/tests/integration_tests/vdb/vikingdb \ - api/tests/integration_tests/vdb/baidu \ - api/tests/integration_tests/vdb/tcvectordb \ - api/tests/integration_tests/vdb/upstash + api/tests/integration_tests/vdb/weaviate From ae2c76bda2dfe6fa75b68f9a6943343094d066f0 Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Wed, 23 Oct 2024 16:42:24 +0800 Subject: [PATCH 165/346] feat: install from marketplace --- .../install-from-marketplace/index.tsx | 155 ++++++------------ .../steps/install.tsx | 36 +++- .../components/plugins/plugin-page/index.tsx | 43 +++-- 3 files changed, 105 insertions(+), 129 deletions(-) diff --git a/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx b/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx index ddea0c346f..411e2cf1f1 100644 --- a/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx +++ b/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx @@ -1,132 +1,73 @@ 'use client' -import React, { useMemo, useState } from 'react' -import { RiInformation2Line } from '@remixicon/react' -import Card from '../../card' -import { extensionDallE, modelGPT4, toolNotion } from '../../card/card-mock' +import React, { useCallback, useState } from 'react' import Modal from '@/app/components/base/modal' -import Button from '@/app/components/base/button' -import Checkbox from '@/app/components/base/checkbox' -import Badge, { BadgeState } from '@/app/components/base/badge/index' +import type { PluginDeclaration } from '../../types' +import { InstallStep } from '../../types' +import Install from './steps/install' +import Installed from './steps/installed' +import { useTranslation } from 'react-i18next' + +const i18nPrefix = 'plugin.installModal' type InstallFromMarketplaceProps = { + packageId: string + manifest: PluginDeclaration + onSuccess: () => void onClose: () => void } -const InstallFromMarketplace: React.FC<InstallFromMarketplaceProps> = ({ onClose }) => { - const plugins = useMemo(() => [toolNotion, extensionDallE, modelGPT4], []) - const [selectedPlugins, setSelectedPlugins] = useState<Set<number>>(new Set()) - const [isInstalling, setIsInstalling] = useState(false) - const [nextStep, setNextStep] = useState(false) +const InstallFromMarketplace: React.FC<InstallFromMarketplaceProps> = ({ + packageId, + manifest, + onSuccess, + onClose, +}) => { + const { t } = useTranslation() + // readyToInstall -> check installed -> installed + const [step, setStep] = useState<InstallStep>(InstallStep.readyToInstall) - const mockInstall = async () => { - setIsInstalling(true) - await new Promise(resolve => setTimeout(resolve, 1500)) - setIsInstalling(false) - } + // TODO: check installed in beta version. - const pluginsToShow = useMemo(() => { - if (plugins.length === 1 || (nextStep && selectedPlugins.size === 1)) - return plugins.length === 1 ? plugins : plugins.filter((_, index) => selectedPlugins.has(index)) + const getTitle = useCallback(() => { + if (step === InstallStep.installed) + return t(`${i18nPrefix}.installedSuccessfully`) + return t(`${i18nPrefix}.installPlugin`) + }, []) - return nextStep ? plugins.filter((_, index) => selectedPlugins.has(index)) : plugins - }, [plugins, nextStep, selectedPlugins]) - - const renderPluginCard = (plugin: any, index: number) => ( - <Card - key={index} - installed={nextStep && !isInstalling} - payload={plugin} - className='w-full' - titleLeft={ - plugin.version === plugin.latest_version - ? ( - <Badge className='mx-1' size="s" state={BadgeState.Default}>{plugin.version}</Badge> - ) - : ( - <> - <Badge className='mx-1' size="s" state={BadgeState.Warning}> - {`${plugin.version} -> ${plugin.latest_version}`} - </Badge> - <div className='flex px-0.5 justify-center items-center gap-0.5'> - <div className='text-text-warning system-xs-medium'>Used in 3 apps</div> - <RiInformation2Line className='w-4 h-4 text-text-tertiary' /> - </div> - </> - ) - } - /> - ) + const handleInstalled = useCallback(async () => { + setStep(InstallStep.installed) + }, []) return ( <Modal isShow={true} onClose={onClose} - className='flex min-w-[560px] flex-col items-start p-0 rounded-2xl border-[0.5px] border-components-panel-border bg-components-panel-bg shadows-shadow-xl' + className='flex min-w-[560px] p-0 flex-col items-start rounded-2xl border-[0.5px] border-components-panel-border bg-components-panel-bg shadows-shadow-xl' closable > <div className='flex pt-6 pl-6 pb-3 pr-14 items-start gap-2 self-stretch'> <div className='self-stretch text-text-primary title-2xl-semi-bold'> - {nextStep ? (isInstalling ? 'Install plugin' : 'Installation successful') : 'Install plugin'} + {getTitle()} </div> </div> - <div className='flex px-6 py-3 flex-col justify-center items-start gap-4 self-stretch'> - <div className='flex flex-col items-start gap-2 self-stretch'> - <div className='text-text-secondary system-md-regular'> - {(nextStep && !isInstalling) - ? `The following ${pluginsToShow.length === 1 ? 'plugin has' : `${pluginsToShow.length} plugins have`} been installed successfully` - : `About to install the following ${pluginsToShow.length === 1 ? 'plugin' : `${pluginsToShow.length} plugins`}`} - </div> - </div> - <div className='flex p-2 items-start content-start gap-1 self-stretch flex-wrap rounded-2xl bg-background-section-burn'> - {pluginsToShow.map((plugin, index) => ( - <div key={index} className={`flex ${(plugins.length > 1 && !nextStep) ? 'pl-1 items-center gap-2' : ''} flex-grow`}> - {(plugins.length > 1 && !nextStep) && ( - <Checkbox - checked={selectedPlugins.has(index)} - onCheck={() => { - const newSelectedPlugins = new Set(selectedPlugins) - newSelectedPlugins.has(index) ? newSelectedPlugins.delete(index) : newSelectedPlugins.add(index) - setSelectedPlugins(newSelectedPlugins) - }} - /> - )} - {renderPluginCard(plugin, index)} - </div> - ))} - </div> - </div> - <div className='flex p-6 pt-5 justify-end items-center gap-2 self-stretch'> - {nextStep - ? ( - <Button - variant='primary' - disabled={isInstalling} - loading={isInstalling} - onClick={onClose} - > - {isInstalling ? 'Installing...' : 'Close'} - </Button> - ) - : ( - <> - <Button variant='secondary' className='min-w-[72px]' onClick={onClose}> - Cancel - </Button> - <Button - variant='primary' - className='min-w-[72px]' - disabled={plugins.length > 1 && selectedPlugins.size < 1} - onClick={() => { - setNextStep(true) - mockInstall() - }} - > - Install - </Button> - </> - )} - </div> + { + step === InstallStep.readyToInstall && ( + <Install + payload={manifest!} + onCancel={onClose} + onInstalled={handleInstalled} + /> + ) + } + { + step === InstallStep.installed && ( + <Installed + payload={manifest!} + onCancel={onSuccess} + /> + ) + } </Modal> ) } diff --git a/web/app/components/plugins/install-plugin/install-from-marketplace/steps/install.tsx b/web/app/components/plugins/install-plugin/install-from-marketplace/steps/install.tsx index 5067dff908..eb5072b7e3 100644 --- a/web/app/components/plugins/install-plugin/install-from-marketplace/steps/install.tsx +++ b/web/app/components/plugins/install-plugin/install-from-marketplace/steps/install.tsx @@ -1,13 +1,15 @@ 'use client' import type { FC } from 'react' -import React from 'react' +import React, { useMemo } from 'react' +import { RiInformation2Line } from '@remixicon/react' import type { PluginDeclaration } from '../../../types' import Card from '../../../card' import { pluginManifestToCardPluginProps } from '../../utils' import Button from '@/app/components/base/button' import { sleep } from '@/utils' -import { Trans, useTranslation } from 'react-i18next' +import { useTranslation } from 'react-i18next' import { RiLoader2Line } from '@remixicon/react' +import Badge, { BadgeState } from '@/app/components/base/badge/index' const i18nPrefix = 'plugin.installModal' @@ -32,22 +34,40 @@ const Installed: FC<Props> = ({ onInstalled() } + const toInstallVersion = '1.3.0' + const supportCheckInstalled = false // TODO: check installed in beta version. + + const versionInfo = useMemo(() => { + return (<>{ + payload.version === toInstallVersion || !supportCheckInstalled + ? ( + <Badge className='mx-1' size="s" state={BadgeState.Default}>{payload.version}</Badge> + ) + : ( + <> + <Badge className='mx-1' size="s" state={BadgeState.Warning}> + {`${payload.version} -> ${toInstallVersion}`} + </Badge> + <div className='flex px-0.5 justify-center items-center gap-0.5'> + <div className='text-text-warning system-xs-medium'>Used in 3 apps</div> + <RiInformation2Line className='w-4 h-4 text-text-tertiary' /> + </div> + </> + ) + }</>) + }, [payload]) + return ( <> <div className='flex flex-col px-6 py-3 justify-center items-start gap-4 self-stretch'> <div className='text-text-secondary system-md-regular'> <p>{t(`${i18nPrefix}.readyToInstall`)}</p> - <p> - <Trans - i18nKey={`${i18nPrefix}.fromTrustSource`} - components={{ trustSource: <span className='system-md-semibold' /> }} - /> - </p> </div> <div className='flex p-2 items-start content-start gap-1 self-stretch flex-wrap rounded-2xl bg-background-section-burn'> <Card className='w-full' payload={pluginManifestToCardPluginProps(payload)} + titleLeft={versionInfo} /> </div> </div> diff --git a/web/app/components/plugins/plugin-page/index.tsx b/web/app/components/plugins/plugin-page/index.tsx index 6c73f0c6ee..9d432df664 100644 --- a/web/app/components/plugins/plugin-page/index.tsx +++ b/web/app/components/plugins/plugin-page/index.tsx @@ -1,6 +1,6 @@ 'use client' -import { useMemo, useState } from 'react' +import { useEffect, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import { RiDragDropLine, @@ -29,6 +29,9 @@ import { useRouter, useSearchParams, } from 'next/navigation' +import type { PluginDeclaration } from '../types' +import { toolNotionManifest } from '../card/card-mock' +import { sleep } from '@/utils' const PACKAGE_IDS_KEY = 'package-ids' @@ -54,7 +57,28 @@ const PluginPage = ({ return '' } }, [searchParams]) - const isInstallPackage = !!packageId + const [isShowInstallFromMarketplace, { + setTrue: showInstallFromMarketplace, + setFalse: doHideInstallFromMarketplace, + }] = useBoolean(false) + + const hideInstallFromMarketplace = () => { + doHideInstallFromMarketplace() + const url = new URL(window.location.href) + url.searchParams.delete(PACKAGE_IDS_KEY) + replace(url.toString()) + } + const [manifest, setManifest] = useState<PluginDeclaration | null>(null) + + useEffect(() => { + (async () => { + await sleep(100) + if (packageId) { + setManifest(toolNotionManifest) + showInstallFromMarketplace() + } + })() + }, [packageId]) const { canManagement, @@ -94,18 +118,6 @@ const PluginPage = ({ const { dragging, fileUploader, fileChangeHandle, removeFile } = uploaderProps - const [isShowInstallFromMarketplace, { - setTrue: showInstallFromMarketplace, - setFalse: doHideInstallFromMarketplace, - }] = useBoolean(isInstallPackage) - - const hideInstallFromMarketplace = () => { - doHideInstallFromMarketplace() - const url = new URL(window.location.href) - url.searchParams.delete(PACKAGE_IDS_KEY) - replace(url.toString()) - } - return ( <div ref={containerRef} @@ -216,7 +228,10 @@ const PluginPage = ({ { isShowInstallFromMarketplace && ( <InstallFromMarketplace + manifest={manifest!} + packageId={packageId} onClose={hideInstallFromMarketplace} + onSuccess={hideInstallFromMarketplace} /> ) } From f6c3d4cadc4b04aabb1163b32e0f097c8af6f31f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 23 Oct 2024 16:57:45 +0800 Subject: [PATCH 166/346] build(deps): bump mermaid from 10.4.0 to 10.9.3 in /web (#9709) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- web/package.json | 2 +- web/yarn.lock | 75 ++++++++++++++++-------------------------------- 2 files changed, 25 insertions(+), 52 deletions(-) diff --git a/web/package.json b/web/package.json index d8bd6e2386..1bdc67e7d2 100644 --- a/web/package.json +++ b/web/package.json @@ -62,7 +62,7 @@ "lamejs": "^1.2.1", "lexical": "^0.16.0", "lodash-es": "^4.17.21", - "mermaid": "10.4.0", + "mermaid": "10.9.3", "mime": "^4.0.4", "negotiator": "^0.6.3", "next": "^14.1.1", diff --git a/web/yarn.lock b/web/yarn.lock index cfd3ea461c..e1c765ed1f 100644 --- a/web/yarn.lock +++ b/web/yarn.lock @@ -5573,13 +5573,6 @@ cose-base@^1.0.0: dependencies: layout-base "^1.0.0" -cose-base@^2.2.0: - version "2.2.0" - resolved "https://registry.npmjs.org/cose-base/-/cose-base-2.2.0.tgz" - integrity sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g== - dependencies: - layout-base "^2.0.0" - cosmiconfig@^7.0.1: version "7.1.0" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz#1443b9afa596b670082ea46cbd8f6a62b84635f6" @@ -5757,20 +5750,10 @@ cytoscape-cose-bilkent@^4.1.0: dependencies: cose-base "^1.0.0" -cytoscape-fcose@^2.1.0: - version "2.2.0" - resolved "https://registry.npmjs.org/cytoscape-fcose/-/cytoscape-fcose-2.2.0.tgz" - integrity sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ== - dependencies: - cose-base "^2.2.0" - -cytoscape@^3.23.0: - version "3.26.0" - resolved "https://registry.npmjs.org/cytoscape/-/cytoscape-3.26.0.tgz" - integrity sha512-IV+crL+KBcrCnVVUCZW+zRRRFUZQcrtdOPXki+o4CFUWLdAEYvuZLcBSJC9EBK++suamERKzeY7roq2hdovV3w== - dependencies: - heap "^0.2.6" - lodash "^4.17.21" +cytoscape@^3.28.1: + version "3.30.2" + resolved "https://registry.yarnpkg.com/cytoscape/-/cytoscape-3.30.2.tgz#94149707fb6547a55e3b44f03ffe232706212161" + integrity sha512-oICxQsjW8uSaRmn4UK/jkczKOqTrVqt5/1WL0POiJUT2EKNc9STM4hYFHv917yu55aTBMFNRzymlJhVAiWPCxw== "d3-array@1 - 2": version "2.12.1" @@ -6404,10 +6387,10 @@ domhandler@^5.0.2, domhandler@^5.0.3: dependencies: domelementtype "^2.3.0" -dompurify@^3.0.5: - version "3.1.7" - resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.1.7.tgz#711a8c96479fb6ced93453732c160c3c72418a6a" - integrity sha512-VaTstWtsneJY8xzy7DekmYWEOZcmzIe3Qb3zPd4STve1OBTa+e+WmS1ITQec1fZYXI3HCsOZZiSMpG6oxoWMWQ== +"dompurify@^3.0.5 <3.1.7": + version "3.1.6" + resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.1.6.tgz#43c714a94c6a7b8801850f82e756685300a027e2" + integrity sha512-cTOAhc36AalkjtBpfG6O8JimdTMWNXjiePT2xQH/ppBGi/4uIpmj8eKyIkMJErXWARyINV/sB38yf8JCLF5pbQ== domutils@^2.5.2, domutils@^2.8.0: version "2.8.0" @@ -6471,10 +6454,10 @@ electron-to-chromium@^1.5.28: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.40.tgz#5f6aec13751123c5c3185999ebe3e7bcaf828c2b" integrity sha512-LYm78o6if4zTasnYclgQzxEcgMoIcybWOhkATWepN95uwVVWV0/IW10v+2sIeHE+bIYWipLneTftVyQm45UY7g== -elkjs@^0.8.2: - version "0.8.2" - resolved "https://registry.npmjs.org/elkjs/-/elkjs-0.8.2.tgz" - integrity sha512-L6uRgvZTH+4OF5NE/MBbzQx/WYpru1xCBE9respNj6qznEewGUIfhzmm7horWWxbNO2M0WckQypGctR8lH79xQ== +elkjs@^0.9.0: + version "0.9.3" + resolved "https://registry.yarnpkg.com/elkjs/-/elkjs-0.9.3.tgz#16711f8ceb09f1b12b99e971b138a8384a529161" + integrity sha512-f/ZeWvW/BCXbhGEf1Ujp29EASo/lk1FDnETgNKwJrsVvGZhUWCZyg3xLJjAsxfOmt8KjswHmI5EwCQcPMpOYhQ== elliptic@^6.5.3, elliptic@^6.5.5: version "6.5.7" @@ -8115,11 +8098,6 @@ he@^1.2.0: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== -heap@^0.2.6: - version "0.2.7" - resolved "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz" - integrity sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg== - highlight.js@^10.4.1, highlight.js@~10.7.0: version "10.7.3" resolved "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz" @@ -9391,10 +9369,10 @@ jwt-decode@^4.0.0: resolved "https://registry.npmmirror.com/jwt-decode/-/jwt-decode-4.0.0.tgz#2270352425fd413785b2faf11f6e755c5151bd4b" integrity sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA== -katex@^0.16.0, katex@^0.16.10: - version "0.16.10" - resolved "https://registry.npmjs.org/katex/-/katex-0.16.10.tgz" - integrity sha512-ZiqaC04tp2O5utMsl2TEZTXxa6WSC4yo0fv5ML++D3QZv/vx2Mct0mTlRx3O+uUkjfuAgOkzsCmq5MiUEsDDdA== +katex@^0.16.0, katex@^0.16.10, katex@^0.16.9: + version "0.16.11" + resolved "https://registry.yarnpkg.com/katex/-/katex-0.16.11.tgz#4bc84d5584f996abece5f01c6ad11304276a33f5" + integrity sha512-RQrI8rlHY92OLf3rho/Ts8i/XvjgguEjOkO1BEXcU3N8BqPpSzBNwV/G0Ukr+P/l3ivvJUE/Fa/CwbS6HesGNQ== dependencies: commander "^8.3.0" @@ -9444,11 +9422,6 @@ layout-base@^1.0.0: resolved "https://registry.npmjs.org/layout-base/-/layout-base-1.0.2.tgz" integrity sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg== -layout-base@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/layout-base/-/layout-base-2.0.1.tgz" - integrity sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg== - leven@^3.1.0: version "3.1.0" resolved "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" @@ -10003,23 +9976,23 @@ merge2@^1.3.0, merge2@^1.4.1: resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== -mermaid@10.4.0: - version "10.4.0" - resolved "https://registry.npmjs.org/mermaid/-/mermaid-10.4.0.tgz" - integrity sha512-4QCQLp79lvz7UZxow5HUX7uWTPJOaQBVExduo91tliXC7v78i6kssZOPHxLL+Xs30KU72cpPn3g3imw/xm/gaw== +mermaid@10.9.3: + version "10.9.3" + resolved "https://registry.yarnpkg.com/mermaid/-/mermaid-10.9.3.tgz#90bc6f15c33dbe5d9507fed31592cc0d88fee9f7" + integrity sha512-V80X1isSEvAewIL3xhmz/rVmc27CVljcsbWxkxlWJWY/1kQa4XOABqpDl2qQLGKzpKm6WbTfUEKImBlUfFYArw== dependencies: "@braintree/sanitize-url" "^6.0.1" "@types/d3-scale" "^4.0.3" "@types/d3-scale-chromatic" "^3.0.0" - cytoscape "^3.23.0" + cytoscape "^3.28.1" cytoscape-cose-bilkent "^4.1.0" - cytoscape-fcose "^2.1.0" d3 "^7.4.0" d3-sankey "^0.12.3" dagre-d3-es "7.0.10" dayjs "^1.11.7" - dompurify "^3.0.5" - elkjs "^0.8.2" + dompurify "^3.0.5 <3.1.7" + elkjs "^0.9.0" + katex "^0.16.9" khroma "^2.0.0" lodash-es "^4.17.21" mdast-util-from-markdown "^1.3.0" From 5d3c88a0b32e6a872df318b67a28d8aaa9fc4ec8 Mon Sep 17 00:00:00 2001 From: nite-knite <nkCoding@gmail.com> Date: Wed, 23 Oct 2024 17:02:38 +0800 Subject: [PATCH 167/346] chore: bump mermaid from 10.4.0 to 10.9.3 --- web/package.json | 4 ++-- web/pnpm-lock.yaml | 50 +++++++++++++--------------------------------- 2 files changed, 16 insertions(+), 38 deletions(-) diff --git a/web/package.json b/web/package.json index a56f218696..970b3f12b1 100644 --- a/web/package.json +++ b/web/package.json @@ -64,7 +64,7 @@ "lamejs": "^1.2.1", "lexical": "^0.16.0", "lodash-es": "^4.17.21", - "mermaid": "10.4.0", + "mermaid": "10.9.3", "negotiator": "^0.6.3", "next": "^14.1.1", "pinyin-pro": "^3.23.0", @@ -180,4 +180,4 @@ "eslint --fix" ] } -} \ No newline at end of file +} diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index 600e7061c4..cfc0b8887b 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -134,8 +134,8 @@ importers: specifier: ^4.17.21 version: 4.17.21 mermaid: - specifier: 10.4.0 - version: 10.4.0 + specifier: 10.9.3 + version: 10.9.3 negotiator: specifier: ^0.6.3 version: 0.6.4 @@ -3568,9 +3568,6 @@ packages: cose-base@1.0.3: resolution: {integrity: sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==} - cose-base@2.2.0: - resolution: {integrity: sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==} - cosmiconfig@7.1.0: resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==} engines: {node: '>=10'} @@ -3661,11 +3658,6 @@ packages: peerDependencies: cytoscape: ^3.2.0 - cytoscape-fcose@2.2.0: - resolution: {integrity: sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==} - peerDependencies: - cytoscape: ^3.2.0 - cytoscape@3.30.2: resolution: {integrity: sha512-oICxQsjW8uSaRmn4UK/jkczKOqTrVqt5/1WL0POiJUT2EKNc9STM4hYFHv917yu55aTBMFNRzymlJhVAiWPCxw==} engines: {node: '>=0.10'} @@ -4015,8 +4007,8 @@ packages: resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==} engines: {node: '>= 4'} - dompurify@3.1.7: - resolution: {integrity: sha512-VaTstWtsneJY8xzy7DekmYWEOZcmzIe3Qb3zPd4STve1OBTa+e+WmS1ITQec1fZYXI3HCsOZZiSMpG6oxoWMWQ==} + dompurify@3.1.6: + resolution: {integrity: sha512-cTOAhc36AalkjtBpfG6O8JimdTMWNXjiePT2xQH/ppBGi/4uIpmj8eKyIkMJErXWARyINV/sB38yf8JCLF5pbQ==} domutils@2.8.0: resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==} @@ -4039,8 +4031,8 @@ packages: electron-to-chromium@1.5.41: resolution: {integrity: sha512-dfdv/2xNjX0P8Vzme4cfzHqnPm5xsZXwsolTYr0eyW18IUmNyG08vL+fttvinTfhKfIKdRoqkDIC9e9iWQCNYQ==} - elkjs@0.8.2: - resolution: {integrity: sha512-L6uRgvZTH+4OF5NE/MBbzQx/WYpru1xCBE9respNj6qznEewGUIfhzmm7horWWxbNO2M0WckQypGctR8lH79xQ==} + elkjs@0.9.3: + resolution: {integrity: sha512-f/ZeWvW/BCXbhGEf1Ujp29EASo/lk1FDnETgNKwJrsVvGZhUWCZyg3xLJjAsxfOmt8KjswHmI5EwCQcPMpOYhQ==} elliptic@6.5.7: resolution: {integrity: sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q==} @@ -5588,9 +5580,6 @@ packages: layout-base@1.0.2: resolution: {integrity: sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==} - layout-base@2.0.1: - resolution: {integrity: sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==} - leven@3.1.0: resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} engines: {node: '>=6'} @@ -5874,8 +5863,8 @@ packages: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} - mermaid@10.4.0: - resolution: {integrity: sha512-4QCQLp79lvz7UZxow5HUX7uWTPJOaQBVExduo91tliXC7v78i6kssZOPHxLL+Xs30KU72cpPn3g3imw/xm/gaw==} + mermaid@10.9.3: + resolution: {integrity: sha512-V80X1isSEvAewIL3xhmz/rVmc27CVljcsbWxkxlWJWY/1kQa4XOABqpDl2qQLGKzpKm6WbTfUEKImBlUfFYArw==} methods@1.1.2: resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} @@ -12073,10 +12062,6 @@ snapshots: dependencies: layout-base: 1.0.2 - cose-base@2.2.0: - dependencies: - layout-base: 2.0.1 - cosmiconfig@7.1.0: dependencies: '@types/parse-json': 4.0.2 @@ -12201,11 +12186,6 @@ snapshots: cose-base: 1.0.3 cytoscape: 3.30.2 - cytoscape-fcose@2.2.0(cytoscape@3.30.2): - dependencies: - cose-base: 2.2.0 - cytoscape: 3.30.2 - cytoscape@3.30.2: {} d3-array@2.12.1: @@ -12541,7 +12521,7 @@ snapshots: dependencies: domelementtype: 2.3.0 - dompurify@3.1.7: {} + dompurify@3.1.6: {} domutils@2.8.0: dependencies: @@ -12570,7 +12550,7 @@ snapshots: electron-to-chromium@1.5.41: {} - elkjs@0.8.2: {} + elkjs@0.9.3: {} elliptic@6.5.7: dependencies: @@ -14755,8 +14735,6 @@ snapshots: layout-base@1.0.2: {} - layout-base@2.0.1: {} - leven@3.1.0: {} levn@0.4.1: @@ -15217,20 +15195,20 @@ snapshots: merge2@1.4.1: {} - mermaid@10.4.0: + mermaid@10.9.3: dependencies: '@braintree/sanitize-url': 6.0.4 '@types/d3-scale': 4.0.8 '@types/d3-scale-chromatic': 3.0.3 cytoscape: 3.30.2 cytoscape-cose-bilkent: 4.1.0(cytoscape@3.30.2) - cytoscape-fcose: 2.2.0(cytoscape@3.30.2) d3: 7.9.0 d3-sankey: 0.12.3 dagre-d3-es: 7.0.10 dayjs: 1.11.13 - dompurify: 3.1.7 - elkjs: 0.8.2 + dompurify: 3.1.6 + elkjs: 0.9.3 + katex: 0.16.11 khroma: 2.1.0 lodash-es: 4.17.21 mdast-util-from-markdown: 1.3.1 From e11d5ac708421517f844b18894a5a4d21afec2a0 Mon Sep 17 00:00:00 2001 From: -LAN- <laipz8200@outlook.com> Date: Wed, 23 Oct 2024 17:03:30 +0800 Subject: [PATCH 168/346] feat(model_runtime): add new model 'claude-3-5-sonnet-20241022' (#9708) --- .../anthropic/llm/_position.yaml | 1 + .../llm/claude-3-5-sonnet-20241022.yaml | 39 +++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 api/core/model_runtime/model_providers/anthropic/llm/claude-3-5-sonnet-20241022.yaml diff --git a/api/core/model_runtime/model_providers/anthropic/llm/_position.yaml b/api/core/model_runtime/model_providers/anthropic/llm/_position.yaml index 8394c4276a..aca9456313 100644 --- a/api/core/model_runtime/model_providers/anthropic/llm/_position.yaml +++ b/api/core/model_runtime/model_providers/anthropic/llm/_position.yaml @@ -1,3 +1,4 @@ +- claude-3-5-sonnet-20241022 - claude-3-5-sonnet-20240620 - claude-3-haiku-20240307 - claude-3-opus-20240229 diff --git a/api/core/model_runtime/model_providers/anthropic/llm/claude-3-5-sonnet-20241022.yaml b/api/core/model_runtime/model_providers/anthropic/llm/claude-3-5-sonnet-20241022.yaml new file mode 100644 index 0000000000..e20b8c4960 --- /dev/null +++ b/api/core/model_runtime/model_providers/anthropic/llm/claude-3-5-sonnet-20241022.yaml @@ -0,0 +1,39 @@ +model: claude-3-5-sonnet-20241022 +label: + en_US: claude-3-5-sonnet-20241022 +model_type: llm +features: + - agent-thought + - vision + - tool-call + - stream-tool-call +model_properties: + mode: chat + context_size: 200000 +parameter_rules: + - name: temperature + use_template: temperature + - name: top_p + use_template: top_p + - name: top_k + label: + zh_Hans: 取样数量 + en_US: Top k + type: int + help: + zh_Hans: 仅从每个后续标记的前 K 个选项中采样。 + en_US: Only sample from the top K options for each subsequent token. + required: false + - name: max_tokens + use_template: max_tokens + required: true + default: 8192 + min: 1 + max: 8192 + - name: response_format + use_template: response_format +pricing: + input: '3.00' + output: '15.00' + unit: '0.000001' + currency: USD From e32116b9a3d3dfa1fd9c9d0b5650fc41eb89f116 Mon Sep 17 00:00:00 2001 From: KVOJJJin <jzongcode@gmail.com> Date: Wed, 23 Oct 2024 17:03:44 +0800 Subject: [PATCH 169/346] Feat: use file size limit from api (#9711) --- .../base/file-uploader/constants.ts | 4 + .../components/base/file-uploader/hooks.ts | 116 ++++++++++++++++-- .../_base/components/file-upload-setting.tsx | 10 +- web/i18n/en-US/app-debug.ts | 2 +- web/i18n/en-US/common.ts | 2 +- web/i18n/zh-Hans/app-debug.ts | 2 +- web/i18n/zh-Hans/common.ts | 2 +- web/models/common.ts | 6 +- 8 files changed, 127 insertions(+), 17 deletions(-) diff --git a/web/app/components/base/file-uploader/constants.ts b/web/app/components/base/file-uploader/constants.ts index e6cc2995f9..629fe2566b 100644 --- a/web/app/components/base/file-uploader/constants.ts +++ b/web/app/components/base/file-uploader/constants.ts @@ -1,3 +1,7 @@ +// fallback for file size limit of dify_config +export const IMG_SIZE_LIMIT = 10 * 1024 * 1024 export const FILE_SIZE_LIMIT = 15 * 1024 * 1024 +export const AUDIO_SIZE_LIMIT = 50 * 1024 * 1024 +export const VIDEO_SIZE_LIMIT = 100 * 1024 * 1024 export const FILE_URL_REGEX = /^(https?|ftp):\/\// diff --git a/web/app/components/base/file-uploader/hooks.ts b/web/app/components/base/file-uploader/hooks.ts index 5e126a87b5..ed299eca3e 100644 --- a/web/app/components/base/file-uploader/hooks.ts +++ b/web/app/components/base/file-uploader/hooks.ts @@ -3,6 +3,7 @@ import { useCallback, useState, } from 'react' +import useSWR from 'swr' import { useParams } from 'next/navigation' import produce from 'immer' import { v4 as uuid4 } from 'uuid' @@ -14,19 +15,113 @@ import { getSupportFileType, isAllowedFileExtension, } from './utils' -import { FILE_SIZE_LIMIT } from './constants' +import { + AUDIO_SIZE_LIMIT, + FILE_SIZE_LIMIT, + IMG_SIZE_LIMIT, + VIDEO_SIZE_LIMIT, +} from '@/app/components/base/file-uploader/constants' import { useToastContext } from '@/app/components/base/toast' import { TransferMethod } from '@/types/app' import { SupportUploadFileTypes } from '@/app/components/workflow/types' import type { FileUpload } from '@/app/components/base/features/types' import { formatFileSize } from '@/utils/format' -import { fetchRemoteFileInfo } from '@/service/common' +import { fetchFileUploadConfig, fetchRemoteFileInfo } from '@/service/common' + +export const useFileSizeLimit = () => { + const { data: fileUploadConfigResponse } = useSWR({ url: '/files/upload' }, fetchFileUploadConfig) + const imgSizeLimit = Number(fileUploadConfigResponse?.image_file_size_limit) * 1024 * 1024 || IMG_SIZE_LIMIT + const docSizeLimit = Number(fileUploadConfigResponse?.file_size_limit) * 1024 * 1024 || FILE_SIZE_LIMIT + const audioSizeLimit = Number(fileUploadConfigResponse?.audio_file_size_limit) * 1024 * 1024 || AUDIO_SIZE_LIMIT + const videoSizeLimit = Number(fileUploadConfigResponse?.video_file_size_limit) * 1024 * 1024 || VIDEO_SIZE_LIMIT + + return { + imgSizeLimit, + docSizeLimit, + audioSizeLimit, + videoSizeLimit, + } +} export const useFile = (fileConfig: FileUpload) => { const { t } = useTranslation() const { notify } = useToastContext() const fileStore = useFileStore() const params = useParams() + const { imgSizeLimit, docSizeLimit, audioSizeLimit, videoSizeLimit } = useFileSizeLimit() + + const checkSizeLimit = (fileType: string, fileSize: number) => { + switch (fileType) { + case SupportUploadFileTypes.image: { + if (fileSize > imgSizeLimit) { + notify({ + type: 'error', + message: t('common.fileUploader.uploadFromComputerLimit', { + type: SupportUploadFileTypes.image, + size: formatFileSize(imgSizeLimit), + }), + }) + return false + } + return true + } + case SupportUploadFileTypes.document: { + if (fileSize > docSizeLimit) { + notify({ + type: 'error', + message: t('common.fileUploader.uploadFromComputerLimit', { + type: SupportUploadFileTypes.document, + size: formatFileSize(docSizeLimit), + }), + }) + return false + } + return true + } + case SupportUploadFileTypes.audio: { + if (fileSize > audioSizeLimit) { + notify({ + type: 'error', + message: t('common.fileUploader.uploadFromComputerLimit', { + type: SupportUploadFileTypes.audio, + size: formatFileSize(audioSizeLimit), + }), + }) + return false + } + return true + } + case SupportUploadFileTypes.video: { + if (fileSize > videoSizeLimit) { + notify({ + type: 'error', + message: t('common.fileUploader.uploadFromComputerLimit', { + type: SupportUploadFileTypes.video, + size: formatFileSize(videoSizeLimit), + }), + }) + return false + } + return true + } + case SupportUploadFileTypes.custom: { + if (fileSize > docSizeLimit) { + notify({ + type: 'error', + message: t('common.fileUploader.uploadFromComputerLimit', { + type: SupportUploadFileTypes.document, + size: formatFileSize(docSizeLimit), + }), + }) + return false + } + return true + } + default: { + return true + } + } + } const handleAddFile = useCallback((newFile: FileEntity) => { const { @@ -117,12 +212,15 @@ export const useFile = (fileConfig: FileUpload) => { progress: 100, supportFileType: getSupportFileType(url, res.file_type, allowedFileTypes?.includes(SupportUploadFileTypes.custom)), } - handleUpdateFile(newFile) + if (!checkSizeLimit(newFile.supportFileType, newFile.size)) + handleRemoveFile(uploadingFile.id) + else + handleUpdateFile(newFile) }).catch(() => { notify({ type: 'error', message: t('common.fileUploader.pasteFileLinkInvalid') }) handleRemoveFile(uploadingFile.id) }) - }, [handleAddFile, handleUpdateFile, notify, t, handleRemoveFile, fileConfig?.allowed_file_types]) + }, [checkSizeLimit, handleAddFile, handleUpdateFile, notify, t, handleRemoveFile, fileConfig?.allowed_file_types]) const handleLoadFileFromLinkSuccess = useCallback(() => { }, []) @@ -140,13 +238,13 @@ export const useFile = (fileConfig: FileUpload) => { notify({ type: 'error', message: t('common.fileUploader.fileExtensionNotSupport') }) return } - if (file.size > FILE_SIZE_LIMIT) { - notify({ type: 'error', message: t('common.fileUploader.uploadFromComputerLimit', { size: formatFileSize(FILE_SIZE_LIMIT) }) }) + const allowedFileTypes = fileConfig.allowed_file_types + const fileType = getSupportFileType(file.name, file.type, allowedFileTypes?.includes(SupportUploadFileTypes.custom)) + if (!checkSizeLimit(fileType, file.size)) return - } + const reader = new FileReader() const isImage = file.type.startsWith('image') - const allowedFileTypes = fileConfig.allowed_file_types reader.addEventListener( 'load', @@ -187,7 +285,7 @@ export const useFile = (fileConfig: FileUpload) => { false, ) reader.readAsDataURL(file) - }, [notify, t, handleAddFile, handleUpdateFile, params.token, fileConfig?.allowed_file_types, fileConfig?.allowed_file_extensions]) + }, [checkSizeLimit, notify, t, handleAddFile, handleUpdateFile, params.token, fileConfig?.allowed_file_types, fileConfig?.allowed_file_extensions]) const handleClipboardPasteFile = useCallback((e: ClipboardEvent<HTMLTextAreaElement>) => { const file = e.clipboardData?.files[0] diff --git a/web/app/components/workflow/nodes/_base/components/file-upload-setting.tsx b/web/app/components/workflow/nodes/_base/components/file-upload-setting.tsx index 77ff2fd5c1..72df3b20d2 100644 --- a/web/app/components/workflow/nodes/_base/components/file-upload-setting.tsx +++ b/web/app/components/workflow/nodes/_base/components/file-upload-setting.tsx @@ -10,7 +10,7 @@ import FileTypeItem from './file-type-item' import InputNumberWithSlider from './input-number-with-slider' import Field from '@/app/components/app/configuration/config-var/config-modal/field' import { TransferMethod } from '@/types/app' -import { FILE_SIZE_LIMIT } from '@/app/components/base/file-uploader/constants' +import { useFileSizeLimit } from '@/app/components/base/file-uploader/hooks' import { formatFileSize } from '@/utils/format' type Props = { @@ -36,6 +36,7 @@ const FileUploadSetting: FC<Props> = ({ allowed_file_types, allowed_file_extensions, } = payload + const { imgSizeLimit, docSizeLimit, audioSizeLimit, videoSizeLimit } = useFileSizeLimit() const handleSupportFileTypeChange = useCallback((type: SupportUploadFileTypes) => { const newPayload = produce(payload, (draft) => { @@ -142,7 +143,12 @@ const FileUploadSetting: FC<Props> = ({ title={t('appDebug.variableConfig.maxNumberOfUploads')!} > <div> - <div className='mb-1.5 text-text-tertiary body-xs-regular'>{t('appDebug.variableConfig.maxNumberTip', { size: formatFileSize(FILE_SIZE_LIMIT) })}</div> + <div className='mb-1.5 text-text-tertiary body-xs-regular'>{t('appDebug.variableConfig.maxNumberTip', { + imgLimit: formatFileSize(imgSizeLimit), + docLimit: formatFileSize(docSizeLimit), + audioLimit: formatFileSize(audioSizeLimit), + videoLimit: formatFileSize(videoSizeLimit), + })}</div> <InputNumberWithSlider value={max_length} min={1} diff --git a/web/i18n/en-US/app-debug.ts b/web/i18n/en-US/app-debug.ts index c0d0193c7c..b2144262f6 100644 --- a/web/i18n/en-US/app-debug.ts +++ b/web/i18n/en-US/app-debug.ts @@ -386,7 +386,7 @@ const translation = { 'localUpload': 'Local Upload', 'both': 'Both', 'maxNumberOfUploads': 'Max number of uploads', - 'maxNumberTip': 'Max {{size}} each', + 'maxNumberTip': 'Document < {{docLimit}}, image < {{imgLimit}}, audio < {{audioLimit}}, video < {{videoLimit}}', 'errorMsg': { labelNameRequired: 'Label name is required', varNameCanBeRepeat: 'Variable name can not be repeated', diff --git a/web/i18n/en-US/common.ts b/web/i18n/en-US/common.ts index 5b82ecf8be..3390280e8a 100644 --- a/web/i18n/en-US/common.ts +++ b/web/i18n/en-US/common.ts @@ -572,7 +572,7 @@ const translation = { pasteFileLinkInputPlaceholder: 'Enter URL...', uploadFromComputerReadError: 'File reading failed, please try again.', uploadFromComputerUploadError: 'File upload failed, please upload again.', - uploadFromComputerLimit: 'Upload File cannot exceed {{size}}', + uploadFromComputerLimit: 'Upload {{type}} cannot exceed {{size}}', pasteFileLinkInvalid: 'Invalid file link', fileExtensionNotSupport: 'File extension not supported', }, diff --git a/web/i18n/zh-Hans/app-debug.ts b/web/i18n/zh-Hans/app-debug.ts index ee8ff7bb29..3e801bcf62 100644 --- a/web/i18n/zh-Hans/app-debug.ts +++ b/web/i18n/zh-Hans/app-debug.ts @@ -379,7 +379,7 @@ const translation = { 'localUpload': '本地上传', 'both': '两者', 'maxNumberOfUploads': '最大上传数', - 'maxNumberTip': '最大上传文件大小为 {{size}}', + 'maxNumberTip': '文档 < {{docLimit}}, 图片 < {{imgLimit}}, 音频 < {{audioLimit}}, 视频 < {{videoLimit}}', 'content': '内容', 'errorMsg': { labelNameRequired: '显示名称必填', diff --git a/web/i18n/zh-Hans/common.ts b/web/i18n/zh-Hans/common.ts index 21e69e666d..7cb5e9810c 100644 --- a/web/i18n/zh-Hans/common.ts +++ b/web/i18n/zh-Hans/common.ts @@ -572,7 +572,7 @@ const translation = { pasteFileLinkInputPlaceholder: '输入文件链接', uploadFromComputerReadError: '文件读取失败,请重新选择。', uploadFromComputerUploadError: '文件上传失败,请重新上传。', - uploadFromComputerLimit: '上传文件不能超过 {{size}}', + uploadFromComputerLimit: '上传 {{type}} 不能超过 {{size}}', pasteFileLinkInvalid: '文件链接无效', fileExtensionNotSupport: '文件类型不支持', }, diff --git a/web/models/common.ts b/web/models/common.ts index 204e89ed9b..febf92e079 100644 --- a/web/models/common.ts +++ b/web/models/common.ts @@ -211,9 +211,11 @@ export type PluginProvider = { } export type FileUploadConfigResponse = { - file_size_limit: number batch_count_limit: number - image_file_size_limit?: number | string + image_file_size_limit?: number | string // default is 10MB + file_size_limit: number // default is 15MB + audio_file_size_limit?: number // default is 50MB + video_file_size_limit?: number // default is 100MB } export type InvitationResult = { From 926609eb59dbf6d91be66cbb6082083b6c5cf9f6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 23 Oct 2024 17:18:35 +0800 Subject: [PATCH 170/346] build(deps): bump next from 14.2.4 to 14.2.10 in /web (#9713) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- web/package.json | 2 +- web/yarn.lock | 124 ++++++++++++++++++++++------------------------- 2 files changed, 58 insertions(+), 68 deletions(-) diff --git a/web/package.json b/web/package.json index 1bdc67e7d2..18b983f289 100644 --- a/web/package.json +++ b/web/package.json @@ -65,7 +65,7 @@ "mermaid": "10.9.3", "mime": "^4.0.4", "negotiator": "^0.6.3", - "next": "^14.1.1", + "next": "^14.2.10", "pinyin-pro": "^3.23.0", "qrcode.react": "^3.1.0", "qs": "^6.11.1", diff --git a/web/yarn.lock b/web/yarn.lock index e1c765ed1f..6f54ec23d4 100644 --- a/web/yarn.lock +++ b/web/yarn.lock @@ -2386,10 +2386,10 @@ dependencies: "@monaco-editor/loader" "^1.4.0" -"@next/env@14.2.4": - version "14.2.4" - resolved "https://registry.npmjs.org/@next/env/-/env-14.2.4.tgz" - integrity sha512-3EtkY5VDkuV2+lNmKlbkibIJxcO4oIHEhBWne6PaAp+76J9KoSsGvNikp6ivzAT8dhhBMYrm6op2pS1ApG0Hzg== +"@next/env@14.2.10": + version "14.2.10" + resolved "https://registry.yarnpkg.com/@next/env/-/env-14.2.10.tgz#1d3178340028ced2d679f84140877db4f420333c" + integrity sha512-dZIu93Bf5LUtluBXIv4woQw2cZVZ2DJTjax5/5DOs3lzEOeKLy7GxRSr4caK9/SCPdaW6bCgpye6+n4Dh9oJPw== "@next/eslint-plugin-next@14.1.0": version "14.1.0" @@ -2405,50 +2405,50 @@ dependencies: source-map "^0.7.0" -"@next/swc-darwin-arm64@14.2.4": - version "14.2.4" - resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.4.tgz#da9f04c34a3d5f0b8401ed745768420e4a604036" - integrity sha512-AH3mO4JlFUqsYcwFUHb1wAKlebHU/Hv2u2kb1pAuRanDZ7pD/A/KPD98RHZmwsJpdHQwfEc/06mgpSzwrJYnNg== +"@next/swc-darwin-arm64@14.2.10": + version "14.2.10" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.10.tgz#49d10ca4086fbd59ee68e204f75d7136eda2aa80" + integrity sha512-V3z10NV+cvMAfxQUMhKgfQnPbjw+Ew3cnr64b0lr8MDiBJs3eLnM6RpGC46nhfMZsiXgQngCJKWGTC/yDcgrDQ== -"@next/swc-darwin-x64@14.2.4": - version "14.2.4" - resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.4.tgz#46dedb29ec5503bf171a72a3ecb8aac6e738e9d6" - integrity sha512-QVadW73sWIO6E2VroyUjuAxhWLZWEpiFqHdZdoQ/AMpN9YWGuHV8t2rChr0ahy+irKX5mlDU7OY68k3n4tAZTg== +"@next/swc-darwin-x64@14.2.10": + version "14.2.10" + resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.10.tgz#0ebeae3afb8eac433882b79543295ab83624a1a8" + integrity sha512-Y0TC+FXbFUQ2MQgimJ/7Ina2mXIKhE7F+GUe1SgnzRmwFY3hX2z8nyVCxE82I2RicspdkZnSWMn4oTjIKz4uzA== -"@next/swc-linux-arm64-gnu@14.2.4": - version "14.2.4" - resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.4.tgz#c9697ab9eb422bd1d7ffd0eb0779cc2aefa9d4a1" - integrity sha512-KT6GUrb3oyCfcfJ+WliXuJnD6pCpZiosx2X3k66HLR+DMoilRb76LpWPGb4tZprawTtcnyrv75ElD6VncVamUQ== +"@next/swc-linux-arm64-gnu@14.2.10": + version "14.2.10" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.10.tgz#7e602916d2fb55a3c532f74bed926a0137c16f20" + integrity sha512-ZfQ7yOy5zyskSj9rFpa0Yd7gkrBnJTkYVSya95hX3zeBG9E55Z6OTNPn1j2BTFWvOVVj65C3T+qsjOyVI9DQpA== -"@next/swc-linux-arm64-musl@14.2.4": - version "14.2.4" - resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.4.tgz#cbbceb2008571c743b5a310a488d2e166d200a75" - integrity sha512-Alv8/XGSs/ytwQcbCHwze1HmiIkIVhDHYLjczSVrf0Wi2MvKn/blt7+S6FJitj3yTlMwMxII1gIJ9WepI4aZ/A== +"@next/swc-linux-arm64-musl@14.2.10": + version "14.2.10" + resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.10.tgz#6b143f628ccee490b527562e934f8de578d4be47" + integrity sha512-n2i5o3y2jpBfXFRxDREr342BGIQCJbdAUi/K4q6Env3aSx8erM9VuKXHw5KNROK9ejFSPf0LhoSkU/ZiNdacpQ== -"@next/swc-linux-x64-gnu@14.2.4": - version "14.2.4" - resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.4.tgz#d79184223f857bacffb92f643cb2943a43632568" - integrity sha512-ze0ShQDBPCqxLImzw4sCdfnB3lRmN3qGMB2GWDRlq5Wqy4G36pxtNOo2usu/Nm9+V2Rh/QQnrRc2l94kYFXO6Q== +"@next/swc-linux-x64-gnu@14.2.10": + version "14.2.10" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.10.tgz#086f2f16a0678890a1eb46518c4dda381b046082" + integrity sha512-GXvajAWh2woTT0GKEDlkVhFNxhJS/XdDmrVHrPOA83pLzlGPQnixqxD8u3bBB9oATBKB//5e4vpACnx5Vaxdqg== -"@next/swc-linux-x64-musl@14.2.4": - version "14.2.4" - resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.4.tgz#6b6c3e5ac02ca5e63394d280ec8ee607491902df" - integrity sha512-8dwC0UJoc6fC7PX70csdaznVMNr16hQrTDAMPvLPloazlcaWfdPogq+UpZX6Drqb1OBlwowz8iG7WR0Tzk/diQ== +"@next/swc-linux-x64-musl@14.2.10": + version "14.2.10" + resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.10.tgz#1befef10ed8dbcc5047b5d637a25ae3c30a0bfc3" + integrity sha512-opFFN5B0SnO+HTz4Wq4HaylXGFV+iHrVxd3YvREUX9K+xfc4ePbRrxqOuPOFjtSuiVouwe6uLeDtabjEIbkmDA== -"@next/swc-win32-arm64-msvc@14.2.4": - version "14.2.4" - resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.4.tgz#dbad3906e870dba84c5883d9d4c4838472e0697f" - integrity sha512-jxyg67NbEWkDyvM+O8UDbPAyYRZqGLQDTPwvrBBeOSyVWW/jFQkQKQ70JDqDSYg1ZDdl+E3nkbFbq8xM8E9x8A== +"@next/swc-win32-arm64-msvc@14.2.10": + version "14.2.10" + resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.10.tgz#731f52c3ae3c56a26cf21d474b11ae1529531209" + integrity sha512-9NUzZuR8WiXTvv+EiU/MXdcQ1XUvFixbLIMNQiVHuzs7ZIFrJDLJDaOF1KaqttoTujpcxljM/RNAOmw1GhPPQQ== -"@next/swc-win32-ia32-msvc@14.2.4": - version "14.2.4" - resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.4.tgz#6074529b91ba49132922ce89a2e16d25d2ec235d" - integrity sha512-twrmN753hjXRdcrZmZttb/m5xaCBFa48Dt3FbeEItpJArxriYDunWxJn+QFXdJ3hPkm4u7CKxncVvnmgQMY1ag== +"@next/swc-win32-ia32-msvc@14.2.10": + version "14.2.10" + resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.10.tgz#32723ef7f04e25be12af357cc72ddfdd42fd1041" + integrity sha512-fr3aEbSd1GeW3YUMBkWAu4hcdjZ6g4NBl1uku4gAn661tcxd1bHs1THWYzdsbTRLcCKLjrDZlNp6j2HTfrw+Bg== -"@next/swc-win32-x64-msvc@14.2.4": - version "14.2.4" - resolved "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.4.tgz" - integrity sha512-tkLrjBzqFTP8DVrAAQmZelEahfR9OxWpFR++vAI9FBhCiIxtwHwBHC23SBHCTURBtwB4kc/x44imVOnkKGNVGg== +"@next/swc-win32-x64-msvc@14.2.10": + version "14.2.10" + resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.10.tgz#ee1d036cb5ec871816f96baee7991035bb242455" + integrity sha512-UjeVoRGKNL2zfbcQ6fscmgjBAS/inHBh63mjIlfPg/NG8Yn2ztqylXt5qilYb6hoHIwaU2ogHknHWWmahJjgZQ== "@nodelib/fs.scandir@2.1.5": version "2.1.5" @@ -5107,17 +5107,7 @@ camelcase@^6.2.0: resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.30001464, caniuse-lite@^1.0.30001579, caniuse-lite@^1.0.30001587: - version "1.0.30001620" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001620.tgz" - integrity sha512-WJvYsOjd1/BYUY6SNGUosK9DUidBPDTnOARHp3fSmFO1ekdxaY6nKRttEVrfMmYi80ctS0kz1wiWmm14fVc3ew== - -caniuse-lite@^1.0.30001640: - version "1.0.30001642" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001642.tgz#6aa6610eb24067c246d30c57f055a9d0a7f8d05f" - integrity sha512-3XQ0DoRgLijXJErLSl+bLnJ+Et4KqV1PY6JJBGAFlsNsz31zeAIncyeZfLCabHK/jtSh+671RM9YMldxjUPZtA== - -caniuse-lite@^1.0.30001663: +caniuse-lite@^1.0.30001464, caniuse-lite@^1.0.30001579, caniuse-lite@^1.0.30001587, caniuse-lite@^1.0.30001640, caniuse-lite@^1.0.30001663: version "1.0.30001669" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001669.tgz#fda8f1d29a8bfdc42de0c170d7f34a9cf19ed7a3" integrity sha512-DlWzFDJqstqtIVx1zeSpIMLjunf5SmwOw0N2Ck/QSQdS8PLS4+9HrLaYei4w8BIAL7IB/UEDu889d8vhCTPA0w== @@ -10590,12 +10580,12 @@ neo-async@^2.6.2: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== -next@^14.1.1: - version "14.2.4" - resolved "https://registry.npmjs.org/next/-/next-14.2.4.tgz" - integrity sha512-R8/V7vugY+822rsQGQCjoLhMuC9oFj9SOi4Cl4b2wjDrseD0LRZ10W7R6Czo4w9ZznVSshKjuIomsRjvm9EKJQ== +next@^14.2.10: + version "14.2.10" + resolved "https://registry.yarnpkg.com/next/-/next-14.2.10.tgz#331981a4fecb1ae8af1817d4db98fc9687ee1cb6" + integrity sha512-sDDExXnh33cY3RkS9JuFEKaS4HmlWmDKP1VJioucCG6z5KuA008DPsDZOzi8UfqEk3Ii+2NCQSJrfbEWtZZfww== dependencies: - "@next/env" "14.2.4" + "@next/env" "14.2.10" "@swc/helpers" "0.5.5" busboy "1.6.0" caniuse-lite "^1.0.30001579" @@ -10603,15 +10593,15 @@ next@^14.1.1: postcss "8.4.31" styled-jsx "5.1.1" optionalDependencies: - "@next/swc-darwin-arm64" "14.2.4" - "@next/swc-darwin-x64" "14.2.4" - "@next/swc-linux-arm64-gnu" "14.2.4" - "@next/swc-linux-arm64-musl" "14.2.4" - "@next/swc-linux-x64-gnu" "14.2.4" - "@next/swc-linux-x64-musl" "14.2.4" - "@next/swc-win32-arm64-msvc" "14.2.4" - "@next/swc-win32-ia32-msvc" "14.2.4" - "@next/swc-win32-x64-msvc" "14.2.4" + "@next/swc-darwin-arm64" "14.2.10" + "@next/swc-darwin-x64" "14.2.10" + "@next/swc-linux-arm64-gnu" "14.2.10" + "@next/swc-linux-arm64-musl" "14.2.10" + "@next/swc-linux-x64-gnu" "14.2.10" + "@next/swc-linux-x64-musl" "14.2.10" + "@next/swc-win32-arm64-msvc" "14.2.10" + "@next/swc-win32-ia32-msvc" "14.2.10" + "@next/swc-win32-x64-msvc" "14.2.10" no-case@^3.0.4: version "3.0.4" @@ -11299,7 +11289,7 @@ postcss-value-parser@^4.0.0, postcss-value-parser@^4.1.0, postcss-value-parser@^ resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== -postcss@8.4.31, postcss@^8.4.23, postcss@^8.4.31: +postcss@8.4.31: version "8.4.31" resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz" integrity sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ== @@ -11308,7 +11298,7 @@ postcss@8.4.31, postcss@^8.4.23, postcss@^8.4.31: picocolors "^1.0.0" source-map-js "^1.0.2" -postcss@^8.2.14, postcss@^8.4.33, postcss@^8.4.38: +postcss@^8.2.14, postcss@^8.4.23, postcss@^8.4.31, postcss@^8.4.33, postcss@^8.4.38: version "8.4.47" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.47.tgz#5bf6c9a010f3e724c503bf03ef7947dcb0fea365" integrity sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ== From 474cedf653d88ab59976d34b010a29fb113bab19 Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Wed, 23 Oct 2024 17:19:43 +0800 Subject: [PATCH 171/346] feat: debug info api --- .../components/plugins/base/key-value-item.tsx | 6 +++--- .../components/plugins/plugin-page/debug-info.tsx | 15 ++++++++++++--- web/app/components/plugins/types.ts | 6 ++++++ web/service/plugins.ts | 7 +++++++ 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/web/app/components/plugins/base/key-value-item.tsx b/web/app/components/plugins/base/key-value-item.tsx index ec8e8155cb..2b4dd06d9a 100644 --- a/web/app/components/plugins/base/key-value-item.tsx +++ b/web/app/components/plugins/base/key-value-item.tsx @@ -43,15 +43,15 @@ const KeyValueItem: FC<Props> = ({ const CopyIcon = isCopied ? ClipboardCheck : RiClipboardLine return ( - <div className='flex items-center gap-1 self-stretch'> + <div className='flex items-center gap-1'> <span className={cn('flex flex-col justify-center items-start text-text-tertiary system-xs-medium', labelWidthClassName)}>{label}</span> <div className='flex justify-center items-center gap-0.5'> - <span className='system-xs-medium text-text-secondary'> + <span className='max-w-[140px] truncate system-xs-medium text-text-secondary'> {value} </span> <Tooltip popupContent={t(`common.operation.${isCopied ? 'copied' : 'copy'}`)} position='top'> <ActionButton onClick={handleCopy}> - <CopyIcon className='w-3.5 h-3.5 text-text-tertiary' /> + <CopyIcon className='shrink-0 w-3.5 h-3.5 text-text-tertiary' /> </ActionButton> </Tooltip> </div> diff --git a/web/app/components/plugins/plugin-page/debug-info.tsx b/web/app/components/plugins/plugin-page/debug-info.tsx index 308b141836..de8149fcd2 100644 --- a/web/app/components/plugins/plugin-page/debug-info.tsx +++ b/web/app/components/plugins/plugin-page/debug-info.tsx @@ -1,6 +1,6 @@ 'use client' import type { FC } from 'react' -import React from 'react' +import React, { useEffect } from 'react' import { RiArrowRightUpLine, RiBugLine, @@ -9,14 +9,23 @@ import { useTranslation } from 'react-i18next' import KeyValueItem from '../base/key-value-item' import Tooltip from '@/app/components/base/tooltip' import Button from '@/app/components/base/button' +import type { DebugInfo as DebugInfoTypes } from '../types' +import { fetchDebugKey } from '@/service/plugins' const i18nPrefix = 'plugin.debugInfo' const DebugInfo: FC = () => { const { t } = useTranslation() + const [info, setInfo] = React.useState<DebugInfoTypes | null>(null) + useEffect(() => { + fetchDebugKey().then((res) => { + setInfo(res) + }) + }, []) return ( <Tooltip triggerMethod='click' + disabled={!info} popupContent={ <> <div className='flex items-center gap-1 self-stretch'> @@ -29,11 +38,11 @@ const DebugInfo: FC = () => { <div className='space-y-0.5'> <KeyValueItem label={'Port'} - value={'cloud.dify,ai:2048'} + value={`${info?.host}:${info?.port}`} /> <KeyValueItem label={'Key'} - value={'A1B2C3D4E5F6G7H8'} + value={info?.key || ''} /> </div> </> diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts index a2c11a8d6c..465f131ed0 100644 --- a/web/app/components/plugins/types.ts +++ b/web/app/components/plugins/types.ts @@ -187,3 +187,9 @@ export type GitHubRepoReleaseResponse = { export type InstallPackageResponse = { plugin_unique_identifier: string } + +export type DebugInfo = { + key: string + host: string + port: number +} diff --git a/web/service/plugins.ts b/web/service/plugins.ts index c072179913..08a7662896 100644 --- a/web/service/plugins.ts +++ b/web/service/plugins.ts @@ -46,3 +46,10 @@ export const installPackageFromGitHub: Fetcher<InstallPackageResponse, { repo: s } // export const fetchInstalledPluginsList: Fetcher< +export const fetchDebugKey = async () => { + return Promise.resolve({ + key: 'f15b079b-bba2-4a62-abad-69119bcd3fa4', + host: 'localhost', + port: 5003, + }) +} From c9dfe1ad92ccfb53e4dc4105a0d3598f6af187a9 Mon Sep 17 00:00:00 2001 From: zhuhao <37029601+hwzhuhao@users.noreply.github.com> Date: Wed, 23 Oct 2024 17:24:36 +0800 Subject: [PATCH 172/346] feat: support user-defined configuration of log file size and retention count (#9610) --- api/.env.example | 4 ++++ api/configs/feature/__init__.py | 10 ++++++++++ api/extensions/ext_logging.py | 4 ++-- docker/.env.example | 6 ++++++ docker/docker-compose.yaml | 2 ++ 5 files changed, 24 insertions(+), 2 deletions(-) diff --git a/api/.env.example b/api/.env.example index 32cf4293f7..960d8b1879 100644 --- a/api/.env.example +++ b/api/.env.example @@ -309,6 +309,10 @@ RESPECT_XFORWARD_HEADERS_ENABLED=false # Log file path LOG_FILE= +# Log file max size, the unit is MB +LOG_FILE_MAX_SIZE=20 +# Log file max backup count +LOG_FILE_BACKUP_COUNT=5 # Indexing configuration INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH=1000 diff --git a/api/configs/feature/__init__.py b/api/configs/feature/__init__.py index 8f87356934..4d6c9aedc1 100644 --- a/api/configs/feature/__init__.py +++ b/api/configs/feature/__init__.py @@ -319,6 +319,16 @@ class LoggingConfig(BaseSettings): default=None, ) + LOG_FILE_MAX_SIZE: PositiveInt = Field( + description="Maximum file size for file rotation retention, the unit is megabytes (MB)", + default=20, + ) + + LOG_FILE_BACKUP_COUNT: PositiveInt = Field( + description="Maximum file backup count file rotation retention", + default=5, + ) + LOG_FORMAT: str = Field( description="Format string for log messages", default="%(asctime)s.%(msecs)03d %(levelname)s [%(threadName)s] [%(filename)s:%(lineno)d] - %(message)s", diff --git a/api/extensions/ext_logging.py b/api/extensions/ext_logging.py index 9e1a241b67..56b1d6bd28 100644 --- a/api/extensions/ext_logging.py +++ b/api/extensions/ext_logging.py @@ -17,8 +17,8 @@ def init_app(app: Flask): log_handlers = [ RotatingFileHandler( filename=log_file, - maxBytes=1024 * 1024 * 1024, - backupCount=5, + maxBytes=dify_config.LOG_FILE_MAX_SIZE * 1024 * 1024, + backupCount=dify_config.LOG_FILE_BACKUP_COUNT, ), logging.StreamHandler(sys.stdout), ] diff --git a/docker/.env.example b/docker/.env.example index f022a451cf..dbdc943b06 100644 --- a/docker/.env.example +++ b/docker/.env.example @@ -48,6 +48,12 @@ FILES_URL= # The log level for the application. # Supported values are `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL` LOG_LEVEL=INFO +# Log file path +LOG_FILE= +# Log file max size, the unit is MB +LOG_FILE_MAX_SIZE=20 +# Log file max backup count +LOG_FILE_BACKUP_COUNT=5 # Debug mode, default is false. # It is recommended to turn on this configuration for local development diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml index 75817949ab..e4ad67892c 100644 --- a/docker/docker-compose.yaml +++ b/docker/docker-compose.yaml @@ -1,6 +1,8 @@ x-shared-env: &shared-api-worker-env LOG_LEVEL: ${LOG_LEVEL:-INFO} LOG_FILE: ${LOG_FILE:-} + LOG_FILE_MAX_SIZE: ${LOG_FILE_MAX_SIZE:-20} + LOG_FILE_BACKUP_COUNT: ${LOG_FILE_BACKUP_COUNT:-5} DEBUG: ${DEBUG:-false} FLASK_DEBUG: ${FLASK_DEBUG:-false} SECRET_KEY: ${SECRET_KEY:-sk-9f73s3ljTXVcMT3Blb3ljTqtsKiGHXVcMT3BlbkFJLK7U} From bf478aeba26b6ab760917f36a772307d3fdbbd59 Mon Sep 17 00:00:00 2001 From: KVOJJJin <jzongcode@gmail.com> Date: Wed, 23 Oct 2024 17:35:07 +0800 Subject: [PATCH 173/346] Revert "Feat: use file size limit from api" (#9714) --- .../base/file-uploader/constants.ts | 4 - .../components/base/file-uploader/hooks.ts | 116 ++---------------- .../_base/components/file-upload-setting.tsx | 10 +- web/i18n/en-US/app-debug.ts | 2 +- web/i18n/en-US/common.ts | 2 +- web/i18n/zh-Hans/app-debug.ts | 2 +- web/i18n/zh-Hans/common.ts | 2 +- web/models/common.ts | 6 +- 8 files changed, 17 insertions(+), 127 deletions(-) diff --git a/web/app/components/base/file-uploader/constants.ts b/web/app/components/base/file-uploader/constants.ts index 629fe2566b..e6cc2995f9 100644 --- a/web/app/components/base/file-uploader/constants.ts +++ b/web/app/components/base/file-uploader/constants.ts @@ -1,7 +1,3 @@ -// fallback for file size limit of dify_config -export const IMG_SIZE_LIMIT = 10 * 1024 * 1024 export const FILE_SIZE_LIMIT = 15 * 1024 * 1024 -export const AUDIO_SIZE_LIMIT = 50 * 1024 * 1024 -export const VIDEO_SIZE_LIMIT = 100 * 1024 * 1024 export const FILE_URL_REGEX = /^(https?|ftp):\/\// diff --git a/web/app/components/base/file-uploader/hooks.ts b/web/app/components/base/file-uploader/hooks.ts index ed299eca3e..5e126a87b5 100644 --- a/web/app/components/base/file-uploader/hooks.ts +++ b/web/app/components/base/file-uploader/hooks.ts @@ -3,7 +3,6 @@ import { useCallback, useState, } from 'react' -import useSWR from 'swr' import { useParams } from 'next/navigation' import produce from 'immer' import { v4 as uuid4 } from 'uuid' @@ -15,113 +14,19 @@ import { getSupportFileType, isAllowedFileExtension, } from './utils' -import { - AUDIO_SIZE_LIMIT, - FILE_SIZE_LIMIT, - IMG_SIZE_LIMIT, - VIDEO_SIZE_LIMIT, -} from '@/app/components/base/file-uploader/constants' +import { FILE_SIZE_LIMIT } from './constants' import { useToastContext } from '@/app/components/base/toast' import { TransferMethod } from '@/types/app' import { SupportUploadFileTypes } from '@/app/components/workflow/types' import type { FileUpload } from '@/app/components/base/features/types' import { formatFileSize } from '@/utils/format' -import { fetchFileUploadConfig, fetchRemoteFileInfo } from '@/service/common' - -export const useFileSizeLimit = () => { - const { data: fileUploadConfigResponse } = useSWR({ url: '/files/upload' }, fetchFileUploadConfig) - const imgSizeLimit = Number(fileUploadConfigResponse?.image_file_size_limit) * 1024 * 1024 || IMG_SIZE_LIMIT - const docSizeLimit = Number(fileUploadConfigResponse?.file_size_limit) * 1024 * 1024 || FILE_SIZE_LIMIT - const audioSizeLimit = Number(fileUploadConfigResponse?.audio_file_size_limit) * 1024 * 1024 || AUDIO_SIZE_LIMIT - const videoSizeLimit = Number(fileUploadConfigResponse?.video_file_size_limit) * 1024 * 1024 || VIDEO_SIZE_LIMIT - - return { - imgSizeLimit, - docSizeLimit, - audioSizeLimit, - videoSizeLimit, - } -} +import { fetchRemoteFileInfo } from '@/service/common' export const useFile = (fileConfig: FileUpload) => { const { t } = useTranslation() const { notify } = useToastContext() const fileStore = useFileStore() const params = useParams() - const { imgSizeLimit, docSizeLimit, audioSizeLimit, videoSizeLimit } = useFileSizeLimit() - - const checkSizeLimit = (fileType: string, fileSize: number) => { - switch (fileType) { - case SupportUploadFileTypes.image: { - if (fileSize > imgSizeLimit) { - notify({ - type: 'error', - message: t('common.fileUploader.uploadFromComputerLimit', { - type: SupportUploadFileTypes.image, - size: formatFileSize(imgSizeLimit), - }), - }) - return false - } - return true - } - case SupportUploadFileTypes.document: { - if (fileSize > docSizeLimit) { - notify({ - type: 'error', - message: t('common.fileUploader.uploadFromComputerLimit', { - type: SupportUploadFileTypes.document, - size: formatFileSize(docSizeLimit), - }), - }) - return false - } - return true - } - case SupportUploadFileTypes.audio: { - if (fileSize > audioSizeLimit) { - notify({ - type: 'error', - message: t('common.fileUploader.uploadFromComputerLimit', { - type: SupportUploadFileTypes.audio, - size: formatFileSize(audioSizeLimit), - }), - }) - return false - } - return true - } - case SupportUploadFileTypes.video: { - if (fileSize > videoSizeLimit) { - notify({ - type: 'error', - message: t('common.fileUploader.uploadFromComputerLimit', { - type: SupportUploadFileTypes.video, - size: formatFileSize(videoSizeLimit), - }), - }) - return false - } - return true - } - case SupportUploadFileTypes.custom: { - if (fileSize > docSizeLimit) { - notify({ - type: 'error', - message: t('common.fileUploader.uploadFromComputerLimit', { - type: SupportUploadFileTypes.document, - size: formatFileSize(docSizeLimit), - }), - }) - return false - } - return true - } - default: { - return true - } - } - } const handleAddFile = useCallback((newFile: FileEntity) => { const { @@ -212,15 +117,12 @@ export const useFile = (fileConfig: FileUpload) => { progress: 100, supportFileType: getSupportFileType(url, res.file_type, allowedFileTypes?.includes(SupportUploadFileTypes.custom)), } - if (!checkSizeLimit(newFile.supportFileType, newFile.size)) - handleRemoveFile(uploadingFile.id) - else - handleUpdateFile(newFile) + handleUpdateFile(newFile) }).catch(() => { notify({ type: 'error', message: t('common.fileUploader.pasteFileLinkInvalid') }) handleRemoveFile(uploadingFile.id) }) - }, [checkSizeLimit, handleAddFile, handleUpdateFile, notify, t, handleRemoveFile, fileConfig?.allowed_file_types]) + }, [handleAddFile, handleUpdateFile, notify, t, handleRemoveFile, fileConfig?.allowed_file_types]) const handleLoadFileFromLinkSuccess = useCallback(() => { }, []) @@ -238,13 +140,13 @@ export const useFile = (fileConfig: FileUpload) => { notify({ type: 'error', message: t('common.fileUploader.fileExtensionNotSupport') }) return } - const allowedFileTypes = fileConfig.allowed_file_types - const fileType = getSupportFileType(file.name, file.type, allowedFileTypes?.includes(SupportUploadFileTypes.custom)) - if (!checkSizeLimit(fileType, file.size)) + if (file.size > FILE_SIZE_LIMIT) { + notify({ type: 'error', message: t('common.fileUploader.uploadFromComputerLimit', { size: formatFileSize(FILE_SIZE_LIMIT) }) }) return - + } const reader = new FileReader() const isImage = file.type.startsWith('image') + const allowedFileTypes = fileConfig.allowed_file_types reader.addEventListener( 'load', @@ -285,7 +187,7 @@ export const useFile = (fileConfig: FileUpload) => { false, ) reader.readAsDataURL(file) - }, [checkSizeLimit, notify, t, handleAddFile, handleUpdateFile, params.token, fileConfig?.allowed_file_types, fileConfig?.allowed_file_extensions]) + }, [notify, t, handleAddFile, handleUpdateFile, params.token, fileConfig?.allowed_file_types, fileConfig?.allowed_file_extensions]) const handleClipboardPasteFile = useCallback((e: ClipboardEvent<HTMLTextAreaElement>) => { const file = e.clipboardData?.files[0] diff --git a/web/app/components/workflow/nodes/_base/components/file-upload-setting.tsx b/web/app/components/workflow/nodes/_base/components/file-upload-setting.tsx index 72df3b20d2..77ff2fd5c1 100644 --- a/web/app/components/workflow/nodes/_base/components/file-upload-setting.tsx +++ b/web/app/components/workflow/nodes/_base/components/file-upload-setting.tsx @@ -10,7 +10,7 @@ import FileTypeItem from './file-type-item' import InputNumberWithSlider from './input-number-with-slider' import Field from '@/app/components/app/configuration/config-var/config-modal/field' import { TransferMethod } from '@/types/app' -import { useFileSizeLimit } from '@/app/components/base/file-uploader/hooks' +import { FILE_SIZE_LIMIT } from '@/app/components/base/file-uploader/constants' import { formatFileSize } from '@/utils/format' type Props = { @@ -36,7 +36,6 @@ const FileUploadSetting: FC<Props> = ({ allowed_file_types, allowed_file_extensions, } = payload - const { imgSizeLimit, docSizeLimit, audioSizeLimit, videoSizeLimit } = useFileSizeLimit() const handleSupportFileTypeChange = useCallback((type: SupportUploadFileTypes) => { const newPayload = produce(payload, (draft) => { @@ -143,12 +142,7 @@ const FileUploadSetting: FC<Props> = ({ title={t('appDebug.variableConfig.maxNumberOfUploads')!} > <div> - <div className='mb-1.5 text-text-tertiary body-xs-regular'>{t('appDebug.variableConfig.maxNumberTip', { - imgLimit: formatFileSize(imgSizeLimit), - docLimit: formatFileSize(docSizeLimit), - audioLimit: formatFileSize(audioSizeLimit), - videoLimit: formatFileSize(videoSizeLimit), - })}</div> + <div className='mb-1.5 text-text-tertiary body-xs-regular'>{t('appDebug.variableConfig.maxNumberTip', { size: formatFileSize(FILE_SIZE_LIMIT) })}</div> <InputNumberWithSlider value={max_length} min={1} diff --git a/web/i18n/en-US/app-debug.ts b/web/i18n/en-US/app-debug.ts index b2144262f6..c0d0193c7c 100644 --- a/web/i18n/en-US/app-debug.ts +++ b/web/i18n/en-US/app-debug.ts @@ -386,7 +386,7 @@ const translation = { 'localUpload': 'Local Upload', 'both': 'Both', 'maxNumberOfUploads': 'Max number of uploads', - 'maxNumberTip': 'Document < {{docLimit}}, image < {{imgLimit}}, audio < {{audioLimit}}, video < {{videoLimit}}', + 'maxNumberTip': 'Max {{size}} each', 'errorMsg': { labelNameRequired: 'Label name is required', varNameCanBeRepeat: 'Variable name can not be repeated', diff --git a/web/i18n/en-US/common.ts b/web/i18n/en-US/common.ts index 3390280e8a..5b82ecf8be 100644 --- a/web/i18n/en-US/common.ts +++ b/web/i18n/en-US/common.ts @@ -572,7 +572,7 @@ const translation = { pasteFileLinkInputPlaceholder: 'Enter URL...', uploadFromComputerReadError: 'File reading failed, please try again.', uploadFromComputerUploadError: 'File upload failed, please upload again.', - uploadFromComputerLimit: 'Upload {{type}} cannot exceed {{size}}', + uploadFromComputerLimit: 'Upload File cannot exceed {{size}}', pasteFileLinkInvalid: 'Invalid file link', fileExtensionNotSupport: 'File extension not supported', }, diff --git a/web/i18n/zh-Hans/app-debug.ts b/web/i18n/zh-Hans/app-debug.ts index 3e801bcf62..ee8ff7bb29 100644 --- a/web/i18n/zh-Hans/app-debug.ts +++ b/web/i18n/zh-Hans/app-debug.ts @@ -379,7 +379,7 @@ const translation = { 'localUpload': '本地上传', 'both': '两者', 'maxNumberOfUploads': '最大上传数', - 'maxNumberTip': '文档 < {{docLimit}}, 图片 < {{imgLimit}}, 音频 < {{audioLimit}}, 视频 < {{videoLimit}}', + 'maxNumberTip': '最大上传文件大小为 {{size}}', 'content': '内容', 'errorMsg': { labelNameRequired: '显示名称必填', diff --git a/web/i18n/zh-Hans/common.ts b/web/i18n/zh-Hans/common.ts index 7cb5e9810c..21e69e666d 100644 --- a/web/i18n/zh-Hans/common.ts +++ b/web/i18n/zh-Hans/common.ts @@ -572,7 +572,7 @@ const translation = { pasteFileLinkInputPlaceholder: '输入文件链接', uploadFromComputerReadError: '文件读取失败,请重新选择。', uploadFromComputerUploadError: '文件上传失败,请重新上传。', - uploadFromComputerLimit: '上传 {{type}} 不能超过 {{size}}', + uploadFromComputerLimit: '上传文件不能超过 {{size}}', pasteFileLinkInvalid: '文件链接无效', fileExtensionNotSupport: '文件类型不支持', }, diff --git a/web/models/common.ts b/web/models/common.ts index febf92e079..204e89ed9b 100644 --- a/web/models/common.ts +++ b/web/models/common.ts @@ -211,11 +211,9 @@ export type PluginProvider = { } export type FileUploadConfigResponse = { + file_size_limit: number batch_count_limit: number - image_file_size_limit?: number | string // default is 10MB - file_size_limit: number // default is 15MB - audio_file_size_limit?: number // default is 50MB - video_file_size_limit?: number // default is 100MB + image_file_size_limit?: number | string } export type InvitationResult = { From 5d0557451895b72db0365d4e2e444b9a76cc6365 Mon Sep 17 00:00:00 2001 From: NFish <douxc512@gmail.com> Date: Wed, 23 Oct 2024 17:48:57 +0800 Subject: [PATCH 174/346] fix: refresh current page if url contains token (#9718) --- web/app/components/swr-initor.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/web/app/components/swr-initor.tsx b/web/app/components/swr-initor.tsx index 89141359d6..ff9a7b832f 100644 --- a/web/app/components/swr-initor.tsx +++ b/web/app/components/swr-initor.tsx @@ -3,7 +3,7 @@ import { SWRConfig } from 'swr' import { useCallback, useEffect, useState } from 'react' import type { ReactNode } from 'react' -import { useRouter, useSearchParams } from 'next/navigation' +import { usePathname, useRouter, useSearchParams } from 'next/navigation' import useRefreshToken from '@/hooks/use-refresh-token' import { fetchSetupStatus } from '@/service/common' @@ -15,6 +15,7 @@ const SwrInitor = ({ }: SwrInitorProps) => { const router = useRouter() const searchParams = useSearchParams() + const pathname = usePathname() const { getNewAccessToken } = useRefreshToken() const consoleToken = searchParams.get('access_token') const refreshToken = searchParams.get('refresh_token') @@ -68,13 +69,16 @@ const SwrInitor = ({ return } await setRefreshToken() + if (searchParams.has('access_token') || searchParams.has('refresh_token')) + router.replace(pathname) + setInit(true) } catch (error) { router.replace('/signin') } })() - }, [isSetupFinished, setRefreshToken, router]) + }, [isSetupFinished, setRefreshToken, router, pathname, searchParams]) return init ? ( From c6b28bc193a7c345dcab23c6726f541ca8c346ce Mon Sep 17 00:00:00 2001 From: -LAN- <laipz8200@outlook.com> Date: Wed, 23 Oct 2024 17:49:51 +0800 Subject: [PATCH 175/346] chore: update version to 0.10.1 (#9689) --- api/configs/packaging/__init__.py | 2 +- docker-legacy/docker-compose.yaml | 6 +++--- docker/docker-compose.yaml | 6 +++--- web/package.json | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/api/configs/packaging/__init__.py b/api/configs/packaging/__init__.py index 635d12fc55..389a64f53e 100644 --- a/api/configs/packaging/__init__.py +++ b/api/configs/packaging/__init__.py @@ -9,7 +9,7 @@ class PackagingInfo(BaseSettings): CURRENT_VERSION: str = Field( description="Dify version", - default="0.10.0", + default="0.10.1", ) COMMIT_SHA: str = Field( diff --git a/docker-legacy/docker-compose.yaml b/docker-legacy/docker-compose.yaml index 3eb0de708f..17b788ff81 100644 --- a/docker-legacy/docker-compose.yaml +++ b/docker-legacy/docker-compose.yaml @@ -2,7 +2,7 @@ version: '3' services: # API service api: - image: langgenius/dify-api:0.10.0 + image: langgenius/dify-api:0.10.1 restart: always environment: # Startup mode, 'api' starts the API server. @@ -227,7 +227,7 @@ services: # worker service # The Celery worker for processing the queue. worker: - image: langgenius/dify-api:0.10.0 + image: langgenius/dify-api:0.10.1 restart: always environment: CONSOLE_WEB_URL: '' @@ -396,7 +396,7 @@ services: # Frontend web application. web: - image: langgenius/dify-web:0.10.0 + image: langgenius/dify-web:0.10.1 restart: always environment: # The base URL of console application api server, refers to the Console base URL of WEB service if console domain is diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml index e4ad67892c..da1a6b4d4e 100644 --- a/docker/docker-compose.yaml +++ b/docker/docker-compose.yaml @@ -241,7 +241,7 @@ x-shared-env: &shared-api-worker-env services: # API service api: - image: langgenius/dify-api:0.10.0 + image: langgenius/dify-api:0.10.1 restart: always environment: # Use the shared environment variables. @@ -261,7 +261,7 @@ services: # worker service # The Celery worker for processing the queue. worker: - image: langgenius/dify-api:0.10.0 + image: langgenius/dify-api:0.10.1 restart: always environment: # Use the shared environment variables. @@ -280,7 +280,7 @@ services: # Frontend web application. web: - image: langgenius/dify-web:0.10.0 + image: langgenius/dify-web:0.10.1 restart: always environment: CONSOLE_API_URL: ${CONSOLE_API_URL:-} diff --git a/web/package.json b/web/package.json index 18b983f289..e01603e8d4 100644 --- a/web/package.json +++ b/web/package.json @@ -1,6 +1,6 @@ { "name": "dify-web", - "version": "0.10.0", + "version": "0.10.1", "private": true, "engines": { "node": ">=18.17.0" From d357f359ab18bf9af78e589a8ff77ff8c5f2b751 Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Wed, 23 Oct 2024 17:52:39 +0800 Subject: [PATCH 176/346] feat: support install failed --- .../plugins/card/base/card-icon.tsx | 20 ++++++++++++++----- web/app/components/plugins/card/index.tsx | 4 +++- .../install-from-local-package/index.tsx | 12 +++++++++-- .../steps/install.tsx | 5 ++++- .../steps/installed.tsx | 8 +++++--- .../install-from-marketplace/index.tsx | 14 ++++++++++--- .../steps/install.tsx | 3 +++ .../steps/installed.tsx | 8 +++++--- web/app/components/plugins/types.ts | 1 + web/i18n/en-US/plugin.ts | 5 ++++- web/i18n/zh-Hans/plugin.ts | 3 +++ 11 files changed, 64 insertions(+), 19 deletions(-) diff --git a/web/app/components/plugins/card/base/card-icon.tsx b/web/app/components/plugins/card/base/card-icon.tsx index 4c0335c248..a30267bc43 100644 --- a/web/app/components/plugins/card/base/card-icon.tsx +++ b/web/app/components/plugins/card/base/card-icon.tsx @@ -1,4 +1,4 @@ -import { RiCheckLine } from '@remixicon/react' +import { RiCheckLine, RiCloseLine } from '@remixicon/react' import AppIcon from '@/app/components/base/app-icon' import cn from '@/utils/classnames' @@ -6,14 +6,17 @@ const Icon = ({ className, src, installed = false, + installFailed = false, }: { className?: string src: string | { - 'content': string - 'background': string + content: string + background: string } installed?: boolean + installFailed?: boolean }) => { + const iconClassName = 'flex justify-center items-center gap-2 absolute bottom-[-4px] right-[-4px] w-[18px] h-[18px] rounded-full border-2 border-components-panel-bg' if (typeof src === 'object') { return ( <div className={cn('relative', className)}> @@ -34,11 +37,18 @@ const Icon = ({ backgroundImage: `url(${src})`, }} > - {installed - && <div className='flex justify-center items-center gap-2 absolute bottom-[-4px] right-[-4px] w-[18px] h-[18px] rounded-full border-2 border-components-panel-bg bg-state-success-solid'> + { + installed + && <div className={cn(iconClassName, 'bg-state-success-solid')}> <RiCheckLine className='w-3 h-3 text-text-primary-on-surface' /> </div> } + { + installFailed + && <div className={cn(iconClassName, 'bg-state-destructive-solid')}> + <RiCloseLine className='w-3 h-3 text-text-primary-on-surface' /> + </div> + } </div> ) } diff --git a/web/app/components/plugins/card/index.tsx b/web/app/components/plugins/card/index.tsx index 14dffe8f37..be68ab0ae1 100644 --- a/web/app/components/plugins/card/index.tsx +++ b/web/app/components/plugins/card/index.tsx @@ -16,6 +16,7 @@ export type Props = { payload: Plugin titleLeft?: React.ReactNode installed?: boolean + installFailed?: boolean hideCornerMark?: boolean descriptionLineRows?: number footer?: React.ReactNode @@ -28,6 +29,7 @@ const Card = ({ payload, titleLeft, installed, + installFailed, hideCornerMark, descriptionLineRows = 2, footer, @@ -56,7 +58,7 @@ const Card = ({ {!hideCornerMark && <CornerMark text={type} />} {/* Header */} <div className="flex"> - <Icon src={icon} installed={installed} /> + <Icon src={icon} installed={installed} installFailed={installFailed} /> <div className="ml-3 grow"> <div className="flex items-center h-5"> <Title title={getLocalizedText(label)} /> diff --git a/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx b/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx index 50478bddb4..3d18625839 100644 --- a/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx +++ b/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx @@ -23,7 +23,7 @@ const InstallFromLocalPackage: React.FC<InstallFromLocalPackageProps> = ({ onClose, }) => { const { t } = useTranslation() - // uploading -> readyToInstall -> installed + // uploading -> readyToInstall -> installed/failed const [step, setStep] = useState<InstallStep>(InstallStep.uploading) const [uniqueIdentifier, setUniqueIdentifier] = useState<string | null>(null) @@ -31,6 +31,8 @@ const InstallFromLocalPackage: React.FC<InstallFromLocalPackageProps> = ({ const getTitle = useCallback(() => { if (step === InstallStep.installed) return t(`${i18nPrefix}.installedSuccessfully`) + if (step === InstallStep.installFailed) + return t(`${i18nPrefix}.installFailed`) return t(`${i18nPrefix}.installPlugin`) }, []) const [manifest, setManifest] = useState<PluginDeclaration | null>(toolNotionManifest) @@ -48,6 +50,10 @@ const InstallFromLocalPackage: React.FC<InstallFromLocalPackageProps> = ({ setStep(InstallStep.installed) }, []) + const handleFailed = useCallback(() => { + setStep(InstallStep.installFailed) + }, []) + return ( <Modal isShow={true} @@ -73,13 +79,15 @@ const InstallFromLocalPackage: React.FC<InstallFromLocalPackageProps> = ({ payload={manifest!} onCancel={onClose} onInstalled={handleInstalled} + onFailed={handleFailed} /> ) } { - step === InstallStep.installed && ( + ([InstallStep.installed, InstallStep.installFailed].includes(step)) && ( <Installed payload={manifest!} + isFailed={step === InstallStep.installFailed} onCancel={onClose} /> ) diff --git a/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx b/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx index 5067dff908..8572d96a3a 100644 --- a/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx +++ b/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx @@ -15,12 +15,14 @@ type Props = { payload: PluginDeclaration onCancel: () => void onInstalled: () => void + onFailed: () => void } const Installed: FC<Props> = ({ payload, onCancel, onInstalled, + onFailed, }) => { const { t } = useTranslation() const [isInstalling, setIsInstalling] = React.useState(false) @@ -29,7 +31,8 @@ const Installed: FC<Props> = ({ if (isInstalling) return setIsInstalling(true) await sleep(1500) - onInstalled() + // onInstalled() + onFailed() } return ( diff --git a/web/app/components/plugins/install-plugin/install-from-local-package/steps/installed.tsx b/web/app/components/plugins/install-plugin/install-from-local-package/steps/installed.tsx index 34fad51691..2288371b7d 100644 --- a/web/app/components/plugins/install-plugin/install-from-local-package/steps/installed.tsx +++ b/web/app/components/plugins/install-plugin/install-from-local-package/steps/installed.tsx @@ -9,24 +9,26 @@ import { useTranslation } from 'react-i18next' type Props = { payload: PluginDeclaration + isFailed: boolean onCancel: () => void - } const Installed: FC<Props> = ({ payload, + isFailed, onCancel, }) => { const { t } = useTranslation() return ( <> <div className='flex flex-col px-6 py-3 justify-center items-start gap-4 self-stretch'> - <p className='text-text-secondary system-md-regular'>The plugin has been installed successfully.</p> + <p className='text-text-secondary system-md-regular'>{t(`plugin.installModal.${isFailed ? 'installFailedDesc' : 'installedSuccessfullyDesc'}`)}</p> <div className='flex p-2 items-start content-start gap-1 self-stretch flex-wrap rounded-2xl bg-background-section-burn'> <Card className='w-full' payload={pluginManifestToCardPluginProps(payload)} - installed + installed={!isFailed} + installFailed={isFailed} /> </div> </div> diff --git a/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx b/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx index 411e2cf1f1..86c0150b5d 100644 --- a/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx +++ b/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx @@ -24,7 +24,7 @@ const InstallFromMarketplace: React.FC<InstallFromMarketplaceProps> = ({ onClose, }) => { const { t } = useTranslation() - // readyToInstall -> check installed -> installed + // readyToInstall -> check installed -> installed/failed const [step, setStep] = useState<InstallStep>(InstallStep.readyToInstall) // TODO: check installed in beta version. @@ -32,13 +32,19 @@ const InstallFromMarketplace: React.FC<InstallFromMarketplaceProps> = ({ const getTitle = useCallback(() => { if (step === InstallStep.installed) return t(`${i18nPrefix}.installedSuccessfully`) + if (step === InstallStep.installFailed) + return t(`${i18nPrefix}.installFailed`) return t(`${i18nPrefix}.installPlugin`) }, []) - const handleInstalled = useCallback(async () => { + const handleInstalled = useCallback(() => { setStep(InstallStep.installed) }, []) + const handleFailed = useCallback(() => { + setStep(InstallStep.installFailed) + }, []) + return ( <Modal isShow={true} @@ -57,13 +63,15 @@ const InstallFromMarketplace: React.FC<InstallFromMarketplaceProps> = ({ payload={manifest!} onCancel={onClose} onInstalled={handleInstalled} + onFailed={handleFailed} /> ) } { - step === InstallStep.installed && ( + ([InstallStep.installed, InstallStep.installFailed].includes(step)) && ( <Installed payload={manifest!} + isFailed={step === InstallStep.installFailed} onCancel={onSuccess} /> ) diff --git a/web/app/components/plugins/install-plugin/install-from-marketplace/steps/install.tsx b/web/app/components/plugins/install-plugin/install-from-marketplace/steps/install.tsx index eb5072b7e3..df5a551339 100644 --- a/web/app/components/plugins/install-plugin/install-from-marketplace/steps/install.tsx +++ b/web/app/components/plugins/install-plugin/install-from-marketplace/steps/install.tsx @@ -17,12 +17,14 @@ type Props = { payload: PluginDeclaration onCancel: () => void onInstalled: () => void + onFailed: () => void } const Installed: FC<Props> = ({ payload, onCancel, onInstalled, + onFailed, }) => { const { t } = useTranslation() const [isInstalling, setIsInstalling] = React.useState(false) @@ -32,6 +34,7 @@ const Installed: FC<Props> = ({ setIsInstalling(true) await sleep(1500) onInstalled() + // onFailed() } const toInstallVersion = '1.3.0' diff --git a/web/app/components/plugins/install-plugin/install-from-marketplace/steps/installed.tsx b/web/app/components/plugins/install-plugin/install-from-marketplace/steps/installed.tsx index 34fad51691..2288371b7d 100644 --- a/web/app/components/plugins/install-plugin/install-from-marketplace/steps/installed.tsx +++ b/web/app/components/plugins/install-plugin/install-from-marketplace/steps/installed.tsx @@ -9,24 +9,26 @@ import { useTranslation } from 'react-i18next' type Props = { payload: PluginDeclaration + isFailed: boolean onCancel: () => void - } const Installed: FC<Props> = ({ payload, + isFailed, onCancel, }) => { const { t } = useTranslation() return ( <> <div className='flex flex-col px-6 py-3 justify-center items-start gap-4 self-stretch'> - <p className='text-text-secondary system-md-regular'>The plugin has been installed successfully.</p> + <p className='text-text-secondary system-md-regular'>{t(`plugin.installModal.${isFailed ? 'installFailedDesc' : 'installedSuccessfullyDesc'}`)}</p> <div className='flex p-2 items-start content-start gap-1 self-stretch flex-wrap rounded-2xl bg-background-section-burn'> <Card className='w-full' payload={pluginManifestToCardPluginProps(payload)} - installed + installed={!isFailed} + installFailed={isFailed} /> </div> </div> diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts index 465f131ed0..8fdea20406 100644 --- a/web/app/components/plugins/types.ts +++ b/web/app/components/plugins/types.ts @@ -171,6 +171,7 @@ export enum InstallStep { readyToInstall = 'readyToInstall', installing = 'installing', installed = 'installed', + installFailed = 'failed', } export type GitHubAsset = { diff --git a/web/i18n/en-US/plugin.ts b/web/i18n/en-US/plugin.ts index cf426e2b4e..1be0398331 100644 --- a/web/i18n/en-US/plugin.ts +++ b/web/i18n/en-US/plugin.ts @@ -61,7 +61,10 @@ const translation = { }, installModal: { installPlugin: 'Install Plugin', - installedSuccessfully: 'Install successful', + installedSuccessfully: 'Installation successful', + installedSuccessfullyDesc: 'The plugin has been installed successfully.', + installFailed: 'Installation failed', + installFailedDesc: 'The plugin has been installed failed.', install: 'Install', installing: 'Installing...', uploadingPackage: 'Uploading {{packageName}}...', diff --git a/web/i18n/zh-Hans/plugin.ts b/web/i18n/zh-Hans/plugin.ts index 2d5a39b7df..91f7a998eb 100644 --- a/web/i18n/zh-Hans/plugin.ts +++ b/web/i18n/zh-Hans/plugin.ts @@ -62,6 +62,9 @@ const translation = { installModal: { installPlugin: '安装插件', installedSuccessfully: '安装成功', + installedSuccessfullyDesc: '插件已成功安装。', + installFailed: '安装失败', + installFailedDesc: '插件安装失败。', install: '安装', installing: '安装中...', uploadingPackage: '上传 {{packageName}} 中...', From 13ccd294cb8c3a8e3e0690d49117437dd957aeed Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Wed, 23 Oct 2024 17:55:25 +0800 Subject: [PATCH 177/346] fix: install error title not update --- .../plugins/install-plugin/install-from-local-package/index.tsx | 2 +- .../plugins/install-plugin/install-from-marketplace/index.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx b/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx index 3d18625839..92b5c6f61f 100644 --- a/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx +++ b/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx @@ -34,7 +34,7 @@ const InstallFromLocalPackage: React.FC<InstallFromLocalPackageProps> = ({ if (step === InstallStep.installFailed) return t(`${i18nPrefix}.installFailed`) return t(`${i18nPrefix}.installPlugin`) - }, []) + }, [step]) const [manifest, setManifest] = useState<PluginDeclaration | null>(toolNotionManifest) const handleUploaded = useCallback((result: { diff --git a/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx b/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx index 86c0150b5d..f555f31c02 100644 --- a/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx +++ b/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx @@ -35,7 +35,7 @@ const InstallFromMarketplace: React.FC<InstallFromMarketplaceProps> = ({ if (step === InstallStep.installFailed) return t(`${i18nPrefix}.installFailed`) return t(`${i18nPrefix}.installPlugin`) - }, []) + }, [step]) const handleInstalled = useCallback(() => { setStep(InstallStep.installed) From d74d79b3d8632dd1310855ce481099e9464a291b Mon Sep 17 00:00:00 2001 From: AAEE86 <33052466+AAEE86@users.noreply.github.com> Date: Wed, 23 Oct 2024 18:00:53 +0800 Subject: [PATCH 178/346] Modify characters (#9707) --- web/i18n/zh-Hans/common.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/i18n/zh-Hans/common.ts b/web/i18n/zh-Hans/common.ts index 21e69e666d..3cd7ece94e 100644 --- a/web/i18n/zh-Hans/common.ts +++ b/web/i18n/zh-Hans/common.ts @@ -377,7 +377,7 @@ const translation = { addConfig: '增加配置', editConfig: '修改配置', loadBalancingLeastKeyWarning: '至少启用 2 个 Key 以使用负载均衡', - loadBalancingInfo: '默认情况下,负载平衡使用 Round-robin 策略。如果触发速率限制,将应用 1 分钟的冷却时间', + loadBalancingInfo: '默认情况下,负载均衡使用 Round-robin 策略。如果触发速率限制,将应用 1 分钟的冷却时间', upgradeForLoadBalancing: '升级以解锁负载均衡功能', apiKey: 'API 密钥', }, From cac1ef7adee352b5dc6b5b1da3d340b46e22dbe7 Mon Sep 17 00:00:00 2001 From: Jyong <76649700+JohnJyong@users.noreply.github.com> Date: Wed, 23 Oct 2024 18:22:30 +0800 Subject: [PATCH 179/346] remove ppt import (#9721) --- api/poetry.lock | 175 ++++++++++++++++++++++++--------------------- api/pyproject.toml | 2 +- 2 files changed, 96 insertions(+), 81 deletions(-) diff --git a/api/poetry.lock b/api/poetry.lock index 02d57b12fa..52270196ff 100644 --- a/api/poetry.lock +++ b/api/poetry.lock @@ -2806,88 +2806,103 @@ files = [ [[package]] name = "frozenlist" -version = "1.4.1" +version = "1.5.0" description = "A list-like structure which implements collections.abc.MutableSequence" optional = false python-versions = ">=3.8" files = [ - {file = "frozenlist-1.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f9aa1878d1083b276b0196f2dfbe00c9b7e752475ed3b682025ff20c1c1f51ac"}, - {file = "frozenlist-1.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:29acab3f66f0f24674b7dc4736477bcd4bc3ad4b896f5f45379a67bce8b96868"}, - {file = "frozenlist-1.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:74fb4bee6880b529a0c6560885fce4dc95936920f9f20f53d99a213f7bf66776"}, - {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:590344787a90ae57d62511dd7c736ed56b428f04cd8c161fcc5e7232c130c69a"}, - {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:068b63f23b17df8569b7fdca5517edef76171cf3897eb68beb01341131fbd2ad"}, - {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c849d495bf5154cd8da18a9eb15db127d4dba2968d88831aff6f0331ea9bd4c"}, - {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9750cc7fe1ae3b1611bb8cfc3f9ec11d532244235d75901fb6b8e42ce9229dfe"}, - {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9b2de4cf0cdd5bd2dee4c4f63a653c61d2408055ab77b151c1957f221cabf2a"}, - {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0633c8d5337cb5c77acbccc6357ac49a1770b8c487e5b3505c57b949b4b82e98"}, - {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:27657df69e8801be6c3638054e202a135c7f299267f1a55ed3a598934f6c0d75"}, - {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:f9a3ea26252bd92f570600098783d1371354d89d5f6b7dfd87359d669f2109b5"}, - {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:4f57dab5fe3407b6c0c1cc907ac98e8a189f9e418f3b6e54d65a718aaafe3950"}, - {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e02a0e11cf6597299b9f3bbd3f93d79217cb90cfd1411aec33848b13f5c656cc"}, - {file = "frozenlist-1.4.1-cp310-cp310-win32.whl", hash = "sha256:a828c57f00f729620a442881cc60e57cfcec6842ba38e1b19fd3e47ac0ff8dc1"}, - {file = "frozenlist-1.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:f56e2333dda1fe0f909e7cc59f021eba0d2307bc6f012a1ccf2beca6ba362439"}, - {file = "frozenlist-1.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a0cb6f11204443f27a1628b0e460f37fb30f624be6051d490fa7d7e26d4af3d0"}, - {file = "frozenlist-1.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b46c8ae3a8f1f41a0d2ef350c0b6e65822d80772fe46b653ab6b6274f61d4a49"}, - {file = "frozenlist-1.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fde5bd59ab5357e3853313127f4d3565fc7dad314a74d7b5d43c22c6a5ed2ced"}, - {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:722e1124aec435320ae01ee3ac7bec11a5d47f25d0ed6328f2273d287bc3abb0"}, - {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2471c201b70d58a0f0c1f91261542a03d9a5e088ed3dc6c160d614c01649c106"}, - {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c757a9dd70d72b076d6f68efdbb9bc943665ae954dad2801b874c8c69e185068"}, - {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f146e0911cb2f1da549fc58fc7bcd2b836a44b79ef871980d605ec392ff6b0d2"}, - {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f9c515e7914626b2a2e1e311794b4c35720a0be87af52b79ff8e1429fc25f19"}, - {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c302220494f5c1ebeb0912ea782bcd5e2f8308037b3c7553fad0e48ebad6ad82"}, - {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:442acde1e068288a4ba7acfe05f5f343e19fac87bfc96d89eb886b0363e977ec"}, - {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:1b280e6507ea8a4fa0c0a7150b4e526a8d113989e28eaaef946cc77ffd7efc0a"}, - {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:fe1a06da377e3a1062ae5fe0926e12b84eceb8a50b350ddca72dc85015873f74"}, - {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:db9e724bebd621d9beca794f2a4ff1d26eed5965b004a97f1f1685a173b869c2"}, - {file = "frozenlist-1.4.1-cp311-cp311-win32.whl", hash = "sha256:e774d53b1a477a67838a904131c4b0eef6b3d8a651f8b138b04f748fccfefe17"}, - {file = "frozenlist-1.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:fb3c2db03683b5767dedb5769b8a40ebb47d6f7f45b1b3e3b4b51ec8ad9d9825"}, - {file = "frozenlist-1.4.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:1979bc0aeb89b33b588c51c54ab0161791149f2461ea7c7c946d95d5f93b56ae"}, - {file = "frozenlist-1.4.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:cc7b01b3754ea68a62bd77ce6020afaffb44a590c2289089289363472d13aedb"}, - {file = "frozenlist-1.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c9c92be9fd329ac801cc420e08452b70e7aeab94ea4233a4804f0915c14eba9b"}, - {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c3894db91f5a489fc8fa6a9991820f368f0b3cbdb9cd8849547ccfab3392d86"}, - {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba60bb19387e13597fb059f32cd4d59445d7b18b69a745b8f8e5db0346f33480"}, - {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8aefbba5f69d42246543407ed2461db31006b0f76c4e32dfd6f42215a2c41d09"}, - {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:780d3a35680ced9ce682fbcf4cb9c2bad3136eeff760ab33707b71db84664e3a"}, - {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9acbb16f06fe7f52f441bb6f413ebae6c37baa6ef9edd49cdd567216da8600cd"}, - {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:23b701e65c7b36e4bf15546a89279bd4d8675faabc287d06bbcfac7d3c33e1e6"}, - {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3e0153a805a98f5ada7e09826255ba99fb4f7524bb81bf6b47fb702666484ae1"}, - {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:dd9b1baec094d91bf36ec729445f7769d0d0cf6b64d04d86e45baf89e2b9059b"}, - {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:1a4471094e146b6790f61b98616ab8e44f72661879cc63fa1049d13ef711e71e"}, - {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5667ed53d68d91920defdf4035d1cdaa3c3121dc0b113255124bcfada1cfa1b8"}, - {file = "frozenlist-1.4.1-cp312-cp312-win32.whl", hash = "sha256:beee944ae828747fd7cb216a70f120767fc9f4f00bacae8543c14a6831673f89"}, - {file = "frozenlist-1.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:64536573d0a2cb6e625cf309984e2d873979709f2cf22839bf2d61790b448ad5"}, - {file = "frozenlist-1.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:20b51fa3f588ff2fe658663db52a41a4f7aa6c04f6201449c6c7c476bd255c0d"}, - {file = "frozenlist-1.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:410478a0c562d1a5bcc2f7ea448359fcb050ed48b3c6f6f4f18c313a9bdb1826"}, - {file = "frozenlist-1.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c6321c9efe29975232da3bd0af0ad216800a47e93d763ce64f291917a381b8eb"}, - {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48f6a4533887e189dae092f1cf981f2e3885175f7a0f33c91fb5b7b682b6bab6"}, - {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6eb73fa5426ea69ee0e012fb59cdc76a15b1283d6e32e4f8dc4482ec67d1194d"}, - {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fbeb989b5cc29e8daf7f976b421c220f1b8c731cbf22b9130d8815418ea45887"}, - {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32453c1de775c889eb4e22f1197fe3bdfe457d16476ea407472b9442e6295f7a"}, - {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:693945278a31f2086d9bf3df0fe8254bbeaef1fe71e1351c3bd730aa7d31c41b"}, - {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:1d0ce09d36d53bbbe566fe296965b23b961764c0bcf3ce2fa45f463745c04701"}, - {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3a670dc61eb0d0eb7080890c13de3066790f9049b47b0de04007090807c776b0"}, - {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:dca69045298ce5c11fd539682cff879cc1e664c245d1c64da929813e54241d11"}, - {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a06339f38e9ed3a64e4c4e43aec7f59084033647f908e4259d279a52d3757d09"}, - {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b7f2f9f912dca3934c1baec2e4585a674ef16fe00218d833856408c48d5beee7"}, - {file = "frozenlist-1.4.1-cp38-cp38-win32.whl", hash = "sha256:e7004be74cbb7d9f34553a5ce5fb08be14fb33bc86f332fb71cbe5216362a497"}, - {file = "frozenlist-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:5a7d70357e7cee13f470c7883a063aae5fe209a493c57d86eb7f5a6f910fae09"}, - {file = "frozenlist-1.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bfa4a17e17ce9abf47a74ae02f32d014c5e9404b6d9ac7f729e01562bbee601e"}, - {file = "frozenlist-1.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b7e3ed87d4138356775346e6845cccbe66cd9e207f3cd11d2f0b9fd13681359d"}, - {file = "frozenlist-1.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c99169d4ff810155ca50b4da3b075cbde79752443117d89429595c2e8e37fed8"}, - {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edb678da49d9f72c9f6c609fbe41a5dfb9a9282f9e6a2253d5a91e0fc382d7c0"}, - {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6db4667b187a6742b33afbbaf05a7bc551ffcf1ced0000a571aedbb4aa42fc7b"}, - {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55fdc093b5a3cb41d420884cdaf37a1e74c3c37a31f46e66286d9145d2063bd0"}, - {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82e8211d69a4f4bc360ea22cd6555f8e61a1bd211d1d5d39d3d228b48c83a897"}, - {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89aa2c2eeb20957be2d950b85974b30a01a762f3308cd02bb15e1ad632e22dc7"}, - {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9d3e0c25a2350080e9319724dede4f31f43a6c9779be48021a7f4ebde8b2d742"}, - {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7268252af60904bf52c26173cbadc3a071cece75f873705419c8681f24d3edea"}, - {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:0c250a29735d4f15321007fb02865f0e6b6a41a6b88f1f523ca1596ab5f50bd5"}, - {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:96ec70beabbd3b10e8bfe52616a13561e58fe84c0101dd031dc78f250d5128b9"}, - {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:23b2d7679b73fe0e5a4560b672a39f98dfc6f60df63823b0a9970525325b95f6"}, - {file = "frozenlist-1.4.1-cp39-cp39-win32.whl", hash = "sha256:a7496bfe1da7fb1a4e1cc23bb67c58fab69311cc7d32b5a99c2007b4b2a0e932"}, - {file = "frozenlist-1.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:e6a20a581f9ce92d389a8c7d7c3dd47c81fd5d6e655c8dddf341e14aa48659d0"}, - {file = "frozenlist-1.4.1-py3-none-any.whl", hash = "sha256:04ced3e6a46b4cfffe20f9ae482818e34eba9b5fb0ce4056e4cc9b6e212d09b7"}, - {file = "frozenlist-1.4.1.tar.gz", hash = "sha256:c037a86e8513059a2613aaba4d817bb90b9d9b6b69aace3ce9c877e8c8ed402b"}, + {file = "frozenlist-1.5.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5b6a66c18b5b9dd261ca98dffcb826a525334b2f29e7caa54e182255c5f6a65a"}, + {file = "frozenlist-1.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d1b3eb7b05ea246510b43a7e53ed1653e55c2121019a97e60cad7efb881a97bb"}, + {file = "frozenlist-1.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:15538c0cbf0e4fa11d1e3a71f823524b0c46299aed6e10ebb4c2089abd8c3bec"}, + {file = "frozenlist-1.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e79225373c317ff1e35f210dd5f1344ff31066ba8067c307ab60254cd3a78ad5"}, + {file = "frozenlist-1.5.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9272fa73ca71266702c4c3e2d4a28553ea03418e591e377a03b8e3659d94fa76"}, + {file = "frozenlist-1.5.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:498524025a5b8ba81695761d78c8dd7382ac0b052f34e66939c42df860b8ff17"}, + {file = "frozenlist-1.5.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:92b5278ed9d50fe610185ecd23c55d8b307d75ca18e94c0e7de328089ac5dcba"}, + {file = "frozenlist-1.5.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f3c8c1dacd037df16e85227bac13cca58c30da836c6f936ba1df0c05d046d8d"}, + {file = "frozenlist-1.5.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f2ac49a9bedb996086057b75bf93538240538c6d9b38e57c82d51f75a73409d2"}, + {file = "frozenlist-1.5.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e66cc454f97053b79c2ab09c17fbe3c825ea6b4de20baf1be28919460dd7877f"}, + {file = "frozenlist-1.5.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:5a3ba5f9a0dfed20337d3e966dc359784c9f96503674c2faf015f7fe8e96798c"}, + {file = "frozenlist-1.5.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:6321899477db90bdeb9299ac3627a6a53c7399c8cd58d25da094007402b039ab"}, + {file = "frozenlist-1.5.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:76e4753701248476e6286f2ef492af900ea67d9706a0155335a40ea21bf3b2f5"}, + {file = "frozenlist-1.5.0-cp310-cp310-win32.whl", hash = "sha256:977701c081c0241d0955c9586ffdd9ce44f7a7795df39b9151cd9a6fd0ce4cfb"}, + {file = "frozenlist-1.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:189f03b53e64144f90990d29a27ec4f7997d91ed3d01b51fa39d2dbe77540fd4"}, + {file = "frozenlist-1.5.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:fd74520371c3c4175142d02a976aee0b4cb4a7cc912a60586ffd8d5929979b30"}, + {file = "frozenlist-1.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2f3f7a0fbc219fb4455264cae4d9f01ad41ae6ee8524500f381de64ffaa077d5"}, + {file = "frozenlist-1.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f47c9c9028f55a04ac254346e92977bf0f166c483c74b4232bee19a6697e4778"}, + {file = "frozenlist-1.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0996c66760924da6e88922756d99b47512a71cfd45215f3570bf1e0b694c206a"}, + {file = "frozenlist-1.5.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a2fe128eb4edeabe11896cb6af88fca5346059f6c8d807e3b910069f39157869"}, + {file = "frozenlist-1.5.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1a8ea951bbb6cacd492e3948b8da8c502a3f814f5d20935aae74b5df2b19cf3d"}, + {file = "frozenlist-1.5.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de537c11e4aa01d37db0d403b57bd6f0546e71a82347a97c6a9f0dcc532b3a45"}, + {file = "frozenlist-1.5.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c2623347b933fcb9095841f1cc5d4ff0b278addd743e0e966cb3d460278840d"}, + {file = "frozenlist-1.5.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cee6798eaf8b1416ef6909b06f7dc04b60755206bddc599f52232606e18179d3"}, + {file = "frozenlist-1.5.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f5f9da7f5dbc00a604fe74aa02ae7c98bcede8a3b8b9666f9f86fc13993bc71a"}, + {file = "frozenlist-1.5.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:90646abbc7a5d5c7c19461d2e3eeb76eb0b204919e6ece342feb6032c9325ae9"}, + {file = "frozenlist-1.5.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:bdac3c7d9b705d253b2ce370fde941836a5f8b3c5c2b8fd70940a3ea3af7f4f2"}, + {file = "frozenlist-1.5.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:03d33c2ddbc1816237a67f66336616416e2bbb6beb306e5f890f2eb22b959cdf"}, + {file = "frozenlist-1.5.0-cp311-cp311-win32.whl", hash = "sha256:237f6b23ee0f44066219dae14c70ae38a63f0440ce6750f868ee08775073f942"}, + {file = "frozenlist-1.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:0cc974cc93d32c42e7b0f6cf242a6bd941c57c61b618e78b6c0a96cb72788c1d"}, + {file = "frozenlist-1.5.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:31115ba75889723431aa9a4e77d5f398f5cf976eea3bdf61749731f62d4a4a21"}, + {file = "frozenlist-1.5.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7437601c4d89d070eac8323f121fcf25f88674627505334654fd027b091db09d"}, + {file = "frozenlist-1.5.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7948140d9f8ece1745be806f2bfdf390127cf1a763b925c4a805c603df5e697e"}, + {file = "frozenlist-1.5.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:feeb64bc9bcc6b45c6311c9e9b99406660a9c05ca8a5b30d14a78555088b0b3a"}, + {file = "frozenlist-1.5.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:683173d371daad49cffb8309779e886e59c2f369430ad28fe715f66d08d4ab1a"}, + {file = "frozenlist-1.5.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7d57d8f702221405a9d9b40f9da8ac2e4a1a8b5285aac6100f3393675f0a85ee"}, + {file = "frozenlist-1.5.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:30c72000fbcc35b129cb09956836c7d7abf78ab5416595e4857d1cae8d6251a6"}, + {file = "frozenlist-1.5.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:000a77d6034fbad9b6bb880f7ec073027908f1b40254b5d6f26210d2dab1240e"}, + {file = "frozenlist-1.5.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5d7f5a50342475962eb18b740f3beecc685a15b52c91f7d975257e13e029eca9"}, + {file = "frozenlist-1.5.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:87f724d055eb4785d9be84e9ebf0f24e392ddfad00b3fe036e43f489fafc9039"}, + {file = "frozenlist-1.5.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:6e9080bb2fb195a046e5177f10d9d82b8a204c0736a97a153c2466127de87784"}, + {file = "frozenlist-1.5.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9b93d7aaa36c966fa42efcaf716e6b3900438632a626fb09c049f6a2f09fc631"}, + {file = "frozenlist-1.5.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:52ef692a4bc60a6dd57f507429636c2af8b6046db8b31b18dac02cbc8f507f7f"}, + {file = "frozenlist-1.5.0-cp312-cp312-win32.whl", hash = "sha256:29d94c256679247b33a3dc96cce0f93cbc69c23bf75ff715919332fdbb6a32b8"}, + {file = "frozenlist-1.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:8969190d709e7c48ea386db202d708eb94bdb29207a1f269bab1196ce0dcca1f"}, + {file = "frozenlist-1.5.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:7a1a048f9215c90973402e26c01d1cff8a209e1f1b53f72b95c13db61b00f953"}, + {file = "frozenlist-1.5.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:dd47a5181ce5fcb463b5d9e17ecfdb02b678cca31280639255ce9d0e5aa67af0"}, + {file = "frozenlist-1.5.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1431d60b36d15cda188ea222033eec8e0eab488f39a272461f2e6d9e1a8e63c2"}, + {file = "frozenlist-1.5.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6482a5851f5d72767fbd0e507e80737f9c8646ae7fd303def99bfe813f76cf7f"}, + {file = "frozenlist-1.5.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:44c49271a937625619e862baacbd037a7ef86dd1ee215afc298a417ff3270608"}, + {file = "frozenlist-1.5.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:12f78f98c2f1c2429d42e6a485f433722b0061d5c0b0139efa64f396efb5886b"}, + {file = "frozenlist-1.5.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ce3aa154c452d2467487765e3adc730a8c153af77ad84096bc19ce19a2400840"}, + {file = "frozenlist-1.5.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9b7dc0c4338e6b8b091e8faf0db3168a37101943e687f373dce00959583f7439"}, + {file = "frozenlist-1.5.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:45e0896250900b5aa25180f9aec243e84e92ac84bd4a74d9ad4138ef3f5c97de"}, + {file = "frozenlist-1.5.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:561eb1c9579d495fddb6da8959fd2a1fca2c6d060d4113f5844b433fc02f2641"}, + {file = "frozenlist-1.5.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:df6e2f325bfee1f49f81aaac97d2aa757c7646534a06f8f577ce184afe2f0a9e"}, + {file = "frozenlist-1.5.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:140228863501b44b809fb39ec56b5d4071f4d0aa6d216c19cbb08b8c5a7eadb9"}, + {file = "frozenlist-1.5.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7707a25d6a77f5d27ea7dc7d1fc608aa0a478193823f88511ef5e6b8a48f9d03"}, + {file = "frozenlist-1.5.0-cp313-cp313-win32.whl", hash = "sha256:31a9ac2b38ab9b5a8933b693db4939764ad3f299fcaa931a3e605bc3460e693c"}, + {file = "frozenlist-1.5.0-cp313-cp313-win_amd64.whl", hash = "sha256:11aabdd62b8b9c4b84081a3c246506d1cddd2dd93ff0ad53ede5defec7886b28"}, + {file = "frozenlist-1.5.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:dd94994fc91a6177bfaafd7d9fd951bc8689b0a98168aa26b5f543868548d3ca"}, + {file = "frozenlist-1.5.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2d0da8bbec082bf6bf18345b180958775363588678f64998c2b7609e34719b10"}, + {file = "frozenlist-1.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:73f2e31ea8dd7df61a359b731716018c2be196e5bb3b74ddba107f694fbd7604"}, + {file = "frozenlist-1.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:828afae9f17e6de596825cf4228ff28fbdf6065974e5ac1410cecc22f699d2b3"}, + {file = "frozenlist-1.5.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1577515d35ed5649d52ab4319db757bb881ce3b2b796d7283e6634d99ace307"}, + {file = "frozenlist-1.5.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2150cc6305a2c2ab33299453e2968611dacb970d2283a14955923062c8d00b10"}, + {file = "frozenlist-1.5.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a72b7a6e3cd2725eff67cd64c8f13335ee18fc3c7befc05aed043d24c7b9ccb9"}, + {file = "frozenlist-1.5.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c16d2fa63e0800723139137d667e1056bee1a1cf7965153d2d104b62855e9b99"}, + {file = "frozenlist-1.5.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:17dcc32fc7bda7ce5875435003220a457bcfa34ab7924a49a1c19f55b6ee185c"}, + {file = "frozenlist-1.5.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:97160e245ea33d8609cd2b8fd997c850b56db147a304a262abc2b3be021a9171"}, + {file = "frozenlist-1.5.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f1e6540b7fa044eee0bb5111ada694cf3dc15f2b0347ca125ee9ca984d5e9e6e"}, + {file = "frozenlist-1.5.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:91d6c171862df0a6c61479d9724f22efb6109111017c87567cfeb7b5d1449fdf"}, + {file = "frozenlist-1.5.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:c1fac3e2ace2eb1052e9f7c7db480818371134410e1f5c55d65e8f3ac6d1407e"}, + {file = "frozenlist-1.5.0-cp38-cp38-win32.whl", hash = "sha256:b97f7b575ab4a8af9b7bc1d2ef7f29d3afee2226bd03ca3875c16451ad5a7723"}, + {file = "frozenlist-1.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:374ca2dabdccad8e2a76d40b1d037f5bd16824933bf7bcea3e59c891fd4a0923"}, + {file = "frozenlist-1.5.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:9bbcdfaf4af7ce002694a4e10a0159d5a8d20056a12b05b45cea944a4953f972"}, + {file = "frozenlist-1.5.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1893f948bf6681733aaccf36c5232c231e3b5166d607c5fa77773611df6dc336"}, + {file = "frozenlist-1.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2b5e23253bb709ef57a8e95e6ae48daa9ac5f265637529e4ce6b003a37b2621f"}, + {file = "frozenlist-1.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f253985bb515ecd89629db13cb58d702035ecd8cfbca7d7a7e29a0e6d39af5f"}, + {file = "frozenlist-1.5.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:04a5c6babd5e8fb7d3c871dc8b321166b80e41b637c31a995ed844a6139942b6"}, + {file = "frozenlist-1.5.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9fe0f1c29ba24ba6ff6abf688cb0b7cf1efab6b6aa6adc55441773c252f7411"}, + {file = "frozenlist-1.5.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:226d72559fa19babe2ccd920273e767c96a49b9d3d38badd7c91a0fdeda8ea08"}, + {file = "frozenlist-1.5.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15b731db116ab3aedec558573c1a5eec78822b32292fe4f2f0345b7f697745c2"}, + {file = "frozenlist-1.5.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:366d8f93e3edfe5a918c874702f78faac300209a4d5bf38352b2c1bdc07a766d"}, + {file = "frozenlist-1.5.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:1b96af8c582b94d381a1c1f51ffaedeb77c821c690ea5f01da3d70a487dd0a9b"}, + {file = "frozenlist-1.5.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:c03eff4a41bd4e38415cbed054bbaff4a075b093e2394b6915dca34a40d1e38b"}, + {file = "frozenlist-1.5.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:50cf5e7ee9b98f22bdecbabf3800ae78ddcc26e4a435515fc72d97903e8488e0"}, + {file = "frozenlist-1.5.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1e76bfbc72353269c44e0bc2cfe171900fbf7f722ad74c9a7b638052afe6a00c"}, + {file = "frozenlist-1.5.0-cp39-cp39-win32.whl", hash = "sha256:666534d15ba8f0fda3f53969117383d5dc021266b3c1a42c9ec4855e4b58b9d3"}, + {file = "frozenlist-1.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:5c28f4b5dbef8a0d8aad0d4de24d1e9e981728628afaf4ea0792f5d0939372f0"}, + {file = "frozenlist-1.5.0-py3-none-any.whl", hash = "sha256:d994863bba198a4a518b467bb971c56e1db3f180a25c6cf7bb1949c267f748c3"}, + {file = "frozenlist-1.5.0.tar.gz", hash = "sha256:81d5af29e61b9c8348e876d442253723928dce6433e0e76cd925cd83f1b4b817"}, ] [[package]] @@ -10475,7 +10490,7 @@ python-docx = {version = ">=1.1.2", optional = true, markers = "extra == \"docx\ python-iso639 = "*" python-magic = "*" python-oxmsg = "*" -python-pptx = {version = ">=1.0.1", optional = true, markers = "extra == \"ppt\" or extra == \"pptx\""} +python-pptx = {version = ">=1.0.1", optional = true, markers = "extra == \"pptx\""} rapidfuzz = "*" requests = "*" tabulate = "*" @@ -11655,4 +11670,4 @@ cffi = ["cffi (>=1.11)"] [metadata] lock-version = "2.0" python-versions = ">=3.10,<3.13" -content-hash = "54eec8f3991658d8b718afa317ad48bd440d618d751c6a45e88a55f35fe2841f" +content-hash = "06d34fe599a86af65ee5c6ff9b542286106bed60570a92242f3f7e2a9b4bdcbd" diff --git a/api/pyproject.toml b/api/pyproject.toml index 4f75fc3c89..43754f6800 100644 --- a/api/pyproject.toml +++ b/api/pyproject.toml @@ -177,7 +177,7 @@ tencentcloud-sdk-python-hunyuan = "~3.0.1158" tiktoken = "~0.8.0" tokenizers = "~0.15.0" transformers = "~4.35.0" -unstructured = { version = "~0.15.7", extras = ["docx", "epub", "md", "msg", "ppt", "pptx", "pdf"] } +unstructured = { version = "~0.15.7", extras = ["docx", "epub", "md", "msg", "pptx", "pdf"] } validators = "0.21.0" volcengine-python-sdk = {extras = ["ark"], version = "~1.0.98"} websocket-client = "~1.7.0" From 121bb99cc2d3159b4135330e340f35563da12ebf Mon Sep 17 00:00:00 2001 From: Jyong <76649700+JohnJyong@users.noreply.github.com> Date: Wed, 23 Oct 2024 19:02:27 +0800 Subject: [PATCH 180/346] downgrade unstructured nltk version (#9726) --- api/poetry.lock | 984 +++------------------------------------------ api/pyproject.toml | 5 +- 2 files changed, 64 insertions(+), 925 deletions(-) diff --git a/api/poetry.lock b/api/poetry.lock index 52270196ff..a0d418ba7b 100644 --- a/api/poetry.lock +++ b/api/poetry.lock @@ -453,16 +453,6 @@ typing-extensions = ">=4.7,<5" bedrock = ["boto3 (>=1.28.57)", "botocore (>=1.31.57)"] vertex = ["google-auth (>=2,<3)"] -[[package]] -name = "antlr4-python3-runtime" -version = "4.9.3" -description = "ANTLR 4.9.3 runtime for Python 3.7" -optional = false -python-versions = "*" -files = [ - {file = "antlr4-python3-runtime-4.9.3.tar.gz", hash = "sha256:f224469b4168294902bb1efa80a8bf7855f24c99aef99cbefc1bcd3cce77881b"}, -] - [[package]] name = "anyio" version = "4.6.2.post1" @@ -2255,24 +2245,6 @@ files = [ {file = "durationpy-0.9.tar.gz", hash = "sha256:fd3feb0a69a0057d582ef643c355c40d2fa1c942191f914d12203b1a01ac722a"}, ] -[[package]] -name = "effdet" -version = "0.4.1" -description = "EfficientDet for PyTorch" -optional = false -python-versions = ">=3.7" -files = [ - {file = "effdet-0.4.1-py3-none-any.whl", hash = "sha256:10889a226228d515c948e3fcf811e64c0d78d7aa94823a300045653b9c284cb7"}, - {file = "effdet-0.4.1.tar.gz", hash = "sha256:ac5589fd304a5650c201986b2ef5f8e10c111093a71b1c49fa6b8817710812b5"}, -] - -[package.dependencies] -omegaconf = ">=2.0" -pycocotools = ">=2.0.2" -timm = ">=0.9.2" -torch = ">=1.12.1" -torchvision = "*" - [[package]] name = "elastic-transport" version = "8.15.1" @@ -2370,20 +2342,6 @@ files = [ {file = "et_xmlfile-1.1.0.tar.gz", hash = "sha256:8eb9e2bc2f8c97e37a2dc85a09ecdcdec9d8a396530a6d5a33b30b9a92da0c5c"}, ] -[[package]] -name = "eval-type-backport" -version = "0.2.0" -description = "Like `typing._eval_type`, but lets older Python versions use newer typing features." -optional = false -python-versions = ">=3.8" -files = [ - {file = "eval_type_backport-0.2.0-py3-none-any.whl", hash = "sha256:ac2f73d30d40c5a30a80b8739a789d6bb5e49fdffa66d7912667e2015d9c9933"}, - {file = "eval_type_backport-0.2.0.tar.gz", hash = "sha256:68796cfbc7371ebf923f03bdf7bef415f3ec098aeced24e054b253a0e78f7b37"}, -] - -[package.extras] -tests = ["pytest"] - [[package]] name = "exceptiongroup" version = "1.2.2" @@ -3336,23 +3294,6 @@ requests = ">=2.18.0,<3.0.0dev" [package.extras] protobuf = ["protobuf (<5.0.0dev)"] -[[package]] -name = "google-cloud-vision" -version = "3.7.4" -description = "Google Cloud Vision API client library" -optional = false -python-versions = ">=3.7" -files = [ - {file = "google_cloud_vision-3.7.4-py2.py3-none-any.whl", hash = "sha256:0b956480002545ab8f13d2b4b8f316e9332cdeb6f65f92c0a20d72e9e0df3ad6"}, - {file = "google_cloud_vision-3.7.4.tar.gz", hash = "sha256:80b67f0a2dc587a31d7482d3d2692a773f25fbd09468fd9de45d00b671aad999"}, -] - -[package.dependencies] -google-api-core = {version = ">=1.34.1,<2.0.dev0 || >=2.11.dev0,<3.0.0dev", extras = ["grpc"]} -google-auth = ">=2.14.1,<2.24.0 || >2.24.0,<2.25.0 || >2.25.0,<3.0.0dev" -proto-plus = ">=1.22.3,<2.0.0dev" -protobuf = ">=3.20.2,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<6.0.0dev" - [[package]] name = "google-crc32c" version = "1.6.0" @@ -4147,24 +4088,6 @@ files = [ {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, ] -[[package]] -name = "iopath" -version = "0.1.10" -description = "A library for providing I/O abstraction." -optional = false -python-versions = ">=3.6" -files = [ - {file = "iopath-0.1.10.tar.gz", hash = "sha256:3311c16a4d9137223e20f141655759933e1eda24f8bff166af834af3c645ef01"}, -] - -[package.dependencies] -portalocker = "*" -tqdm = "*" -typing_extensions = "*" - -[package.extras] -aws = ["boto3"] - [[package]] name = "isodate" version = "0.7.2" @@ -4356,17 +4279,6 @@ files = [ [package.dependencies] ply = "*" -[[package]] -name = "jsonpath-python" -version = "1.0.6" -description = "A more powerful JSONPath implementation in modern python" -optional = false -python-versions = ">=3.6" -files = [ - {file = "jsonpath-python-1.0.6.tar.gz", hash = "sha256:dd5be4a72d8a2995c3f583cf82bf3cd1a9544cfdabf2d22595b67aff07349666"}, - {file = "jsonpath_python-1.0.6-py3-none-any.whl", hash = "sha256:1e3b78df579f5efc23565293612decee04214609208a2335884b3ee3f786b575"}, -] - [[package]] name = "jsonschema" version = "4.23.0" @@ -4660,36 +4572,6 @@ pydantic = [ requests = ">=2,<3" requests-toolbelt = ">=1.0.0,<2.0.0" -[[package]] -name = "layoutparser" -version = "0.3.4" -description = "A unified toolkit for Deep Learning Based Document Image Analysis" -optional = false -python-versions = ">=3.6" -files = [ - {file = "layoutparser-0.3.4-py3-none-any.whl", hash = "sha256:269aedfab8a0caa50aef8d0fa62740fbee1f2964880daae3a0e6a0415363126a"}, - {file = "layoutparser-0.3.4.tar.gz", hash = "sha256:0dfb2194c36a5ad1075b8310f3cbc280c00306d1758cef127d20283f7ce085ea"}, -] - -[package.dependencies] -iopath = "*" -numpy = "*" -opencv-python = "*" -pandas = "*" -pdf2image = "*" -pdfplumber = "*" -pillow = "*" -pyyaml = ">=5.1" -scipy = "*" - -[package.extras] -effdet = ["effdet", "torch", "torchvision"] -gcv = ["google-cloud-vision (==1)"] -layoutmodels = ["effdet", "torch", "torchvision"] -ocr = ["google-cloud-vision (==1)", "pytesseract"] -paddledetection = ["paddlepaddle (==2.1.0)"] -tesseract = ["pytesseract"] - [[package]] name = "llvmlite" version = "0.43.0" @@ -5383,6 +5265,23 @@ files = [ msal = ">=1.29,<2" portalocker = ">=1.4,<3" +[[package]] +name = "msg-parser" +version = "1.2.0" +description = "This module enables reading, parsing and converting Microsoft Outlook MSG E-Mail files." +optional = false +python-versions = ">=3.4" +files = [ + {file = "msg_parser-1.2.0-py2.py3-none-any.whl", hash = "sha256:d47a2f0b2a359cb189fad83cc991b63ea781ecc70d91410324273fbf93e95375"}, + {file = "msg_parser-1.2.0.tar.gz", hash = "sha256:0de858d4fcebb6c8f6f028da83a17a20fe01cdce67c490779cf43b3b0162aa66"}, +] + +[package.dependencies] +olefile = ">=0.46" + +[package.extras] +rtf = ["compressed-rtf (>=1.0.5)"] + [[package]] name = "msrest" version = "0.7.1" @@ -5558,36 +5457,6 @@ files = [ {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, ] -[[package]] -name = "nest-asyncio" -version = "1.6.0" -description = "Patch asyncio to allow nested event loops" -optional = false -python-versions = ">=3.5" -files = [ - {file = "nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c"}, - {file = "nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe"}, -] - -[[package]] -name = "networkx" -version = "3.4.2" -description = "Python package for creating and manipulating graphs and networks" -optional = false -python-versions = ">=3.10" -files = [ - {file = "networkx-3.4.2-py3-none-any.whl", hash = "sha256:df5d4365b724cf81b8c6a7312509d0c22386097011ad1abe274afd5e9d3bbc5f"}, - {file = "networkx-3.4.2.tar.gz", hash = "sha256:307c3669428c5362aab27c8a1260aa8f47c4e91d3891f48be0141738d8d053e1"}, -] - -[package.extras] -default = ["matplotlib (>=3.7)", "numpy (>=1.24)", "pandas (>=2.0)", "scipy (>=1.10,!=1.11.0,!=1.11.1)"] -developer = ["changelist (==0.5)", "mypy (>=1.1)", "pre-commit (>=3.2)", "rtoml"] -doc = ["intersphinx-registry", "myst-nb (>=1.1)", "numpydoc (>=1.8.0)", "pillow (>=9.4)", "pydata-sphinx-theme (>=0.15)", "sphinx (>=7.3)", "sphinx-gallery (>=0.16)", "texext (>=0.6.7)"] -example = ["cairocffi (>=1.7)", "contextily (>=1.6)", "igraph (>=0.11)", "momepy (>=0.7.2)", "osmnx (>=1.9)", "scikit-learn (>=1.5)", "seaborn (>=0.13)"] -extra = ["lxml (>=4.6)", "pydot (>=3.0.1)", "pygraphviz (>=1.14)", "sympy (>=1.10)"] -test = ["pytest (>=7.2)", "pytest-cov (>=4.0)"] - [[package]] name = "newspaper3k" version = "0.2.8" @@ -5616,13 +5485,13 @@ tldextract = ">=2.0.1" [[package]] name = "nltk" -version = "3.9.1" +version = "3.8.1" description = "Natural Language Toolkit" optional = false -python-versions = ">=3.8" +python-versions = ">=3.7" files = [ - {file = "nltk-3.9.1-py3-none-any.whl", hash = "sha256:4fa26829c5b00715afe3061398a8989dc643b92ce7dd93fb4585a70930d168a1"}, - {file = "nltk-3.9.1.tar.gz", hash = "sha256:87d127bd3de4bd89a4f81265e5fa59cb1b199b27440175370f7417d2bc7ae868"}, + {file = "nltk-3.8.1-py3-none-any.whl", hash = "sha256:fd5c9109f976fa86bcadba8f91e47f5e9293bd034474752e92a520f81c93dda5"}, + {file = "nltk-3.8.1.zip", hash = "sha256:1834da3d0682cba4f2cede2f9aad6b0fafb6461ba451db0efb6f9c39798d64d3"}, ] [package.dependencies] @@ -5805,150 +5674,6 @@ files = [ {file = "numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010"}, ] -[[package]] -name = "nvidia-cublas-cu12" -version = "12.1.3.1" -description = "CUBLAS native runtime libraries" -optional = false -python-versions = ">=3" -files = [ - {file = "nvidia_cublas_cu12-12.1.3.1-py3-none-manylinux1_x86_64.whl", hash = "sha256:ee53ccca76a6fc08fb9701aa95b6ceb242cdaab118c3bb152af4e579af792728"}, - {file = "nvidia_cublas_cu12-12.1.3.1-py3-none-win_amd64.whl", hash = "sha256:2b964d60e8cf11b5e1073d179d85fa340c120e99b3067558f3cf98dd69d02906"}, -] - -[[package]] -name = "nvidia-cuda-cupti-cu12" -version = "12.1.105" -description = "CUDA profiling tools runtime libs." -optional = false -python-versions = ">=3" -files = [ - {file = "nvidia_cuda_cupti_cu12-12.1.105-py3-none-manylinux1_x86_64.whl", hash = "sha256:e54fde3983165c624cb79254ae9818a456eb6e87a7fd4d56a2352c24ee542d7e"}, - {file = "nvidia_cuda_cupti_cu12-12.1.105-py3-none-win_amd64.whl", hash = "sha256:bea8236d13a0ac7190bd2919c3e8e6ce1e402104276e6f9694479e48bb0eb2a4"}, -] - -[[package]] -name = "nvidia-cuda-nvrtc-cu12" -version = "12.1.105" -description = "NVRTC native runtime libraries" -optional = false -python-versions = ">=3" -files = [ - {file = "nvidia_cuda_nvrtc_cu12-12.1.105-py3-none-manylinux1_x86_64.whl", hash = "sha256:339b385f50c309763ca65456ec75e17bbefcbbf2893f462cb8b90584cd27a1c2"}, - {file = "nvidia_cuda_nvrtc_cu12-12.1.105-py3-none-win_amd64.whl", hash = "sha256:0a98a522d9ff138b96c010a65e145dc1b4850e9ecb75a0172371793752fd46ed"}, -] - -[[package]] -name = "nvidia-cuda-runtime-cu12" -version = "12.1.105" -description = "CUDA Runtime native Libraries" -optional = false -python-versions = ">=3" -files = [ - {file = "nvidia_cuda_runtime_cu12-12.1.105-py3-none-manylinux1_x86_64.whl", hash = "sha256:6e258468ddf5796e25f1dc591a31029fa317d97a0a94ed93468fc86301d61e40"}, - {file = "nvidia_cuda_runtime_cu12-12.1.105-py3-none-win_amd64.whl", hash = "sha256:dfb46ef84d73fababab44cf03e3b83f80700d27ca300e537f85f636fac474344"}, -] - -[[package]] -name = "nvidia-cudnn-cu12" -version = "9.1.0.70" -description = "cuDNN runtime libraries" -optional = false -python-versions = ">=3" -files = [ - {file = "nvidia_cudnn_cu12-9.1.0.70-py3-none-manylinux2014_x86_64.whl", hash = "sha256:165764f44ef8c61fcdfdfdbe769d687e06374059fbb388b6c89ecb0e28793a6f"}, - {file = "nvidia_cudnn_cu12-9.1.0.70-py3-none-win_amd64.whl", hash = "sha256:6278562929433d68365a07a4a1546c237ba2849852c0d4b2262a486e805b977a"}, -] - -[package.dependencies] -nvidia-cublas-cu12 = "*" - -[[package]] -name = "nvidia-cufft-cu12" -version = "11.0.2.54" -description = "CUFFT native runtime libraries" -optional = false -python-versions = ">=3" -files = [ - {file = "nvidia_cufft_cu12-11.0.2.54-py3-none-manylinux1_x86_64.whl", hash = "sha256:794e3948a1aa71fd817c3775866943936774d1c14e7628c74f6f7417224cdf56"}, - {file = "nvidia_cufft_cu12-11.0.2.54-py3-none-win_amd64.whl", hash = "sha256:d9ac353f78ff89951da4af698f80870b1534ed69993f10a4cf1d96f21357e253"}, -] - -[[package]] -name = "nvidia-curand-cu12" -version = "10.3.2.106" -description = "CURAND native runtime libraries" -optional = false -python-versions = ">=3" -files = [ - {file = "nvidia_curand_cu12-10.3.2.106-py3-none-manylinux1_x86_64.whl", hash = "sha256:9d264c5036dde4e64f1de8c50ae753237c12e0b1348738169cd0f8a536c0e1e0"}, - {file = "nvidia_curand_cu12-10.3.2.106-py3-none-win_amd64.whl", hash = "sha256:75b6b0c574c0037839121317e17fd01f8a69fd2ef8e25853d826fec30bdba74a"}, -] - -[[package]] -name = "nvidia-cusolver-cu12" -version = "11.4.5.107" -description = "CUDA solver native runtime libraries" -optional = false -python-versions = ">=3" -files = [ - {file = "nvidia_cusolver_cu12-11.4.5.107-py3-none-manylinux1_x86_64.whl", hash = "sha256:8a7ec542f0412294b15072fa7dab71d31334014a69f953004ea7a118206fe0dd"}, - {file = "nvidia_cusolver_cu12-11.4.5.107-py3-none-win_amd64.whl", hash = "sha256:74e0c3a24c78612192a74fcd90dd117f1cf21dea4822e66d89e8ea80e3cd2da5"}, -] - -[package.dependencies] -nvidia-cublas-cu12 = "*" -nvidia-cusparse-cu12 = "*" -nvidia-nvjitlink-cu12 = "*" - -[[package]] -name = "nvidia-cusparse-cu12" -version = "12.1.0.106" -description = "CUSPARSE native runtime libraries" -optional = false -python-versions = ">=3" -files = [ - {file = "nvidia_cusparse_cu12-12.1.0.106-py3-none-manylinux1_x86_64.whl", hash = "sha256:f3b50f42cf363f86ab21f720998517a659a48131e8d538dc02f8768237bd884c"}, - {file = "nvidia_cusparse_cu12-12.1.0.106-py3-none-win_amd64.whl", hash = "sha256:b798237e81b9719373e8fae8d4f091b70a0cf09d9d85c95a557e11df2d8e9a5a"}, -] - -[package.dependencies] -nvidia-nvjitlink-cu12 = "*" - -[[package]] -name = "nvidia-nccl-cu12" -version = "2.20.5" -description = "NVIDIA Collective Communication Library (NCCL) Runtime" -optional = false -python-versions = ">=3" -files = [ - {file = "nvidia_nccl_cu12-2.20.5-py3-none-manylinux2014_aarch64.whl", hash = "sha256:1fc150d5c3250b170b29410ba682384b14581db722b2531b0d8d33c595f33d01"}, - {file = "nvidia_nccl_cu12-2.20.5-py3-none-manylinux2014_x86_64.whl", hash = "sha256:057f6bf9685f75215d0c53bf3ac4a10b3e6578351de307abad9e18a99182af56"}, -] - -[[package]] -name = "nvidia-nvjitlink-cu12" -version = "12.6.77" -description = "Nvidia JIT LTO Library" -optional = false -python-versions = ">=3" -files = [ - {file = "nvidia_nvjitlink_cu12-12.6.77-py3-none-manylinux2014_aarch64.whl", hash = "sha256:3bf10d85bb1801e9c894c6e197e44dd137d2a0a9e43f8450e9ad13f2df0dd52d"}, - {file = "nvidia_nvjitlink_cu12-12.6.77-py3-none-manylinux2014_x86_64.whl", hash = "sha256:9ae346d16203ae4ea513be416495167a0101d33d2d14935aa9c1829a3fb45142"}, - {file = "nvidia_nvjitlink_cu12-12.6.77-py3-none-win_amd64.whl", hash = "sha256:410718cd44962bed862a31dd0318620f6f9a8b28a6291967bcfcb446a6516771"}, -] - -[[package]] -name = "nvidia-nvtx-cu12" -version = "12.1.105" -description = "NVIDIA Tools Extension" -optional = false -python-versions = ">=3" -files = [ - {file = "nvidia_nvtx_cu12-12.1.105-py3-none-manylinux1_x86_64.whl", hash = "sha256:dc21cf308ca5691e7c04d962e213f8a4aa9bbfa23d95412f452254c2caeb09e5"}, - {file = "nvidia_nvtx_cu12-12.1.105-py3-none-win_amd64.whl", hash = "sha256:65f4d98982b31b60026e0e6de73fbdfc09d08a96f4656dd3665ca616a11e1e82"}, -] - [[package]] name = "oauthlib" version = "3.2.2" @@ -6011,63 +5736,6 @@ files = [ [package.extras] tests = ["pytest", "pytest-cov"] -[[package]] -name = "omegaconf" -version = "2.3.0" -description = "A flexible configuration library" -optional = false -python-versions = ">=3.6" -files = [ - {file = "omegaconf-2.3.0-py3-none-any.whl", hash = "sha256:7b4df175cdb08ba400f45cae3bdcae7ba8365db4d165fc65fd04b050ab63b46b"}, - {file = "omegaconf-2.3.0.tar.gz", hash = "sha256:d5d4b6d29955cc50ad50c46dc269bcd92c6e00f5f90d23ab5fee7bfca4ba4cc7"}, -] - -[package.dependencies] -antlr4-python3-runtime = "==4.9.*" -PyYAML = ">=5.1.0" - -[[package]] -name = "onnx" -version = "1.17.0" -description = "Open Neural Network Exchange" -optional = false -python-versions = ">=3.8" -files = [ - {file = "onnx-1.17.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:38b5df0eb22012198cdcee527cc5f917f09cce1f88a69248aaca22bd78a7f023"}, - {file = "onnx-1.17.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d545335cb49d4d8c47cc803d3a805deb7ad5d9094dc67657d66e568610a36d7d"}, - {file = "onnx-1.17.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3193a3672fc60f1a18c0f4c93ac81b761bc72fd8a6c2035fa79ff5969f07713e"}, - {file = "onnx-1.17.0-cp310-cp310-win32.whl", hash = "sha256:0141c2ce806c474b667b7e4499164227ef594584da432fd5613ec17c1855e311"}, - {file = "onnx-1.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:dfd777d95c158437fda6b34758f0877d15b89cbe9ff45affbedc519b35345cf9"}, - {file = "onnx-1.17.0-cp311-cp311-macosx_12_0_universal2.whl", hash = "sha256:d6fc3a03fc0129b8b6ac03f03bc894431ffd77c7d79ec023d0afd667b4d35869"}, - {file = "onnx-1.17.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f01a4b63d4e1d8ec3e2f069e7b798b2955810aa434f7361f01bc8ca08d69cce4"}, - {file = "onnx-1.17.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a183c6178be001bf398260e5ac2c927dc43e7746e8638d6c05c20e321f8c949"}, - {file = "onnx-1.17.0-cp311-cp311-win32.whl", hash = "sha256:081ec43a8b950171767d99075b6b92553901fa429d4bc5eb3ad66b36ef5dbe3a"}, - {file = "onnx-1.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:95c03e38671785036bb704c30cd2e150825f6ab4763df3a4f1d249da48525957"}, - {file = "onnx-1.17.0-cp312-cp312-macosx_12_0_universal2.whl", hash = "sha256:0e906e6a83437de05f8139ea7eaf366bf287f44ae5cc44b2850a30e296421f2f"}, - {file = "onnx-1.17.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d955ba2939878a520a97614bcf2e79c1df71b29203e8ced478fa78c9a9c63c2"}, - {file = "onnx-1.17.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f3fb5cc4e2898ac5312a7dc03a65133dd2abf9a5e520e69afb880a7251ec97a"}, - {file = "onnx-1.17.0-cp312-cp312-win32.whl", hash = "sha256:317870fca3349d19325a4b7d1b5628f6de3811e9710b1e3665c68b073d0e68d7"}, - {file = "onnx-1.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:659b8232d627a5460d74fd3c96947ae83db6d03f035ac633e20cd69cfa029227"}, - {file = "onnx-1.17.0-cp38-cp38-macosx_12_0_universal2.whl", hash = "sha256:23b8d56a9df492cdba0eb07b60beea027d32ff5e4e5fe271804eda635bed384f"}, - {file = "onnx-1.17.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ecf2b617fd9a39b831abea2df795e17bac705992a35a98e1f0363f005c4a5247"}, - {file = "onnx-1.17.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea5023a8dcdadbb23fd0ed0179ce64c1f6b05f5b5c34f2909b4e927589ebd0e4"}, - {file = "onnx-1.17.0-cp38-cp38-win32.whl", hash = "sha256:f0e437f8f2f0c36f629e9743d28cf266312baa90be6a899f405f78f2d4cb2e1d"}, - {file = "onnx-1.17.0-cp38-cp38-win_amd64.whl", hash = "sha256:e4673276b558b5b572b960b7f9ef9214dce9305673683eb289bb97a7df379a4b"}, - {file = "onnx-1.17.0-cp39-cp39-macosx_12_0_universal2.whl", hash = "sha256:67e1c59034d89fff43b5301b6178222e54156eadd6ab4cd78ddc34b2f6274a66"}, - {file = "onnx-1.17.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e19fd064b297f7773b4c1150f9ce6213e6d7d041d7a9201c0d348041009cdcd"}, - {file = "onnx-1.17.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8167295f576055158a966161f8ef327cb491c06ede96cc23392be6022071b6ed"}, - {file = "onnx-1.17.0-cp39-cp39-win32.whl", hash = "sha256:76884fe3e0258c911c749d7d09667fb173365fd27ee66fcedaf9fa039210fd13"}, - {file = "onnx-1.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:5ca7a0894a86d028d509cdcf99ed1864e19bfe5727b44322c11691d834a1c546"}, - {file = "onnx-1.17.0.tar.gz", hash = "sha256:48ca1a91ff73c1d5e3ea2eef20ae5d0e709bb8a2355ed798ffc2169753013fd3"}, -] - -[package.dependencies] -numpy = ">=1.20" -protobuf = ">=3.20.2" - -[package.extras] -reference = ["Pillow", "google-re2"] - [[package]] name = "onnxruntime" version = "1.19.2" @@ -6193,30 +5861,6 @@ files = [ [package.dependencies] opencensus = ">=0.8.0,<1.0.0" -[[package]] -name = "opencv-python" -version = "4.10.0.84" -description = "Wrapper package for OpenCV python bindings." -optional = false -python-versions = ">=3.6" -files = [ - {file = "opencv-python-4.10.0.84.tar.gz", hash = "sha256:72d234e4582e9658ffea8e9cae5b63d488ad06994ef12d81dc303b17472f3526"}, - {file = "opencv_python-4.10.0.84-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:fc182f8f4cda51b45f01c64e4cbedfc2f00aff799debebc305d8d0210c43f251"}, - {file = "opencv_python-4.10.0.84-cp37-abi3-macosx_12_0_x86_64.whl", hash = "sha256:71e575744f1d23f79741450254660442785f45a0797212852ee5199ef12eed98"}, - {file = "opencv_python-4.10.0.84-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09a332b50488e2dda866a6c5573ee192fe3583239fb26ff2f7f9ceb0bc119ea6"}, - {file = "opencv_python-4.10.0.84-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ace140fc6d647fbe1c692bcb2abce768973491222c067c131d80957c595b71f"}, - {file = "opencv_python-4.10.0.84-cp37-abi3-win32.whl", hash = "sha256:2db02bb7e50b703f0a2d50c50ced72e95c574e1e5a0bb35a8a86d0b35c98c236"}, - {file = "opencv_python-4.10.0.84-cp37-abi3-win_amd64.whl", hash = "sha256:32dbbd94c26f611dc5cc6979e6b7aa1f55a64d6b463cc1dcd3c95505a63e48fe"}, -] - -[package.dependencies] -numpy = [ - {version = ">=1.21.4", markers = "python_version >= \"3.10\" and platform_system == \"Darwin\" and python_version < \"3.11\""}, - {version = ">=1.21.2", markers = "platform_system != \"Darwin\" and python_version >= \"3.10\" and python_version < \"3.11\""}, - {version = ">=1.23.5", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, - {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, -] - [[package]] name = "openpyxl" version = "3.1.5" @@ -6680,56 +6324,6 @@ multiprocess = ">=0.70.17" pox = ">=0.3.5" ppft = ">=1.7.6.9" -[[package]] -name = "pdf2image" -version = "1.17.0" -description = "A wrapper around the pdftoppm and pdftocairo command line tools to convert PDF to a PIL Image list." -optional = false -python-versions = "*" -files = [ - {file = "pdf2image-1.17.0-py3-none-any.whl", hash = "sha256:ecdd58d7afb810dffe21ef2b1bbc057ef434dabbac6c33778a38a3f7744a27e2"}, - {file = "pdf2image-1.17.0.tar.gz", hash = "sha256:eaa959bc116b420dd7ec415fcae49b98100dda3dd18cd2fdfa86d09f112f6d57"}, -] - -[package.dependencies] -pillow = "*" - -[[package]] -name = "pdfminer-six" -version = "20221105" -description = "PDF parser and analyzer" -optional = false -python-versions = ">=3.6" -files = [ - {file = "pdfminer.six-20221105-py3-none-any.whl", hash = "sha256:1eaddd712d5b2732f8ac8486824533514f8ba12a0787b3d5fe1e686cd826532d"}, - {file = "pdfminer.six-20221105.tar.gz", hash = "sha256:8448ab7b939d18b64820478ecac5394f482d7a79f5f7eaa7703c6c959c175e1d"}, -] - -[package.dependencies] -charset-normalizer = ">=2.0.0" -cryptography = ">=36.0.0" - -[package.extras] -dev = ["black", "mypy (==0.931)", "nox", "pytest"] -docs = ["sphinx", "sphinx-argparse"] -image = ["Pillow"] - -[[package]] -name = "pdfplumber" -version = "0.9.0" -description = "Plumb a PDF for detailed information about each char, rectangle, and line." -optional = false -python-versions = ">=3.7" -files = [ - {file = "pdfplumber-0.9.0-py3-none-any.whl", hash = "sha256:b396f2919670eb863124f649a907dc846c8653bbb6ba8024fe274952de121077"}, - {file = "pdfplumber-0.9.0.tar.gz", hash = "sha256:a43a213e125ed72b2358c0d3428f9b72f83939109ec33b77ef9325eeab9846f0"}, -] - -[package.dependencies] -"pdfminer.six" = "20221105" -Pillow = ">=9.1" -Wand = ">=0.6.10" - [[package]] name = "peewee" version = "3.17.7" @@ -6775,129 +6369,6 @@ files = [ [package.dependencies] numpy = "*" -[[package]] -name = "pi-heif" -version = "0.20.0" -description = "Python interface for libheif library" -optional = false -python-versions = ">=3.9" -files = [ - {file = "pi_heif-0.20.0-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:1371a3a34bffdc98b5bacf48b01c8bba0fd49183fd425a6f152390fda792e8da"}, - {file = "pi_heif-0.20.0-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:397e7839682771a21e7756a4822b4bc45251805d3188bb6275eb51fd63e6c1b2"}, - {file = "pi_heif-0.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee28de31da7d1a8cc08e4fa1b5a1c095b3e1c8be5edd5cf26c8ac4c365b806b3"}, - {file = "pi_heif-0.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33cf72ec7d344ae681046455ab7b2d3210e8369ed46f921038fd980ba1b5b27f"}, - {file = "pi_heif-0.20.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:393868800055271ae7ad876055e7b3f2eae5ab2fe1980ebe28a5761725c2c189"}, - {file = "pi_heif-0.20.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e81e28f0c7330133b5b1ce7e1ad118663eb9eac4cad6638bfca07c0eb761129a"}, - {file = "pi_heif-0.20.0-cp310-cp310-win_amd64.whl", hash = "sha256:b6bfcc917d3b11f6bcf80db8c64f721ce1ab7335459c0f109e933ca92e6dfb1a"}, - {file = "pi_heif-0.20.0-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:89c8e89b7615a0aa717f366169c4be31451af72a937314104cc88cbe40e1da11"}, - {file = "pi_heif-0.20.0-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:2484c8b5f447bc0018d9045faea9880e177c818c89eb333239aa02b9ed4a9ffb"}, - {file = "pi_heif-0.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9050f675bdc43333c1ac6aab734e253a3ba92a0efc8014d3431953add906ead5"}, - {file = "pi_heif-0.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:834b188f4963ac29b2ea92153e7d437993d8dd9e5adbff1640695563832f2157"}, - {file = "pi_heif-0.20.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:18b8c3269d1e07f85d146217616b117f5f2c8142328c6669a46d8d762699aadb"}, - {file = "pi_heif-0.20.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:eadcc3cec45d3c021e4c41c5a85e56f4c2b8b8942fa9a1720d9376b29c2e39cb"}, - {file = "pi_heif-0.20.0-cp311-cp311-win_amd64.whl", hash = "sha256:b23d891b4b788a00fb8e0c170e4744d86708bc682b3bf095143b10074bdd694c"}, - {file = "pi_heif-0.20.0-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:52436771e1e9198145a3db25885ec9fda4eda11f5753e1317ae9459b190cd6a4"}, - {file = "pi_heif-0.20.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:1f482ac86090c0d8adf65bd3a6b97f485ceaa0876123225913e3e2ac687e5bfe"}, - {file = "pi_heif-0.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6a4d350ac12fb5f45bc83eb35747156a4faa12d001dcdd9525a3912ae5b4d7a"}, - {file = "pi_heif-0.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8cd2a83ee8cc597ddf7e13d2adec60b7206357ff55649c4aea2f4c76bdb11c2"}, - {file = "pi_heif-0.20.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6edf3cf270838d26329e1f0d93a3a85963e4f811de8e80173e18a2f137020deb"}, - {file = "pi_heif-0.20.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:05b938736a4712fbc1224d4207ceb226670568f7db329b61895876c1ae7fe241"}, - {file = "pi_heif-0.20.0-cp312-cp312-win_amd64.whl", hash = "sha256:f082f12fb3954ac0140e9eead2d3a2be4aa60aa834a3998665175fde67f50793"}, - {file = "pi_heif-0.20.0-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:81e0f769d62f7af250518a99c75c3cc357147ab78ad673b5c0e96b3c1e3ef21b"}, - {file = "pi_heif-0.20.0-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:137af16fc31f8862775a82287e0c1ea0627fb0e9ffa53fccf84cacd1f4e0a90a"}, - {file = "pi_heif-0.20.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:030df62463a03053d68af01fb3fafb3dae3bc578b8da24280f0787469c22bdd0"}, - {file = "pi_heif-0.20.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b71571e792389151a679f4cb477a54ee1f3834d4b21c2f9e272068a4166964a"}, - {file = "pi_heif-0.20.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5ca9ccfda3b114229c92b5470f8fe451b5d07f4c8677edc3525403ef379b53ba"}, - {file = "pi_heif-0.20.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d57f48a08b0cdc492e17fe33312b47356a17fcf6a93c508a9e503e497e03ef4f"}, - {file = "pi_heif-0.20.0-cp313-cp313-win_amd64.whl", hash = "sha256:086d101461f0580b621de1cf24e6cf9c136015e6ff9408fec7f254c2c4f49243"}, - {file = "pi_heif-0.20.0-cp39-cp39-macosx_12_0_x86_64.whl", hash = "sha256:2a38a50b33cec5261037e625c35270656ec16c2febdcbbb529a9a96857b16a5b"}, - {file = "pi_heif-0.20.0-cp39-cp39-macosx_14_0_arm64.whl", hash = "sha256:ff50c2c090c2af6347e9caa8f2e3998c29f9ff8d4fac625bd48e0072f2133464"}, - {file = "pi_heif-0.20.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:627cc28de13eab9eabef9931c0ae260bdeb61200f6ce3d2cb8444a6979053ef9"}, - {file = "pi_heif-0.20.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f4b94f5ea91cfe180ead680528a197da8f77ff27b339aceb169bd7e2a51b53b1"}, - {file = "pi_heif-0.20.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:3e00bab005d97e6a60b2a52e9fc14fb8d50d9a7ff290d52b0e6491848e853550"}, - {file = "pi_heif-0.20.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:0305ea6e108979eee370fed0486df8b90ff25c619db9d9d539b00603e139626f"}, - {file = "pi_heif-0.20.0-cp39-cp39-win_amd64.whl", hash = "sha256:13146a8d4873198cf614c70ea344b69932637c28fb506427caffe9b951cc5694"}, - {file = "pi_heif-0.20.0-pp310-pypy310_pp73-macosx_12_0_x86_64.whl", hash = "sha256:f3f1e59b802d96c0dcf1b91ed2cc7d196a94b9e3d985ef80a86700e16e45bb28"}, - {file = "pi_heif-0.20.0-pp310-pypy310_pp73-macosx_14_0_arm64.whl", hash = "sha256:d002ca0b10e39b3f034385f1d453f4effd94bf83bbb4464ee72a386dcdbb1c4c"}, - {file = "pi_heif-0.20.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:33ab67a27bcbe24840bb26bf71a097e66c1ac63e1c5c155456913b8f933c9582"}, - {file = "pi_heif-0.20.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:323b7d1ed4a702fe7b8ca2f959f01f33879e38c413542408d522383b65857492"}, - {file = "pi_heif-0.20.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d7866ea2735d8cbc7501a98735a940ea22098303e340f2218caad3427f261abb"}, - {file = "pi_heif-0.20.0-pp39-pypy39_pp73-macosx_12_0_x86_64.whl", hash = "sha256:3bc6d86cdc42c22fe0821db2771eefa7e9651922668dd008c1cf8d786c1b13cc"}, - {file = "pi_heif-0.20.0-pp39-pypy39_pp73-macosx_14_0_arm64.whl", hash = "sha256:849d6ff186128d563b494cd463abc156a73ad4598b38dcaed0d52c0e78ec8cc4"}, - {file = "pi_heif-0.20.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:90e1e4ccd08e7256d1a19519b546efd7d5baf75337d522cbaa813fd6155675ec"}, - {file = "pi_heif-0.20.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4908b6e6be10062bf06dd5512184b1ad495291b73aa8f0b82f0fc9d66f2bcc1b"}, - {file = "pi_heif-0.20.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:695417ff1050cf79bca5c47bead807d7eb30fcf76fd64457f686a6342712284f"}, - {file = "pi_heif-0.20.0.tar.gz", hash = "sha256:f63b5ab190697c91dec482112bfa90751e48070899f4888317e943075dccf0be"}, -] - -[package.dependencies] -pillow = ">=10.1.0" - -[package.extras] -tests = ["defusedxml", "numpy", "packaging", "pympler", "pytest"] -tests-min = ["defusedxml", "packaging", "pytest"] - -[[package]] -name = "pikepdf" -version = "9.3.0" -description = "Read and write PDFs with Python, powered by qpdf" -optional = false -python-versions = ">=3.9" -files = [ - {file = "pikepdf-9.3.0-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:f54ad2d6d3e4c564bf1f9c33e4165b4c36aea62c49654f356a5570f99b89c647"}, - {file = "pikepdf-9.3.0-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:a09688758168a86585bb0baeae0a704349285ef40a02da8739be4ad8f4b1aee7"}, - {file = "pikepdf-9.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8422a3944187a8d24626812044b6b09c865426e2bf8d0b2ead80f56f609b3345"}, - {file = "pikepdf-9.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40724cb905ce682c97f048e4eb3a728eade6dd1bc64425f3b7bb9872688964ea"}, - {file = "pikepdf-9.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:663ddb129d823f9e1d1e5b4118906c508b801bf1d86fd8583938f96588bf8dda"}, - {file = "pikepdf-9.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:dbe7d9930789ea56e8b38b3b6b2b0b4e1090509825ceb572b906a1d23dea0282"}, - {file = "pikepdf-9.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:d0d6b11da16d280f83c5406ae0db03521e613c7758212b9104bad3dbf9bf2098"}, - {file = "pikepdf-9.3.0-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:180e7423f3b517688cf14d6c5537e97a1a9b047421915bb28d3198f881b46f14"}, - {file = "pikepdf-9.3.0-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:7a9feafdb688e64e4017b4596c3cf90793cd658b53e915e6c5a2668d1b3eb0c9"}, - {file = "pikepdf-9.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f74ba40a3c6f450d19b0958df5c92f84965f4160fd973d4a00f00492093f01c"}, - {file = "pikepdf-9.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7dd4166bb14db7d0711f2a32b21cf479217e34828af435b7ece0fab6ea02664d"}, - {file = "pikepdf-9.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7ac65c0ace97d995dc7263d2912208ac5310c2f84f42f1fdf043b47d77c01852"}, - {file = "pikepdf-9.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:287206055d2543ee768f85c24146e267c2465c1b2024e37ccf80b5a16674d2a2"}, - {file = "pikepdf-9.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:689fcd1e89857ddc31191d4cc7a1fab2dbb5ce88c347f4de0db41abb176a11fb"}, - {file = "pikepdf-9.3.0-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:5eef37caae6ad7a4baa4a6cdb35690945ee1a83bc0da5bbbf0023bc27d113f9c"}, - {file = "pikepdf-9.3.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:d96804a7e26e2ff37a9c2d796042754b7cae0668ed118a9185169fe1fc3b18d6"}, - {file = "pikepdf-9.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38b3f882351d17f65d38d43d24772cfe471b63dc8c09dad52434c4fe02693e33"}, - {file = "pikepdf-9.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08d0c72ba70cbe9f45772168e0c922b8d7625899cbfbcbd0dfd1316acff90258"}, - {file = "pikepdf-9.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98e546120b0d5707836a5ced43b09c086f5866f6eed93cfe4a0555c987fcba6f"}, - {file = "pikepdf-9.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0da5ebba4a31e257ca86a93657a4d47afffeda2ee48cde25227ce43d6dabae13"}, - {file = "pikepdf-9.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:cd796a039cbaddb6106127f210d5f2160654c0e629c1b663f2d9e6f67bba96b8"}, - {file = "pikepdf-9.3.0-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:7a9a738186b07a1177369713e8003371d0393808e5a62b2af86751dad6684a92"}, - {file = "pikepdf-9.3.0-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:8dbab43c6a6fa2737df6cfccd049bbe5b762c39809a0b14484d0154f403be4fb"}, - {file = "pikepdf-9.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e5bb5e40394d6a15c494469be5026c063676918cbabf48345c7fdf8b2f776f5"}, - {file = "pikepdf-9.3.0-cp39-cp39-macosx_12_0_x86_64.whl", hash = "sha256:344602b23ae6852180587c8e3280719ac31c78a4ca6cf08d8a51467d5f1741ba"}, - {file = "pikepdf-9.3.0-cp39-cp39-macosx_14_0_arm64.whl", hash = "sha256:363d01aa89f871c12fdc3d08c677456d693028cfb865e314cebe679273a7ebcb"}, - {file = "pikepdf-9.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8022a925cb2c67a1de3736c19de5d280d43241e1b118f1188b94df07e84c8b8f"}, - {file = "pikepdf-9.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53202d816838e87ee80c28af695b554e3cbfd5cb3598d7bcfba533f9dbd411e9"}, - {file = "pikepdf-9.3.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:84555d4039ea10935fa2d0084577de5b81b508b9716ce482163e2dc65db1b180"}, - {file = "pikepdf-9.3.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:6b905b05fc32c4e279aceb1578d7d917ed9a4e70a8a8e8d1b40ee8afff9d6bfc"}, - {file = "pikepdf-9.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:3afa0ea7b57a125a7744313b08062e59ecca15b2b3b31d13431244ec99b4d683"}, - {file = "pikepdf-9.3.0-pp310-pypy310_pp73-macosx_12_0_x86_64.whl", hash = "sha256:58e256aec46ee13256e264bae949e23a98707833fc27a3e3c7172c034d0ab870"}, - {file = "pikepdf-9.3.0-pp310-pypy310_pp73-macosx_14_0_arm64.whl", hash = "sha256:18e48cc0359f29b5083bad94237b53d928d8491f7ba5d4a389ca5c366226d766"}, - {file = "pikepdf-9.3.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a56b7ccf13817689adb977ba92efa8d567d42a307154acff156179ddb76668b"}, - {file = "pikepdf-9.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:3ffc14ad4172f7acd7c1c7eb22eeac66f92c93c83941c63a3b56961602af67d7"}, - {file = "pikepdf-9.3.0-pp39-pypy39_pp73-macosx_12_0_x86_64.whl", hash = "sha256:e6bb3466f92b7a741a58fe348285d7bec69ea6102bbe3b2a3f49af0e6f2f3327"}, - {file = "pikepdf-9.3.0-pp39-pypy39_pp73-macosx_14_0_arm64.whl", hash = "sha256:ecb8ab93305f07f806399101858ab9ff350c3e1de819d6043b5d54220cf81e71"}, - {file = "pikepdf-9.3.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f1153d3f7be818ba0f9f0875f37ed5203c3d500c33a4058a4d2d0f978d3ce29"}, - {file = "pikepdf-9.3.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:80630a897d4203be10861e4e7fca8774cf1a85a1abcc41f978984564fb729ef6"}, - {file = "pikepdf-9.3.0.tar.gz", hash = "sha256:906d8afc1aa4f2f7409381a58e158207170f3aeba8ad2aec40072a648e8a2914"}, -] - -[package.dependencies] -Deprecated = "*" -lxml = ">=4.8" -packaging = "*" -Pillow = ">=10.0.1" - -[package.extras] -dev = ["pre-commit", "typer"] -docs = ["Sphinx (>=3)", "sphinx-autoapi", "sphinx-design", "sphinx-issues", "sphinx-rtd-theme", "tomli"] -mypy = ["lxml-stubs", "types-Pillow", "types-requests", "types-setuptools"] -test = ["attrs (>=20.2.0)", "coverage[toml]", "hypothesis (>=6.36)", "numpy (>=1.21.0)", "psutil (>=5.9)", "pybind11", "pytest (>=6.2.5)", "pytest-cov (>=3.0.0)", "pytest-timeout (>=2.1.0)", "pytest-xdist (>=2.5.0)", "python-dateutil (>=2.8.1)", "python-xmp-toolkit (>=2.0.1)", "tomli"] - [[package]] name = "pillow" version = "11.0.0" @@ -7393,48 +6864,6 @@ files = [ [package.dependencies] pyasn1 = ">=0.4.6,<0.7.0" -[[package]] -name = "pycocotools" -version = "2.0.8" -description = "Official APIs for the MS-COCO dataset" -optional = false -python-versions = ">=3.9" -files = [ - {file = "pycocotools-2.0.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:9a66886f45b04cee1ff0492e9f5e25d430d8aa3eb63e63c4ebc620945caa11b9"}, - {file = "pycocotools-2.0.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:257130b65b7b0f122ce1ed62942867ca9789e56a68109682796cc85c9770c74a"}, - {file = "pycocotools-2.0.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:663c14cd471913aabecb17ddb52b3b254a65dcaba26ccfea408c52c75cc3862c"}, - {file = "pycocotools-2.0.8-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:35a6ef931448632efe1c83eb2ac3c37c53b3c080a5432bc6ff1858944a603a2d"}, - {file = "pycocotools-2.0.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e7b4ee8b15539d6f789857faefe7d3eef81755f7b17f60903798524e4f321a5c"}, - {file = "pycocotools-2.0.8-cp310-cp310-win_amd64.whl", hash = "sha256:889edd2dbf61f4d2fe77c2e8e5608476903d1911d2ed00f9911354eff23f2423"}, - {file = "pycocotools-2.0.8-cp310-cp310-win_arm64.whl", hash = "sha256:52e06a833fad735485cad5c1f8fe40e2b586261b2856806b5d6923b0b5a3c971"}, - {file = "pycocotools-2.0.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:92bf788e6936fc52b57ccaaa78ecdaeac81872eebbfc45b6fe16ae18b85709bd"}, - {file = "pycocotools-2.0.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a07f57f991e379959c0f4a1b9ea35d875876433b7f45c6d8fe6b718e58834bc"}, - {file = "pycocotools-2.0.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5968a1e5421719af9eb7ccee4c540bfb18b1fc95d30d9a48571d0aaeb159a1ae"}, - {file = "pycocotools-2.0.8-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:59eb7b1839f269262456347b6fe2bb88a8be56b32d87fab946483746e1f18a07"}, - {file = "pycocotools-2.0.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:05480f731fcd7c5d05389081f84198f3b8117f4560227185bc462cccb5c79181"}, - {file = "pycocotools-2.0.8-cp311-cp311-win_amd64.whl", hash = "sha256:e680e27e58b840c105fa09a3bb1d91706038c5c8d7b7bf09c2e5ecbd1b05ad7f"}, - {file = "pycocotools-2.0.8-cp311-cp311-win_arm64.whl", hash = "sha256:16c5a1d2c8726149b5a0e6fe95095ffc172d4012ece5dee9b5beeef708fc0284"}, - {file = "pycocotools-2.0.8-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:dd4616621d062882db677de5c64b1b0f6efbcaed9fd284b61e7ba4b16ab24d7a"}, - {file = "pycocotools-2.0.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5683ba2612c39094a2e8453d40349768a3da6673376786651481d6f553ff7b50"}, - {file = "pycocotools-2.0.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b89f399eb851d18f68dfa7f126380394ec0820915c7b3831dd37563bc58daa95"}, - {file = "pycocotools-2.0.8-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:e6d528c4f35580347ee3cd57f92cf0926e9b6a688d0904b2ea8a814ae2e57a47"}, - {file = "pycocotools-2.0.8-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:56bbe8be608def61da0b4430562b8d5ff14525f509631a667cfd8405325193da"}, - {file = "pycocotools-2.0.8-cp312-cp312-win_amd64.whl", hash = "sha256:d004033e760a172b2ccbdf4a62d20d2bcf0c9b40dc3c0d1d724045b0a6944862"}, - {file = "pycocotools-2.0.8-cp312-cp312-win_arm64.whl", hash = "sha256:87853ca11e9b130e461d6b5284ea475efe35429060a915844e1998d206ba028e"}, - {file = "pycocotools-2.0.8-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2b432353a20ce9dd44d85d093c4520fa941cd6cd8a5346443f2056eb0cbdae2b"}, - {file = "pycocotools-2.0.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b53d36452ec0f1069d94a311aea051a36e8c7f8f63411db372e0ac89e826149"}, - {file = "pycocotools-2.0.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7aba650cc2e0472cc773a994f196c24937c8da1be87e02e72c180c8144aea11f"}, - {file = "pycocotools-2.0.8-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a7029806ceea48379ee2f33cc33d79bbaf64b627df444641f123a00f70e8609a"}, - {file = "pycocotools-2.0.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:fa750afead393671f6c6e40e22d8fd197157f9fa5ee1fa4aba325bbe86c0de1b"}, - {file = "pycocotools-2.0.8-cp39-cp39-win_amd64.whl", hash = "sha256:5ecb969dd07390b593893dbc45fc361d9b1f2cb3abd5dc7ff68afb0803f71b29"}, - {file = "pycocotools-2.0.8-cp39-cp39-win_arm64.whl", hash = "sha256:26b329c27e42e092f412faa5ff5bf6e1c4286a8e1709e474b640d356d1d0ae07"}, - {file = "pycocotools-2.0.8.tar.gz", hash = "sha256:8f2bcedb786ba26c367a3680f9c4eb5b2ad9dccb2b34eaeb205e0a021e1dfb8d"}, -] - -[package.dependencies] -matplotlib = ">=2.1.0" -numpy = "*" - [[package]] name = "pycparser" version = "2.22" @@ -7811,27 +7240,6 @@ files = [ [package.extras] diagrams = ["jinja2", "railroad-diagrams"] -[[package]] -name = "pypdf" -version = "5.0.1" -description = "A pure-python PDF library capable of splitting, merging, cropping, and transforming PDF files" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pypdf-5.0.1-py3-none-any.whl", hash = "sha256:ff8a32da6c7a63fea9c32fa4dd837cdd0db7966adf6c14f043e3f12592e992db"}, - {file = "pypdf-5.0.1.tar.gz", hash = "sha256:a361c3c372b4a659f9c8dd438d5ce29a753c79c620dc6e1fd66977651f5547ea"}, -] - -[package.dependencies] -typing_extensions = {version = ">=4.0", markers = "python_version < \"3.11\""} - -[package.extras] -crypto = ["PyCryptodome", "cryptography"] -dev = ["black", "flit", "pip-tools", "pre-commit (<2.18.0)", "pytest-cov", "pytest-socket", "pytest-timeout", "pytest-xdist", "wheel"] -docs = ["myst_parser", "sphinx", "sphinx_rtd_theme"] -full = ["Pillow (>=8.0.0)", "PyCryptodome", "cryptography"] -image = ["Pillow (>=8.0.0)"] - [[package]] name = "pypdfium2" version = "4.17.0" @@ -8087,13 +7495,13 @@ files = [ [[package]] name = "python-dateutil" -version = "2.8.2" +version = "2.9.0.post0" description = "Extensions to the standard Python datetime module" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, - {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, ] [package.dependencies] @@ -8153,48 +7561,20 @@ files = [ {file = "python_magic-0.4.27-py2.py3-none-any.whl", hash = "sha256:c212960ad306f700aa0d01e5d7a325d20548ff97eb9920dcd29513174f0294d3"}, ] -[[package]] -name = "python-multipart" -version = "0.0.12" -description = "A streaming multipart parser for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "python_multipart-0.0.12-py3-none-any.whl", hash = "sha256:43dcf96cf65888a9cd3423544dd0d75ac10f7aa0c3c28a175bbcd00c9ce1aebf"}, - {file = "python_multipart-0.0.12.tar.gz", hash = "sha256:045e1f98d719c1ce085ed7f7e1ef9d8ccc8c02ba02b5566d5f7521410ced58cb"}, -] - -[[package]] -name = "python-oxmsg" -version = "0.0.1" -description = "Extract attachments from Outlook .msg files." -optional = false -python-versions = ">=3.9" -files = [ - {file = "python_oxmsg-0.0.1-py3-none-any.whl", hash = "sha256:8ea7d5dda1bc161a413213da9e18ed152927c1fda2feaf5d1f02192d8ad45eea"}, - {file = "python_oxmsg-0.0.1.tar.gz", hash = "sha256:b65c1f93d688b85a9410afa824192a1ddc39da359b04a0bd2cbd3874e84d4994"}, -] - -[package.dependencies] -click = "*" -olefile = "*" -typing-extensions = ">=4.9.0" - [[package]] name = "python-pptx" -version = "1.0.2" -description = "Create, read, and update PowerPoint 2007+ (.pptx) files." +version = "0.6.23" +description = "Generate and manipulate Open XML PowerPoint (.pptx) files" optional = false -python-versions = ">=3.8" +python-versions = "*" files = [ - {file = "python_pptx-1.0.2-py3-none-any.whl", hash = "sha256:160838e0b8565a8b1f67947675886e9fea18aa5e795db7ae531606d68e785cba"}, - {file = "python_pptx-1.0.2.tar.gz", hash = "sha256:479a8af0eaf0f0d76b6f00b0887732874ad2e3188230315290cd1f9dd9cc7095"}, + {file = "python-pptx-0.6.23.tar.gz", hash = "sha256:587497ff28e779ab18dbb074f6d4052893c85dedc95ed75df319364f331fedee"}, + {file = "python_pptx-0.6.23-py3-none-any.whl", hash = "sha256:dd0527194627a2b7cc05f3ba23ecaa2d9a0d5ac9b6193a28ed1b7a716f4217d4"}, ] [package.dependencies] lxml = ">=3.1.0" Pillow = ">=3.3.2" -typing-extensions = ">=4.9.0" XlsxWriter = ">=0.5.7" [[package]] @@ -9864,24 +9244,6 @@ requests = ">=2.26.0" [package.extras] blobfile = ["blobfile (>=2)"] -[[package]] -name = "timm" -version = "1.0.11" -description = "PyTorch Image Models" -optional = false -python-versions = ">=3.8" -files = [ - {file = "timm-1.0.11-py3-none-any.whl", hash = "sha256:52a6f895e2cbec35a87d0846870419c2c0aa40de9b205bcda917f38278bf3044"}, - {file = "timm-1.0.11.tar.gz", hash = "sha256:a005f72b87e67ed30cdbf405a9ffd4e723360c780a43b1cefe266af8ecc9d151"}, -] - -[package.dependencies] -huggingface_hub = "*" -pyyaml = "*" -safetensors = "*" -torch = "*" -torchvision = "*" - [[package]] name = "tinysegmenter" version = "0.3" @@ -10062,98 +9424,6 @@ files = [ {file = "tomli-2.0.2.tar.gz", hash = "sha256:d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed"}, ] -[[package]] -name = "torch" -version = "2.4.1" -description = "Tensors and Dynamic neural networks in Python with strong GPU acceleration" -optional = false -python-versions = ">=3.8.0" -files = [ - {file = "torch-2.4.1-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:362f82e23a4cd46341daabb76fba08f04cd646df9bfaf5da50af97cb60ca4971"}, - {file = "torch-2.4.1-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:e8ac1985c3ff0f60d85b991954cfc2cc25f79c84545aead422763148ed2759e3"}, - {file = "torch-2.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:91e326e2ccfb1496e3bee58f70ef605aeb27bd26be07ba64f37dcaac3d070ada"}, - {file = "torch-2.4.1-cp310-none-macosx_11_0_arm64.whl", hash = "sha256:d36a8ef100f5bff3e9c3cea934b9e0d7ea277cb8210c7152d34a9a6c5830eadd"}, - {file = "torch-2.4.1-cp311-cp311-manylinux1_x86_64.whl", hash = "sha256:0b5f88afdfa05a335d80351e3cea57d38e578c8689f751d35e0ff36bce872113"}, - {file = "torch-2.4.1-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:ef503165f2341942bfdf2bd520152f19540d0c0e34961232f134dc59ad435be8"}, - {file = "torch-2.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:092e7c2280c860eff762ac08c4bdcd53d701677851670695e0c22d6d345b269c"}, - {file = "torch-2.4.1-cp311-none-macosx_11_0_arm64.whl", hash = "sha256:ddddbd8b066e743934a4200b3d54267a46db02106876d21cf31f7da7a96f98ea"}, - {file = "torch-2.4.1-cp312-cp312-manylinux1_x86_64.whl", hash = "sha256:fdc4fe11db3eb93c1115d3e973a27ac7c1a8318af8934ffa36b0370efe28e042"}, - {file = "torch-2.4.1-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:18835374f599207a9e82c262153c20ddf42ea49bc76b6eadad8e5f49729f6e4d"}, - {file = "torch-2.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:ebea70ff30544fc021d441ce6b219a88b67524f01170b1c538d7d3ebb5e7f56c"}, - {file = "torch-2.4.1-cp312-none-macosx_11_0_arm64.whl", hash = "sha256:72b484d5b6cec1a735bf3fa5a1c4883d01748698c5e9cfdbeb4ffab7c7987e0d"}, - {file = "torch-2.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:c99e1db4bf0c5347107845d715b4aa1097e601bdc36343d758963055e9599d93"}, - {file = "torch-2.4.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:b57f07e92858db78c5b72857b4f0b33a65b00dc5d68e7948a8494b0314efb880"}, - {file = "torch-2.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:f18197f3f7c15cde2115892b64f17c80dbf01ed72b008020e7da339902742cf6"}, - {file = "torch-2.4.1-cp38-none-macosx_11_0_arm64.whl", hash = "sha256:5fc1d4d7ed265ef853579caf272686d1ed87cebdcd04f2a498f800ffc53dab71"}, - {file = "torch-2.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:40f6d3fe3bae74efcf08cb7f8295eaddd8a838ce89e9d26929d4edd6d5e4329d"}, - {file = "torch-2.4.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:c9299c16c9743001ecef515536ac45900247f4338ecdf70746f2461f9e4831db"}, - {file = "torch-2.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:6bce130f2cd2d52ba4e2c6ada461808de7e5eccbac692525337cfb4c19421846"}, - {file = "torch-2.4.1-cp39-none-macosx_11_0_arm64.whl", hash = "sha256:a38de2803ee6050309aac032676536c3d3b6a9804248537e38e098d0e14817ec"}, -] - -[package.dependencies] -filelock = "*" -fsspec = "*" -jinja2 = "*" -networkx = "*" -nvidia-cublas-cu12 = {version = "12.1.3.1", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} -nvidia-cuda-cupti-cu12 = {version = "12.1.105", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} -nvidia-cuda-nvrtc-cu12 = {version = "12.1.105", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} -nvidia-cuda-runtime-cu12 = {version = "12.1.105", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} -nvidia-cudnn-cu12 = {version = "9.1.0.70", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} -nvidia-cufft-cu12 = {version = "11.0.2.54", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} -nvidia-curand-cu12 = {version = "10.3.2.106", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} -nvidia-cusolver-cu12 = {version = "11.4.5.107", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} -nvidia-cusparse-cu12 = {version = "12.1.0.106", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} -nvidia-nccl-cu12 = {version = "2.20.5", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} -nvidia-nvtx-cu12 = {version = "12.1.105", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} -setuptools = "*" -sympy = "*" -triton = {version = "3.0.0", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\" and python_version < \"3.13\""} -typing-extensions = ">=4.8.0" - -[package.extras] -opt-einsum = ["opt-einsum (>=3.3)"] -optree = ["optree (>=0.11.0)"] - -[[package]] -name = "torchvision" -version = "0.19.1" -description = "image and video datasets and models for torch deep learning" -optional = false -python-versions = ">=3.8" -files = [ - {file = "torchvision-0.19.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:54e8513099e6f586356c70f809d34f391af71ad182fe071cc328a28af2c40608"}, - {file = "torchvision-0.19.1-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:20a1f5e02bfdad7714e55fa3fa698347c11d829fa65e11e5a84df07d93350eed"}, - {file = "torchvision-0.19.1-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:7b063116164be52fc6deb4762de7f8c90bfa3a65f8d5caf17f8e2d5aadc75a04"}, - {file = "torchvision-0.19.1-cp310-cp310-win_amd64.whl", hash = "sha256:f40b6acabfa886da1bc3768f47679c61feee6bde90deb979d9f300df8c8a0145"}, - {file = "torchvision-0.19.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:40514282b4896d62765b8e26d7091c32e17c35817d00ec4be2362ea3ba3d1787"}, - {file = "torchvision-0.19.1-cp311-cp311-manylinux1_x86_64.whl", hash = "sha256:5a91be061ae5d6d5b95e833b93e57ca4d3c56c5a57444dd15da2e3e7fba96050"}, - {file = "torchvision-0.19.1-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:d71a6a6fe3a5281ca3487d4c56ad4aad20ff70f82f1d7c79bcb6e7b0c2af00c8"}, - {file = "torchvision-0.19.1-cp311-cp311-win_amd64.whl", hash = "sha256:70dea324174f5e9981b68e4b7cd524512c106ba64aedef560a86a0bbf2fbf62c"}, - {file = "torchvision-0.19.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:27ece277ff0f6cdc7fed0627279c632dcb2e58187da771eca24b0fbcf3f8590d"}, - {file = "torchvision-0.19.1-cp312-cp312-manylinux1_x86_64.whl", hash = "sha256:c659ff92a61f188a1a7baef2850f3c0b6c85685447453c03d0e645ba8f1dcc1c"}, - {file = "torchvision-0.19.1-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:c07bf43c2a145d792ecd9d0503d6c73577147ece508d45600d8aac77e4cdfcf9"}, - {file = "torchvision-0.19.1-cp312-cp312-win_amd64.whl", hash = "sha256:b4283d283675556bb0eae31d29996f53861b17cbdcdf3509e6bc050414ac9289"}, - {file = "torchvision-0.19.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4c4e4f5b24ea6b087b02ed492ab1e21bba3352c4577e2def14248cfc60732338"}, - {file = "torchvision-0.19.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:9281d63ead929bb19143731154cd1d8bf0b5e9873dff8578a40e90a6bec3c6fa"}, - {file = "torchvision-0.19.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:4d10bc9083c4d5fadd7edd7b729700a7be48dab4f62278df3bc73fa48e48a155"}, - {file = "torchvision-0.19.1-cp38-cp38-win_amd64.whl", hash = "sha256:ccf085ef1824fb9e16f1901285bf89c298c62dfd93267a39e8ee42c71255242f"}, - {file = "torchvision-0.19.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:731f434d91586769e255b5d70ed1a4457e0a1394a95f4aacf0e1e7e21f80c098"}, - {file = "torchvision-0.19.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:febe4f14d4afcb47cc861d8be7760ab6a123cd0817f97faf5771488cb6aa90f4"}, - {file = "torchvision-0.19.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:e328309b8670a2e889b2fe76a1c2744a099c11c984da9a822357bd9debd699a5"}, - {file = "torchvision-0.19.1-cp39-cp39-win_amd64.whl", hash = "sha256:6616f12e00a22e7f3fedbd0fccb0804c05e8fe22871668f10eae65cf3f283614"}, -] - -[package.dependencies] -numpy = "*" -pillow = ">=5.3.0,<8.3.dev0 || >=8.4.dev0" -torch = "2.4.1" - -[package.extras] -gdown = ["gdown (>=4.7.3)"] -scipy = ["scipy"] - [[package]] name = "tos" version = "2.7.2" @@ -10259,28 +9529,6 @@ torchhub = ["filelock", "huggingface-hub (>=0.16.4,<1.0)", "importlib-metadata", video = ["av (==9.2.0)", "decord (==0.6.0)"] vision = ["Pillow (<10.0.0)"] -[[package]] -name = "triton" -version = "3.0.0" -description = "A language and compiler for custom Deep Learning operations" -optional = false -python-versions = "*" -files = [ - {file = "triton-3.0.0-1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e1efef76935b2febc365bfadf74bcb65a6f959a9872e5bddf44cc9e0adce1e1a"}, - {file = "triton-3.0.0-1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5ce8520437c602fb633f1324cc3871c47bee3b67acf9756c1a66309b60e3216c"}, - {file = "triton-3.0.0-1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:34e509deb77f1c067d8640725ef00c5cbfcb2052a1a3cb6a6d343841f92624eb"}, - {file = "triton-3.0.0-1-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:bcbf3b1c48af6a28011a5c40a5b3b9b5330530c3827716b5fbf6d7adcc1e53e9"}, - {file = "triton-3.0.0-1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6e5727202f7078c56f91ff13ad0c1abab14a0e7f2c87e91b12b6f64f3e8ae609"}, -] - -[package.dependencies] -filelock = "*" - -[package.extras] -build = ["cmake (>=3.20)", "lit"] -tests = ["autopep8", "flake8", "isort", "llnl-hatchet", "numpy", "pytest", "scipy (>=1.7.1)"] -tutorials = ["matplotlib", "pandas", "tabulate"] - [[package]] name = "twilio" version = "9.0.5" @@ -10455,13 +9703,13 @@ files = [ [[package]] name = "unstructured" -version = "0.15.14" +version = "0.10.30" description = "A library that prepares raw documents for downstream ML tasks." optional = false -python-versions = "<3.13,>=3.9.0" +python-versions = ">=3.7.0" files = [ - {file = "unstructured-0.15.14-py3-none-any.whl", hash = "sha256:502903cbcc60844c82f5351a0bc2e77f00f16a144cb884ac44d2f175470a1df8"}, - {file = "unstructured-0.15.14.tar.gz", hash = "sha256:876546c308c257314865996ce15745139c9fd4f79c7b4f09ad9d719d466b5b55"}, + {file = "unstructured-0.10.30-py3-none-any.whl", hash = "sha256:0615f14daa37450e9c0fcf3c3fd178c3a06b6b8d006a36d1a5e54dbe487aa6b6"}, + {file = "unstructured-0.10.30.tar.gz", hash = "sha256:a86c3d15c572a28322d83cb5ecf0ac7a24f1c36864fb7c68df096de8a1acc106"}, ] [package.dependencies] @@ -10469,166 +9717,73 @@ backoff = "*" beautifulsoup4 = "*" chardet = "*" dataclasses-json = "*" -effdet = {version = "*", optional = true, markers = "extra == \"pdf\""} emoji = "*" filetype = "*" -google-cloud-vision = {version = "*", optional = true, markers = "extra == \"pdf\""} langdetect = "*" lxml = "*" markdown = {version = "*", optional = true, markers = "extra == \"md\""} +msg-parser = {version = "*", optional = true, markers = "extra == \"msg\""} nltk = "*" -numpy = "<2" -onnx = {version = "*", optional = true, markers = "extra == \"pdf\""} -pdf2image = {version = "*", optional = true, markers = "extra == \"pdf\""} -"pdfminer.six" = {version = "*", optional = true, markers = "extra == \"pdf\""} -pi-heif = {version = "*", optional = true, markers = "extra == \"pdf\""} -pikepdf = {version = "*", optional = true, markers = "extra == \"pdf\""} -psutil = "*" +numpy = "*" pypandoc = {version = "*", optional = true, markers = "extra == \"epub\""} -pypdf = {version = "*", optional = true, markers = "extra == \"pdf\""} -python-docx = {version = ">=1.1.2", optional = true, markers = "extra == \"docx\""} +python-docx = {version = ">=1.1.0", optional = true, markers = "extra == \"docx\""} python-iso639 = "*" python-magic = "*" -python-oxmsg = "*" -python-pptx = {version = ">=1.0.1", optional = true, markers = "extra == \"pptx\""} +python-pptx = {version = "<=0.6.23", optional = true, markers = "extra == \"ppt\" or extra == \"pptx\""} rapidfuzz = "*" requests = "*" tabulate = "*" -tqdm = "*" typing-extensions = "*" -unstructured-client = "*" -unstructured-inference = {version = "0.7.36", optional = true, markers = "extra == \"pdf\""} -"unstructured.pytesseract" = {version = ">=0.3.12", optional = true, markers = "extra == \"pdf\""} -wrapt = "*" [package.extras] airtable = ["pyairtable"] -all-docs = ["effdet", "google-cloud-vision", "markdown", "networkx", "onnx", "openpyxl", "pandas", "pdf2image", "pdfminer.six", "pi-heif", "pikepdf", "pypandoc", "pypdf", "python-docx (>=1.1.2)", "python-pptx (>=1.0.1)", "unstructured-inference (==0.7.36)", "unstructured.pytesseract (>=0.3.12)", "xlrd"] -astradb = ["astrapy"] -azure = ["adlfs", "fsspec"] +all-docs = ["markdown", "msg-parser", "networkx", "onnx", "openpyxl", "pandas", "pdf2image", "pdfminer.six", "pypandoc", "python-docx (>=1.1.0)", "python-pptx (<=0.6.23)", "unstructured-inference (==0.7.11)", "unstructured.pytesseract (>=0.3.12)", "xlrd"] +azure = ["adlfs", "fsspec (==2023.9.1)"] azure-cognitive-search = ["azure-search-documents"] -bedrock = ["boto3", "langchain-community"] +bedrock = ["boto3", "langchain"] biomed = ["bs4"] -box = ["boxfs", "fsspec"] -chroma = ["chromadb (>0.4.14)", "importlib-metadata (>=8.2.0)", "tenacity (==8.5.0)", "typer (<=0.9.0)"] -clarifai = ["clarifai"] +box = ["boxfs", "fsspec (==2023.9.1)"] confluence = ["atlassian-python-api"] csv = ["pandas"] -databricks-volumes = ["databricks-sdk"] -delta-table = ["deltalake (<=0.19.1)", "fsspec"] +delta-table = ["deltalake", "fsspec (==2023.9.1)"] discord = ["discord-py"] -doc = ["python-docx (>=1.1.2)"] -docx = ["python-docx (>=1.1.2)"] -dropbox = ["dropboxdrivefs", "fsspec"] -elasticsearch = ["elasticsearch[async]"] -embed-huggingface = ["langchain-huggingface"] -embed-mixedbreadai = ["mixedbread-ai"] -embed-octoai = ["openai", "tiktoken"] -embed-vertexai = ["langchain", "langchain-community", "langchain-google-vertexai"] -embed-voyageai = ["langchain", "langchain-voyageai"] +doc = ["python-docx (>=1.1.0)"] +docx = ["python-docx (>=1.1.0)"] +dropbox = ["dropboxdrivefs", "fsspec (==2023.9.1)"] +elasticsearch = ["elasticsearch", "jq"] +embed-huggingface = ["huggingface", "langchain", "sentence-transformers"] epub = ["pypandoc"] -gcs = ["bs4", "fsspec", "gcsfs"] +gcs = ["bs4", "fsspec (==2023.9.1)", "gcsfs"] github = ["pygithub (>1.58.0)"] gitlab = ["python-gitlab"] google-drive = ["google-api-python-client"] -hubspot = ["hubspot-api-client", "urllib3"] huggingface = ["langdetect", "sacremoses", "sentencepiece", "torch", "transformers"] -image = ["effdet", "google-cloud-vision", "onnx", "pdf2image", "pdfminer.six", "pi-heif", "pikepdf", "pypdf", "unstructured-inference (==0.7.36)", "unstructured.pytesseract (>=0.3.12)"] +image = ["onnx", "pdf2image", "pdfminer.six", "unstructured-inference (==0.7.11)", "unstructured.pytesseract (>=0.3.12)"] jira = ["atlassian-python-api"] -kafka = ["confluent-kafka"] -local-inference = ["effdet", "google-cloud-vision", "markdown", "networkx", "onnx", "openpyxl", "pandas", "pdf2image", "pdfminer.six", "pi-heif", "pikepdf", "pypandoc", "pypdf", "python-docx (>=1.1.2)", "python-pptx (>=1.0.1)", "unstructured-inference (==0.7.36)", "unstructured.pytesseract (>=0.3.12)", "xlrd"] +local-inference = ["markdown", "msg-parser", "networkx", "onnx", "openpyxl", "pandas", "pdf2image", "pdfminer.six", "pypandoc", "python-docx (>=1.1.0)", "python-pptx (<=0.6.23)", "unstructured-inference (==0.7.11)", "unstructured.pytesseract (>=0.3.12)", "xlrd"] md = ["markdown"] -mongodb = ["pymongo"] +msg = ["msg-parser"] notion = ["htmlBuilder", "notion-client"] -odt = ["pypandoc", "python-docx (>=1.1.2)"] -onedrive = ["Office365-REST-Python-Client", "bs4", "msal"] -openai = ["langchain-openai"] -opensearch = ["opensearch-py"] +odt = ["pypandoc", "python-docx (>=1.1.0)"] +onedrive = ["Office365-REST-Python-Client (<2.4.3)", "bs4", "msal"] +openai = ["langchain", "openai", "tiktoken"] org = ["pypandoc"] -outlook = ["Office365-REST-Python-Client", "msal"] -paddleocr = ["paddlepaddle (==3.0.0b1)", "unstructured.paddleocr (==2.8.1.0)"] -pdf = ["effdet", "google-cloud-vision", "onnx", "pdf2image", "pdfminer.six", "pi-heif", "pikepdf", "pypdf", "unstructured-inference (==0.7.36)", "unstructured.pytesseract (>=0.3.12)"] -pinecone = ["pinecone-client (>=3.7.1)"] -postgres = ["psycopg2-binary"] -ppt = ["python-pptx (>=1.0.1)"] -pptx = ["python-pptx (>=1.0.1)"] -qdrant = ["qdrant-client"] +outlook = ["Office365-REST-Python-Client (<2.4.3)", "msal"] +paddleocr = ["unstructured.paddleocr (==2.6.1.3)"] +pdf = ["onnx", "pdf2image", "pdfminer.six", "unstructured-inference (==0.7.11)", "unstructured.pytesseract (>=0.3.12)"] +ppt = ["python-pptx (<=0.6.23)"] +pptx = ["python-pptx (<=0.6.23)"] reddit = ["praw"] rst = ["pypandoc"] rtf = ["pypandoc"] -s3 = ["fsspec", "s3fs"] +s3 = ["fsspec (==2023.9.1)", "s3fs"] salesforce = ["simple-salesforce"] -sftp = ["fsspec", "paramiko"] -sharepoint = ["Office365-REST-Python-Client", "msal"] -singlestore = ["singlestoredb"] +sharepoint = ["Office365-REST-Python-Client (<2.4.3)", "msal"] slack = ["slack-sdk"] tsv = ["pandas"] -weaviate = ["weaviate-client"] wikipedia = ["wikipedia"] xlsx = ["networkx", "openpyxl", "pandas", "xlrd"] -[[package]] -name = "unstructured-client" -version = "0.26.1" -description = "Python Client SDK for Unstructured API" -optional = false -python-versions = "<4.0,>=3.8" -files = [ - {file = "unstructured_client-0.26.1-py3-none-any.whl", hash = "sha256:b8b839d477122bab3f37242cbe44b39f7eb7b564b07b53500321f953710119b6"}, - {file = "unstructured_client-0.26.1.tar.gz", hash = "sha256:907cceb470529b45b0fddb2d0f1bbf4d6568f347c757ab68639a7bb620ec2484"}, -] - -[package.dependencies] -cryptography = ">=3.1" -eval-type-backport = ">=0.2.0,<0.3.0" -httpx = ">=0.27.0" -jsonpath-python = ">=1.0.6,<2.0.0" -nest-asyncio = ">=1.6.0" -pydantic = ">=2.9.0,<2.10.0" -pypdf = ">=4.0" -python-dateutil = "2.8.2" -requests-toolbelt = ">=1.0.0" -typing-inspect = ">=0.9.0,<0.10.0" - -[[package]] -name = "unstructured-inference" -version = "0.7.36" -description = "A library for performing inference using trained models." -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "unstructured_inference-0.7.36-py3-none-any.whl", hash = "sha256:6e59c2226c0d049d8e78e102d95bba1a126e14ede4d40494a72ef82ecf7fb64f"}, - {file = "unstructured_inference-0.7.36.tar.gz", hash = "sha256:0b998b311c6156df021d309147b724de4f88f80ef17d8328dfc37eedab67d82a"}, -] - -[package.dependencies] -huggingface-hub = "*" -layoutparser = "*" -matplotlib = "*" -onnx = "*" -onnxruntime = ">=1.17.0" -opencv-python = "!=4.7.0.68" -python-multipart = "*" -rapidfuzz = "*" -timm = "*" -torch = "*" -transformers = ">=4.25.1" - -[[package]] -name = "unstructured-pytesseract" -version = "0.3.13" -description = "Python-tesseract is a python wrapper for Google's Tesseract-OCR" -optional = false -python-versions = ">=3.8" -files = [ - {file = "unstructured.pytesseract-0.3.13-py3-none-any.whl", hash = "sha256:8001bc860470d56185176eb3ceb4623e888eba058ca3b30af79003784bc40e19"}, - {file = "unstructured.pytesseract-0.3.13.tar.gz", hash = "sha256:ff2e6391496e457dbf4b4e327f4a4577cce18921ea6570dc74bd64381b10e963"}, -] - -[package.dependencies] -packaging = ">=21.3" -Pillow = ">=8.0.0" - [[package]] name = "upstash-vector" version = "0.6.0" @@ -10869,21 +10024,6 @@ urllib3 = ">=1.23" [package.extras] ark = ["anyio (>=3.5.0,<5)", "cached-property", "httpx (>=0.23.0,<1)", "pydantic (>=1.9.0,<3)"] -[[package]] -name = "wand" -version = "0.6.13" -description = "Ctypes-based simple MagickWand API binding for Python" -optional = false -python-versions = "*" -files = [ - {file = "Wand-0.6.13-py2.py3-none-any.whl", hash = "sha256:e5dda0ac2204a40c29ef5c4cb310770c95d3d05c37b1379e69c94ea79d7d19c0"}, - {file = "Wand-0.6.13.tar.gz", hash = "sha256:f5013484eaf7a20eb22d1821aaefe60b50cc329722372b5f8565d46d4aaafcca"}, -] - -[package.extras] -doc = ["Sphinx (>=5.3.0)"] -test = ["pytest (>=7.2.0)"] - [[package]] name = "watchfiles" version = "0.24.0" @@ -11670,4 +10810,4 @@ cffi = ["cffi (>=1.11)"] [metadata] lock-version = "2.0" python-versions = ">=3.10,<3.13" -content-hash = "06d34fe599a86af65ee5c6ff9b542286106bed60570a92242f3f7e2a9b4bdcbd" +content-hash = "32fd52006f75e42fbc8f787e559a72f4e033383c73225231e4ecadabfec926f7" diff --git a/api/pyproject.toml b/api/pyproject.toml index 43754f6800..e9529a192e 100644 --- a/api/pyproject.toml +++ b/api/pyproject.toml @@ -172,12 +172,11 @@ sagemaker = "2.231.0" scikit-learn = "~1.5.1" sentry-sdk = { version = "~1.44.1", extras = ["flask"] } sqlalchemy = "~2.0.29" -starlette = "0.41.0" tencentcloud-sdk-python-hunyuan = "~3.0.1158" tiktoken = "~0.8.0" tokenizers = "~0.15.0" transformers = "~4.35.0" -unstructured = { version = "~0.15.7", extras = ["docx", "epub", "md", "msg", "pptx", "pdf"] } +unstructured = { version = "~0.10.27", extras = ["docx", "epub", "md", "msg", "ppt", "pptx"] } validators = "0.21.0" volcengine-python-sdk = {extras = ["ark"], version = "~1.0.98"} websocket-client = "~1.7.0" @@ -207,7 +206,7 @@ duckduckgo-search = "~6.3.0" jsonpath-ng = "1.6.1" matplotlib = "~3.8.2" newspaper3k = "0.2.8" -nltk = "3.9.1" +nltk = "3.8.1" numexpr = "~2.9.0" pydub = "~0.25.1" qrcode = "~7.4.2" From eca66f957783bbd3116df029a96d43cf5151eeac Mon Sep 17 00:00:00 2001 From: Jyong <76649700+JohnJyong@users.noreply.github.com> Date: Wed, 23 Oct 2024 19:14:24 +0800 Subject: [PATCH 181/346] add vdb py test (#9706) --- dev/pytest/pytest_vdb.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/dev/pytest/pytest_vdb.sh b/dev/pytest/pytest_vdb.sh index 47122b537f..579da6a30e 100755 --- a/dev/pytest/pytest_vdb.sh +++ b/dev/pytest/pytest_vdb.sh @@ -6,4 +6,9 @@ pytest api/tests/integration_tests/vdb/chroma \ api/tests/integration_tests/vdb/pgvecto_rs \ api/tests/integration_tests/vdb/pgvector \ api/tests/integration_tests/vdb/qdrant \ - api/tests/integration_tests/vdb/weaviate + api/tests/integration_tests/vdb/weaviate \ + api/tests/integration_tests/vdb/elasticsearch \ + api/tests/integration_tests/vdb/vikingdb \ + api/tests/integration_tests/vdb/baidu \ + api/tests/integration_tests/vdb/tcvectordb \ + api/tests/integration_tests/vdb/upstash \ No newline at end of file From 400392230b47fff5d011b55afd8b0f8b8083ade0 Mon Sep 17 00:00:00 2001 From: luckylhb90 <luckylhb90@gmail.com> Date: Wed, 23 Oct 2024 14:17:06 +0300 Subject: [PATCH 182/346] fixed: variable reference error (#9722) Co-authored-by: hobo.l <hobo.l@binance.com> --- api/core/app/apps/message_based_app_generator.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/api/core/app/apps/message_based_app_generator.py b/api/core/app/apps/message_based_app_generator.py index 2b5597e055..bae64368e3 100644 --- a/api/core/app/apps/message_based_app_generator.py +++ b/api/core/app/apps/message_based_app_generator.py @@ -27,6 +27,7 @@ from core.app.task_pipeline.easy_ui_based_generate_task_pipeline import EasyUIBa from core.prompt.utils.prompt_template_parser import PromptTemplateParser from extensions.ext_database import db from models import Account +from models.enums import CreatedByRole from models.model import App, AppMode, AppModelConfig, Conversation, EndUser, Message, MessageFile from services.errors.app_model_config import AppModelConfigBrokenError from services.errors.conversation import ConversationCompletedError, ConversationNotExistsError @@ -240,7 +241,7 @@ class MessageBasedAppGenerator(BaseAppGenerator): belongs_to="user", url=file.remote_url, upload_file_id=file.related_id, - created_by_role=("account" if account_id else "end_user"), + created_by_role=(CreatedByRole.ACCOUNT if account_id else CreatedByRole.END_USER), created_by=account_id or end_user_id or "", ) db.session.add(message_file) From 7daa365564f032994a9b43d2d2c31b05e709d205 Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Thu, 24 Oct 2024 11:10:44 +0800 Subject: [PATCH 183/346] chore: to common install comp --- .../steps => base}/installed.tsx | 6 +-- .../install-from-local-package/index.tsx | 2 +- .../install-from-marketplace/index.tsx | 2 +- .../steps/installed.tsx | 48 ------------------- 4 files changed, 5 insertions(+), 53 deletions(-) rename web/app/components/plugins/install-plugin/{install-from-local-package/steps => base}/installed.tsx (89%) delete mode 100644 web/app/components/plugins/install-plugin/install-from-marketplace/steps/installed.tsx diff --git a/web/app/components/plugins/install-plugin/install-from-local-package/steps/installed.tsx b/web/app/components/plugins/install-plugin/base/installed.tsx similarity index 89% rename from web/app/components/plugins/install-plugin/install-from-local-package/steps/installed.tsx rename to web/app/components/plugins/install-plugin/base/installed.tsx index 2288371b7d..03f392447c 100644 --- a/web/app/components/plugins/install-plugin/install-from-local-package/steps/installed.tsx +++ b/web/app/components/plugins/install-plugin/base/installed.tsx @@ -1,10 +1,10 @@ 'use client' import type { FC } from 'react' import React from 'react' -import type { PluginDeclaration } from '../../../types' -import Card from '../../../card' +import type { PluginDeclaration } from '../../types' +import Card from '../../card' import Button from '@/app/components/base/button' -import { pluginManifestToCardPluginProps } from '../../utils' +import { pluginManifestToCardPluginProps } from '../utils' import { useTranslation } from 'react-i18next' type Props = { diff --git a/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx b/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx index 92b5c6f61f..0f75d7cf5b 100644 --- a/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx +++ b/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx @@ -6,7 +6,7 @@ import type { PluginDeclaration } from '../../types' import { InstallStep } from '../../types' import Uploading from './steps/uploading' import Install from './steps/install' -import Installed from './steps/installed' +import Installed from '../base/installed' import { useTranslation } from 'react-i18next' import { toolNotionManifest } from '../../card/card-mock' diff --git a/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx b/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx index f555f31c02..26b0d117e8 100644 --- a/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx +++ b/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx @@ -5,7 +5,7 @@ import Modal from '@/app/components/base/modal' import type { PluginDeclaration } from '../../types' import { InstallStep } from '../../types' import Install from './steps/install' -import Installed from './steps/installed' +import Installed from '../base/installed' import { useTranslation } from 'react-i18next' const i18nPrefix = 'plugin.installModal' diff --git a/web/app/components/plugins/install-plugin/install-from-marketplace/steps/installed.tsx b/web/app/components/plugins/install-plugin/install-from-marketplace/steps/installed.tsx deleted file mode 100644 index 2288371b7d..0000000000 --- a/web/app/components/plugins/install-plugin/install-from-marketplace/steps/installed.tsx +++ /dev/null @@ -1,48 +0,0 @@ -'use client' -import type { FC } from 'react' -import React from 'react' -import type { PluginDeclaration } from '../../../types' -import Card from '../../../card' -import Button from '@/app/components/base/button' -import { pluginManifestToCardPluginProps } from '../../utils' -import { useTranslation } from 'react-i18next' - -type Props = { - payload: PluginDeclaration - isFailed: boolean - onCancel: () => void -} - -const Installed: FC<Props> = ({ - payload, - isFailed, - onCancel, -}) => { - const { t } = useTranslation() - return ( - <> - <div className='flex flex-col px-6 py-3 justify-center items-start gap-4 self-stretch'> - <p className='text-text-secondary system-md-regular'>{t(`plugin.installModal.${isFailed ? 'installFailedDesc' : 'installedSuccessfullyDesc'}`)}</p> - <div className='flex p-2 items-start content-start gap-1 self-stretch flex-wrap rounded-2xl bg-background-section-burn'> - <Card - className='w-full' - payload={pluginManifestToCardPluginProps(payload)} - installed={!isFailed} - installFailed={isFailed} - /> - </div> - </div> - {/* Action Buttons */} - <div className='flex p-6 pt-5 justify-end items-center gap-2 self-stretch'> - <Button - variant='primary' - className='min-w-[72px]' - onClick={onCancel} - > - {t('common.operation.close')} - </Button> - </div> - </> - ) -} -export default React.memo(Installed) From 95dc90e6b2ba50eb9795b7879fc9e1bfe8897959 Mon Sep 17 00:00:00 2001 From: Kota-Yamaguchi <50980947+Kota-Yamaguchi@users.noreply.github.com> Date: Thu, 24 Oct 2024 12:23:35 +0900 Subject: [PATCH 184/346] Update Code Generator to use the currently configured model. (#9740) --- .../code-generator/get-code-generator-res.tsx | 30 +++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/web/app/components/app/configuration/config/code-generator/get-code-generator-res.tsx b/web/app/components/app/configuration/config/code-generator/get-code-generator-res.tsx index b2d45d2733..b63e3e2693 100644 --- a/web/app/components/app/configuration/config/code-generator/get-code-generator-res.tsx +++ b/web/app/components/app/configuration/config/code-generator/get-code-generator-res.tsx @@ -7,8 +7,7 @@ import ConfigPrompt from '../../config-prompt' import { languageMap } from '../../../../workflow/nodes/_base/components/editor/code-editor/index' import { generateRuleCode } from '@/service/debug' import type { CodeGenRes } from '@/service/debug' -import { ModelModeType } from '@/types/app' -import type { AppType, Model } from '@/types/app' +import { type AppType, type Model, ModelModeType } from '@/types/app' import Modal from '@/app/components/base/modal' import Button from '@/app/components/base/button' import { Generator } from '@/app/components/base/icons/src/vender/other' @@ -16,6 +15,10 @@ import Toast from '@/app/components/base/toast' import Loading from '@/app/components/base/loading' import Confirm from '@/app/components/base/confirm' import type { CodeLanguage } from '@/app/components/workflow/nodes/code/types' +import { useModelListAndDefaultModelAndCurrentProviderAndModel } from '@/app/components/header/account-setting/model-provider-page/hooks' +import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations' +import ModelIcon from '@/app/components/header/account-setting/model-provider-page/model-icon' +import ModelName from '@/app/components/header/account-setting/model-provider-page/model-name' export type IGetCodeGeneratorResProps = { mode: AppType isShow: boolean @@ -31,9 +34,12 @@ export const GetCodeGeneratorResModal: FC<IGetCodeGeneratorResProps> = ( codeLanguages, onClose, onFinished, - }, ) => { + const { + currentProvider, + currentModel, + } = useModelListAndDefaultModelAndCurrentProviderAndModel(ModelTypeEnum.textGeneration) const { t } = useTranslation() const [instruction, setInstruction] = React.useState<string>('') const [isLoading, { setTrue: setLoadingTrue, setFalse: setLoadingFalse }] = useBoolean(false) @@ -51,9 +57,10 @@ export const GetCodeGeneratorResModal: FC<IGetCodeGeneratorResProps> = ( return true } const model: Model = { - provider: 'openai', - name: 'gpt-4o-mini', + provider: currentProvider?.provider || '', + name: currentModel?.model || '', mode: ModelModeType.chat, + // This is a fixed parameter completion_params: { temperature: 0.7, max_tokens: 0, @@ -112,6 +119,19 @@ export const GetCodeGeneratorResModal: FC<IGetCodeGeneratorResProps> = ( <div className={'leading-[28px] text-lg font-bold'}>{t('appDebug.codegen.title')}</div> <div className='mt-1 text-[13px] font-normal text-gray-500'>{t('appDebug.codegen.description')}</div> </div> + <div className='flex items-center'> + <ModelIcon + className='shrink-0 mr-1.5' + provider={currentProvider} + modelName={currentModel?.model} + /> + <ModelName + className='grow' + modelItem={currentModel!} + showMode + showFeatures + /> + </div> <div className='mt-6'> <div className='text-[0px]'> <div className='mb-2 leading-5 text-sm font-medium text-gray-900'>{t('appDebug.codegen.instruction')}</div> From 2c26f77a25528d116d4c647fde9118a86491fdea Mon Sep 17 00:00:00 2001 From: -LAN- <laipz8200@outlook.com> Date: Thu, 24 Oct 2024 11:43:57 +0800 Subject: [PATCH 185/346] fix(api): handle missing upload_file_id for tool_file messages (#9756) --- api/models/model.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/api/models/model.py b/api/models/model.py index e289423d16..3bd5886d75 100644 --- a/api/models/model.py +++ b/api/models/model.py @@ -977,6 +977,9 @@ class Message(db.Model): config=FileExtraConfig(), ) elif message_file.transfer_method == "tool_file": + if message_file.upload_file_id is None: + assert message_file.url is not None + message_file.upload_file_id = message_file.url.split("/")[-1].split(".")[0] mapping = { "id": message_file.id, "type": message_file.type, @@ -1001,6 +1004,7 @@ class Message(db.Model): for (file, message_file) in zip(files, message_files) ] + db.session.commit() return result @property From 57ec12eb6b01a72aa500d9fa3da5a9587670a4d0 Mon Sep 17 00:00:00 2001 From: Hash Brown <hi@xzd.me> Date: Thu, 24 Oct 2024 12:09:46 +0800 Subject: [PATCH 186/346] feat: regenerate history switch navigation (#8749) --- api/controllers/console/app/message.py | 2 + web/__mocks__/mime.js | 0 web/app/components/app/log/list.tsx | 69 +- .../__snapshots__/utils.spec.ts.snap | 2281 +++++++++++++++++ .../chat/__tests__/branchedTestMessages.json | 42 + .../chat/__tests__/legacyTestMessages.json | 42 + .../chat/__tests__/mixedTestMessages.json | 42 + .../__tests__/multiRootNodesMessages.json | 52 + .../multiRootNodesWithLegacyTestMessages.json | 52 + .../chat/__tests__/realWorldMessages.json | 441 ++++ .../base/chat/__tests__/utils.spec.ts | 258 ++ .../base/chat/chat/answer/index.tsx | 20 + web/app/components/base/chat/chat/index.tsx | 3 + web/app/components/base/chat/chat/type.ts | 6 +- web/app/components/base/chat/types.ts | 4 + web/app/components/base/chat/utils.ts | 128 +- .../workflow/panel/chat-record/index.tsx | 87 +- web/babel.config.js | 3 + web/jest.config.ts | 1 + 19 files changed, 3460 insertions(+), 73 deletions(-) create mode 100644 web/__mocks__/mime.js create mode 100644 web/app/components/base/chat/__tests__/__snapshots__/utils.spec.ts.snap create mode 100644 web/app/components/base/chat/__tests__/branchedTestMessages.json create mode 100644 web/app/components/base/chat/__tests__/legacyTestMessages.json create mode 100644 web/app/components/base/chat/__tests__/mixedTestMessages.json create mode 100644 web/app/components/base/chat/__tests__/multiRootNodesMessages.json create mode 100644 web/app/components/base/chat/__tests__/multiRootNodesWithLegacyTestMessages.json create mode 100644 web/app/components/base/chat/__tests__/realWorldMessages.json create mode 100644 web/app/components/base/chat/__tests__/utils.spec.ts create mode 100644 web/babel.config.js diff --git a/api/controllers/console/app/message.py b/api/controllers/console/app/message.py index 2fba3e0af0..fe06201982 100644 --- a/api/controllers/console/app/message.py +++ b/api/controllers/console/app/message.py @@ -105,6 +105,8 @@ class ChatMessageListApi(Resource): if rest_count > 0: has_more = True + history_messages = list(reversed(history_messages)) + return InfiniteScrollPagination(data=history_messages, limit=args["limit"], has_more=has_more) diff --git a/web/__mocks__/mime.js b/web/__mocks__/mime.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/web/app/components/app/log/list.tsx b/web/app/components/app/log/list.tsx index 6d643a01a3..af678b0f9e 100644 --- a/web/app/components/app/log/list.tsx +++ b/web/app/components/app/log/list.tsx @@ -17,6 +17,7 @@ import { createContext, useContext } from 'use-context-selector' import { useShallow } from 'zustand/react/shallow' import { useTranslation } from 'react-i18next' import { UUID_NIL } from '../../base/chat/constants' +import type { ChatItemInTree } from '../../base/chat/types' import VarPanel from './var-panel' import cn from '@/utils/classnames' import type { FeedbackFunc, FeedbackType, IChatItem, SubmitAnnotationFunc } from '@/app/components/base/chat/chat/type' @@ -41,6 +42,7 @@ import { useAppContext } from '@/context/app-context' import useTimestamp from '@/hooks/use-timestamp' import Tooltip from '@/app/components/base/tooltip' import { CopyIcon } from '@/app/components/base/copy-icon' +import { buildChatItemTree, getThreadMessages } from '@/app/components/base/chat/utils' import { getProcessedFilesFromResponse } from '@/app/components/base/file-uploader/utils' dayjs.extend(utc) @@ -139,6 +141,7 @@ function appendQAToChatList(newChatList: IChatItem[], item: any, conversationId: })(), parentMessageId: `question-${item.id}`, }) + const questionFiles = item.message_files?.filter((file: any) => file.belongs_to === 'user') || [] newChatList.push({ id: `question-${item.id}`, @@ -193,50 +196,66 @@ function DetailPanel({ detail, onFeedback }: IDetailPanel) { currentLogModalActiveTab: state.currentLogModalActiveTab, }))) const { t } = useTranslation() - const [items, setItems] = React.useState<IChatItem[]>([]) - const fetchedMessages = useRef<ChatMessage[]>([]) const [hasMore, setHasMore] = useState(true) const [varValues, setVarValues] = useState<Record<string, string>>({}) - const fetchData = async () => { + + const [allChatItems, setAllChatItems] = useState<IChatItem[]>([]) + const [chatItemTree, setChatItemTree] = useState<ChatItemInTree[]>([]) + const [threadChatItems, setThreadChatItems] = useState<IChatItem[]>([]) + + const fetchData = useCallback(async () => { try { if (!hasMore) return + const params: ChatMessagesRequest = { conversation_id: detail.id, limit: 10, } - if (items?.[0]?.id) - params.first_id = items?.[0]?.id.replace('question-', '') - + if (allChatItems.at(-1)?.id) + params.first_id = allChatItems.at(-1)?.id.replace('question-', '') const messageRes = await fetchChatMessages({ url: `/apps/${appDetail?.id}/chat-messages`, params, }) if (messageRes.data.length > 0) { - const varValues = messageRes.data[0].inputs + const varValues = messageRes.data.at(-1)!.inputs setVarValues(varValues) } - fetchedMessages.current = [...fetchedMessages.current, ...messageRes.data] - const newItems = getFormattedChatList(fetchedMessages.current, detail.id, timezone!, t('appLog.dateTimeFormat') as string) + setHasMore(messageRes.has_more) + + const newAllChatItems = [ + ...getFormattedChatList(messageRes.data, detail.id, timezone!, t('appLog.dateTimeFormat') as string), + ...allChatItems, + ] + setAllChatItems(newAllChatItems) + + let tree = buildChatItemTree(newAllChatItems) if (messageRes.has_more === false && detail?.model_config?.configs?.introduction) { - newItems.unshift({ + tree = [{ id: 'introduction', isAnswer: true, isOpeningStatement: true, content: detail?.model_config?.configs?.introduction ?? 'hello', feedbackDisabled: true, - }) + children: tree, + }] } - setItems(newItems) - setHasMore(messageRes.has_more) + setChatItemTree(tree) + + setThreadChatItems(getThreadMessages(tree, newAllChatItems.at(-1)?.id)) } catch (err) { console.error(err) } - } + }, [allChatItems, detail.id, hasMore, timezone, t, appDetail, detail?.model_config?.configs?.introduction]) + + const switchSibling = useCallback((siblingMessageId: string) => { + setThreadChatItems(getThreadMessages(chatItemTree, siblingMessageId)) + }, [chatItemTree]) const handleAnnotationEdited = useCallback((query: string, answer: string, index: number) => { - setItems(items.map((item, i) => { + setAllChatItems(allChatItems.map((item, i) => { if (i === index - 1) { return { ...item, @@ -257,9 +276,9 @@ function DetailPanel({ detail, onFeedback }: IDetailPanel) { } return item })) - }, [items]) + }, [allChatItems]) const handleAnnotationAdded = useCallback((annotationId: string, authorName: string, query: string, answer: string, index: number) => { - setItems(items.map((item, i) => { + setAllChatItems(allChatItems.map((item, i) => { if (i === index - 1) { return { ...item, @@ -287,9 +306,9 @@ function DetailPanel({ detail, onFeedback }: IDetailPanel) { } return item })) - }, [items]) + }, [allChatItems]) const handleAnnotationRemoved = useCallback((index: number) => { - setItems(items.map((item, i) => { + setAllChatItems(allChatItems.map((item, i) => { if (i === index) { return { ...item, @@ -299,7 +318,7 @@ function DetailPanel({ detail, onFeedback }: IDetailPanel) { } return item })) - }, [items]) + }, [allChatItems]) const fetchInitiated = useRef(false) @@ -464,7 +483,7 @@ function DetailPanel({ detail, onFeedback }: IDetailPanel) { siteInfo={null} /> </div> - : (items.length < 8 && !hasMore) + : threadChatItems.length < 8 ? <div className="pt-4 mb-4"> <Chat config={{ @@ -478,7 +497,7 @@ function DetailPanel({ detail, onFeedback }: IDetailPanel) { }, supportFeedback: true, } as any} - chatList={items} + chatList={threadChatItems} onAnnotationAdded={handleAnnotationAdded} onAnnotationEdited={handleAnnotationEdited} onAnnotationRemoved={handleAnnotationRemoved} @@ -487,6 +506,7 @@ function DetailPanel({ detail, onFeedback }: IDetailPanel) { showPromptLog hideProcessDetail chatContainerInnerClassName='px-6' + switchSibling={switchSibling} /> </div> : <div @@ -501,7 +521,7 @@ function DetailPanel({ detail, onFeedback }: IDetailPanel) { {/* Put the scroll bar always on the bottom */} <InfiniteScroll scrollableTarget="scrollableDiv" - dataLength={items.length} + dataLength={threadChatItems.length} next={fetchData} hasMore={hasMore} loader={<div className='text-center text-gray-400 text-xs'>{t('appLog.detail.loading')}...</div>} @@ -532,7 +552,7 @@ function DetailPanel({ detail, onFeedback }: IDetailPanel) { }, supportFeedback: true, } as any} - chatList={items} + chatList={threadChatItems} onAnnotationAdded={handleAnnotationAdded} onAnnotationEdited={handleAnnotationEdited} onAnnotationRemoved={handleAnnotationRemoved} @@ -541,6 +561,7 @@ function DetailPanel({ detail, onFeedback }: IDetailPanel) { showPromptLog hideProcessDetail chatContainerInnerClassName='px-6' + switchSibling={switchSibling} /> </InfiniteScroll> </div> diff --git a/web/app/components/base/chat/__tests__/__snapshots__/utils.spec.ts.snap b/web/app/components/base/chat/__tests__/__snapshots__/utils.spec.ts.snap new file mode 100644 index 0000000000..070975bfa7 --- /dev/null +++ b/web/app/components/base/chat/__tests__/__snapshots__/utils.spec.ts.snap @@ -0,0 +1,2281 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`build chat item tree and get thread messages should get thread messages from tree6, using specified message as target 1`] = ` +[ + { + "children": [ + { + "agent_thoughts": [ + { + "chain_id": null, + "created_at": 1726105791, + "files": [], + "id": "f9d7ff7c-3a3b-4d9a-a289-657817f4caff", + "message_id": "ff4c2b43-48a5-47ad-9dc5-08b34ddba61b", + "observation": "", + "position": 1, + "thought": "Sure, I'll play! My number is 57. Your turn!", + "tool": "", + "tool_input": "", + "tool_labels": {}, + }, + ], + "children": [ + { + "children": [ + { + "agent_thoughts": [ + { + "chain_id": null, + "created_at": 1726105795, + "files": [], + "id": "f61a3fce-37ac-4f9d-9935-95f97e598dfe", + "message_id": "73bbad14-d915-499d-87bf-0df14d40779d", + "observation": "", + "position": 1, + "thought": "I choose 83. What's your next number?", + "tool": "", + "tool_input": "", + "tool_labels": {}, + }, + ], + "children": [ + { + "children": [ + { + "agent_thoughts": [ + { + "chain_id": null, + "created_at": 1726105799, + "files": [], + "id": "9730d587-9268-4683-9dd9-91a1cab9510b", + "message_id": "4c5d0841-1206-463e-95d8-71f812877658", + "observation": "", + "position": 1, + "thought": "I'll go with 112. Your turn!", + "tool": "", + "tool_input": "", + "tool_labels": {}, + }, + ], + "children": [], + "content": "I'll go with 112. Your turn!", + "conversationId": "dd6c9cfd-2656-48ec-bd51-2139c1790d80", + "feedbackDisabled": false, + "id": "4c5d0841-1206-463e-95d8-71f812877658", + "input": { + "inputs": {}, + "query": "99", + }, + "isAnswer": true, + "log": [ + { + "files": [], + "role": "user", + "text": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + }, + { + "files": [], + "role": "assistant", + "text": "Sure, I'll play! My number is 57. Your turn!", + }, + { + "files": [], + "role": "user", + "text": "58", + }, + { + "files": [], + "role": "assistant", + "text": "I choose 83. What's your next number?", + }, + { + "files": [], + "role": "user", + "text": "99", + }, + { + "files": [], + "role": "assistant", + "text": "I'll go with 112. Your turn!", + }, + ], + "message_files": [], + "more": { + "latency": "1.49", + "time": "09/11/2024 09:50 PM", + "tokens": 86, + }, + "parentMessageId": "question-4c5d0841-1206-463e-95d8-71f812877658", + "siblingIndex": 0, + "workflow_run_id": null, + }, + ], + "content": "99", + "id": "question-4c5d0841-1206-463e-95d8-71f812877658", + "isAnswer": false, + "message_files": [], + "parentMessageId": "73bbad14-d915-499d-87bf-0df14d40779d", + }, + ], + "content": "I choose 83. What's your next number?", + "conversationId": "dd6c9cfd-2656-48ec-bd51-2139c1790d80", + "feedbackDisabled": false, + "id": "73bbad14-d915-499d-87bf-0df14d40779d", + "input": { + "inputs": {}, + "query": "58", + }, + "isAnswer": true, + "log": [ + { + "files": [], + "role": "user", + "text": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + }, + { + "files": [], + "role": "assistant", + "text": "Sure, I'll play! My number is 57. Your turn!", + }, + { + "files": [], + "role": "user", + "text": "58", + }, + { + "files": [], + "role": "assistant", + "text": "I choose 83. What's your next number?", + }, + ], + "message_files": [], + "more": { + "latency": "1.33", + "time": "09/11/2024 09:49 PM", + "tokens": 68, + }, + "parentMessageId": "question-73bbad14-d915-499d-87bf-0df14d40779d", + "siblingIndex": 0, + "workflow_run_id": null, + }, + ], + "content": "58", + "id": "question-73bbad14-d915-499d-87bf-0df14d40779d", + "isAnswer": false, + "message_files": [], + "parentMessageId": "ff4c2b43-48a5-47ad-9dc5-08b34ddba61b", + }, + ], + "content": "Sure, I'll play! My number is 57. Your turn!", + "conversationId": "dd6c9cfd-2656-48ec-bd51-2139c1790d80", + "feedbackDisabled": false, + "id": "ff4c2b43-48a5-47ad-9dc5-08b34ddba61b", + "input": { + "inputs": {}, + "query": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + }, + "isAnswer": true, + "log": [ + { + "files": [], + "role": "user", + "text": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + }, + { + "files": [], + "role": "assistant", + "text": "Sure, I'll play! My number is 57. Your turn!", + }, + ], + "message_files": [], + "more": { + "latency": "1.56", + "time": "09/11/2024 09:49 PM", + "tokens": 49, + }, + "parentMessageId": "question-ff4c2b43-48a5-47ad-9dc5-08b34ddba61b", + "siblingIndex": 0, + "workflow_run_id": null, + }, + ], + "content": "Let's play a game, I say a number , and you response me with another bigger, yet random-looking number. I'll start first, 38", + "id": "question-ff4c2b43-48a5-47ad-9dc5-08b34ddba61b", + "isAnswer": false, + "message_files": [], + }, + { + "agent_thoughts": [ + { + "chain_id": null, + "created_at": 1726105791, + "files": [], + "id": "f9d7ff7c-3a3b-4d9a-a289-657817f4caff", + "message_id": "ff4c2b43-48a5-47ad-9dc5-08b34ddba61b", + "observation": "", + "position": 1, + "thought": "Sure, I'll play! My number is 57. Your turn!", + "tool": "", + "tool_input": "", + "tool_labels": {}, + }, + ], + "children": [ + { + "children": [ + { + "agent_thoughts": [ + { + "chain_id": null, + "created_at": 1726105795, + "files": [], + "id": "f61a3fce-37ac-4f9d-9935-95f97e598dfe", + "message_id": "73bbad14-d915-499d-87bf-0df14d40779d", + "observation": "", + "position": 1, + "thought": "I choose 83. What's your next number?", + "tool": "", + "tool_input": "", + "tool_labels": {}, + }, + ], + "children": [ + { + "children": [ + { + "agent_thoughts": [ + { + "chain_id": null, + "created_at": 1726105799, + "files": [], + "id": "9730d587-9268-4683-9dd9-91a1cab9510b", + "message_id": "4c5d0841-1206-463e-95d8-71f812877658", + "observation": "", + "position": 1, + "thought": "I'll go with 112. Your turn!", + "tool": "", + "tool_input": "", + "tool_labels": {}, + }, + ], + "children": [], + "content": "I'll go with 112. Your turn!", + "conversationId": "dd6c9cfd-2656-48ec-bd51-2139c1790d80", + "feedbackDisabled": false, + "id": "4c5d0841-1206-463e-95d8-71f812877658", + "input": { + "inputs": {}, + "query": "99", + }, + "isAnswer": true, + "log": [ + { + "files": [], + "role": "user", + "text": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + }, + { + "files": [], + "role": "assistant", + "text": "Sure, I'll play! My number is 57. Your turn!", + }, + { + "files": [], + "role": "user", + "text": "58", + }, + { + "files": [], + "role": "assistant", + "text": "I choose 83. What's your next number?", + }, + { + "files": [], + "role": "user", + "text": "99", + }, + { + "files": [], + "role": "assistant", + "text": "I'll go with 112. Your turn!", + }, + ], + "message_files": [], + "more": { + "latency": "1.49", + "time": "09/11/2024 09:50 PM", + "tokens": 86, + }, + "parentMessageId": "question-4c5d0841-1206-463e-95d8-71f812877658", + "siblingIndex": 0, + "workflow_run_id": null, + }, + ], + "content": "99", + "id": "question-4c5d0841-1206-463e-95d8-71f812877658", + "isAnswer": false, + "message_files": [], + "parentMessageId": "73bbad14-d915-499d-87bf-0df14d40779d", + }, + ], + "content": "I choose 83. What's your next number?", + "conversationId": "dd6c9cfd-2656-48ec-bd51-2139c1790d80", + "feedbackDisabled": false, + "id": "73bbad14-d915-499d-87bf-0df14d40779d", + "input": { + "inputs": {}, + "query": "58", + }, + "isAnswer": true, + "log": [ + { + "files": [], + "role": "user", + "text": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + }, + { + "files": [], + "role": "assistant", + "text": "Sure, I'll play! My number is 57. Your turn!", + }, + { + "files": [], + "role": "user", + "text": "58", + }, + { + "files": [], + "role": "assistant", + "text": "I choose 83. What's your next number?", + }, + ], + "message_files": [], + "more": { + "latency": "1.33", + "time": "09/11/2024 09:49 PM", + "tokens": 68, + }, + "parentMessageId": "question-73bbad14-d915-499d-87bf-0df14d40779d", + "siblingIndex": 0, + "workflow_run_id": null, + }, + ], + "content": "58", + "id": "question-73bbad14-d915-499d-87bf-0df14d40779d", + "isAnswer": false, + "message_files": [], + "parentMessageId": "ff4c2b43-48a5-47ad-9dc5-08b34ddba61b", + }, + ], + "content": "Sure, I'll play! My number is 57. Your turn!", + "conversationId": "dd6c9cfd-2656-48ec-bd51-2139c1790d80", + "feedbackDisabled": false, + "id": "ff4c2b43-48a5-47ad-9dc5-08b34ddba61b", + "input": { + "inputs": {}, + "query": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + }, + "isAnswer": true, + "log": [ + { + "files": [], + "role": "user", + "text": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + }, + { + "files": [], + "role": "assistant", + "text": "Sure, I'll play! My number is 57. Your turn!", + }, + ], + "message_files": [], + "more": { + "latency": "1.56", + "time": "09/11/2024 09:49 PM", + "tokens": 49, + }, + "nextSibling": "cd5affb0-7bc2-4a6f-be7e-25e74595c9dd", + "parentMessageId": "question-ff4c2b43-48a5-47ad-9dc5-08b34ddba61b", + "prevSibling": undefined, + "siblingCount": 2, + "siblingIndex": 0, + "workflow_run_id": null, + }, + { + "children": [ + { + "agent_thoughts": [ + { + "chain_id": null, + "created_at": 1726105795, + "files": [], + "id": "f61a3fce-37ac-4f9d-9935-95f97e598dfe", + "message_id": "73bbad14-d915-499d-87bf-0df14d40779d", + "observation": "", + "position": 1, + "thought": "I choose 83. What's your next number?", + "tool": "", + "tool_input": "", + "tool_labels": {}, + }, + ], + "children": [ + { + "children": [ + { + "agent_thoughts": [ + { + "chain_id": null, + "created_at": 1726105799, + "files": [], + "id": "9730d587-9268-4683-9dd9-91a1cab9510b", + "message_id": "4c5d0841-1206-463e-95d8-71f812877658", + "observation": "", + "position": 1, + "thought": "I'll go with 112. Your turn!", + "tool": "", + "tool_input": "", + "tool_labels": {}, + }, + ], + "children": [], + "content": "I'll go with 112. Your turn!", + "conversationId": "dd6c9cfd-2656-48ec-bd51-2139c1790d80", + "feedbackDisabled": false, + "id": "4c5d0841-1206-463e-95d8-71f812877658", + "input": { + "inputs": {}, + "query": "99", + }, + "isAnswer": true, + "log": [ + { + "files": [], + "role": "user", + "text": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + }, + { + "files": [], + "role": "assistant", + "text": "Sure, I'll play! My number is 57. Your turn!", + }, + { + "files": [], + "role": "user", + "text": "58", + }, + { + "files": [], + "role": "assistant", + "text": "I choose 83. What's your next number?", + }, + { + "files": [], + "role": "user", + "text": "99", + }, + { + "files": [], + "role": "assistant", + "text": "I'll go with 112. Your turn!", + }, + ], + "message_files": [], + "more": { + "latency": "1.49", + "time": "09/11/2024 09:50 PM", + "tokens": 86, + }, + "parentMessageId": "question-4c5d0841-1206-463e-95d8-71f812877658", + "siblingIndex": 0, + "workflow_run_id": null, + }, + ], + "content": "99", + "id": "question-4c5d0841-1206-463e-95d8-71f812877658", + "isAnswer": false, + "message_files": [], + "parentMessageId": "73bbad14-d915-499d-87bf-0df14d40779d", + }, + ], + "content": "I choose 83. What's your next number?", + "conversationId": "dd6c9cfd-2656-48ec-bd51-2139c1790d80", + "feedbackDisabled": false, + "id": "73bbad14-d915-499d-87bf-0df14d40779d", + "input": { + "inputs": {}, + "query": "58", + }, + "isAnswer": true, + "log": [ + { + "files": [], + "role": "user", + "text": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + }, + { + "files": [], + "role": "assistant", + "text": "Sure, I'll play! My number is 57. Your turn!", + }, + { + "files": [], + "role": "user", + "text": "58", + }, + { + "files": [], + "role": "assistant", + "text": "I choose 83. What's your next number?", + }, + ], + "message_files": [], + "more": { + "latency": "1.33", + "time": "09/11/2024 09:49 PM", + "tokens": 68, + }, + "parentMessageId": "question-73bbad14-d915-499d-87bf-0df14d40779d", + "siblingIndex": 0, + "workflow_run_id": null, + }, + ], + "content": "58", + "id": "question-73bbad14-d915-499d-87bf-0df14d40779d", + "isAnswer": false, + "message_files": [], + "parentMessageId": "ff4c2b43-48a5-47ad-9dc5-08b34ddba61b", + }, + { + "agent_thoughts": [ + { + "chain_id": null, + "created_at": 1726105795, + "files": [], + "id": "f61a3fce-37ac-4f9d-9935-95f97e598dfe", + "message_id": "73bbad14-d915-499d-87bf-0df14d40779d", + "observation": "", + "position": 1, + "thought": "I choose 83. What's your next number?", + "tool": "", + "tool_input": "", + "tool_labels": {}, + }, + ], + "children": [ + { + "children": [ + { + "agent_thoughts": [ + { + "chain_id": null, + "created_at": 1726105799, + "files": [], + "id": "9730d587-9268-4683-9dd9-91a1cab9510b", + "message_id": "4c5d0841-1206-463e-95d8-71f812877658", + "observation": "", + "position": 1, + "thought": "I'll go with 112. Your turn!", + "tool": "", + "tool_input": "", + "tool_labels": {}, + }, + ], + "children": [], + "content": "I'll go with 112. Your turn!", + "conversationId": "dd6c9cfd-2656-48ec-bd51-2139c1790d80", + "feedbackDisabled": false, + "id": "4c5d0841-1206-463e-95d8-71f812877658", + "input": { + "inputs": {}, + "query": "99", + }, + "isAnswer": true, + "log": [ + { + "files": [], + "role": "user", + "text": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + }, + { + "files": [], + "role": "assistant", + "text": "Sure, I'll play! My number is 57. Your turn!", + }, + { + "files": [], + "role": "user", + "text": "58", + }, + { + "files": [], + "role": "assistant", + "text": "I choose 83. What's your next number?", + }, + { + "files": [], + "role": "user", + "text": "99", + }, + { + "files": [], + "role": "assistant", + "text": "I'll go with 112. Your turn!", + }, + ], + "message_files": [], + "more": { + "latency": "1.49", + "time": "09/11/2024 09:50 PM", + "tokens": 86, + }, + "parentMessageId": "question-4c5d0841-1206-463e-95d8-71f812877658", + "siblingIndex": 0, + "workflow_run_id": null, + }, + ], + "content": "99", + "id": "question-4c5d0841-1206-463e-95d8-71f812877658", + "isAnswer": false, + "message_files": [], + "parentMessageId": "73bbad14-d915-499d-87bf-0df14d40779d", + }, + ], + "content": "I choose 83. What's your next number?", + "conversationId": "dd6c9cfd-2656-48ec-bd51-2139c1790d80", + "feedbackDisabled": false, + "id": "73bbad14-d915-499d-87bf-0df14d40779d", + "input": { + "inputs": {}, + "query": "58", + }, + "isAnswer": true, + "log": [ + { + "files": [], + "role": "user", + "text": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + }, + { + "files": [], + "role": "assistant", + "text": "Sure, I'll play! My number is 57. Your turn!", + }, + { + "files": [], + "role": "user", + "text": "58", + }, + { + "files": [], + "role": "assistant", + "text": "I choose 83. What's your next number?", + }, + ], + "message_files": [], + "more": { + "latency": "1.33", + "time": "09/11/2024 09:49 PM", + "tokens": 68, + }, + "parentMessageId": "question-73bbad14-d915-499d-87bf-0df14d40779d", + "prevSibling": undefined, + "siblingCount": 1, + "siblingIndex": 0, + "workflow_run_id": null, + }, + { + "children": [ + { + "agent_thoughts": [ + { + "chain_id": null, + "created_at": 1726105799, + "files": [], + "id": "9730d587-9268-4683-9dd9-91a1cab9510b", + "message_id": "4c5d0841-1206-463e-95d8-71f812877658", + "observation": "", + "position": 1, + "thought": "I'll go with 112. Your turn!", + "tool": "", + "tool_input": "", + "tool_labels": {}, + }, + ], + "children": [], + "content": "I'll go with 112. Your turn!", + "conversationId": "dd6c9cfd-2656-48ec-bd51-2139c1790d80", + "feedbackDisabled": false, + "id": "4c5d0841-1206-463e-95d8-71f812877658", + "input": { + "inputs": {}, + "query": "99", + }, + "isAnswer": true, + "log": [ + { + "files": [], + "role": "user", + "text": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + }, + { + "files": [], + "role": "assistant", + "text": "Sure, I'll play! My number is 57. Your turn!", + }, + { + "files": [], + "role": "user", + "text": "58", + }, + { + "files": [], + "role": "assistant", + "text": "I choose 83. What's your next number?", + }, + { + "files": [], + "role": "user", + "text": "99", + }, + { + "files": [], + "role": "assistant", + "text": "I'll go with 112. Your turn!", + }, + ], + "message_files": [], + "more": { + "latency": "1.49", + "time": "09/11/2024 09:50 PM", + "tokens": 86, + }, + "parentMessageId": "question-4c5d0841-1206-463e-95d8-71f812877658", + "siblingIndex": 0, + "workflow_run_id": null, + }, + ], + "content": "99", + "id": "question-4c5d0841-1206-463e-95d8-71f812877658", + "isAnswer": false, + "message_files": [], + "parentMessageId": "73bbad14-d915-499d-87bf-0df14d40779d", + }, + { + "agent_thoughts": [ + { + "chain_id": null, + "created_at": 1726105799, + "files": [], + "id": "9730d587-9268-4683-9dd9-91a1cab9510b", + "message_id": "4c5d0841-1206-463e-95d8-71f812877658", + "observation": "", + "position": 1, + "thought": "I'll go with 112. Your turn!", + "tool": "", + "tool_input": "", + "tool_labels": {}, + }, + ], + "children": [], + "content": "I'll go with 112. Your turn!", + "conversationId": "dd6c9cfd-2656-48ec-bd51-2139c1790d80", + "feedbackDisabled": false, + "id": "4c5d0841-1206-463e-95d8-71f812877658", + "input": { + "inputs": {}, + "query": "99", + }, + "isAnswer": true, + "log": [ + { + "files": [], + "role": "user", + "text": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + }, + { + "files": [], + "role": "assistant", + "text": "Sure, I'll play! My number is 57. Your turn!", + }, + { + "files": [], + "role": "user", + "text": "58", + }, + { + "files": [], + "role": "assistant", + "text": "I choose 83. What's your next number?", + }, + { + "files": [], + "role": "user", + "text": "99", + }, + { + "files": [], + "role": "assistant", + "text": "I'll go with 112. Your turn!", + }, + ], + "message_files": [], + "more": { + "latency": "1.49", + "time": "09/11/2024 09:50 PM", + "tokens": 86, + }, + "parentMessageId": "question-4c5d0841-1206-463e-95d8-71f812877658", + "prevSibling": undefined, + "siblingCount": 1, + "siblingIndex": 0, + "workflow_run_id": null, + }, +] +`; + +exports[`build chat item tree and get thread messages should get thread messages from tree6, using the last message as target 1`] = ` +[ + { + "children": [ + { + "agent_thoughts": [ + { + "chain_id": null, + "created_at": 1726105809, + "files": [], + "id": "1019cd79-d141-4f9f-880a-fc1441cfd802", + "message_id": "cd5affb0-7bc2-4a6f-be7e-25e74595c9dd", + "observation": "", + "position": 1, + "thought": "Sure! My number is 54. Your turn!", + "tool": "", + "tool_input": "", + "tool_labels": {}, + }, + ], + "children": [ + { + "children": [ + { + "agent_thoughts": [ + { + "chain_id": null, + "created_at": 1726105822, + "files": [], + "id": "0773bec7-b992-4a53-92b2-20ebaeae8798", + "message_id": "324bce32-c98c-435d-a66b-bac974ebb5ed", + "observation": "", + "position": 1, + "thought": "My number is 4729. Your turn!", + "tool": "", + "tool_input": "", + "tool_labels": {}, + }, + ], + "children": [], + "content": "My number is 4729. Your turn!", + "conversationId": "dd6c9cfd-2656-48ec-bd51-2139c1790d80", + "feedbackDisabled": false, + "id": "324bce32-c98c-435d-a66b-bac974ebb5ed", + "input": { + "inputs": {}, + "query": "3306", + }, + "isAnswer": true, + "log": [ + { + "files": [], + "role": "user", + "text": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + }, + { + "files": [], + "role": "assistant", + "text": "Sure! My number is 54. Your turn!", + }, + { + "files": [], + "role": "user", + "text": "3306", + }, + { + "files": [], + "role": "assistant", + "text": "My number is 4729. Your turn!", + }, + ], + "message_files": [], + "more": { + "latency": "1.30", + "time": "09/11/2024 09:50 PM", + "tokens": 66, + }, + "parentMessageId": "question-324bce32-c98c-435d-a66b-bac974ebb5ed", + "siblingIndex": 0, + "workflow_run_id": null, + }, + ], + "content": "3306", + "id": "question-324bce32-c98c-435d-a66b-bac974ebb5ed", + "isAnswer": false, + "message_files": [], + "parentMessageId": "cd5affb0-7bc2-4a6f-be7e-25e74595c9dd", + }, + { + "children": [ + { + "agent_thoughts": [ + { + "chain_id": null, + "created_at": 1726107812, + "files": [], + "id": "5ca650f3-982c-4399-8b95-9ea241c76707", + "message_id": "684b5396-4e91-4043-88e9-aabe48b21acc", + "observation": "", + "position": 1, + "thought": "My number is 4821. Your turn!", + "tool": "", + "tool_input": "", + "tool_labels": {}, + }, + ], + "children": [ + { + "children": [ + { + "agent_thoughts": [ + { + "chain_id": null, + "created_at": 1726111024, + "files": [], + "id": "095cacab-afad-4387-a41d-1662578b8b13", + "message_id": "19904a7b-7494-4ed8-b72c-1d18668cea8c", + "observation": "", + "position": 1, + "thought": "My number is 1456. Your turn!", + "tool": "", + "tool_input": "", + "tool_labels": {}, + }, + ], + "children": [], + "content": "My number is 1456. Your turn!", + "conversationId": "dd6c9cfd-2656-48ec-bd51-2139c1790d80", + "feedbackDisabled": false, + "id": "19904a7b-7494-4ed8-b72c-1d18668cea8c", + "input": { + "inputs": {}, + "query": "1003", + }, + "isAnswer": true, + "log": [ + { + "files": [], + "role": "user", + "text": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + }, + { + "files": [], + "role": "assistant", + "text": "Sure! My number is 54. Your turn!", + }, + { + "files": [], + "role": "user", + "text": "3306", + }, + { + "files": [], + "role": "assistant", + "text": "My number is 4821. Your turn!", + }, + { + "files": [], + "role": "user", + "text": "1003", + }, + { + "files": [], + "role": "assistant", + "text": "My number is 1456. Your turn!", + }, + ], + "message_files": [], + "more": { + "latency": "1.38", + "time": "09/11/2024 11:17 PM", + "tokens": 86, + }, + "parentMessageId": "question-19904a7b-7494-4ed8-b72c-1d18668cea8c", + "siblingIndex": 0, + "workflow_run_id": null, + }, + ], + "content": "1003", + "id": "question-19904a7b-7494-4ed8-b72c-1d18668cea8c", + "isAnswer": false, + "message_files": [], + "parentMessageId": "684b5396-4e91-4043-88e9-aabe48b21acc", + }, + ], + "content": "My number is 4821. Your turn!", + "conversationId": "dd6c9cfd-2656-48ec-bd51-2139c1790d80", + "feedbackDisabled": false, + "id": "684b5396-4e91-4043-88e9-aabe48b21acc", + "input": { + "inputs": {}, + "query": "3306", + }, + "isAnswer": true, + "log": [ + { + "files": [], + "role": "user", + "text": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + }, + { + "files": [], + "role": "assistant", + "text": "Sure! My number is 54. Your turn!", + }, + { + "files": [], + "role": "user", + "text": "3306", + }, + { + "files": [], + "role": "assistant", + "text": "My number is 4821. Your turn!", + }, + ], + "message_files": [], + "more": { + "latency": "1.48", + "time": "09/11/2024 10:23 PM", + "tokens": 66, + }, + "parentMessageId": "question-684b5396-4e91-4043-88e9-aabe48b21acc", + "siblingIndex": 1, + "workflow_run_id": null, + }, + ], + "content": "3306", + "id": "question-684b5396-4e91-4043-88e9-aabe48b21acc", + "isAnswer": false, + "message_files": [], + "parentMessageId": "cd5affb0-7bc2-4a6f-be7e-25e74595c9dd", + }, + ], + "content": "Sure! My number is 54. Your turn!", + "conversationId": "dd6c9cfd-2656-48ec-bd51-2139c1790d80", + "feedbackDisabled": false, + "id": "cd5affb0-7bc2-4a6f-be7e-25e74595c9dd", + "input": { + "inputs": {}, + "query": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + }, + "isAnswer": true, + "log": [ + { + "files": [], + "role": "user", + "text": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + }, + { + "files": [], + "role": "assistant", + "text": "Sure! My number is 54. Your turn!", + }, + ], + "message_files": [], + "more": { + "latency": "1.52", + "time": "09/11/2024 09:50 PM", + "tokens": 46, + }, + "parentMessageId": "question-cd5affb0-7bc2-4a6f-be7e-25e74595c9dd", + "siblingIndex": 1, + "workflow_run_id": null, + }, + ], + "content": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + "id": "question-cd5affb0-7bc2-4a6f-be7e-25e74595c9dd", + "isAnswer": false, + "message_files": [], + }, + { + "agent_thoughts": [ + { + "chain_id": null, + "created_at": 1726105809, + "files": [], + "id": "1019cd79-d141-4f9f-880a-fc1441cfd802", + "message_id": "cd5affb0-7bc2-4a6f-be7e-25e74595c9dd", + "observation": "", + "position": 1, + "thought": "Sure! My number is 54. Your turn!", + "tool": "", + "tool_input": "", + "tool_labels": {}, + }, + ], + "children": [ + { + "children": [ + { + "agent_thoughts": [ + { + "chain_id": null, + "created_at": 1726105822, + "files": [], + "id": "0773bec7-b992-4a53-92b2-20ebaeae8798", + "message_id": "324bce32-c98c-435d-a66b-bac974ebb5ed", + "observation": "", + "position": 1, + "thought": "My number is 4729. Your turn!", + "tool": "", + "tool_input": "", + "tool_labels": {}, + }, + ], + "children": [], + "content": "My number is 4729. Your turn!", + "conversationId": "dd6c9cfd-2656-48ec-bd51-2139c1790d80", + "feedbackDisabled": false, + "id": "324bce32-c98c-435d-a66b-bac974ebb5ed", + "input": { + "inputs": {}, + "query": "3306", + }, + "isAnswer": true, + "log": [ + { + "files": [], + "role": "user", + "text": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + }, + { + "files": [], + "role": "assistant", + "text": "Sure! My number is 54. Your turn!", + }, + { + "files": [], + "role": "user", + "text": "3306", + }, + { + "files": [], + "role": "assistant", + "text": "My number is 4729. Your turn!", + }, + ], + "message_files": [], + "more": { + "latency": "1.30", + "time": "09/11/2024 09:50 PM", + "tokens": 66, + }, + "parentMessageId": "question-324bce32-c98c-435d-a66b-bac974ebb5ed", + "siblingIndex": 0, + "workflow_run_id": null, + }, + ], + "content": "3306", + "id": "question-324bce32-c98c-435d-a66b-bac974ebb5ed", + "isAnswer": false, + "message_files": [], + "parentMessageId": "cd5affb0-7bc2-4a6f-be7e-25e74595c9dd", + }, + { + "children": [ + { + "agent_thoughts": [ + { + "chain_id": null, + "created_at": 1726107812, + "files": [], + "id": "5ca650f3-982c-4399-8b95-9ea241c76707", + "message_id": "684b5396-4e91-4043-88e9-aabe48b21acc", + "observation": "", + "position": 1, + "thought": "My number is 4821. Your turn!", + "tool": "", + "tool_input": "", + "tool_labels": {}, + }, + ], + "children": [ + { + "children": [ + { + "agent_thoughts": [ + { + "chain_id": null, + "created_at": 1726111024, + "files": [], + "id": "095cacab-afad-4387-a41d-1662578b8b13", + "message_id": "19904a7b-7494-4ed8-b72c-1d18668cea8c", + "observation": "", + "position": 1, + "thought": "My number is 1456. Your turn!", + "tool": "", + "tool_input": "", + "tool_labels": {}, + }, + ], + "children": [], + "content": "My number is 1456. Your turn!", + "conversationId": "dd6c9cfd-2656-48ec-bd51-2139c1790d80", + "feedbackDisabled": false, + "id": "19904a7b-7494-4ed8-b72c-1d18668cea8c", + "input": { + "inputs": {}, + "query": "1003", + }, + "isAnswer": true, + "log": [ + { + "files": [], + "role": "user", + "text": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + }, + { + "files": [], + "role": "assistant", + "text": "Sure! My number is 54. Your turn!", + }, + { + "files": [], + "role": "user", + "text": "3306", + }, + { + "files": [], + "role": "assistant", + "text": "My number is 4821. Your turn!", + }, + { + "files": [], + "role": "user", + "text": "1003", + }, + { + "files": [], + "role": "assistant", + "text": "My number is 1456. Your turn!", + }, + ], + "message_files": [], + "more": { + "latency": "1.38", + "time": "09/11/2024 11:17 PM", + "tokens": 86, + }, + "parentMessageId": "question-19904a7b-7494-4ed8-b72c-1d18668cea8c", + "siblingIndex": 0, + "workflow_run_id": null, + }, + ], + "content": "1003", + "id": "question-19904a7b-7494-4ed8-b72c-1d18668cea8c", + "isAnswer": false, + "message_files": [], + "parentMessageId": "684b5396-4e91-4043-88e9-aabe48b21acc", + }, + ], + "content": "My number is 4821. Your turn!", + "conversationId": "dd6c9cfd-2656-48ec-bd51-2139c1790d80", + "feedbackDisabled": false, + "id": "684b5396-4e91-4043-88e9-aabe48b21acc", + "input": { + "inputs": {}, + "query": "3306", + }, + "isAnswer": true, + "log": [ + { + "files": [], + "role": "user", + "text": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + }, + { + "files": [], + "role": "assistant", + "text": "Sure! My number is 54. Your turn!", + }, + { + "files": [], + "role": "user", + "text": "3306", + }, + { + "files": [], + "role": "assistant", + "text": "My number is 4821. Your turn!", + }, + ], + "message_files": [], + "more": { + "latency": "1.48", + "time": "09/11/2024 10:23 PM", + "tokens": 66, + }, + "parentMessageId": "question-684b5396-4e91-4043-88e9-aabe48b21acc", + "siblingIndex": 1, + "workflow_run_id": null, + }, + ], + "content": "3306", + "id": "question-684b5396-4e91-4043-88e9-aabe48b21acc", + "isAnswer": false, + "message_files": [], + "parentMessageId": "cd5affb0-7bc2-4a6f-be7e-25e74595c9dd", + }, + ], + "content": "Sure! My number is 54. Your turn!", + "conversationId": "dd6c9cfd-2656-48ec-bd51-2139c1790d80", + "feedbackDisabled": false, + "id": "cd5affb0-7bc2-4a6f-be7e-25e74595c9dd", + "input": { + "inputs": {}, + "query": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + }, + "isAnswer": true, + "log": [ + { + "files": [], + "role": "user", + "text": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + }, + { + "files": [], + "role": "assistant", + "text": "Sure! My number is 54. Your turn!", + }, + ], + "message_files": [], + "more": { + "latency": "1.52", + "time": "09/11/2024 09:50 PM", + "tokens": 46, + }, + "nextSibling": undefined, + "parentMessageId": "question-cd5affb0-7bc2-4a6f-be7e-25e74595c9dd", + "prevSibling": "ff4c2b43-48a5-47ad-9dc5-08b34ddba61b", + "siblingCount": 2, + "siblingIndex": 1, + "workflow_run_id": null, + }, + { + "children": [ + { + "agent_thoughts": [ + { + "chain_id": null, + "created_at": 1726107812, + "files": [], + "id": "5ca650f3-982c-4399-8b95-9ea241c76707", + "message_id": "684b5396-4e91-4043-88e9-aabe48b21acc", + "observation": "", + "position": 1, + "thought": "My number is 4821. Your turn!", + "tool": "", + "tool_input": "", + "tool_labels": {}, + }, + ], + "children": [ + { + "children": [ + { + "agent_thoughts": [ + { + "chain_id": null, + "created_at": 1726111024, + "files": [], + "id": "095cacab-afad-4387-a41d-1662578b8b13", + "message_id": "19904a7b-7494-4ed8-b72c-1d18668cea8c", + "observation": "", + "position": 1, + "thought": "My number is 1456. Your turn!", + "tool": "", + "tool_input": "", + "tool_labels": {}, + }, + ], + "children": [], + "content": "My number is 1456. Your turn!", + "conversationId": "dd6c9cfd-2656-48ec-bd51-2139c1790d80", + "feedbackDisabled": false, + "id": "19904a7b-7494-4ed8-b72c-1d18668cea8c", + "input": { + "inputs": {}, + "query": "1003", + }, + "isAnswer": true, + "log": [ + { + "files": [], + "role": "user", + "text": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + }, + { + "files": [], + "role": "assistant", + "text": "Sure! My number is 54. Your turn!", + }, + { + "files": [], + "role": "user", + "text": "3306", + }, + { + "files": [], + "role": "assistant", + "text": "My number is 4821. Your turn!", + }, + { + "files": [], + "role": "user", + "text": "1003", + }, + { + "files": [], + "role": "assistant", + "text": "My number is 1456. Your turn!", + }, + ], + "message_files": [], + "more": { + "latency": "1.38", + "time": "09/11/2024 11:17 PM", + "tokens": 86, + }, + "parentMessageId": "question-19904a7b-7494-4ed8-b72c-1d18668cea8c", + "siblingIndex": 0, + "workflow_run_id": null, + }, + ], + "content": "1003", + "id": "question-19904a7b-7494-4ed8-b72c-1d18668cea8c", + "isAnswer": false, + "message_files": [], + "parentMessageId": "684b5396-4e91-4043-88e9-aabe48b21acc", + }, + ], + "content": "My number is 4821. Your turn!", + "conversationId": "dd6c9cfd-2656-48ec-bd51-2139c1790d80", + "feedbackDisabled": false, + "id": "684b5396-4e91-4043-88e9-aabe48b21acc", + "input": { + "inputs": {}, + "query": "3306", + }, + "isAnswer": true, + "log": [ + { + "files": [], + "role": "user", + "text": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + }, + { + "files": [], + "role": "assistant", + "text": "Sure! My number is 54. Your turn!", + }, + { + "files": [], + "role": "user", + "text": "3306", + }, + { + "files": [], + "role": "assistant", + "text": "My number is 4821. Your turn!", + }, + ], + "message_files": [], + "more": { + "latency": "1.48", + "time": "09/11/2024 10:23 PM", + "tokens": 66, + }, + "parentMessageId": "question-684b5396-4e91-4043-88e9-aabe48b21acc", + "siblingIndex": 1, + "workflow_run_id": null, + }, + ], + "content": "3306", + "id": "question-684b5396-4e91-4043-88e9-aabe48b21acc", + "isAnswer": false, + "message_files": [], + "parentMessageId": "cd5affb0-7bc2-4a6f-be7e-25e74595c9dd", + }, + { + "agent_thoughts": [ + { + "chain_id": null, + "created_at": 1726107812, + "files": [], + "id": "5ca650f3-982c-4399-8b95-9ea241c76707", + "message_id": "684b5396-4e91-4043-88e9-aabe48b21acc", + "observation": "", + "position": 1, + "thought": "My number is 4821. Your turn!", + "tool": "", + "tool_input": "", + "tool_labels": {}, + }, + ], + "children": [ + { + "children": [ + { + "agent_thoughts": [ + { + "chain_id": null, + "created_at": 1726111024, + "files": [], + "id": "095cacab-afad-4387-a41d-1662578b8b13", + "message_id": "19904a7b-7494-4ed8-b72c-1d18668cea8c", + "observation": "", + "position": 1, + "thought": "My number is 1456. Your turn!", + "tool": "", + "tool_input": "", + "tool_labels": {}, + }, + ], + "children": [], + "content": "My number is 1456. Your turn!", + "conversationId": "dd6c9cfd-2656-48ec-bd51-2139c1790d80", + "feedbackDisabled": false, + "id": "19904a7b-7494-4ed8-b72c-1d18668cea8c", + "input": { + "inputs": {}, + "query": "1003", + }, + "isAnswer": true, + "log": [ + { + "files": [], + "role": "user", + "text": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + }, + { + "files": [], + "role": "assistant", + "text": "Sure! My number is 54. Your turn!", + }, + { + "files": [], + "role": "user", + "text": "3306", + }, + { + "files": [], + "role": "assistant", + "text": "My number is 4821. Your turn!", + }, + { + "files": [], + "role": "user", + "text": "1003", + }, + { + "files": [], + "role": "assistant", + "text": "My number is 1456. Your turn!", + }, + ], + "message_files": [], + "more": { + "latency": "1.38", + "time": "09/11/2024 11:17 PM", + "tokens": 86, + }, + "parentMessageId": "question-19904a7b-7494-4ed8-b72c-1d18668cea8c", + "siblingIndex": 0, + "workflow_run_id": null, + }, + ], + "content": "1003", + "id": "question-19904a7b-7494-4ed8-b72c-1d18668cea8c", + "isAnswer": false, + "message_files": [], + "parentMessageId": "684b5396-4e91-4043-88e9-aabe48b21acc", + }, + ], + "content": "My number is 4821. Your turn!", + "conversationId": "dd6c9cfd-2656-48ec-bd51-2139c1790d80", + "feedbackDisabled": false, + "id": "684b5396-4e91-4043-88e9-aabe48b21acc", + "input": { + "inputs": {}, + "query": "3306", + }, + "isAnswer": true, + "log": [ + { + "files": [], + "role": "user", + "text": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + }, + { + "files": [], + "role": "assistant", + "text": "Sure! My number is 54. Your turn!", + }, + { + "files": [], + "role": "user", + "text": "3306", + }, + { + "files": [], + "role": "assistant", + "text": "My number is 4821. Your turn!", + }, + ], + "message_files": [], + "more": { + "latency": "1.48", + "time": "09/11/2024 10:23 PM", + "tokens": 66, + }, + "nextSibling": undefined, + "parentMessageId": "question-684b5396-4e91-4043-88e9-aabe48b21acc", + "prevSibling": "324bce32-c98c-435d-a66b-bac974ebb5ed", + "siblingCount": 2, + "siblingIndex": 1, + "workflow_run_id": null, + }, + { + "children": [ + { + "agent_thoughts": [ + { + "chain_id": null, + "created_at": 1726111024, + "files": [], + "id": "095cacab-afad-4387-a41d-1662578b8b13", + "message_id": "19904a7b-7494-4ed8-b72c-1d18668cea8c", + "observation": "", + "position": 1, + "thought": "My number is 1456. Your turn!", + "tool": "", + "tool_input": "", + "tool_labels": {}, + }, + ], + "children": [], + "content": "My number is 1456. Your turn!", + "conversationId": "dd6c9cfd-2656-48ec-bd51-2139c1790d80", + "feedbackDisabled": false, + "id": "19904a7b-7494-4ed8-b72c-1d18668cea8c", + "input": { + "inputs": {}, + "query": "1003", + }, + "isAnswer": true, + "log": [ + { + "files": [], + "role": "user", + "text": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + }, + { + "files": [], + "role": "assistant", + "text": "Sure! My number is 54. Your turn!", + }, + { + "files": [], + "role": "user", + "text": "3306", + }, + { + "files": [], + "role": "assistant", + "text": "My number is 4821. Your turn!", + }, + { + "files": [], + "role": "user", + "text": "1003", + }, + { + "files": [], + "role": "assistant", + "text": "My number is 1456. Your turn!", + }, + ], + "message_files": [], + "more": { + "latency": "1.38", + "time": "09/11/2024 11:17 PM", + "tokens": 86, + }, + "parentMessageId": "question-19904a7b-7494-4ed8-b72c-1d18668cea8c", + "siblingIndex": 0, + "workflow_run_id": null, + }, + ], + "content": "1003", + "id": "question-19904a7b-7494-4ed8-b72c-1d18668cea8c", + "isAnswer": false, + "message_files": [], + "parentMessageId": "684b5396-4e91-4043-88e9-aabe48b21acc", + }, + { + "agent_thoughts": [ + { + "chain_id": null, + "created_at": 1726111024, + "files": [], + "id": "095cacab-afad-4387-a41d-1662578b8b13", + "message_id": "19904a7b-7494-4ed8-b72c-1d18668cea8c", + "observation": "", + "position": 1, + "thought": "My number is 1456. Your turn!", + "tool": "", + "tool_input": "", + "tool_labels": {}, + }, + ], + "children": [], + "content": "My number is 1456. Your turn!", + "conversationId": "dd6c9cfd-2656-48ec-bd51-2139c1790d80", + "feedbackDisabled": false, + "id": "19904a7b-7494-4ed8-b72c-1d18668cea8c", + "input": { + "inputs": {}, + "query": "1003", + }, + "isAnswer": true, + "log": [ + { + "files": [], + "role": "user", + "text": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + }, + { + "files": [], + "role": "assistant", + "text": "Sure! My number is 54. Your turn!", + }, + { + "files": [], + "role": "user", + "text": "3306", + }, + { + "files": [], + "role": "assistant", + "text": "My number is 4821. Your turn!", + }, + { + "files": [], + "role": "user", + "text": "1003", + }, + { + "files": [], + "role": "assistant", + "text": "My number is 1456. Your turn!", + }, + ], + "message_files": [], + "more": { + "latency": "1.38", + "time": "09/11/2024 11:17 PM", + "tokens": 86, + }, + "nextSibling": undefined, + "parentMessageId": "question-19904a7b-7494-4ed8-b72c-1d18668cea8c", + "prevSibling": undefined, + "siblingCount": 1, + "siblingIndex": 0, + "workflow_run_id": null, + }, +] +`; + +exports[`build chat item tree and get thread messages should work with real world messages 1`] = ` +[ + { + "children": [ + { + "agent_thoughts": [ + { + "chain_id": null, + "created_at": 1726105791, + "files": [], + "id": "f9d7ff7c-3a3b-4d9a-a289-657817f4caff", + "message_id": "ff4c2b43-48a5-47ad-9dc5-08b34ddba61b", + "observation": "", + "position": 1, + "thought": "Sure, I'll play! My number is 57. Your turn!", + "tool": "", + "tool_input": "", + "tool_labels": {}, + }, + ], + "children": [ + { + "children": [ + { + "agent_thoughts": [ + { + "chain_id": null, + "created_at": 1726105795, + "files": [], + "id": "f61a3fce-37ac-4f9d-9935-95f97e598dfe", + "message_id": "73bbad14-d915-499d-87bf-0df14d40779d", + "observation": "", + "position": 1, + "thought": "I choose 83. What's your next number?", + "tool": "", + "tool_input": "", + "tool_labels": {}, + }, + ], + "children": [ + { + "children": [ + { + "agent_thoughts": [ + { + "chain_id": null, + "created_at": 1726105799, + "files": [], + "id": "9730d587-9268-4683-9dd9-91a1cab9510b", + "message_id": "4c5d0841-1206-463e-95d8-71f812877658", + "observation": "", + "position": 1, + "thought": "I'll go with 112. Your turn!", + "tool": "", + "tool_input": "", + "tool_labels": {}, + }, + ], + "children": [], + "content": "I'll go with 112. Your turn!", + "conversationId": "dd6c9cfd-2656-48ec-bd51-2139c1790d80", + "feedbackDisabled": false, + "id": "4c5d0841-1206-463e-95d8-71f812877658", + "input": { + "inputs": {}, + "query": "99", + }, + "isAnswer": true, + "log": [ + { + "files": [], + "role": "user", + "text": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + }, + { + "files": [], + "role": "assistant", + "text": "Sure, I'll play! My number is 57. Your turn!", + }, + { + "files": [], + "role": "user", + "text": "58", + }, + { + "files": [], + "role": "assistant", + "text": "I choose 83. What's your next number?", + }, + { + "files": [], + "role": "user", + "text": "99", + }, + { + "files": [], + "role": "assistant", + "text": "I'll go with 112. Your turn!", + }, + ], + "message_files": [], + "more": { + "latency": "1.49", + "time": "09/11/2024 09:50 PM", + "tokens": 86, + }, + "parentMessageId": "question-4c5d0841-1206-463e-95d8-71f812877658", + "siblingIndex": 0, + "workflow_run_id": null, + }, + ], + "content": "99", + "id": "question-4c5d0841-1206-463e-95d8-71f812877658", + "isAnswer": false, + "message_files": [], + "parentMessageId": "73bbad14-d915-499d-87bf-0df14d40779d", + }, + ], + "content": "I choose 83. What's your next number?", + "conversationId": "dd6c9cfd-2656-48ec-bd51-2139c1790d80", + "feedbackDisabled": false, + "id": "73bbad14-d915-499d-87bf-0df14d40779d", + "input": { + "inputs": {}, + "query": "58", + }, + "isAnswer": true, + "log": [ + { + "files": [], + "role": "user", + "text": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + }, + { + "files": [], + "role": "assistant", + "text": "Sure, I'll play! My number is 57. Your turn!", + }, + { + "files": [], + "role": "user", + "text": "58", + }, + { + "files": [], + "role": "assistant", + "text": "I choose 83. What's your next number?", + }, + ], + "message_files": [], + "more": { + "latency": "1.33", + "time": "09/11/2024 09:49 PM", + "tokens": 68, + }, + "parentMessageId": "question-73bbad14-d915-499d-87bf-0df14d40779d", + "siblingIndex": 0, + "workflow_run_id": null, + }, + ], + "content": "58", + "id": "question-73bbad14-d915-499d-87bf-0df14d40779d", + "isAnswer": false, + "message_files": [], + "parentMessageId": "ff4c2b43-48a5-47ad-9dc5-08b34ddba61b", + }, + ], + "content": "Sure, I'll play! My number is 57. Your turn!", + "conversationId": "dd6c9cfd-2656-48ec-bd51-2139c1790d80", + "feedbackDisabled": false, + "id": "ff4c2b43-48a5-47ad-9dc5-08b34ddba61b", + "input": { + "inputs": {}, + "query": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + }, + "isAnswer": true, + "log": [ + { + "files": [], + "role": "user", + "text": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + }, + { + "files": [], + "role": "assistant", + "text": "Sure, I'll play! My number is 57. Your turn!", + }, + ], + "message_files": [], + "more": { + "latency": "1.56", + "time": "09/11/2024 09:49 PM", + "tokens": 49, + }, + "parentMessageId": "question-ff4c2b43-48a5-47ad-9dc5-08b34ddba61b", + "siblingIndex": 0, + "workflow_run_id": null, + }, + ], + "content": "Let's play a game, I say a number , and you response me with another bigger, yet random-looking number. I'll start first, 38", + "id": "question-ff4c2b43-48a5-47ad-9dc5-08b34ddba61b", + "isAnswer": false, + "message_files": [], + }, + { + "children": [ + { + "agent_thoughts": [ + { + "chain_id": null, + "created_at": 1726105809, + "files": [], + "id": "1019cd79-d141-4f9f-880a-fc1441cfd802", + "message_id": "cd5affb0-7bc2-4a6f-be7e-25e74595c9dd", + "observation": "", + "position": 1, + "thought": "Sure! My number is 54. Your turn!", + "tool": "", + "tool_input": "", + "tool_labels": {}, + }, + ], + "children": [ + { + "children": [ + { + "agent_thoughts": [ + { + "chain_id": null, + "created_at": 1726105822, + "files": [], + "id": "0773bec7-b992-4a53-92b2-20ebaeae8798", + "message_id": "324bce32-c98c-435d-a66b-bac974ebb5ed", + "observation": "", + "position": 1, + "thought": "My number is 4729. Your turn!", + "tool": "", + "tool_input": "", + "tool_labels": {}, + }, + ], + "children": [], + "content": "My number is 4729. Your turn!", + "conversationId": "dd6c9cfd-2656-48ec-bd51-2139c1790d80", + "feedbackDisabled": false, + "id": "324bce32-c98c-435d-a66b-bac974ebb5ed", + "input": { + "inputs": {}, + "query": "3306", + }, + "isAnswer": true, + "log": [ + { + "files": [], + "role": "user", + "text": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + }, + { + "files": [], + "role": "assistant", + "text": "Sure! My number is 54. Your turn!", + }, + { + "files": [], + "role": "user", + "text": "3306", + }, + { + "files": [], + "role": "assistant", + "text": "My number is 4729. Your turn!", + }, + ], + "message_files": [], + "more": { + "latency": "1.30", + "time": "09/11/2024 09:50 PM", + "tokens": 66, + }, + "parentMessageId": "question-324bce32-c98c-435d-a66b-bac974ebb5ed", + "siblingIndex": 0, + "workflow_run_id": null, + }, + ], + "content": "3306", + "id": "question-324bce32-c98c-435d-a66b-bac974ebb5ed", + "isAnswer": false, + "message_files": [], + "parentMessageId": "cd5affb0-7bc2-4a6f-be7e-25e74595c9dd", + }, + { + "children": [ + { + "agent_thoughts": [ + { + "chain_id": null, + "created_at": 1726107812, + "files": [], + "id": "5ca650f3-982c-4399-8b95-9ea241c76707", + "message_id": "684b5396-4e91-4043-88e9-aabe48b21acc", + "observation": "", + "position": 1, + "thought": "My number is 4821. Your turn!", + "tool": "", + "tool_input": "", + "tool_labels": {}, + }, + ], + "children": [ + { + "children": [ + { + "agent_thoughts": [ + { + "chain_id": null, + "created_at": 1726111024, + "files": [], + "id": "095cacab-afad-4387-a41d-1662578b8b13", + "message_id": "19904a7b-7494-4ed8-b72c-1d18668cea8c", + "observation": "", + "position": 1, + "thought": "My number is 1456. Your turn!", + "tool": "", + "tool_input": "", + "tool_labels": {}, + }, + ], + "children": [], + "content": "My number is 1456. Your turn!", + "conversationId": "dd6c9cfd-2656-48ec-bd51-2139c1790d80", + "feedbackDisabled": false, + "id": "19904a7b-7494-4ed8-b72c-1d18668cea8c", + "input": { + "inputs": {}, + "query": "1003", + }, + "isAnswer": true, + "log": [ + { + "files": [], + "role": "user", + "text": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + }, + { + "files": [], + "role": "assistant", + "text": "Sure! My number is 54. Your turn!", + }, + { + "files": [], + "role": "user", + "text": "3306", + }, + { + "files": [], + "role": "assistant", + "text": "My number is 4821. Your turn!", + }, + { + "files": [], + "role": "user", + "text": "1003", + }, + { + "files": [], + "role": "assistant", + "text": "My number is 1456. Your turn!", + }, + ], + "message_files": [], + "more": { + "latency": "1.38", + "time": "09/11/2024 11:17 PM", + "tokens": 86, + }, + "parentMessageId": "question-19904a7b-7494-4ed8-b72c-1d18668cea8c", + "siblingIndex": 0, + "workflow_run_id": null, + }, + ], + "content": "1003", + "id": "question-19904a7b-7494-4ed8-b72c-1d18668cea8c", + "isAnswer": false, + "message_files": [], + "parentMessageId": "684b5396-4e91-4043-88e9-aabe48b21acc", + }, + ], + "content": "My number is 4821. Your turn!", + "conversationId": "dd6c9cfd-2656-48ec-bd51-2139c1790d80", + "feedbackDisabled": false, + "id": "684b5396-4e91-4043-88e9-aabe48b21acc", + "input": { + "inputs": {}, + "query": "3306", + }, + "isAnswer": true, + "log": [ + { + "files": [], + "role": "user", + "text": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + }, + { + "files": [], + "role": "assistant", + "text": "Sure! My number is 54. Your turn!", + }, + { + "files": [], + "role": "user", + "text": "3306", + }, + { + "files": [], + "role": "assistant", + "text": "My number is 4821. Your turn!", + }, + ], + "message_files": [], + "more": { + "latency": "1.48", + "time": "09/11/2024 10:23 PM", + "tokens": 66, + }, + "parentMessageId": "question-684b5396-4e91-4043-88e9-aabe48b21acc", + "siblingIndex": 1, + "workflow_run_id": null, + }, + ], + "content": "3306", + "id": "question-684b5396-4e91-4043-88e9-aabe48b21acc", + "isAnswer": false, + "message_files": [], + "parentMessageId": "cd5affb0-7bc2-4a6f-be7e-25e74595c9dd", + }, + ], + "content": "Sure! My number is 54. Your turn!", + "conversationId": "dd6c9cfd-2656-48ec-bd51-2139c1790d80", + "feedbackDisabled": false, + "id": "cd5affb0-7bc2-4a6f-be7e-25e74595c9dd", + "input": { + "inputs": {}, + "query": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + }, + "isAnswer": true, + "log": [ + { + "files": [], + "role": "user", + "text": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + }, + { + "files": [], + "role": "assistant", + "text": "Sure! My number is 54. Your turn!", + }, + ], + "message_files": [], + "more": { + "latency": "1.52", + "time": "09/11/2024 09:50 PM", + "tokens": 46, + }, + "parentMessageId": "question-cd5affb0-7bc2-4a6f-be7e-25e74595c9dd", + "siblingIndex": 1, + "workflow_run_id": null, + }, + ], + "content": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + "id": "question-cd5affb0-7bc2-4a6f-be7e-25e74595c9dd", + "isAnswer": false, + "message_files": [], + }, +] +`; diff --git a/web/app/components/base/chat/__tests__/branchedTestMessages.json b/web/app/components/base/chat/__tests__/branchedTestMessages.json new file mode 100644 index 0000000000..30e0a82cb5 --- /dev/null +++ b/web/app/components/base/chat/__tests__/branchedTestMessages.json @@ -0,0 +1,42 @@ +[ + { + "id": "question-1", + "isAnswer": false, + "parentMessageId": null + }, + { + "id": "1", + "isAnswer": true, + "parentMessageId": "question-1" + }, + { + "id": "question-2", + "isAnswer": false, + "parentMessageId": "1" + }, + { + "id": "2", + "isAnswer": true, + "parentMessageId": "question-2" + }, + { + "id": "question-3", + "isAnswer": false, + "parentMessageId": "2" + }, + { + "id": "3", + "isAnswer": true, + "parentMessageId": "question-3" + }, + { + "id": "question-4", + "isAnswer": false, + "parentMessageId": "1" + }, + { + "id": "4", + "isAnswer": true, + "parentMessageId": "question-4" + } +] diff --git a/web/app/components/base/chat/__tests__/legacyTestMessages.json b/web/app/components/base/chat/__tests__/legacyTestMessages.json new file mode 100644 index 0000000000..2dab58985a --- /dev/null +++ b/web/app/components/base/chat/__tests__/legacyTestMessages.json @@ -0,0 +1,42 @@ +[ + { + "id": "question-1", + "isAnswer": false, + "parentMessageId": "00000000-0000-0000-0000-000000000000" + }, + { + "id": "1", + "isAnswer": true, + "parentMessageId": "question-1" + }, + { + "id": "question-2", + "isAnswer": false, + "parentMessageId": "00000000-0000-0000-0000-000000000000" + }, + { + "id": "2", + "isAnswer": true, + "parentMessageId": "question-2" + }, + { + "id": "question-3", + "isAnswer": false, + "parentMessageId": "00000000-0000-0000-0000-000000000000" + }, + { + "id": "3", + "isAnswer": true, + "parentMessageId": "question-3" + }, + { + "id": "question-4", + "isAnswer": false, + "parentMessageId": "00000000-0000-0000-0000-000000000000" + }, + { + "id": "4", + "isAnswer": true, + "parentMessageId": "question-4" + } +] diff --git a/web/app/components/base/chat/__tests__/mixedTestMessages.json b/web/app/components/base/chat/__tests__/mixedTestMessages.json new file mode 100644 index 0000000000..14789d9518 --- /dev/null +++ b/web/app/components/base/chat/__tests__/mixedTestMessages.json @@ -0,0 +1,42 @@ +[ + { + "id": "question-1", + "isAnswer": false, + "parentMessageId": "00000000-0000-0000-0000-000000000000" + }, + { + "id": "1", + "isAnswer": true, + "parentMessageId": "question-1" + }, + { + "id": "question-2", + "isAnswer": false, + "parentMessageId": "00000000-0000-0000-0000-000000000000" + }, + { + "id": "2", + "isAnswer": true, + "parentMessageId": "question-2" + }, + { + "id": "question-3", + "isAnswer": false, + "parentMessageId": "2" + }, + { + "id": "3", + "isAnswer": true, + "parentMessageId": "question-3" + }, + { + "id": "question-4", + "isAnswer": false, + "parentMessageId": "1" + }, + { + "id": "4", + "isAnswer": true, + "parentMessageId": "question-4" + } +] diff --git a/web/app/components/base/chat/__tests__/multiRootNodesMessages.json b/web/app/components/base/chat/__tests__/multiRootNodesMessages.json new file mode 100644 index 0000000000..782ccb7f94 --- /dev/null +++ b/web/app/components/base/chat/__tests__/multiRootNodesMessages.json @@ -0,0 +1,52 @@ +[ + { + "id": "question-1", + "isAnswer": false, + "parentMessageId": null + }, + { + "id": "1", + "isAnswer": true, + "parentMessageId": "question-1" + }, + { + "id": "question-2", + "isAnswer": false, + "parentMessageId": "1" + }, + { + "id": "2", + "isAnswer": true, + "parentMessageId": "question-2" + }, + { + "id": "question-3", + "isAnswer": false, + "parentMessageId": "2" + }, + { + "id": "3", + "isAnswer": true, + "parentMessageId": "question-3" + }, + { + "id": "question-4", + "isAnswer": false, + "parentMessageId": "1" + }, + { + "id": "4", + "isAnswer": true, + "parentMessageId": "question-4" + }, + { + "id": "question-5", + "isAnswer": false, + "parentMessageId": null + }, + { + "id": "5", + "isAnswer": true, + "parentMessageId": "question-5" + } +] diff --git a/web/app/components/base/chat/__tests__/multiRootNodesWithLegacyTestMessages.json b/web/app/components/base/chat/__tests__/multiRootNodesWithLegacyTestMessages.json new file mode 100644 index 0000000000..5eadc726e5 --- /dev/null +++ b/web/app/components/base/chat/__tests__/multiRootNodesWithLegacyTestMessages.json @@ -0,0 +1,52 @@ +[ + { + "id": "question-1", + "isAnswer": false, + "parentMessageId": "00000000-0000-0000-0000-000000000000" + }, + { + "id": "1", + "isAnswer": true, + "parentMessageId": "question-1" + }, + { + "id": "question-2", + "isAnswer": false, + "parentMessageId": "00000000-0000-0000-0000-000000000000" + }, + { + "id": "2", + "isAnswer": true, + "parentMessageId": "question-2" + }, + { + "id": "question-3", + "isAnswer": false, + "parentMessageId": "00000000-0000-0000-0000-000000000000" + }, + { + "id": "3", + "isAnswer": true, + "parentMessageId": "question-3" + }, + { + "id": "question-4", + "isAnswer": false, + "parentMessageId": "1" + }, + { + "id": "4", + "isAnswer": true, + "parentMessageId": "question-4" + }, + { + "id": "question-5", + "isAnswer": false, + "parentMessageId": null + }, + { + "id": "5", + "isAnswer": true, + "parentMessageId": "question-5" + } +] diff --git a/web/app/components/base/chat/__tests__/realWorldMessages.json b/web/app/components/base/chat/__tests__/realWorldMessages.json new file mode 100644 index 0000000000..858052c77f --- /dev/null +++ b/web/app/components/base/chat/__tests__/realWorldMessages.json @@ -0,0 +1,441 @@ +[ + { + "id": "question-ff4c2b43-48a5-47ad-9dc5-08b34ddba61b", + "content": "Let's play a game, I say a number , and you response me with another bigger, yet random-looking number. I'll start first, 38", + "isAnswer": false, + "message_files": [] + }, + { + "id": "ff4c2b43-48a5-47ad-9dc5-08b34ddba61b", + "content": "Sure, I'll play! My number is 57. Your turn!", + "agent_thoughts": [ + { + "id": "f9d7ff7c-3a3b-4d9a-a289-657817f4caff", + "chain_id": null, + "message_id": "ff4c2b43-48a5-47ad-9dc5-08b34ddba61b", + "position": 1, + "thought": "Sure, I'll play! My number is 57. Your turn!", + "tool": "", + "tool_labels": {}, + "tool_input": "", + "created_at": 1726105791, + "observation": "", + "files": [] + } + ], + "feedbackDisabled": false, + "isAnswer": true, + "message_files": [], + "log": [ + { + "role": "user", + "text": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + "files": [] + }, + { + "role": "assistant", + "text": "Sure, I'll play! My number is 57. Your turn!", + "files": [] + } + ], + "workflow_run_id": null, + "conversationId": "dd6c9cfd-2656-48ec-bd51-2139c1790d80", + "input": { + "inputs": {}, + "query": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38" + }, + "more": { + "time": "09/11/2024 09:49 PM", + "tokens": 49, + "latency": "1.56" + }, + "parentMessageId": "question-ff4c2b43-48a5-47ad-9dc5-08b34ddba61b" + }, + { + "id": "question-73bbad14-d915-499d-87bf-0df14d40779d", + "content": "58", + "isAnswer": false, + "message_files": [], + "parentMessageId": "ff4c2b43-48a5-47ad-9dc5-08b34ddba61b" + }, + { + "id": "73bbad14-d915-499d-87bf-0df14d40779d", + "content": "I choose 83. What's your next number?", + "agent_thoughts": [ + { + "id": "f61a3fce-37ac-4f9d-9935-95f97e598dfe", + "chain_id": null, + "message_id": "73bbad14-d915-499d-87bf-0df14d40779d", + "position": 1, + "thought": "I choose 83. What's your next number?", + "tool": "", + "tool_labels": {}, + "tool_input": "", + "created_at": 1726105795, + "observation": "", + "files": [] + } + ], + "feedbackDisabled": false, + "isAnswer": true, + "message_files": [], + "log": [ + { + "role": "user", + "text": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + "files": [] + }, + { + "role": "assistant", + "text": "Sure, I'll play! My number is 57. Your turn!", + "files": [] + }, + { + "role": "user", + "text": "58", + "files": [] + }, + { + "role": "assistant", + "text": "I choose 83. What's your next number?", + "files": [] + } + ], + "workflow_run_id": null, + "conversationId": "dd6c9cfd-2656-48ec-bd51-2139c1790d80", + "input": { + "inputs": {}, + "query": "58" + }, + "more": { + "time": "09/11/2024 09:49 PM", + "tokens": 68, + "latency": "1.33" + }, + "parentMessageId": "question-73bbad14-d915-499d-87bf-0df14d40779d" + }, + { + "id": "question-4c5d0841-1206-463e-95d8-71f812877658", + "content": "99", + "isAnswer": false, + "message_files": [], + "parentMessageId": "73bbad14-d915-499d-87bf-0df14d40779d" + }, + { + "id": "4c5d0841-1206-463e-95d8-71f812877658", + "content": "I'll go with 112. Your turn!", + "agent_thoughts": [ + { + "id": "9730d587-9268-4683-9dd9-91a1cab9510b", + "chain_id": null, + "message_id": "4c5d0841-1206-463e-95d8-71f812877658", + "position": 1, + "thought": "I'll go with 112. Your turn!", + "tool": "", + "tool_labels": {}, + "tool_input": "", + "created_at": 1726105799, + "observation": "", + "files": [] + } + ], + "feedbackDisabled": false, + "isAnswer": true, + "message_files": [], + "log": [ + { + "role": "user", + "text": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + "files": [] + }, + { + "role": "assistant", + "text": "Sure, I'll play! My number is 57. Your turn!", + "files": [] + }, + { + "role": "user", + "text": "58", + "files": [] + }, + { + "role": "assistant", + "text": "I choose 83. What's your next number?", + "files": [] + }, + { + "role": "user", + "text": "99", + "files": [] + }, + { + "role": "assistant", + "text": "I'll go with 112. Your turn!", + "files": [] + } + ], + "workflow_run_id": null, + "conversationId": "dd6c9cfd-2656-48ec-bd51-2139c1790d80", + "input": { + "inputs": {}, + "query": "99" + }, + "more": { + "time": "09/11/2024 09:50 PM", + "tokens": 86, + "latency": "1.49" + }, + "parentMessageId": "question-4c5d0841-1206-463e-95d8-71f812877658" + }, + { + "id": "question-cd5affb0-7bc2-4a6f-be7e-25e74595c9dd", + "content": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + "isAnswer": false, + "message_files": [] + }, + { + "id": "cd5affb0-7bc2-4a6f-be7e-25e74595c9dd", + "content": "Sure! My number is 54. Your turn!", + "agent_thoughts": [ + { + "id": "1019cd79-d141-4f9f-880a-fc1441cfd802", + "chain_id": null, + "message_id": "cd5affb0-7bc2-4a6f-be7e-25e74595c9dd", + "position": 1, + "thought": "Sure! My number is 54. Your turn!", + "tool": "", + "tool_labels": {}, + "tool_input": "", + "created_at": 1726105809, + "observation": "", + "files": [] + } + ], + "feedbackDisabled": false, + "isAnswer": true, + "message_files": [], + "log": [ + { + "role": "user", + "text": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + "files": [] + }, + { + "role": "assistant", + "text": "Sure! My number is 54. Your turn!", + "files": [] + } + ], + "workflow_run_id": null, + "conversationId": "dd6c9cfd-2656-48ec-bd51-2139c1790d80", + "input": { + "inputs": {}, + "query": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38" + }, + "more": { + "time": "09/11/2024 09:50 PM", + "tokens": 46, + "latency": "1.52" + }, + "parentMessageId": "question-cd5affb0-7bc2-4a6f-be7e-25e74595c9dd" + }, + { + "id": "question-324bce32-c98c-435d-a66b-bac974ebb5ed", + "content": "3306", + "isAnswer": false, + "message_files": [], + "parentMessageId": "cd5affb0-7bc2-4a6f-be7e-25e74595c9dd" + }, + { + "id": "324bce32-c98c-435d-a66b-bac974ebb5ed", + "content": "My number is 4729. Your turn!", + "agent_thoughts": [ + { + "id": "0773bec7-b992-4a53-92b2-20ebaeae8798", + "chain_id": null, + "message_id": "324bce32-c98c-435d-a66b-bac974ebb5ed", + "position": 1, + "thought": "My number is 4729. Your turn!", + "tool": "", + "tool_labels": {}, + "tool_input": "", + "created_at": 1726105822, + "observation": "", + "files": [] + } + ], + "feedbackDisabled": false, + "isAnswer": true, + "message_files": [], + "log": [ + { + "role": "user", + "text": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + "files": [] + }, + { + "role": "assistant", + "text": "Sure! My number is 54. Your turn!", + "files": [] + }, + { + "role": "user", + "text": "3306", + "files": [] + }, + { + "role": "assistant", + "text": "My number is 4729. Your turn!", + "files": [] + } + ], + "workflow_run_id": null, + "conversationId": "dd6c9cfd-2656-48ec-bd51-2139c1790d80", + "input": { + "inputs": {}, + "query": "3306" + }, + "more": { + "time": "09/11/2024 09:50 PM", + "tokens": 66, + "latency": "1.30" + }, + "parentMessageId": "question-324bce32-c98c-435d-a66b-bac974ebb5ed" + }, + { + "id": "question-684b5396-4e91-4043-88e9-aabe48b21acc", + "content": "3306", + "isAnswer": false, + "message_files": [], + "parentMessageId": "cd5affb0-7bc2-4a6f-be7e-25e74595c9dd" + }, + { + "id": "684b5396-4e91-4043-88e9-aabe48b21acc", + "content": "My number is 4821. Your turn!", + "agent_thoughts": [ + { + "id": "5ca650f3-982c-4399-8b95-9ea241c76707", + "chain_id": null, + "message_id": "684b5396-4e91-4043-88e9-aabe48b21acc", + "position": 1, + "thought": "My number is 4821. Your turn!", + "tool": "", + "tool_labels": {}, + "tool_input": "", + "created_at": 1726107812, + "observation": "", + "files": [] + } + ], + "feedbackDisabled": false, + "isAnswer": true, + "message_files": [], + "log": [ + { + "role": "user", + "text": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + "files": [] + }, + { + "role": "assistant", + "text": "Sure! My number is 54. Your turn!", + "files": [] + }, + { + "role": "user", + "text": "3306", + "files": [] + }, + { + "role": "assistant", + "text": "My number is 4821. Your turn!", + "files": [] + } + ], + "workflow_run_id": null, + "conversationId": "dd6c9cfd-2656-48ec-bd51-2139c1790d80", + "input": { + "inputs": {}, + "query": "3306" + }, + "more": { + "time": "09/11/2024 10:23 PM", + "tokens": 66, + "latency": "1.48" + }, + "parentMessageId": "question-684b5396-4e91-4043-88e9-aabe48b21acc" + }, + { + "id": "question-19904a7b-7494-4ed8-b72c-1d18668cea8c", + "content": "1003", + "isAnswer": false, + "message_files": [], + "parentMessageId": "684b5396-4e91-4043-88e9-aabe48b21acc" + }, + { + "id": "19904a7b-7494-4ed8-b72c-1d18668cea8c", + "content": "My number is 1456. Your turn!", + "agent_thoughts": [ + { + "id": "095cacab-afad-4387-a41d-1662578b8b13", + "chain_id": null, + "message_id": "19904a7b-7494-4ed8-b72c-1d18668cea8c", + "position": 1, + "thought": "My number is 1456. Your turn!", + "tool": "", + "tool_labels": {}, + "tool_input": "", + "created_at": 1726111024, + "observation": "", + "files": [] + } + ], + "feedbackDisabled": false, + "isAnswer": true, + "message_files": [], + "log": [ + { + "role": "user", + "text": "Let's play a game, I say a number , and you response me with another bigger, yet randomly number. I'll start first, 38", + "files": [] + }, + { + "role": "assistant", + "text": "Sure! My number is 54. Your turn!", + "files": [] + }, + { + "role": "user", + "text": "3306", + "files": [] + }, + { + "role": "assistant", + "text": "My number is 4821. Your turn!", + "files": [] + }, + { + "role": "user", + "text": "1003", + "files": [] + }, + { + "role": "assistant", + "text": "My number is 1456. Your turn!", + "files": [] + } + ], + "workflow_run_id": null, + "conversationId": "dd6c9cfd-2656-48ec-bd51-2139c1790d80", + "input": { + "inputs": {}, + "query": "1003" + }, + "more": { + "time": "09/11/2024 11:17 PM", + "tokens": 86, + "latency": "1.38" + }, + "parentMessageId": "question-19904a7b-7494-4ed8-b72c-1d18668cea8c" + } +] diff --git a/web/app/components/base/chat/__tests__/utils.spec.ts b/web/app/components/base/chat/__tests__/utils.spec.ts new file mode 100644 index 0000000000..c602ac8a99 --- /dev/null +++ b/web/app/components/base/chat/__tests__/utils.spec.ts @@ -0,0 +1,258 @@ +import { get } from 'lodash' +import { buildChatItemTree, getThreadMessages } from '../utils' +import type { ChatItemInTree } from '../types' +import branchedTestMessages from './branchedTestMessages.json' +import legacyTestMessages from './legacyTestMessages.json' +import mixedTestMessages from './mixedTestMessages.json' +import multiRootNodesMessages from './multiRootNodesMessages.json' +import multiRootNodesWithLegacyTestMessages from './multiRootNodesWithLegacyTestMessages.json' +import realWorldMessages from './realWorldMessages.json' + +function visitNode(tree: ChatItemInTree | ChatItemInTree[], path: string): ChatItemInTree { + return get(tree, path) +} + +describe('build chat item tree and get thread messages', () => { + const tree1 = buildChatItemTree(branchedTestMessages as ChatItemInTree[]) + + it('should build chat item tree1', () => { + const a1 = visitNode(tree1, '0.children.0') + expect(a1.id).toBe('1') + expect(a1.children).toHaveLength(2) + + const a2 = visitNode(a1, 'children.0.children.0') + expect(a2.id).toBe('2') + expect(a2.siblingIndex).toBe(0) + + const a3 = visitNode(a2, 'children.0.children.0') + expect(a3.id).toBe('3') + + const a4 = visitNode(a1, 'children.1.children.0') + expect(a4.id).toBe('4') + expect(a4.siblingIndex).toBe(1) + }) + + it('should get thread messages from tree1, using the last message as the target', () => { + const threadChatItems1_1 = getThreadMessages(tree1) + expect(threadChatItems1_1).toHaveLength(4) + + const q1 = visitNode(threadChatItems1_1, '0') + const a1 = visitNode(threadChatItems1_1, '1') + const q4 = visitNode(threadChatItems1_1, '2') + const a4 = visitNode(threadChatItems1_1, '3') + + expect(q1.id).toBe('question-1') + expect(a1.id).toBe('1') + expect(q4.id).toBe('question-4') + expect(a4.id).toBe('4') + + expect(a4.siblingCount).toBe(2) + expect(a4.siblingIndex).toBe(1) + }) + + it('should get thread messages from tree1, using the message with id 3 as the target', () => { + const threadChatItems1_2 = getThreadMessages(tree1, '3') + expect(threadChatItems1_2).toHaveLength(6) + + const q1 = visitNode(threadChatItems1_2, '0') + const a1 = visitNode(threadChatItems1_2, '1') + const q2 = visitNode(threadChatItems1_2, '2') + const a2 = visitNode(threadChatItems1_2, '3') + const q3 = visitNode(threadChatItems1_2, '4') + const a3 = visitNode(threadChatItems1_2, '5') + + expect(q1.id).toBe('question-1') + expect(a1.id).toBe('1') + expect(q2.id).toBe('question-2') + expect(a2.id).toBe('2') + expect(q3.id).toBe('question-3') + expect(a3.id).toBe('3') + + expect(a2.siblingCount).toBe(2) + expect(a2.siblingIndex).toBe(0) + }) + + const tree2 = buildChatItemTree(legacyTestMessages as ChatItemInTree[]) + it('should work with legacy chat items', () => { + expect(tree2).toHaveLength(1) + const q1 = visitNode(tree2, '0') + const a1 = visitNode(q1, 'children.0') + const q2 = visitNode(a1, 'children.0') + const a2 = visitNode(q2, 'children.0') + const q3 = visitNode(a2, 'children.0') + const a3 = visitNode(q3, 'children.0') + const q4 = visitNode(a3, 'children.0') + const a4 = visitNode(q4, 'children.0') + + expect(q1.id).toBe('question-1') + expect(a1.id).toBe('1') + expect(q2.id).toBe('question-2') + expect(a2.id).toBe('2') + expect(q3.id).toBe('question-3') + expect(a3.id).toBe('3') + expect(q4.id).toBe('question-4') + expect(a4.id).toBe('4') + }) + + it('should get thread messages from tree2, using the last message as the target', () => { + const threadMessages2 = getThreadMessages(tree2) + expect(threadMessages2).toHaveLength(8) + + const q1 = visitNode(threadMessages2, '0') + const a1 = visitNode(threadMessages2, '1') + const q2 = visitNode(threadMessages2, '2') + const a2 = visitNode(threadMessages2, '3') + const q3 = visitNode(threadMessages2, '4') + const a3 = visitNode(threadMessages2, '5') + const q4 = visitNode(threadMessages2, '6') + const a4 = visitNode(threadMessages2, '7') + + expect(q1.id).toBe('question-1') + expect(a1.id).toBe('1') + expect(q2.id).toBe('question-2') + expect(a2.id).toBe('2') + expect(q3.id).toBe('question-3') + expect(a3.id).toBe('3') + expect(q4.id).toBe('question-4') + expect(a4.id).toBe('4') + + expect(a1.siblingCount).toBe(1) + expect(a1.siblingIndex).toBe(0) + expect(a2.siblingCount).toBe(1) + expect(a2.siblingIndex).toBe(0) + expect(a3.siblingCount).toBe(1) + expect(a3.siblingIndex).toBe(0) + expect(a4.siblingCount).toBe(1) + expect(a4.siblingIndex).toBe(0) + }) + + const tree3 = buildChatItemTree(mixedTestMessages as ChatItemInTree[]) + it('should build mixed chat items tree', () => { + expect(tree3).toHaveLength(1) + + const a1 = visitNode(tree3, '0.children.0') + expect(a1.id).toBe('1') + expect(a1.children).toHaveLength(2) + + const a2 = visitNode(a1, 'children.0.children.0') + expect(a2.id).toBe('2') + expect(a2.siblingIndex).toBe(0) + + const a3 = visitNode(a2, 'children.0.children.0') + expect(a3.id).toBe('3') + + const a4 = visitNode(a1, 'children.1.children.0') + expect(a4.id).toBe('4') + expect(a4.siblingIndex).toBe(1) + }) + + it('should get thread messages from tree3, using the last message as the target', () => { + const threadMessages3_1 = getThreadMessages(tree3) + expect(threadMessages3_1).toHaveLength(4) + + const q1 = visitNode(threadMessages3_1, '0') + const a1 = visitNode(threadMessages3_1, '1') + const q4 = visitNode(threadMessages3_1, '2') + const a4 = visitNode(threadMessages3_1, '3') + + expect(q1.id).toBe('question-1') + expect(a1.id).toBe('1') + expect(q4.id).toBe('question-4') + expect(a4.id).toBe('4') + + expect(a4.siblingCount).toBe(2) + expect(a4.siblingIndex).toBe(1) + }) + + it('should get thread messages from tree3, using the message with id 3 as the target', () => { + const threadMessages3_2 = getThreadMessages(tree3, '3') + expect(threadMessages3_2).toHaveLength(6) + + const q1 = visitNode(threadMessages3_2, '0') + const a1 = visitNode(threadMessages3_2, '1') + const q2 = visitNode(threadMessages3_2, '2') + const a2 = visitNode(threadMessages3_2, '3') + const q3 = visitNode(threadMessages3_2, '4') + const a3 = visitNode(threadMessages3_2, '5') + + expect(q1.id).toBe('question-1') + expect(a1.id).toBe('1') + expect(q2.id).toBe('question-2') + expect(a2.id).toBe('2') + expect(q3.id).toBe('question-3') + expect(a3.id).toBe('3') + + expect(a2.siblingCount).toBe(2) + expect(a2.siblingIndex).toBe(0) + }) + + const tree4 = buildChatItemTree(multiRootNodesMessages as ChatItemInTree[]) + it('should build multi root nodes chat items tree', () => { + expect(tree4).toHaveLength(2) + + const a5 = visitNode(tree4, '1.children.0') + expect(a5.id).toBe('5') + expect(a5.siblingIndex).toBe(1) + }) + + it('should get thread messages from tree4, using the last message as the target', () => { + const threadMessages4 = getThreadMessages(tree4) + expect(threadMessages4).toHaveLength(2) + + const a1 = visitNode(threadMessages4, '0.children.0') + expect(a1.id).toBe('5') + }) + + it('should get thread messages from tree4, using the message with id 2 as the target', () => { + const threadMessages4_1 = getThreadMessages(tree4, '2') + expect(threadMessages4_1).toHaveLength(6) + const a1 = visitNode(threadMessages4_1, '1') + expect(a1.id).toBe('1') + const a2 = visitNode(threadMessages4_1, '3') + expect(a2.id).toBe('2') + const a3 = visitNode(threadMessages4_1, '5') + expect(a3.id).toBe('3') + }) + + const tree5 = buildChatItemTree(multiRootNodesWithLegacyTestMessages as ChatItemInTree[]) + it('should work with multi root nodes chat items with legacy chat items', () => { + expect(tree5).toHaveLength(2) + + const q5 = visitNode(tree5, '1') + expect(q5.id).toBe('question-5') + expect(q5.parentMessageId).toBe(null) + + const a5 = visitNode(q5, 'children.0') + expect(a5.id).toBe('5') + expect(a5.children).toHaveLength(0) + }) + + it('should get thread messages from tree5, using the last message as the target', () => { + const threadMessages5 = getThreadMessages(tree5) + expect(threadMessages5).toHaveLength(2) + + const q5 = visitNode(threadMessages5, '0') + const a5 = visitNode(threadMessages5, '1') + + expect(q5.id).toBe('question-5') + expect(a5.id).toBe('5') + + expect(a5.siblingCount).toBe(2) + expect(a5.siblingIndex).toBe(1) + }) + + const tree6 = buildChatItemTree(realWorldMessages as ChatItemInTree[]) + it('should work with real world messages', () => { + expect(tree6).toMatchSnapshot() + }) + + it ('should get thread messages from tree6, using the last message as target', () => { + const threadMessages6_1 = getThreadMessages(tree6) + expect(threadMessages6_1).toMatchSnapshot() + }) + + it ('should get thread messages from tree6, using specified message as target', () => { + const threadMessages6_2 = getThreadMessages(tree6, 'ff4c2b43-48a5-47ad-9dc5-08b34ddba61b') + expect(threadMessages6_2).toMatchSnapshot() + }) +}) diff --git a/web/app/components/base/chat/chat/answer/index.tsx b/web/app/components/base/chat/chat/answer/index.tsx index 50f51f521f..1ff390bd58 100644 --- a/web/app/components/base/chat/chat/answer/index.tsx +++ b/web/app/components/base/chat/chat/answer/index.tsx @@ -19,6 +19,7 @@ import Citation from '@/app/components/base/chat/chat/citation' import { EditTitle } from '@/app/components/app/annotation/edit-annotation-modal/edit-item' import type { AppData } from '@/models/share' import AnswerIcon from '@/app/components/base/answer-icon' +import { ChevronRight } from '@/app/components/base/icons/src/vender/line/arrows' import cn from '@/utils/classnames' import { FileList } from '@/app/components/base/file-uploader' @@ -34,6 +35,7 @@ type AnswerProps = { hideProcessDetail?: boolean appData?: AppData noChatInput?: boolean + switchSibling?: (siblingMessageId: string) => void } const Answer: FC<AnswerProps> = ({ item, @@ -47,6 +49,7 @@ const Answer: FC<AnswerProps> = ({ hideProcessDetail, appData, noChatInput, + switchSibling, }) => { const { t } = useTranslation() const { @@ -203,6 +206,23 @@ const Answer: FC<AnswerProps> = ({ <Citation data={citation} showHitInfo={config?.supportCitationHitInfo} /> ) } + {item.siblingCount && item.siblingCount > 1 && item.siblingIndex !== undefined && <div className="pt-3.5 flex justify-center items-center text-sm"> + <button + className={`${item.prevSibling ? 'opacity-100' : 'opacity-65'}`} + disabled={!item.prevSibling} + onClick={() => item.prevSibling && switchSibling?.(item.prevSibling)} + > + <ChevronRight className="w-[14px] h-[14px] rotate-180 text-gray-500" /> + </button> + <span className="px-2 text-xs text-gray-700">{item.siblingIndex + 1} / {item.siblingCount}</span> + <button + className={`${item.nextSibling ? 'opacity-100' : 'opacity-65'}`} + disabled={!item.nextSibling} + onClick={() => item.nextSibling && switchSibling?.(item.nextSibling)} + > + <ChevronRight className="w-[14px] h-[14px] text-gray-500" /> + </button> + </div>} </div> </div> <More more={more} /> diff --git a/web/app/components/base/chat/chat/index.tsx b/web/app/components/base/chat/chat/index.tsx index 742632a1ad..22020066b4 100644 --- a/web/app/components/base/chat/chat/index.tsx +++ b/web/app/components/base/chat/chat/index.tsx @@ -65,6 +65,7 @@ export type ChatProps = { hideProcessDetail?: boolean hideLogModal?: boolean themeBuilder?: ThemeBuilder + switchSibling?: (siblingMessageId: string) => void showFeatureBar?: boolean showFileUpload?: boolean onFeatureBarClick?: (state: boolean) => void @@ -100,6 +101,7 @@ const Chat: FC<ChatProps> = ({ hideProcessDetail, hideLogModal, themeBuilder, + switchSibling, showFeatureBar, showFileUpload, onFeatureBarClick, @@ -232,6 +234,7 @@ const Chat: FC<ChatProps> = ({ chatAnswerContainerInner={chatAnswerContainerInner} hideProcessDetail={hideProcessDetail} noChatInput={noChatInput} + switchSibling={switchSibling} /> ) } diff --git a/web/app/components/base/chat/chat/type.ts b/web/app/components/base/chat/chat/type.ts index 40cc32e859..7f22ba05b7 100644 --- a/web/app/components/base/chat/chat/type.ts +++ b/web/app/components/base/chat/chat/type.ts @@ -97,7 +97,11 @@ export type IChatItem = { // for agent log conversationId?: string input?: any - parentMessageId?: string + parentMessageId?: string | null + siblingCount?: number + siblingIndex?: number + prevSibling?: string + nextSibling?: string } export type Metadata = { diff --git a/web/app/components/base/chat/types.ts b/web/app/components/base/chat/types.ts index 402392ac2a..8d9dacdcd7 100644 --- a/web/app/components/base/chat/types.ts +++ b/web/app/components/base/chat/types.ts @@ -65,6 +65,10 @@ export type ChatItem = IChatItem & { allFiles?: FileEntity[] } +export type ChatItemInTree = { + children?: ChatItemInTree[] +} & IChatItem + export type OnSend = (message: string, files?: FileEntity[], last_answer?: ChatItem | null) => void export type OnRegenerate = (chatItem: ChatItem) => void diff --git a/web/app/components/base/chat/utils.ts b/web/app/components/base/chat/utils.ts index 3840f6a2b8..9205225f9f 100644 --- a/web/app/components/base/chat/utils.ts +++ b/web/app/components/base/chat/utils.ts @@ -1,6 +1,7 @@ import { addFileInfos, sortAgentSorts } from '../../tools/utils' import { UUID_NIL } from './constants' -import type { ChatItem } from './types' +import type { IChatItem } from './chat/type' +import type { ChatItem, ChatItemInTree } from './types' import { getProcessedFilesFromResponse } from '@/app/components/base/file-uploader/utils' async function decodeBase64AndDecompress(base64String: string) { @@ -81,8 +82,131 @@ function getPrevChatList(fetchedMessages: any[]) { return ret.reverse() } +function buildChatItemTree(allMessages: IChatItem[]): ChatItemInTree[] { + const map: Record<string, ChatItemInTree> = {} + const rootNodes: ChatItemInTree[] = [] + const childrenCount: Record<string, number> = {} + + let lastAppendedLegacyAnswer: ChatItemInTree | null = null + for (let i = 0; i < allMessages.length; i += 2) { + const question = allMessages[i]! + const answer = allMessages[i + 1]! + + const isLegacy = question.parentMessageId === UUID_NIL + const parentMessageId = isLegacy + ? (lastAppendedLegacyAnswer?.id || '') + : (question.parentMessageId || '') + + // Process question + childrenCount[parentMessageId] = (childrenCount[parentMessageId] || 0) + 1 + const questionNode: ChatItemInTree = { + ...question, + children: [], + } + map[question.id] = questionNode + + // Process answer + childrenCount[question.id] = 1 + const answerNode: ChatItemInTree = { + ...answer, + children: [], + siblingIndex: isLegacy ? 0 : childrenCount[parentMessageId] - 1, + } + map[answer.id] = answerNode + + // Connect question and answer + questionNode.children!.push(answerNode) + + // Append to parent or add to root + if (isLegacy) { + if (!lastAppendedLegacyAnswer) + rootNodes.push(questionNode) + else + lastAppendedLegacyAnswer.children!.push(questionNode) + + lastAppendedLegacyAnswer = answerNode + } + else { + if (!parentMessageId) + rootNodes.push(questionNode) + else + map[parentMessageId]?.children!.push(questionNode) + } + } + + return rootNodes +} + +function getThreadMessages(tree: ChatItemInTree[], targetMessageId?: string): ChatItemInTree[] { + let ret: ChatItemInTree[] = [] + let targetNode: ChatItemInTree | undefined + + // find path to the target message + const stack = tree.toReversed().map(rootNode => ({ + node: rootNode, + path: [rootNode], + })) + while (stack.length > 0) { + const { node, path } = stack.pop()! + if ( + node.id === targetMessageId + || (!targetMessageId && !node.children?.length && !stack.length) // if targetMessageId is not provided, we use the last message in the tree as the target + ) { + targetNode = node + ret = path.map((item, index) => { + if (!item.isAnswer) + return item + + const parentAnswer = path[index - 2] + const siblingCount = !parentAnswer ? tree.length : parentAnswer.children!.length + const prevSibling = !parentAnswer ? tree[item.siblingIndex! - 1]?.children?.[0]?.id : parentAnswer.children![item.siblingIndex! - 1]?.children?.[0].id + const nextSibling = !parentAnswer ? tree[item.siblingIndex! + 1]?.children?.[0]?.id : parentAnswer.children![item.siblingIndex! + 1]?.children?.[0].id + + return { ...item, siblingCount, prevSibling, nextSibling } + }) + break + } + if (node.children) { + for (let i = node.children.length - 1; i >= 0; i--) { + stack.push({ + node: node.children[i], + path: [...path, node.children[i]], + }) + } + } + } + + // append all descendant messages to the path + if (targetNode) { + const stack = [targetNode] + while (stack.length > 0) { + const node = stack.pop()! + if (node !== targetNode) + ret.push(node) + if (node.children?.length) { + const lastChild = node.children.at(-1)! + + if (!lastChild.isAnswer) { + stack.push(lastChild) + continue + } + + const parentAnswer = ret.at(-2) + const siblingCount = parentAnswer?.children?.length + const prevSibling = parentAnswer?.children?.at(-2)?.children?.[0]?.id + + stack.push({ ...lastChild, siblingCount, prevSibling }) + } + } + } + + return ret +} + export { getProcessedInputsFromUrlParams, - getLastAnswer, getPrevChatList, + getLastAnswer, + buildChatItemTree, + getThreadMessages, } diff --git a/web/app/components/workflow/panel/chat-record/index.tsx b/web/app/components/workflow/panel/chat-record/index.tsx index 2786310288..2c76e89b0c 100644 --- a/web/app/components/workflow/panel/chat-record/index.tsx +++ b/web/app/components/workflow/panel/chat-record/index.tsx @@ -12,59 +12,44 @@ import { import { useWorkflowRun } from '../../hooks' import UserInput from './user-input' import Chat from '@/app/components/base/chat/chat' -import type { ChatItem } from '@/app/components/base/chat/types' +import type { ChatItem, ChatItemInTree } from '@/app/components/base/chat/types' import { fetchConversationMessages } from '@/service/debug' import { useStore as useAppStore } from '@/app/components/app/store' import Loading from '@/app/components/base/loading' -import { UUID_NIL } from '@/app/components/base/chat/constants' import { getProcessedFilesFromResponse } from '@/app/components/base/file-uploader/utils' - -function appendQAToChatList(newChatList: ChatItem[], item: any) { - const answerFiles = item.message_files?.filter((file: any) => file.belongs_to === 'assistant') || [] - newChatList.push({ - id: item.id, - content: item.answer, - feedback: item.feedback, - isAnswer: true, - citation: item.metadata?.retriever_resources, - message_files: getProcessedFilesFromResponse(answerFiles.map((item: any) => ({ ...item, related_id: item.id }))), - workflow_run_id: item.workflow_run_id, - }) - const questionFiles = item.message_files?.filter((file: any) => file.belongs_to === 'user') || [] - newChatList.push({ - id: `question-${item.id}`, - content: item.query, - isAnswer: false, - message_files: getProcessedFilesFromResponse(questionFiles.map((item: any) => ({ ...item, related_id: item.id }))), - }) -} +import type { IChatItem } from '@/app/components/base/chat/chat/type' +import { buildChatItemTree, getThreadMessages } from '@/app/components/base/chat/utils' function getFormattedChatList(messages: any[]) { - const newChatList: ChatItem[] = [] - let nextMessageId = null - for (const item of messages) { - if (!item.parent_message_id) { - appendQAToChatList(newChatList, item) - break - } - - if (!nextMessageId) { - appendQAToChatList(newChatList, item) - nextMessageId = item.parent_message_id - } - else { - if (item.id === nextMessageId || nextMessageId === UUID_NIL) { - appendQAToChatList(newChatList, item) - nextMessageId = item.parent_message_id - } - } - } - return newChatList.reverse() + const res: ChatItem[] = [] + messages.forEach((item: any) => { + const questionFiles = item.message_files?.filter((file: any) => file.belongs_to === 'user') || [] + res.push({ + id: `question-${item.id}`, + content: item.query, + isAnswer: false, + message_files: getProcessedFilesFromResponse(questionFiles.map((item: any) => ({ ...item, related_id: item.id }))), + parentMessageId: item.parent_message_id || undefined, + }) + const answerFiles = item.message_files?.filter((file: any) => file.belongs_to === 'assistant') || [] + res.push({ + id: item.id, + content: item.answer, + feedback: item.feedback, + isAnswer: true, + citation: item.metadata?.retriever_resources, + message_files: getProcessedFilesFromResponse(answerFiles.map((item: any) => ({ ...item, related_id: item.id }))), + workflow_run_id: item.workflow_run_id, + parentMessageId: `question-${item.id}`, + }) + }) + return res } const ChatRecord = () => { const [fetched, setFetched] = useState(false) - const [chatList, setChatList] = useState<ChatItem[]>([]) + const [chatItemTree, setChatItemTree] = useState<ChatItemInTree[]>([]) + const [threadChatItems, setThreadChatItems] = useState<IChatItem[]>([]) const appDetail = useAppStore(s => s.appDetail) const workflowStore = useWorkflowStore() const { handleLoadBackupDraft } = useWorkflowRun() @@ -76,20 +61,29 @@ const ChatRecord = () => { try { setFetched(false) const res = await fetchConversationMessages(appDetail.id, currentConversationID) - setChatList(getFormattedChatList((res as any).data)) + + const newAllChatItems = getFormattedChatList((res as any).data) + + const tree = buildChatItemTree(newAllChatItems) + setChatItemTree(tree) + setThreadChatItems(getThreadMessages(tree, newAllChatItems.at(-1)?.id)) } catch (e) { - console.error(e) } finally { setFetched(true) } } }, [appDetail, currentConversationID]) + useEffect(() => { handleFetchConversationMessages() }, [currentConversationID, appDetail, handleFetchConversationMessages]) + const switchSibling = useCallback((siblingMessageId: string) => { + setThreadChatItems(getThreadMessages(chatItemTree, siblingMessageId)) + }, [chatItemTree]) + return ( <div className={` @@ -123,7 +117,7 @@ const ChatRecord = () => { config={{ supportCitationHitInfo: true, } as any} - chatList={chatList} + chatList={threadChatItems} chatContainerClassName='px-3' chatContainerInnerClassName='pt-6 w-full max-w-full mx-auto' chatFooterClassName='px-4 rounded-b-2xl' @@ -132,6 +126,7 @@ const ChatRecord = () => { noChatInput allToolIcons={{}} showPromptLog + switchSibling={switchSibling} noSpacing chatAnswerContainerInner='!pr-2' /> diff --git a/web/babel.config.js b/web/babel.config.js new file mode 100644 index 0000000000..e6196ef3d3 --- /dev/null +++ b/web/babel.config.js @@ -0,0 +1,3 @@ +module.exports = { + presets: ['@babel/preset-env'], +} diff --git a/web/jest.config.ts b/web/jest.config.ts index d7c68308cb..232f90252d 100644 --- a/web/jest.config.ts +++ b/web/jest.config.ts @@ -99,6 +99,7 @@ const config: Config = { // A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module moduleNameMapper: { '^@/components/(.*)$': '<rootDir>/components/$1', + '^lodash-es$': 'lodash', }, // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader From 25f34f6703df1ea983196f3244e62a813b9ac71b Mon Sep 17 00:00:00 2001 From: StyleZhang <jasonapring2015@outlook.com> Date: Thu, 24 Oct 2024 14:21:12 +0800 Subject: [PATCH 187/346] fix: marketplace plugin type icon --- web/app/components/plugins/hooks.ts | 15 +++++++++++ .../marketplace/plugin-type-switch.tsx | 26 +++++++++++++------ 2 files changed, 33 insertions(+), 8 deletions(-) create mode 100644 web/app/components/plugins/hooks.ts diff --git a/web/app/components/plugins/hooks.ts b/web/app/components/plugins/hooks.ts new file mode 100644 index 0000000000..ebee3a6331 --- /dev/null +++ b/web/app/components/plugins/hooks.ts @@ -0,0 +1,15 @@ +import { useRequest } from 'ahooks' + +export const useCheckInstallStatus = () => { + const { data, run, cancel } = useRequest(async () => {}, { + manual: true, + pollingInterval: 5000, + pollingErrorRetryCount: 2, + }) + + return { + data, + run, + cancel, + } +} diff --git a/web/app/components/plugins/marketplace/plugin-type-switch.tsx b/web/app/components/plugins/marketplace/plugin-type-switch.tsx index 16be79db26..8f3c478c57 100644 --- a/web/app/components/plugins/marketplace/plugin-type-switch.tsx +++ b/web/app/components/plugins/marketplace/plugin-type-switch.tsx @@ -1,46 +1,56 @@ 'use client' import { useState } from 'react' +import { PluginType } from '../types' import { + RiArchive2Line, + RiBrain2Line, RiHammerLine, RiPuzzle2Line, } from '@remixicon/react' import cn from '@/utils/classnames' +const PLUGIN_TYPE_SEARCH_MAP = { + all: 'all', + model: PluginType.model, + tool: PluginType.tool, + extension: PluginType.extension, + bundle: 'bundle', +} type PluginTypeSwitchProps = { onChange?: (type: string) => void } const options = [ { - value: 'all', + value: PLUGIN_TYPE_SEARCH_MAP.all, text: 'All', icon: null, }, { - value: 'models', + value: PLUGIN_TYPE_SEARCH_MAP.model, text: 'Models', - icon: null, + icon: <RiBrain2Line className='mr-1.5 w-4 h-4' />, }, { - value: 'tools', + value: PLUGIN_TYPE_SEARCH_MAP.tool, text: 'Tools', icon: <RiHammerLine className='mr-1.5 w-4 h-4' />, }, { - value: 'extensions', + value: PLUGIN_TYPE_SEARCH_MAP.extension, text: 'Extensions', icon: <RiPuzzle2Line className='mr-1.5 w-4 h-4' />, }, { - value: 'bundles', + value: PLUGIN_TYPE_SEARCH_MAP.bundle, text: 'Bundles', - icon: null, + icon: <RiArchive2Line className='mr-1.5 w-4 h-4' />, }, ] const PluginTypeSwitch = ({ onChange, }: PluginTypeSwitchProps) => { - const [activeType, setActiveType] = useState('all') + const [activeType, setActiveType] = useState(PLUGIN_TYPE_SEARCH_MAP.all) return ( <div className={cn( From 169f7440ac98f281b14b9e7b70a1fc19c502fc11 Mon Sep 17 00:00:00 2001 From: Orion <jiangtaoa@foxmail.com> Date: Thu, 24 Oct 2024 14:27:53 +0800 Subject: [PATCH 188/346] feat:Add host volume env variables for postgres, redis and weaviate (#9761) --- docker/docker-compose.middleware.yaml | 6 +++--- docker/middleware.env.example | 7 +++++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/docker/docker-compose.middleware.yaml b/docker/docker-compose.middleware.yaml index 0c9edd2b55..31624285b1 100644 --- a/docker/docker-compose.middleware.yaml +++ b/docker/docker-compose.middleware.yaml @@ -16,7 +16,7 @@ services: -c 'maintenance_work_mem=${POSTGRES_MAINTENANCE_WORK_MEM:-64MB}' -c 'effective_cache_size=${POSTGRES_EFFECTIVE_CACHE_SIZE:-4096MB}' volumes: - - ./volumes/db/data:/var/lib/postgresql/data + - ${PGDATA_HOST_VOLUME:-./volumes/db/data}:/var/lib/postgresql/data ports: - "${EXPOSE_POSTGRES_PORT:-5432}:5432" healthcheck: @@ -31,7 +31,7 @@ services: restart: always volumes: # Mount the redis data directory to the container. - - ./volumes/redis/data:/data + - ${REDIS_HOST_VOLUME:-./volumes/redis/data}:/data # Set the redis password when startup redis server. command: redis-server --requirepass difyai123456 ports: @@ -94,7 +94,7 @@ services: restart: always volumes: # Mount the Weaviate data directory to the container. - - ./volumes/weaviate:/var/lib/weaviate + - ${WEAVIATE_HOST_VOLUME:-./volumes/weaviate}:/var/lib/weaviate env_file: - ./middleware.env environment: diff --git a/docker/middleware.env.example b/docker/middleware.env.example index 04d0fb5ed3..17ac819527 100644 --- a/docker/middleware.env.example +++ b/docker/middleware.env.example @@ -8,6 +8,7 @@ POSTGRES_PASSWORD=difyai123456 POSTGRES_DB=dify # postgres data directory PGDATA=/var/lib/postgresql/data/pgdata +PGDATA_HOST_VOLUME=./volumes/db/data # Maximum number of connections to the database # Default is 100 @@ -39,6 +40,11 @@ POSTGRES_MAINTENANCE_WORK_MEM=64MB # Reference: https://www.postgresql.org/docs/current/runtime-config-query.html#GUC-EFFECTIVE-CACHE-SIZE POSTGRES_EFFECTIVE_CACHE_SIZE=4096MB +# ----------------------------- +# Environment Variables for redis Service +REDIS_HOST_VOLUME=./volumes/redis/data +# ----------------------------- + # ------------------------------ # Environment Variables for sandbox Service SANDBOX_API_KEY=dify-sandbox @@ -70,6 +76,7 @@ WEAVIATE_AUTHENTICATION_APIKEY_ALLOWED_KEYS=WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih WEAVIATE_AUTHENTICATION_APIKEY_USERS=hello@dify.ai WEAVIATE_AUTHORIZATION_ADMINLIST_ENABLED=true WEAVIATE_AUTHORIZATION_ADMINLIST_USERS=hello@dify.ai +WEAVIATE_HOST_VOLUME=./volumes/weaviate # ------------------------------ # Docker Compose Service Expose Host Port Configurations From b6a560ce8638589e0e356daa30d7d8ba419fc3d8 Mon Sep 17 00:00:00 2001 From: AkaraChen <akarachen@outlook.com> Date: Thu, 24 Oct 2024 14:52:07 +0800 Subject: [PATCH 189/346] style: lint --- web/app/components/app/configuration/config-var/index.tsx | 7 +++---- .../provider-added-card/cooldown-timer.tsx | 6 +++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/web/app/components/app/configuration/config-var/index.tsx b/web/app/components/app/configuration/config-var/index.tsx index fc165571c4..91297d73e3 100644 --- a/web/app/components/app/configuration/config-var/index.tsx +++ b/web/app/components/app/configuration/config-var/index.tsx @@ -3,7 +3,6 @@ import type { FC } from 'react' import React, { useState } from 'react' import { useTranslation } from 'react-i18next' import { useBoolean } from 'ahooks' -import type { Timeout } from 'ahooks/lib/useRequest/src/types' import { useContext } from 'use-context-selector' import produce from 'immer' import { @@ -50,7 +49,7 @@ export type IConfigVarProps = { onPromptVariablesChange?: (promptVariables: PromptVariable[]) => void } -let conflictTimer: Timeout +let conflictTimer: number const ConfigVar: FC<IConfigVarProps> = ({ promptVariables, readonly, onPromptVariablesChange }) => { const { t } = useTranslation() @@ -107,7 +106,7 @@ const ConfigVar: FC<IConfigVarProps> = ({ promptVariables, readonly, onPromptVar onPromptVariablesChange?.(newPromptVariables) } const updatePromptKey = (index: number, newKey: string) => { - clearTimeout(conflictTimer) + window.clearTimeout(conflictTimer) const { isValid, errorKey, errorMessageKey } = checkKeys([newKey], true) if (!isValid) { Toast.notify({ @@ -127,7 +126,7 @@ const ConfigVar: FC<IConfigVarProps> = ({ promptVariables, readonly, onPromptVar return item }) - conflictTimer = setTimeout(() => { + conflictTimer = window.setTimeout(() => { const isKeyExists = promptVariables.some(item => item.key?.trim() === newKey.trim()) if (isKeyExists) { Toast.notify({ diff --git a/web/app/components/header/account-setting/model-provider-page/provider-added-card/cooldown-timer.tsx b/web/app/components/header/account-setting/model-provider-page/provider-added-card/cooldown-timer.tsx index bdf93fe527..a21483c29f 100644 --- a/web/app/components/header/account-setting/model-provider-page/provider-added-card/cooldown-timer.tsx +++ b/web/app/components/header/account-setting/model-provider-page/provider-added-card/cooldown-timer.tsx @@ -19,10 +19,10 @@ const CooldownTimer = ({ secondsRemaining, onFinish }: CooldownTimerProps) => { [currentTime], ) - const countdownTimeout = useRef<NodeJS.Timeout>() + const countdownTimeout = useRef<number>(undefined) const clearCountdown = useCallback(() => { if (countdownTimeout.current) { - clearTimeout(countdownTimeout.current) + window.clearTimeout(countdownTimeout.current) countdownTimeout.current = undefined } }, []) @@ -31,7 +31,7 @@ const CooldownTimer = ({ secondsRemaining, onFinish }: CooldownTimerProps) => { const countdown = useCallback(() => { clearCountdown() - countdownTimeout.current = setTimeout(() => { + countdownTimeout.current = window.setTimeout(() => { const now = Date.now() if (now <= targetTime.current) { setCurrentTime(Date.now()) From 710230a29414e3bcab33a2b0880cfca1b5e2607f Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Thu, 24 Oct 2024 14:54:38 +0800 Subject: [PATCH 190/346] fix: fe can not start (#9768) --- web/babel.config.js | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 web/babel.config.js diff --git a/web/babel.config.js b/web/babel.config.js deleted file mode 100644 index e6196ef3d3..0000000000 --- a/web/babel.config.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - presets: ['@babel/preset-env'], -} From b674c598f98b9dde18e418a9fa5b8253c6bc4062 Mon Sep 17 00:00:00 2001 From: Sun Zhigang <sunner@gmail.com> Date: Thu, 24 Oct 2024 14:59:40 +0800 Subject: [PATCH 191/346] Update README_CN.md (#9766) --- README_CN.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README_CN.md b/README_CN.md index 689f98ccf4..070951699a 100644 --- a/README_CN.md +++ b/README_CN.md @@ -154,7 +154,7 @@ Dify 是一个开源的 LLM 应用开发平台。其直观的界面结合了 AI 我们提供[ Dify 云服务](https://dify.ai),任何人都可以零设置尝试。它提供了自部署版本的所有功能,并在沙盒计划中包含 200 次免费的 GPT-4 调用。 - **自托管 Dify 社区版</br>** -使用这个[入门指南](#quick-start)快速在您的环境中运行 Dify。 +使用这个[入门指南](#快速启动)快速在您的环境中运行 Dify。 使用我们的[文档](https://docs.dify.ai)进行进一步的参考和更深入的说明。 - **面向企业/组织的 Dify</br>** From d7def41acc67402e94c9a17bb44d0738acf5233b Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Thu, 24 Oct 2024 16:07:39 +0800 Subject: [PATCH 192/346] feat: fetch debug key api --- web/service/plugins.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/web/service/plugins.ts b/web/service/plugins.ts index 08a7662896..55309ae944 100644 --- a/web/service/plugins.ts +++ b/web/service/plugins.ts @@ -8,6 +8,7 @@ import type { InstallPackageResponse, UpdateEndpointRequest, } from '@/app/components/plugins/types' +import type { DebugInfo as DebugInfoTypes } from '@/app/components/plugins/types' export const createEndpoint: Fetcher<EndpointOperationResponse, { url: string; body: CreateEndpointRequest }> = ({ url, body }) => { // url = /workspaces/current/endpoints/create @@ -45,11 +46,6 @@ export const installPackageFromGitHub: Fetcher<InstallPackageResponse, { repo: s }) } -// export const fetchInstalledPluginsList: Fetcher< export const fetchDebugKey = async () => { - return Promise.resolve({ - key: 'f15b079b-bba2-4a62-abad-69119bcd3fa4', - host: 'localhost', - port: 5003, - }) + return get<DebugInfoTypes>('/workspaces/current/plugin/debugging-key') } From fc638411694a37b5d1bf41a469afee5795b1089c Mon Sep 17 00:00:00 2001 From: Hash Brown <hi@xzd.me> Date: Thu, 24 Oct 2024 16:21:50 +0800 Subject: [PATCH 193/346] fix: chat log not showing correctly (#9777) --- web/app/components/app/log/list.tsx | 154 +++++++++++------------- web/app/components/tools/utils/index.ts | 3 +- 2 files changed, 69 insertions(+), 88 deletions(-) diff --git a/web/app/components/app/log/list.tsx b/web/app/components/app/log/list.tsx index af678b0f9e..22585aa678 100644 --- a/web/app/components/app/log/list.tsx +++ b/web/app/components/app/log/list.tsx @@ -16,7 +16,6 @@ import timezone from 'dayjs/plugin/timezone' import { createContext, useContext } from 'use-context-selector' import { useShallow } from 'zustand/react/shallow' import { useTranslation } from 'react-i18next' -import { UUID_NIL } from '../../base/chat/constants' import type { ChatItemInTree } from '../../base/chat/types' import VarPanel from './var-panel' import cn from '@/utils/classnames' @@ -84,95 +83,76 @@ const PARAM_MAP = { frequency_penalty: 'Frequency Penalty', } -function appendQAToChatList(newChatList: IChatItem[], item: any, conversationId: string, timezone: string, format: string) { - const answerFiles = item.message_files?.filter((file: any) => file.belongs_to === 'assistant') || [] - newChatList.push({ - id: item.id, - content: item.answer, - agent_thoughts: addFileInfos(item.agent_thoughts ? sortAgentSorts(item.agent_thoughts) : item.agent_thoughts, item.message_files), - feedback: item.feedbacks.find((item: any) => item.from_source === 'user'), // user feedback - adminFeedback: item.feedbacks.find((item: any) => item.from_source === 'admin'), // admin feedback - feedbackDisabled: false, - isAnswer: true, - message_files: getProcessedFilesFromResponse(answerFiles.map((item: any) => ({ ...item, related_id: item.id }))), - log: [ - ...item.message, - ...(item.message[item.message.length - 1]?.role !== 'assistant' - ? [ - { - role: 'assistant', - text: item.answer, - files: item.message_files?.filter((file: any) => file.belongs_to === 'assistant') || [], - }, - ] - : []), - ], - workflow_run_id: item.workflow_run_id, - conversationId, - input: { - inputs: item.inputs, - query: item.query, - }, - more: { - time: dayjs.unix(item.created_at).tz(timezone).format(format), - tokens: item.answer_tokens + item.message_tokens, - latency: item.provider_response_latency.toFixed(2), - }, - citation: item.metadata?.retriever_resources, - annotation: (() => { - if (item.annotation_hit_history) { - return { - id: item.annotation_hit_history.annotation_id, - authorName: item.annotation_hit_history.annotation_create_account?.name || 'N/A', - created_at: item.annotation_hit_history.created_at, - } - } - - if (item.annotation) { - return { - id: item.annotation.id, - authorName: item.annotation.account.name, - logAnnotation: item.annotation, - created_at: 0, - } - } - - return undefined - })(), - parentMessageId: `question-${item.id}`, - }) - - const questionFiles = item.message_files?.filter((file: any) => file.belongs_to === 'user') || [] - newChatList.push({ - id: `question-${item.id}`, - content: item.inputs.query || item.inputs.default_input || item.query, // text generation: item.inputs.query; chat: item.query - isAnswer: false, - message_files: getProcessedFilesFromResponse(questionFiles.map((item: any) => ({ ...item, related_id: item.id }))), - parentMessageId: item.parent_message_id || undefined, - }) -} - const getFormattedChatList = (messages: ChatMessage[], conversationId: string, timezone: string, format: string) => { const newChatList: IChatItem[] = [] - let nextMessageId = null - for (const item of messages) { - if (!item.parent_message_id) { - appendQAToChatList(newChatList, item, conversationId, timezone, format) - break - } + messages.forEach((item: ChatMessage) => { + const questionFiles = item.message_files?.filter((file: any) => file.belongs_to === 'user') || [] + newChatList.push({ + id: `question-${item.id}`, + content: item.inputs.query || item.inputs.default_input || item.query, // text generation: item.inputs.query; chat: item.query + isAnswer: false, + message_files: getProcessedFilesFromResponse(questionFiles.map((item: any) => ({ ...item, related_id: item.id }))), + parentMessageId: item.parent_message_id || undefined, + }) - if (!nextMessageId) { - appendQAToChatList(newChatList, item, conversationId, timezone, format) - nextMessageId = item.parent_message_id - } - else { - if (item.id === nextMessageId || nextMessageId === UUID_NIL) { - appendQAToChatList(newChatList, item, conversationId, timezone, format) - nextMessageId = item.parent_message_id - } - } - } - return newChatList.reverse() + const answerFiles = item.message_files?.filter((file: any) => file.belongs_to === 'assistant') || [] + newChatList.push({ + id: item.id, + content: item.answer, + agent_thoughts: addFileInfos(item.agent_thoughts ? sortAgentSorts(item.agent_thoughts) : item.agent_thoughts, item.message_files), + feedback: item.feedbacks.find(item => item.from_source === 'user'), // user feedback + adminFeedback: item.feedbacks.find(item => item.from_source === 'admin'), // admin feedback + feedbackDisabled: false, + isAnswer: true, + message_files: getProcessedFilesFromResponse(answerFiles.map((item: any) => ({ ...item, related_id: item.id }))), + log: [ + ...item.message, + ...(item.message[item.message.length - 1]?.role !== 'assistant' + ? [ + { + role: 'assistant', + text: item.answer, + files: item.message_files?.filter((file: any) => file.belongs_to === 'assistant') || [], + }, + ] + : []), + ] as IChatItem['log'], + workflow_run_id: item.workflow_run_id, + conversationId, + input: { + inputs: item.inputs, + query: item.query, + }, + more: { + time: dayjs.unix(item.created_at).tz(timezone).format(format), + tokens: item.answer_tokens + item.message_tokens, + latency: item.provider_response_latency.toFixed(2), + }, + citation: item.metadata?.retriever_resources, + annotation: (() => { + if (item.annotation_hit_history) { + return { + id: item.annotation_hit_history.annotation_id, + authorName: item.annotation_hit_history.annotation_create_account?.name || 'N/A', + created_at: item.annotation_hit_history.created_at, + } + } + + if (item.annotation) { + return { + id: item.annotation.id, + authorName: item.annotation.account.name, + logAnnotation: item.annotation, + created_at: 0, + } + } + + return undefined + })(), + parentMessageId: `question-${item.id}`, + }) + }) + return newChatList } // const displayedParams = CompletionParams.slice(0, -2) diff --git a/web/app/components/tools/utils/index.ts b/web/app/components/tools/utils/index.ts index 988c2c725c..ced9ca1879 100644 --- a/web/app/components/tools/utils/index.ts +++ b/web/app/components/tools/utils/index.ts @@ -1,5 +1,6 @@ import type { ThoughtItem } from '@/app/components/base/chat/chat/type' import type { FileEntity } from '@/app/components/base/file-uploader/types' +import type { VisionFile } from '@/types/app' export const sortAgentSorts = (list: ThoughtItem[]) => { if (!list) @@ -11,7 +12,7 @@ export const sortAgentSorts = (list: ThoughtItem[]) => { return temp } -export const addFileInfos = (list: ThoughtItem[], messageFiles: FileEntity[]) => { +export const addFileInfos = (list: ThoughtItem[], messageFiles: (FileEntity | VisionFile)[]) => { if (!list || !messageFiles) return list return list.map((item) => { From e54b7cda3d543408b045170bd854dd31002296fc Mon Sep 17 00:00:00 2001 From: -LAN- <laipz8200@outlook.com> Date: Thu, 24 Oct 2024 17:07:20 +0800 Subject: [PATCH 194/346] refactor(file_factory): improve filename and mime type determination (#9784) --- api/factories/file_factory.py | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/api/factories/file_factory.py b/api/factories/file_factory.py index fa88e2b4fe..ead7b9a8b3 100644 --- a/api/factories/file_factory.py +++ b/api/factories/file_factory.py @@ -179,27 +179,19 @@ def _build_from_remote_url( if not url: raise ValueError("Invalid file url") + mime_type = mimetypes.guess_type(url)[0] or "" + file_size = -1 + filename = url.split("/")[-1].split("?")[0] or "unknown_file" + resp = ssrf_proxy.head(url, follow_redirects=True) if resp.status_code == httpx.codes.OK: - # Try to extract filename from response headers or URL - content_disposition = resp.headers.get("Content-Disposition") - if content_disposition: + if content_disposition := resp.headers.get("Content-Disposition"): filename = content_disposition.split("filename=")[-1].strip('"') - else: - filename = url.split("/")[-1].split("?")[0] - # Create the File object - file_size = int(resp.headers.get("Content-Length", -1)) - mime_type = str(resp.headers.get("Content-Type", "")) - else: - filename = "" - file_size = -1 - mime_type = "" + file_size = int(resp.headers.get("Content-Length", file_size)) + mime_type = mime_type or str(resp.headers.get("Content-Type", "")) - # If filename is empty, set a default one - if not filename: - filename = "unknown_file" # Determine file extension - extension = "." + filename.split(".")[-1] if "." in filename else ".bin" + extension = mimetypes.guess_extension(mime_type) or "." + filename.split(".")[-1] if "." in filename else ".bin" if not mime_type: mime_type, _ = mimetypes.guess_type(url) From 606fc7be0c0e5e3b9e828d2f04735e9060c1ab93 Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Thu, 24 Oct 2024 17:14:17 +0800 Subject: [PATCH 195/346] feat: support upload pkg --- .../plugins/install-plugin/base/installed.tsx | 26 ++++++++++++------- .../install-from-local-package/index.tsx | 24 +++++++++++------ .../steps/install.tsx | 2 ++ .../steps/uploading.tsx | 23 ++++++++++------ web/app/components/plugins/types.ts | 1 + web/i18n/en-US/plugin.ts | 1 + web/i18n/zh-Hans/plugin.ts | 1 + web/service/plugins.ts | 11 +++++++- 8 files changed, 62 insertions(+), 27 deletions(-) diff --git a/web/app/components/plugins/install-plugin/base/installed.tsx b/web/app/components/plugins/install-plugin/base/installed.tsx index 03f392447c..af39b47995 100644 --- a/web/app/components/plugins/install-plugin/base/installed.tsx +++ b/web/app/components/plugins/install-plugin/base/installed.tsx @@ -6,31 +6,37 @@ import Card from '../../card' import Button from '@/app/components/base/button' import { pluginManifestToCardPluginProps } from '../utils' import { useTranslation } from 'react-i18next' +import Badge, { BadgeState } from '@/app/components/base/badge/index' type Props = { - payload: PluginDeclaration + payload?: PluginDeclaration | null isFailed: boolean + errMsg?: string | null onCancel: () => void } const Installed: FC<Props> = ({ payload, isFailed, + errMsg, onCancel, }) => { const { t } = useTranslation() return ( <> <div className='flex flex-col px-6 py-3 justify-center items-start gap-4 self-stretch'> - <p className='text-text-secondary system-md-regular'>{t(`plugin.installModal.${isFailed ? 'installFailedDesc' : 'installedSuccessfullyDesc'}`)}</p> - <div className='flex p-2 items-start content-start gap-1 self-stretch flex-wrap rounded-2xl bg-background-section-burn'> - <Card - className='w-full' - payload={pluginManifestToCardPluginProps(payload)} - installed={!isFailed} - installFailed={isFailed} - /> - </div> + <p className='text-text-secondary system-md-regular'>{(isFailed && errMsg) ? errMsg : t(`plugin.installModal.${isFailed ? 'installFailedDesc' : 'installedSuccessfullyDesc'}`)}</p> + {payload && ( + <div className='flex p-2 items-start content-start gap-1 self-stretch flex-wrap rounded-2xl bg-background-section-burn'> + <Card + className='w-full' + payload={pluginManifestToCardPluginProps(payload)} + installed={!isFailed} + installFailed={isFailed} + titleLeft={<Badge className='mx-1' size="s" state={BadgeState.Default}>{payload.version}</Badge>} + /> + </div> + )} </div> {/* Action Buttons */} <div className='flex p-6 pt-5 justify-end items-center gap-2 self-stretch'> diff --git a/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx b/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx index 0f75d7cf5b..e71f5f7e2f 100644 --- a/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx +++ b/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx @@ -8,7 +8,6 @@ import Uploading from './steps/uploading' import Install from './steps/install' import Installed from '../base/installed' import { useTranslation } from 'react-i18next' -import { toolNotionManifest } from '../../card/card-mock' const i18nPrefix = 'plugin.installModal' @@ -23,19 +22,21 @@ const InstallFromLocalPackage: React.FC<InstallFromLocalPackageProps> = ({ onClose, }) => { const { t } = useTranslation() - // uploading -> readyToInstall -> installed/failed + // uploading -> !uploadFailed -> readyToInstall -> installed/failed const [step, setStep] = useState<InstallStep>(InstallStep.uploading) - const [uniqueIdentifier, setUniqueIdentifier] = useState<string | null>(null) - + const [manifest, setManifest] = useState<PluginDeclaration | null>(null) + const [errorMsg, setErrorMsg] = useState<string | null>(null) const getTitle = useCallback(() => { + if (step === InstallStep.uploadFailed) + return t(`${i18nPrefix}.uploadFailed`) if (step === InstallStep.installed) return t(`${i18nPrefix}.installedSuccessfully`) if (step === InstallStep.installFailed) return t(`${i18nPrefix}.installFailed`) + return t(`${i18nPrefix}.installPlugin`) }, [step]) - const [manifest, setManifest] = useState<PluginDeclaration | null>(toolNotionManifest) const handleUploaded = useCallback((result: { uniqueIdentifier: string @@ -46,6 +47,11 @@ const InstallFromLocalPackage: React.FC<InstallFromLocalPackageProps> = ({ setStep(InstallStep.readyToInstall) }, []) + const handleUploadFail = useCallback((errorMsg: string) => { + setErrorMsg(errorMsg) + setStep(InstallStep.uploadFailed) + }, []) + const handleInstalled = useCallback(async () => { setStep(InstallStep.installed) }, []) @@ -71,6 +77,7 @@ const InstallFromLocalPackage: React.FC<InstallFromLocalPackageProps> = ({ file={file} onCancel={onClose} onUploaded={handleUploaded} + onFailed={handleUploadFail} /> )} { @@ -84,10 +91,11 @@ const InstallFromLocalPackage: React.FC<InstallFromLocalPackageProps> = ({ ) } { - ([InstallStep.installed, InstallStep.installFailed].includes(step)) && ( + ([InstallStep.uploadFailed, InstallStep.installed, InstallStep.installFailed].includes(step)) && ( <Installed - payload={manifest!} - isFailed={step === InstallStep.installFailed} + payload={manifest} + isFailed={[InstallStep.uploadFailed, InstallStep.installFailed].includes(step)} + errMsg={errorMsg} onCancel={onClose} /> ) diff --git a/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx b/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx index 8572d96a3a..42e3ef74b8 100644 --- a/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx +++ b/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx @@ -8,6 +8,7 @@ import Button from '@/app/components/base/button' import { sleep } from '@/utils' import { Trans, useTranslation } from 'react-i18next' import { RiLoader2Line } from '@remixicon/react' +import Badge, { BadgeState } from '@/app/components/base/badge/index' const i18nPrefix = 'plugin.installModal' @@ -51,6 +52,7 @@ const Installed: FC<Props> = ({ <Card className='w-full' payload={pluginManifestToCardPluginProps(payload)} + titleLeft={<Badge className='mx-1' size="s" state={BadgeState.Default}>{payload.version}</Badge>} /> </div> </div> diff --git a/web/app/components/plugins/install-plugin/install-from-local-package/steps/uploading.tsx b/web/app/components/plugins/install-plugin/install-from-local-package/steps/uploading.tsx index 6a8068515d..50b23ca9f0 100644 --- a/web/app/components/plugins/install-plugin/install-from-local-package/steps/uploading.tsx +++ b/web/app/components/plugins/install-plugin/install-from-local-package/steps/uploading.tsx @@ -5,10 +5,8 @@ import { RiLoader2Line } from '@remixicon/react' import Card from '../../../card' import type { PluginDeclaration } from '../../../types' import Button from '@/app/components/base/button' -import { sleep } from '@/utils' import { useTranslation } from 'react-i18next' -import { toolNotionManifest } from '../../../card/card-mock' - +import { uploadPackageFile } from '@/service/plugins' const i18nPrefix = 'plugin.installModal' type Props = { @@ -18,21 +16,30 @@ type Props = { uniqueIdentifier: string manifest: PluginDeclaration }) => void + onFailed: (errorMsg: string) => void } const Uploading: FC<Props> = ({ file, onCancel, onUploaded, + onFailed, }) => { const { t } = useTranslation() const fileName = file.name const handleUpload = async () => { - await sleep(3000) - onUploaded({ - uniqueIdentifier: 'yeuoly/neko:0.0.1@5395654da2c0b919b3d9b946a1a0545b737004380765e5f3b8c49976d3276c87', - manifest: toolNotionManifest, - }) + try { + const res = await uploadPackageFile(file) + onUploaded(res) + } + catch (e: any) { + if (e.response?.message) { + onFailed(e.response?.message) + } + else { // Why it would into this branch? + onUploaded(e.response) + } + } } React.useEffect(() => { diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts index 8fdea20406..ba430a87c3 100644 --- a/web/app/components/plugins/types.ts +++ b/web/app/components/plugins/types.ts @@ -168,6 +168,7 @@ export type UpdateEndpointRequest = { export enum InstallStep { uploading = 'uploading', + uploadFailed = 'uploadFailed', readyToInstall = 'readyToInstall', installing = 'installing', installed = 'installed', diff --git a/web/i18n/en-US/plugin.ts b/web/i18n/en-US/plugin.ts index 1be0398331..62b3facdc3 100644 --- a/web/i18n/en-US/plugin.ts +++ b/web/i18n/en-US/plugin.ts @@ -63,6 +63,7 @@ const translation = { installPlugin: 'Install Plugin', installedSuccessfully: 'Installation successful', installedSuccessfullyDesc: 'The plugin has been installed successfully.', + uploadFailed: 'Upload failed', installFailed: 'Installation failed', installFailedDesc: 'The plugin has been installed failed.', install: 'Install', diff --git a/web/i18n/zh-Hans/plugin.ts b/web/i18n/zh-Hans/plugin.ts index 91f7a998eb..573ced6f94 100644 --- a/web/i18n/zh-Hans/plugin.ts +++ b/web/i18n/zh-Hans/plugin.ts @@ -63,6 +63,7 @@ const translation = { installPlugin: '安装插件', installedSuccessfully: '安装成功', installedSuccessfullyDesc: '插件已成功安装。', + uploadFailed: '上传失败', installFailed: '安装失败', installFailedDesc: '插件安装失败。', install: '安装', diff --git a/web/service/plugins.ts b/web/service/plugins.ts index 55309ae944..dfee63009b 100644 --- a/web/service/plugins.ts +++ b/web/service/plugins.ts @@ -1,5 +1,5 @@ import type { Fetcher } from 'swr' -import { del, get, post } from './base' +import { del, get, post, upload } from './base' import type { CreateEndpointRequest, EndpointOperationResponse, @@ -49,3 +49,12 @@ export const installPackageFromGitHub: Fetcher<InstallPackageResponse, { repo: s export const fetchDebugKey = async () => { return get<DebugInfoTypes>('/workspaces/current/plugin/debugging-key') } + +export const uploadPackageFile = async (file: File) => { + const formData = new FormData() + formData.append('pkg', file) + return upload({ + xhr: new XMLHttpRequest(), + data: formData, + }, false, '/workspaces/current/plugin/upload/pkg') +} From 9a9d90ad7f1c1ed73a5d281f678d63cf611699de Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Thu, 24 Oct 2024 17:24:46 +0800 Subject: [PATCH 196/346] feat: can install --- .../install-from-local-package/index.tsx | 1 + .../install-from-local-package/steps/install.tsx | 12 ++++++++++-- .../install-from-local-package/steps/uploading.tsx | 8 ++++++-- web/service/plugins.ts | 6 ++++++ 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx b/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx index e71f5f7e2f..bbfc195a4d 100644 --- a/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx +++ b/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx @@ -83,6 +83,7 @@ const InstallFromLocalPackage: React.FC<InstallFromLocalPackageProps> = ({ { step === InstallStep.readyToInstall && ( <Install + uniqueIdentifier={uniqueIdentifier!} payload={manifest!} onCancel={onClose} onInstalled={handleInstalled} diff --git a/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx b/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx index 42e3ef74b8..4d58ab3cb7 100644 --- a/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx +++ b/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx @@ -9,10 +9,12 @@ import { sleep } from '@/utils' import { Trans, useTranslation } from 'react-i18next' import { RiLoader2Line } from '@remixicon/react' import Badge, { BadgeState } from '@/app/components/base/badge/index' +import { installPackageFromLocal } from '@/service/plugins' const i18nPrefix = 'plugin.installModal' type Props = { + uniqueIdentifier: string payload: PluginDeclaration onCancel: () => void onInstalled: () => void @@ -20,6 +22,7 @@ type Props = { } const Installed: FC<Props> = ({ + uniqueIdentifier, payload, onCancel, onInstalled, @@ -31,9 +34,14 @@ const Installed: FC<Props> = ({ const handleInstall = async () => { if (isInstalling) return setIsInstalling(true) + try { + await installPackageFromLocal(uniqueIdentifier) + onInstalled() + } + catch (e) { + onFailed() + } await sleep(1500) - // onInstalled() - onFailed() } return ( diff --git a/web/app/components/plugins/install-plugin/install-from-local-package/steps/uploading.tsx b/web/app/components/plugins/install-plugin/install-from-local-package/steps/uploading.tsx index 50b23ca9f0..d9fa05ff21 100644 --- a/web/app/components/plugins/install-plugin/install-from-local-package/steps/uploading.tsx +++ b/web/app/components/plugins/install-plugin/install-from-local-package/steps/uploading.tsx @@ -30,14 +30,18 @@ const Uploading: FC<Props> = ({ const handleUpload = async () => { try { const res = await uploadPackageFile(file) - onUploaded(res) + // onUploaded(res) } catch (e: any) { if (e.response?.message) { onFailed(e.response?.message) } else { // Why it would into this branch? - onUploaded(e.response) + const res = e.response + onUploaded({ + uniqueIdentifier: res.unique_identifier, + manifest: res.manifest, + }) } } } diff --git a/web/service/plugins.ts b/web/service/plugins.ts index dfee63009b..f1d6f8e223 100644 --- a/web/service/plugins.ts +++ b/web/service/plugins.ts @@ -58,3 +58,9 @@ export const uploadPackageFile = async (file: File) => { data: formData, }, false, '/workspaces/current/plugin/upload/pkg') } + +export const installPackageFromLocal = async (uniqueIdentifier: string) => { + return post<InstallPackageResponse>('/workspaces/current/plugin/install/pkg', { + body: { plugin_unique_identifiers: [uniqueIdentifier] }, + }) +} From d018b32d0b75cfaa6f6f38fb7e5e15984f0172ff Mon Sep 17 00:00:00 2001 From: -LAN- <laipz8200@outlook.com> Date: Thu, 24 Oct 2024 17:52:11 +0800 Subject: [PATCH 197/346] fix(workflow): enhance prompt handling with vision support (#9790) --- api/core/workflow/nodes/llm/node.py | 8 +++++++- .../nodes/question_classifier/question_classifier_node.py | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/api/core/workflow/nodes/llm/node.py b/api/core/workflow/nodes/llm/node.py index 94aa8c5eab..abf77f3339 100644 --- a/api/core/workflow/nodes/llm/node.py +++ b/api/core/workflow/nodes/llm/node.py @@ -127,9 +127,10 @@ class LLMNode(BaseNode[LLMNodeData]): context=context, memory=memory, model_config=model_config, - vision_detail=self.node_data.vision.configs.detail, prompt_template=self.node_data.prompt_template, memory_config=self.node_data.memory, + vision_enabled=self.node_data.vision.enabled, + vision_detail=self.node_data.vision.configs.detail, ) process_data = { @@ -518,6 +519,7 @@ class LLMNode(BaseNode[LLMNodeData]): model_config: ModelConfigWithCredentialsEntity, prompt_template: Sequence[LLMNodeChatModelMessage] | LLMNodeCompletionModelPromptTemplate, memory_config: MemoryConfig | None = None, + vision_enabled: bool = False, vision_detail: ImagePromptMessageContent.DETAIL, ) -> tuple[list[PromptMessage], Optional[list[str]]]: inputs = inputs or {} @@ -542,6 +544,10 @@ class LLMNode(BaseNode[LLMNodeData]): if not isinstance(prompt_message.content, str): prompt_message_content = [] for content_item in prompt_message.content or []: + # Skip image if vision is disabled + if not vision_enabled and content_item.type == PromptMessageContentType.IMAGE: + continue + if isinstance(content_item, ImagePromptMessageContent): # Override vision config if LLM node has vision config, # cuz vision detail is related to the configuration from FileUpload feature. diff --git a/api/core/workflow/nodes/question_classifier/question_classifier_node.py b/api/core/workflow/nodes/question_classifier/question_classifier_node.py index e6af453dcf..ee160e7c69 100644 --- a/api/core/workflow/nodes/question_classifier/question_classifier_node.py +++ b/api/core/workflow/nodes/question_classifier/question_classifier_node.py @@ -88,6 +88,7 @@ class QuestionClassifierNode(LLMNode): memory=memory, model_config=model_config, files=files, + vision_enabled=node_data.vision.enabled, vision_detail=node_data.vision.configs.detail, ) From 5f11fe521dfc2e8d94990d5067cefd08fa1f51bc Mon Sep 17 00:00:00 2001 From: Jyong <76649700+JohnJyong@users.noreply.github.com> Date: Thu, 24 Oct 2024 18:13:05 +0800 Subject: [PATCH 198/346] remove unstructured pdf extract (#9794) --- api/core/rag/extractor/extract_processor.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/api/core/rag/extractor/extract_processor.py b/api/core/rag/extractor/extract_processor.py index 603f7555dd..6a23f3cfef 100644 --- a/api/core/rag/extractor/extract_processor.py +++ b/api/core/rag/extractor/extract_processor.py @@ -21,7 +21,6 @@ from core.rag.extractor.unstructured.unstructured_eml_extractor import Unstructu from core.rag.extractor.unstructured.unstructured_epub_extractor import UnstructuredEpubExtractor from core.rag.extractor.unstructured.unstructured_markdown_extractor import UnstructuredMarkdownExtractor from core.rag.extractor.unstructured.unstructured_msg_extractor import UnstructuredMsgExtractor -from core.rag.extractor.unstructured.unstructured_pdf_extractor import UnstructuredPDFExtractor from core.rag.extractor.unstructured.unstructured_ppt_extractor import UnstructuredPPTExtractor from core.rag.extractor.unstructured.unstructured_pptx_extractor import UnstructuredPPTXExtractor from core.rag.extractor.unstructured.unstructured_text_extractor import UnstructuredTextExtractor @@ -103,7 +102,7 @@ class ExtractProcessor: if file_extension in {".xlsx", ".xls"}: extractor = ExcelExtractor(file_path) elif file_extension == ".pdf": - extractor = UnstructuredPDFExtractor(file_path, unstructured_api_url, unstructured_api_key) + extractor = PdfExtractor(file_path) elif file_extension in {".md", ".markdown"}: extractor = ( UnstructuredMarkdownExtractor(file_path, unstructured_api_url, unstructured_api_key) From e2710161f6d711ab809585ec45b8eda8e798cbab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9D=9E=E6=B3=95=E6=93=8D=E4=BD=9C?= <hjlarry@163.com> Date: Thu, 24 Oct 2024 18:49:49 +0800 Subject: [PATCH 199/346] fix: chart tool can't display chinese (#9686) --- api/Dockerfile | 2 + .../tools/provider/builtin/chart/chart.py | 91 +++++-------------- 2 files changed, 27 insertions(+), 66 deletions(-) diff --git a/api/Dockerfile b/api/Dockerfile index c6381859b3..d58b4d02e2 100644 --- a/api/Dockerfile +++ b/api/Dockerfile @@ -56,6 +56,8 @@ RUN apt-get update \ && apt-get update \ # For Security && apt-get install -y --no-install-recommends zlib1g=1:1.3.dfsg+really1.3.1-1 expat=2.6.3-1 libldap-2.5-0=2.5.18+dfsg-3 perl=5.38.2-5 libsqlite3-0=3.46.1-1 \ + # install a chinese font to support the use of tools like matplotlib + && apt-get install -y fonts-noto-cjk \ && apt-get autoremove -y \ && rm -rf /var/lib/apt/lists/* diff --git a/api/core/tools/provider/builtin/chart/chart.py b/api/core/tools/provider/builtin/chart/chart.py index 8a24d33428..209d6ecba4 100644 --- a/api/core/tools/provider/builtin/chart/chart.py +++ b/api/core/tools/provider/builtin/chart/chart.py @@ -1,77 +1,36 @@ import matplotlib.pyplot as plt -from fontTools.ttLib import TTFont -from matplotlib.font_manager import findSystemFonts +from matplotlib.font_manager import FontProperties -from core.tools.errors import ToolProviderCredentialValidationError -from core.tools.provider.builtin.chart.tools.line import LinearChartTool from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController + +def set_chinese_font(): + font_list = [ + "PingFang SC", + "SimHei", + "Microsoft YaHei", + "STSong", + "SimSun", + "Arial Unicode MS", + "Noto Sans CJK SC", + "Noto Sans CJK JP", + ] + + for font in font_list: + chinese_font = FontProperties(font) + if chinese_font.get_name() == font: + return chinese_font + + return FontProperties() + + # use a business theme plt.style.use("seaborn-v0_8-darkgrid") plt.rcParams["axes.unicode_minus"] = False - - -def init_fonts(): - fonts = findSystemFonts() - - popular_unicode_fonts = [ - "Arial Unicode MS", - "DejaVu Sans", - "DejaVu Sans Mono", - "DejaVu Serif", - "FreeMono", - "FreeSans", - "FreeSerif", - "Liberation Mono", - "Liberation Sans", - "Liberation Serif", - "Noto Mono", - "Noto Sans", - "Noto Serif", - "Open Sans", - "Roboto", - "Source Code Pro", - "Source Sans Pro", - "Source Serif Pro", - "Ubuntu", - "Ubuntu Mono", - ] - - supported_fonts = [] - - for font_path in fonts: - try: - font = TTFont(font_path) - # get family name - family_name = font["name"].getName(1, 3, 1).toUnicode() - if family_name in popular_unicode_fonts: - supported_fonts.append(family_name) - except: - pass - - plt.rcParams["font.family"] = "sans-serif" - # sort by order of popular_unicode_fonts - for font in popular_unicode_fonts: - if font in supported_fonts: - plt.rcParams["font.sans-serif"] = font - break - - -init_fonts() +font_properties = set_chinese_font() +plt.rcParams["font.family"] = font_properties.get_name() class ChartProvider(BuiltinToolProviderController): def _validate_credentials(self, credentials: dict) -> None: - try: - LinearChartTool().fork_tool_runtime( - runtime={ - "credentials": credentials, - } - ).invoke( - user_id="", - tool_parameters={ - "data": "1,3,5,7,9,2,4,6,8,10", - }, - ) - except Exception as e: - raise ToolProviderCredentialValidationError(str(e)) + pass From 9986e4c6d0da10d02f027f75c21686f83eab7185 Mon Sep 17 00:00:00 2001 From: -LAN- <laipz8200@outlook.com> Date: Thu, 24 Oct 2024 19:07:03 +0800 Subject: [PATCH 200/346] chore(docker): correct package version for expat and perl in Dockerfile (#9801) --- api/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/Dockerfile b/api/Dockerfile index d58b4d02e2..f078181264 100644 --- a/api/Dockerfile +++ b/api/Dockerfile @@ -55,7 +55,7 @@ RUN apt-get update \ && echo "deb http://deb.debian.org/debian testing main" > /etc/apt/sources.list \ && apt-get update \ # For Security - && apt-get install -y --no-install-recommends zlib1g=1:1.3.dfsg+really1.3.1-1 expat=2.6.3-1 libldap-2.5-0=2.5.18+dfsg-3 perl=5.38.2-5 libsqlite3-0=3.46.1-1 \ + && apt-get install -y --no-install-recommends zlib1g=1:1.3.dfsg+really1.3.1-1 expat=2.6.3-1 libldap-2.5-0=2.5.18+dfsg-3+b1 perl=5.40.0-6 libsqlite3-0=3.46.1-1 \ # install a chinese font to support the use of tools like matplotlib && apt-get install -y fonts-noto-cjk \ && apt-get autoremove -y \ From 70ddc0ce4354b3985d77f3a7ea3995199b6bfd4c Mon Sep 17 00:00:00 2001 From: guogeer <1500065870@qq.com> Date: Thu, 24 Oct 2024 21:51:36 +0800 Subject: [PATCH 201/346] openai compatiable api usage and id (#9800) Co-authored-by: jinqi.guo <jinqi.guo@ubtrobot.com> --- .../model_runtime/entities/llm_entities.py | 1 + .../openai_api_compatible/llm/llm.py | 33 +++++++++++++++---- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/api/core/model_runtime/entities/llm_entities.py b/api/core/model_runtime/entities/llm_entities.py index 52b590f66a..88531d8ae0 100644 --- a/api/core/model_runtime/entities/llm_entities.py +++ b/api/core/model_runtime/entities/llm_entities.py @@ -105,6 +105,7 @@ class LLMResult(BaseModel): Model class for llm result. """ + id: Optional[str] = None model: str prompt_messages: list[PromptMessage] message: AssistantPromptMessage diff --git a/api/core/model_runtime/model_providers/openai_api_compatible/llm/llm.py b/api/core/model_runtime/model_providers/openai_api_compatible/llm/llm.py index 356ac56b1e..e1342fe985 100644 --- a/api/core/model_runtime/model_providers/openai_api_compatible/llm/llm.py +++ b/api/core/model_runtime/model_providers/openai_api_compatible/llm/llm.py @@ -397,16 +397,21 @@ class OAIAPICompatLargeLanguageModel(_CommonOaiApiCompat, LargeLanguageModel): chunk_index = 0 def create_final_llm_result_chunk( - index: int, message: AssistantPromptMessage, finish_reason: str + id: Optional[str], index: int, message: AssistantPromptMessage, finish_reason: str, usage: dict ) -> LLMResultChunk: # calculate num tokens - prompt_tokens = self._num_tokens_from_string(model, prompt_messages[0].content) - completion_tokens = self._num_tokens_from_string(model, full_assistant_content) + prompt_tokens = usage and usage.get("prompt_tokens") + if prompt_tokens is None: + prompt_tokens = self._num_tokens_from_string(model, prompt_messages[0].content) + completion_tokens = usage and usage.get("completion_tokens") + if completion_tokens is None: + completion_tokens = self._num_tokens_from_string(model, full_assistant_content) # transform usage usage = self._calc_response_usage(model, credentials, prompt_tokens, completion_tokens) return LLMResultChunk( + id=id, model=model, prompt_messages=prompt_messages, delta=LLMResultChunkDelta(index=index, message=message, finish_reason=finish_reason, usage=usage), @@ -450,7 +455,7 @@ class OAIAPICompatLargeLanguageModel(_CommonOaiApiCompat, LargeLanguageModel): tool_call.function.arguments += new_tool_call.function.arguments finish_reason = None # The default value of finish_reason is None - + message_id, usage = None, None for chunk in response.iter_lines(decode_unicode=True, delimiter=delimiter): chunk = chunk.strip() if chunk: @@ -462,20 +467,26 @@ class OAIAPICompatLargeLanguageModel(_CommonOaiApiCompat, LargeLanguageModel): continue try: - chunk_json = json.loads(decoded_chunk) + chunk_json: dict = json.loads(decoded_chunk) # stream ended except json.JSONDecodeError as e: yield create_final_llm_result_chunk( + id=message_id, index=chunk_index + 1, message=AssistantPromptMessage(content=""), finish_reason="Non-JSON encountered.", + usage=usage, ) break + if chunk_json: + if u := chunk_json.get("usage"): + usage = u if not chunk_json or len(chunk_json["choices"]) == 0: continue choice = chunk_json["choices"][0] finish_reason = chunk_json["choices"][0].get("finish_reason") + message_id = chunk_json.get("id") chunk_index += 1 if "delta" in choice: @@ -524,6 +535,7 @@ class OAIAPICompatLargeLanguageModel(_CommonOaiApiCompat, LargeLanguageModel): continue yield LLMResultChunk( + id=message_id, model=model, prompt_messages=prompt_messages, delta=LLMResultChunkDelta( @@ -536,6 +548,7 @@ class OAIAPICompatLargeLanguageModel(_CommonOaiApiCompat, LargeLanguageModel): if tools_calls: yield LLMResultChunk( + id=message_id, model=model, prompt_messages=prompt_messages, delta=LLMResultChunkDelta( @@ -545,17 +558,22 @@ class OAIAPICompatLargeLanguageModel(_CommonOaiApiCompat, LargeLanguageModel): ) yield create_final_llm_result_chunk( - index=chunk_index, message=AssistantPromptMessage(content=""), finish_reason=finish_reason + id=message_id, + index=chunk_index, + message=AssistantPromptMessage(content=""), + finish_reason=finish_reason, + usage=usage, ) def _handle_generate_response( self, model: str, credentials: dict, response: requests.Response, prompt_messages: list[PromptMessage] ) -> LLMResult: - response_json = response.json() + response_json: dict = response.json() completion_type = LLMMode.value_of(credentials["mode"]) output = response_json["choices"][0] + message_id = response_json.get("id") response_content = "" tool_calls = None @@ -593,6 +611,7 @@ class OAIAPICompatLargeLanguageModel(_CommonOaiApiCompat, LargeLanguageModel): # transform response result = LLMResult( + id=message_id, model=response_json["model"], prompt_messages=prompt_messages, message=assistant_message, From 6477bb8d77799b5a13a3535d16f3699ba00e930c Mon Sep 17 00:00:00 2001 From: -LAN- <laipz8200@outlook.com> Date: Thu, 24 Oct 2024 21:52:48 +0800 Subject: [PATCH 202/346] chore(docker): add default for MAX_VARIABLE_SIZE in docker-compose (#9798) --- docker/.env.example | 1 + docker/docker-compose.yaml | 1 + 2 files changed, 2 insertions(+) diff --git a/docker/.env.example b/docker/.env.example index dbdc943b06..0a9e0814c7 100644 --- a/docker/.env.example +++ b/docker/.env.example @@ -630,6 +630,7 @@ CODE_MAX_NUMBER_ARRAY_LENGTH=1000 WORKFLOW_MAX_EXECUTION_STEPS=500 WORKFLOW_MAX_EXECUTION_TIME=1200 WORKFLOW_CALL_MAX_DEPTH=5 +MAX_VARIABLE_SIZE=204800 # HTTP request node in workflow configuration HTTP_REQUEST_NODE_MAX_BINARY_SIZE=10485760 diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml index da1a6b4d4e..24e1328e95 100644 --- a/docker/docker-compose.yaml +++ b/docker/docker-compose.yaml @@ -237,6 +237,7 @@ x-shared-env: &shared-api-worker-env POSITION_PROVIDER_PINS: ${POSITION_PROVIDER_PINS:-} POSITION_PROVIDER_INCLUDES: ${POSITION_PROVIDER_INCLUDES:-} POSITION_PROVIDER_EXCLUDES: ${POSITION_PROVIDER_EXCLUDES:-} + MAX_VARIABLE_SIZE: ${MAX_VARIABLE_SIZE:-204800} services: # API service From 22bb0414a1f931d4490044c4f768f71027607c49 Mon Sep 17 00:00:00 2001 From: -LAN- <laipz8200@outlook.com> Date: Thu, 24 Oct 2024 21:52:57 +0800 Subject: [PATCH 203/346] feat(parameters): standardize system parameter field types and values (#9797) --- api/controllers/console/explore/parameter.py | 12 ++++++++++-- api/controllers/service_api/app/app.py | 12 ++++++++++-- api/controllers/web/app.py | 12 ++++++++++-- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/api/controllers/console/explore/parameter.py b/api/controllers/console/explore/parameter.py index aab7dd7888..3ad92a5436 100644 --- a/api/controllers/console/explore/parameter.py +++ b/api/controllers/console/explore/parameter.py @@ -21,7 +21,11 @@ class AppParameterApi(InstalledAppResource): "options": fields.List(fields.String), } - system_parameters_fields = {"image_file_size_limit": fields.String} + system_parameters_fields = { + "image_file_size_limit": fields.Integer, + "video_file_size_limit": fields.Integer, + "audio_file_size_limit": fields.Integer, + } parameters_fields = { "opening_statement": fields.String, @@ -82,7 +86,11 @@ class AppParameterApi(InstalledAppResource): } }, ), - "system_parameters": {"image_file_size_limit": dify_config.UPLOAD_IMAGE_FILE_SIZE_LIMIT}, + "system_parameters": { + "image_file_size_limit": dify_config.UPLOAD_IMAGE_FILE_SIZE_LIMIT, + "video_file_size_limit": dify_config.UPLOAD_VIDEO_FILE_SIZE_LIMIT, + "audio_file_size_limit": dify_config.UPLOAD_AUDIO_FILE_SIZE_LIMIT, + }, } diff --git a/api/controllers/service_api/app/app.py b/api/controllers/service_api/app/app.py index f7c091217b..85d5388c50 100644 --- a/api/controllers/service_api/app/app.py +++ b/api/controllers/service_api/app/app.py @@ -21,7 +21,11 @@ class AppParameterApi(Resource): "options": fields.List(fields.String), } - system_parameters_fields = {"image_file_size_limit": fields.String} + system_parameters_fields = { + "image_file_size_limit": fields.String, + "video_file_size_limit": fields.Integer, + "audio_file_size_limit": fields.Integer, + } parameters_fields = { "opening_statement": fields.String, @@ -81,7 +85,11 @@ class AppParameterApi(Resource): } }, ), - "system_parameters": {"image_file_size_limit": dify_config.UPLOAD_IMAGE_FILE_SIZE_LIMIT}, + "system_parameters": { + "image_file_size_limit": dify_config.UPLOAD_IMAGE_FILE_SIZE_LIMIT, + "video_file_size_limit": dify_config.UPLOAD_VIDEO_FILE_SIZE_LIMIT, + "audio_file_size_limit": dify_config.UPLOAD_AUDIO_FILE_SIZE_LIMIT, + }, } diff --git a/api/controllers/web/app.py b/api/controllers/web/app.py index 20b4e4674c..62106d9893 100644 --- a/api/controllers/web/app.py +++ b/api/controllers/web/app.py @@ -21,7 +21,11 @@ class AppParameterApi(WebApiResource): "options": fields.List(fields.String), } - system_parameters_fields = {"image_file_size_limit": fields.String} + system_parameters_fields = { + "image_file_size_limit": fields.Integer, + "video_file_size_limit": fields.Integer, + "audio_file_size_limit": fields.Integer, + } parameters_fields = { "opening_statement": fields.String, @@ -80,7 +84,11 @@ class AppParameterApi(WebApiResource): } }, ), - "system_parameters": {"image_file_size_limit": dify_config.UPLOAD_IMAGE_FILE_SIZE_LIMIT}, + "system_parameters": { + "image_file_size_limit": dify_config.UPLOAD_IMAGE_FILE_SIZE_LIMIT, + "video_file_size_limit": dify_config.UPLOAD_VIDEO_FILE_SIZE_LIMIT, + "audio_file_size_limit": dify_config.UPLOAD_AUDIO_FILE_SIZE_LIMIT, + }, } From e71f494839a616bba58f463ab2207e2d39f1338f Mon Sep 17 00:00:00 2001 From: ice yao <yao3690093@gmail.com> Date: Thu, 24 Oct 2024 21:53:37 +0800 Subject: [PATCH 204/346] chore: abstract common function with local storage (#9811) --- api/extensions/storage/local_fs_storage.py | 66 ++++++++-------------- 1 file changed, 23 insertions(+), 43 deletions(-) diff --git a/api/extensions/storage/local_fs_storage.py b/api/extensions/storage/local_fs_storage.py index e458b3ce8a..b4146d7384 100644 --- a/api/extensions/storage/local_fs_storage.py +++ b/api/extensions/storage/local_fs_storage.py @@ -19,68 +19,48 @@ class LocalFsStorage(BaseStorage): folder = os.path.join(current_app.root_path, folder) self.folder = folder - def save(self, filename, data): + def _build_filepath(self, filename: str) -> str: + """Build the full file path based on the folder and filename.""" if not self.folder or self.folder.endswith("/"): - filename = self.folder + filename + return self.folder + filename else: - filename = self.folder + "/" + filename + return self.folder + "/" + filename - folder = os.path.dirname(filename) + def save(self, filename, data): + filepath = self._build_filepath(filename) + folder = os.path.dirname(filepath) os.makedirs(folder, exist_ok=True) - - Path(os.path.join(os.getcwd(), filename)).write_bytes(data) + Path(os.path.join(os.getcwd(), filepath)).write_bytes(data) def load_once(self, filename: str) -> bytes: - if not self.folder or self.folder.endswith("/"): - filename = self.folder + filename - else: - filename = self.folder + "/" + filename - - if not os.path.exists(filename): + filepath = self._build_filepath(filename) + if not os.path.exists(filepath): raise FileNotFoundError("File not found") - - data = Path(filename).read_bytes() - return data + return Path(filepath).read_bytes() def load_stream(self, filename: str) -> Generator: - def generate(filename: str = filename) -> Generator: - if not self.folder or self.folder.endswith("/"): - filename = self.folder + filename - else: - filename = self.folder + "/" + filename + filepath = self._build_filepath(filename) - if not os.path.exists(filename): + def generate() -> Generator: + if not os.path.exists(filepath): raise FileNotFoundError("File not found") - - with open(filename, "rb") as f: + with open(filepath, "rb") as f: while chunk := f.read(4096): # Read in chunks of 4KB yield chunk return generate() def download(self, filename, target_filepath): - if not self.folder or self.folder.endswith("/"): - filename = self.folder + filename - else: - filename = self.folder + "/" + filename - - if not os.path.exists(filename): + filepath = self._build_filepath(filename) + if not os.path.exists(filepath): raise FileNotFoundError("File not found") - - shutil.copyfile(filename, target_filepath) + shutil.copyfile(filepath, target_filepath) def exists(self, filename): - if not self.folder or self.folder.endswith("/"): - filename = self.folder + filename - else: - filename = self.folder + "/" + filename - - return os.path.exists(filename) + filepath = self._build_filepath(filename) + return os.path.exists(filepath) def delete(self, filename): - if not self.folder or self.folder.endswith("/"): - filename = self.folder + filename - else: - filename = self.folder + "/" + filename - if os.path.exists(filename): - os.remove(filename) + filepath = self._build_filepath(filename) + if os.path.exists(filepath): + os.remove(filepath) From 88dec6ef2b33f03302f1a9405c3662b85aef1c6b Mon Sep 17 00:00:00 2001 From: Zixuan Cheng <61724187+Theysua@users.noreply.github.com> Date: Thu, 24 Oct 2024 07:13:06 -0700 Subject: [PATCH 205/346] Added description for .ppt, specify the reason for unstructured.io (#9452) Co-authored-by: crazywoola <427733928@qq.com> --- api/core/rag/extractor/extract_processor.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/api/core/rag/extractor/extract_processor.py b/api/core/rag/extractor/extract_processor.py index 6a23f3cfef..a0b1aa4cef 100644 --- a/api/core/rag/extractor/extract_processor.py +++ b/api/core/rag/extractor/extract_processor.py @@ -121,6 +121,8 @@ class ExtractProcessor: extractor = UnstructuredEmailExtractor(file_path, unstructured_api_url, unstructured_api_key) elif file_extension == ".ppt": extractor = UnstructuredPPTExtractor(file_path, unstructured_api_url, unstructured_api_key) + # You must first specify the API key + # because unstructured_api_key is necessary to parse .ppt documents elif file_extension == ".pptx": extractor = UnstructuredPPTXExtractor(file_path, unstructured_api_url, unstructured_api_key) elif file_extension == ".xml": From 2346b0ab9992b867922b09322a1789ae94f4330f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9D=9E=E6=B3=95=E6=93=8D=E4=BD=9C?= <hjlarry@163.com> Date: Thu, 24 Oct 2024 22:54:48 +0800 Subject: [PATCH 206/346] chore: make doc extractor node also can extract text by file extension (#9543) --- .../workflow/nodes/document_extractor/node.py | 38 +++++++++++++++++-- .../nodes/test_document_extractor_node.py | 19 +++++++--- 2 files changed, 48 insertions(+), 9 deletions(-) diff --git a/api/core/workflow/nodes/document_extractor/node.py b/api/core/workflow/nodes/document_extractor/node.py index 3efcc373b1..b4ffee1f13 100644 --- a/api/core/workflow/nodes/document_extractor/node.py +++ b/api/core/workflow/nodes/document_extractor/node.py @@ -75,7 +75,7 @@ class DocumentExtractorNode(BaseNode[DocumentExtractorNodeData]): ) -def _extract_text(*, file_content: bytes, mime_type: str) -> str: +def _extract_text_by_mime_type(*, file_content: bytes, mime_type: str) -> str: """Extract text from a file based on its MIME type.""" if mime_type.startswith("text/plain") or mime_type in {"text/html", "text/htm", "text/markdown", "text/xml"}: return _extract_text_from_plain_text(file_content) @@ -107,6 +107,33 @@ def _extract_text(*, file_content: bytes, mime_type: str) -> str: raise UnsupportedFileTypeError(f"Unsupported MIME type: {mime_type}") +def _extract_text_by_file_extension(*, file_content: bytes, file_extension: str) -> str: + """Extract text from a file based on its file extension.""" + match file_extension: + case ".txt" | ".markdown" | ".md" | ".html" | ".htm" | ".xml": + return _extract_text_from_plain_text(file_content) + case ".pdf": + return _extract_text_from_pdf(file_content) + case ".doc" | ".docx": + return _extract_text_from_doc(file_content) + case ".csv": + return _extract_text_from_csv(file_content) + case ".xls" | ".xlsx": + return _extract_text_from_excel(file_content) + case ".ppt": + return _extract_text_from_ppt(file_content) + case ".pptx": + return _extract_text_from_pptx(file_content) + case ".epub": + return _extract_text_from_epub(file_content) + case ".eml": + return _extract_text_from_eml(file_content) + case ".msg": + return _extract_text_from_msg(file_content) + case _: + raise UnsupportedFileTypeError(f"Unsupported Extension Type: {file_extension}") + + def _extract_text_from_plain_text(file_content: bytes) -> str: try: return file_content.decode("utf-8") @@ -159,7 +186,10 @@ def _extract_text_from_file(file: File): if file.mime_type is None: raise UnsupportedFileTypeError("Unable to determine file type: MIME type is missing") file_content = _download_file_content(file) - extracted_text = _extract_text(file_content=file_content, mime_type=file.mime_type) + if file.transfer_method == FileTransferMethod.REMOTE_URL: + extracted_text = _extract_text_by_mime_type(file_content=file_content, mime_type=file.mime_type) + else: + extracted_text = _extract_text_by_file_extension(file_content=file_content, file_extension=file.extension) return extracted_text @@ -172,7 +202,7 @@ def _extract_text_from_csv(file_content: bytes) -> str: if not rows: return "" - # Create markdown table + # Create Markdown table markdown_table = "| " + " | ".join(rows[0]) + " |\n" markdown_table += "| " + " | ".join(["---"] * len(rows[0])) + " |\n" for row in rows[1:]: @@ -192,7 +222,7 @@ def _extract_text_from_excel(file_content: bytes) -> str: # Drop rows where all elements are NaN df.dropna(how="all", inplace=True) - # Convert DataFrame to markdown table + # Convert DataFrame to Markdown table markdown_table = df.to_markdown(index=False) return markdown_table except Exception as e: diff --git a/api/tests/unit_tests/core/workflow/nodes/test_document_extractor_node.py b/api/tests/unit_tests/core/workflow/nodes/test_document_extractor_node.py index 7471e13e1e..a141fa9a13 100644 --- a/api/tests/unit_tests/core/workflow/nodes/test_document_extractor_node.py +++ b/api/tests/unit_tests/core/workflow/nodes/test_document_extractor_node.py @@ -63,17 +63,24 @@ def test_run_invalid_variable_type(document_extractor_node, mock_graph_runtime_s @pytest.mark.parametrize( - ("mime_type", "file_content", "expected_text", "transfer_method"), + ("mime_type", "file_content", "expected_text", "transfer_method", "extension"), [ - ("text/plain", b"Hello, world!", ["Hello, world!"], FileTransferMethod.LOCAL_FILE), - ("application/pdf", b"%PDF-1.5\n%Test PDF content", ["Mocked PDF content"], FileTransferMethod.LOCAL_FILE), + ("text/plain", b"Hello, world!", ["Hello, world!"], FileTransferMethod.LOCAL_FILE, ".txt"), + ( + "application/pdf", + b"%PDF-1.5\n%Test PDF content", + ["Mocked PDF content"], + FileTransferMethod.LOCAL_FILE, + ".pdf", + ), ( "application/vnd.openxmlformats-officedocument.wordprocessingml.document", b"PK\x03\x04", ["Mocked DOCX content"], - FileTransferMethod.LOCAL_FILE, + FileTransferMethod.REMOTE_URL, + "", ), - ("text/plain", b"Remote content", ["Remote content"], FileTransferMethod.REMOTE_URL), + ("text/plain", b"Remote content", ["Remote content"], FileTransferMethod.REMOTE_URL, None), ], ) def test_run_extract_text( @@ -83,6 +90,7 @@ def test_run_extract_text( file_content, expected_text, transfer_method, + extension, monkeypatch, ): document_extractor_node.graph_runtime_state = mock_graph_runtime_state @@ -92,6 +100,7 @@ def test_run_extract_text( mock_file.transfer_method = transfer_method mock_file.related_id = "test_file_id" if transfer_method == FileTransferMethod.LOCAL_FILE else None mock_file.remote_url = "https://example.com/file.txt" if transfer_method == FileTransferMethod.REMOTE_URL else None + mock_file.extension = extension mock_array_file_segment = Mock(spec=ArrayFileSegment) mock_array_file_segment.value = [mock_file] From 5d1424f67c86ddef745686896606ffbe6edea8e1 Mon Sep 17 00:00:00 2001 From: KVOJJJin <jzongcode@gmail.com> Date: Thu, 24 Oct 2024 22:55:17 +0800 Subject: [PATCH 207/346] Feat: use file size limit from api (#9739) --- .../app/configuration/debug/index.tsx | 5 +- .../components/app/configuration/index.tsx | 12 +- .../chat/chat-with-history/chat-wrapper.tsx | 4 + .../chat-with-history/config-panel/form.tsx | 3 + .../chat/embedded-chatbot/chat-wrapper.tsx | 4 + .../embedded-chatbot/config-panel/form.tsx | 3 + web/app/components/base/features/types.ts | 2 + .../base/file-uploader/constants.ts | 4 + .../components/base/file-uploader/hooks.ts | 113 ++++++++++++++++-- .../share/text-generation/index.tsx | 1 + .../share/text-generation/run-once/index.tsx | 10 +- web/app/components/workflow/index.tsx | 4 + .../components/before-run-form/form-item.tsx | 39 +++++- .../_base/components/file-upload-setting.tsx | 14 ++- web/i18n/en-US/app-debug.ts | 2 +- web/i18n/en-US/common.ts | 2 +- web/i18n/zh-Hans/app-debug.ts | 2 +- web/i18n/zh-Hans/common.ts | 2 +- web/models/common.ts | 7 +- 19 files changed, 205 insertions(+), 28 deletions(-) diff --git a/web/app/components/app/configuration/debug/index.tsx b/web/app/components/app/configuration/debug/index.tsx index 71e441d415..480bd782ae 100644 --- a/web/app/components/app/configuration/debug/index.tsx +++ b/web/app/components/app/configuration/debug/index.tsx @@ -1,6 +1,5 @@ 'use client' import type { FC } from 'react' -import useSWR from 'swr' import { useTranslation } from 'react-i18next' import React, { useCallback, useEffect, useRef, useState } from 'react' import produce, { setAutoFreeze } from 'immer' @@ -39,7 +38,6 @@ import { promptVariablesToUserInputsForm } from '@/utils/model-config' import TextGeneration from '@/app/components/app/text-generate/item' import { IS_CE_EDITION } from '@/config' import type { Inputs } from '@/models/debug' -import { fetchFileUploadConfig } from '@/service/common' import { useDefaultModel } from '@/app/components/header/account-setting/model-provider-page/hooks' import { ModelFeatureEnum, ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations' import type { ModelParameterModalProps } from '@/app/components/header/account-setting/model-provider-page/model-parameter-modal' @@ -94,7 +92,6 @@ const Debug: FC<IDebug> = ({ } = useContext(ConfigContext) const { eventEmitter } = useEventEmitterContextContext() const { data: text2speechDefaultModel } = useDefaultModel(ModelTypeEnum.textEmbedding) - const { data: fileUploadConfigResponse } = useSWR({ url: '/files/upload' }, fetchFileUploadConfig) useEffect(() => { setAutoFreeze(false) return () => { @@ -452,7 +449,7 @@ const Debug: FC<IDebug> = ({ visionConfig={{ ...features.file! as VisionSettings, transfer_methods: features.file!.allowed_file_upload_methods || [], - image_file_size_limit: fileUploadConfigResponse?.image_file_size_limit, + image_file_size_limit: features.file?.fileUploadConfig?.image_file_size_limit, }} onVisionFilesChange={setCompletionFiles} /> diff --git a/web/app/components/app/configuration/index.tsx b/web/app/components/app/configuration/index.tsx index 434b54ab91..12ee7d75ad 100644 --- a/web/app/components/app/configuration/index.tsx +++ b/web/app/components/app/configuration/index.tsx @@ -1,6 +1,7 @@ 'use client' import type { FC } from 'react' import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react' +import useSWR from 'swr' import { useTranslation } from 'react-i18next' import { useContext } from 'use-context-selector' import { usePathname } from 'next/navigation' @@ -69,6 +70,7 @@ import type { Features as FeaturesData, FileUpload } from '@/app/components/base import { FILE_EXTS } from '@/app/components/base/prompt-editor/constants' import { SupportUploadFileTypes } from '@/app/components/workflow/types' import NewFeaturePanel from '@/app/components/base/features/new-feature-panel' +import { fetchFileUploadConfig } from '@/service/common' type PublishConfig = { modelConfig: ModelConfig @@ -84,6 +86,8 @@ const Configuration: FC = () => { showAppConfigureFeaturesModal: state.showAppConfigureFeaturesModal, setShowAppConfigureFeaturesModal: state.setShowAppConfigureFeaturesModal, }))) + const { data: fileUploadConfigResponse } = useSWR({ url: '/files/upload' }, fetchFileUploadConfig) + const latestPublishedAt = useMemo(() => appDetail?.model_config.updated_at, [appDetail]) const [formattingChanged, setFormattingChanged] = useState(false) const { setShowAccountSettingModal } = useModalContext() @@ -462,12 +466,13 @@ const Configuration: FC = () => { allowed_file_extensions: modelConfig.file_upload?.allowed_file_extensions || FILE_EXTS[SupportUploadFileTypes.image].map(ext => `.${ext}`), allowed_file_upload_methods: modelConfig.file_upload?.allowed_file_upload_methods || modelConfig.file_upload?.image?.transfer_methods || ['local_file', 'remote_url'], number_limits: modelConfig.file_upload?.number_limits || modelConfig.file_upload?.image?.number_limits || 3, + fileUploadConfig: fileUploadConfigResponse, } as FileUpload, suggested: modelConfig.suggested_questions_after_answer || { enabled: false }, citation: modelConfig.retriever_resource || { enabled: false }, annotationReply: modelConfig.annotation_reply || { enabled: false }, } - }, [modelConfig]) + }, [fileUploadConfigResponse, modelConfig]) const handleFeaturesChange = useCallback((flag: any) => { setShowAppConfigureFeaturesModal(true) if (flag) @@ -684,6 +689,9 @@ const Configuration: FC = () => { }, })) + const fileUpload = { ...features?.file } + delete fileUpload?.fileUploadConfig + // new model config data struct const data: BackendModelConfig = { // Simple Mode prompt @@ -700,7 +708,7 @@ const Configuration: FC = () => { sensitive_word_avoidance: features?.moderation as any, speech_to_text: features?.speech2text as any, text_to_speech: features?.text2speech as any, - file_upload: features?.file as any, + file_upload: fileUpload as any, suggested_questions_after_answer: features?.suggested as any, retriever_resource: features?.citation as any, agent_mode: { diff --git a/web/app/components/base/chat/chat-with-history/chat-wrapper.tsx b/web/app/components/base/chat/chat-with-history/chat-wrapper.tsx index e632b14969..724ef78e75 100644 --- a/web/app/components/base/chat/chat-with-history/chat-wrapper.tsx +++ b/web/app/components/base/chat/chat-with-history/chat-wrapper.tsx @@ -40,6 +40,10 @@ const ChatWrapper = () => { return { ...config, + file_upload: { + ...(config as any).file_upload, + fileUploadConfig: (config as any).system_parameters, + }, supportFeedback: true, opening_statement: currentConversationId ? currentConversationItem?.introduction : (config as any).opening_statement, } as ChatConfig diff --git a/web/app/components/base/chat/chat-with-history/config-panel/form.tsx b/web/app/components/base/chat/chat-with-history/config-panel/form.tsx index 298d8ccd7f..1292edabd2 100644 --- a/web/app/components/base/chat/chat-with-history/config-panel/form.tsx +++ b/web/app/components/base/chat/chat-with-history/config-panel/form.tsx @@ -9,6 +9,7 @@ import { FileUploaderInAttachmentWrapper } from '@/app/components/base/file-uplo const Form = () => { const { t } = useTranslation() const { + appParams, inputsForms, newConversationInputs, newConversationInputsRef, @@ -61,6 +62,7 @@ const Form = () => { allowed_file_extensions: form.allowed_file_extensions, allowed_file_upload_methods: form.allowed_file_upload_methods, number_limits: 1, + fileUploadConfig: (appParams as any).system_parameters, }} /> ) @@ -75,6 +77,7 @@ const Form = () => { allowed_file_extensions: form.allowed_file_extensions, allowed_file_upload_methods: form.allowed_file_upload_methods, number_limits: form.max_length, + fileUploadConfig: (appParams as any).system_parameters, }} /> ) diff --git a/web/app/components/base/chat/embedded-chatbot/chat-wrapper.tsx b/web/app/components/base/chat/embedded-chatbot/chat-wrapper.tsx index ae4667306f..04f65b549c 100644 --- a/web/app/components/base/chat/embedded-chatbot/chat-wrapper.tsx +++ b/web/app/components/base/chat/embedded-chatbot/chat-wrapper.tsx @@ -42,6 +42,10 @@ const ChatWrapper = () => { return { ...config, + file_upload: { + ...(config as any).file_upload, + fileUploadConfig: (config as any).system_parameters, + }, supportFeedback: true, opening_statement: currentConversationId ? currentConversationItem?.introduction : (config as any).opening_statement, } as ChatConfig diff --git a/web/app/components/base/chat/embedded-chatbot/config-panel/form.tsx b/web/app/components/base/chat/embedded-chatbot/config-panel/form.tsx index 211907d48b..718b9a9d94 100644 --- a/web/app/components/base/chat/embedded-chatbot/config-panel/form.tsx +++ b/web/app/components/base/chat/embedded-chatbot/config-panel/form.tsx @@ -9,6 +9,7 @@ import { FileUploaderInAttachmentWrapper } from '@/app/components/base/file-uplo const Form = () => { const { t } = useTranslation() const { + appParams, inputsForms, newConversationInputs, newConversationInputsRef, @@ -73,6 +74,7 @@ const Form = () => { allowed_file_extensions: form.allowed_file_extensions, allowed_file_upload_methods: form.allowed_file_upload_methods, number_limits: 1, + fileUploadConfig: (appParams as any).system_parameters, }} /> ) @@ -87,6 +89,7 @@ const Form = () => { allowed_file_extensions: form.allowed_file_extensions, allowed_file_upload_methods: form.allowed_file_upload_methods, number_limits: form.max_length, + fileUploadConfig: (appParams as any).system_parameters, }} /> ) diff --git a/web/app/components/base/features/types.ts b/web/app/components/base/features/types.ts index 3307f12cda..83f876383d 100644 --- a/web/app/components/base/features/types.ts +++ b/web/app/components/base/features/types.ts @@ -1,4 +1,5 @@ import type { Resolution, TransferMethod, TtsAutoPlay } from '@/types/app' +import type { FileUploadConfigResponse } from '@/models/common' export type EnabledOrDisabled = { enabled?: boolean @@ -38,6 +39,7 @@ export type FileUpload = { allowed_file_extensions?: string[] allowed_file_upload_methods?: TransferMethod[] number_limits?: number + fileUploadConfig?: FileUploadConfigResponse } & EnabledOrDisabled export type AnnotationReplyConfig = { diff --git a/web/app/components/base/file-uploader/constants.ts b/web/app/components/base/file-uploader/constants.ts index e6cc2995f9..629fe2566b 100644 --- a/web/app/components/base/file-uploader/constants.ts +++ b/web/app/components/base/file-uploader/constants.ts @@ -1,3 +1,7 @@ +// fallback for file size limit of dify_config +export const IMG_SIZE_LIMIT = 10 * 1024 * 1024 export const FILE_SIZE_LIMIT = 15 * 1024 * 1024 +export const AUDIO_SIZE_LIMIT = 50 * 1024 * 1024 +export const VIDEO_SIZE_LIMIT = 100 * 1024 * 1024 export const FILE_URL_REGEX = /^(https?|ftp):\/\// diff --git a/web/app/components/base/file-uploader/hooks.ts b/web/app/components/base/file-uploader/hooks.ts index 5e126a87b5..942e5d612a 100644 --- a/web/app/components/base/file-uploader/hooks.ts +++ b/web/app/components/base/file-uploader/hooks.ts @@ -14,19 +14,113 @@ import { getSupportFileType, isAllowedFileExtension, } from './utils' -import { FILE_SIZE_LIMIT } from './constants' +import { + AUDIO_SIZE_LIMIT, + FILE_SIZE_LIMIT, + IMG_SIZE_LIMIT, + VIDEO_SIZE_LIMIT, +} from '@/app/components/base/file-uploader/constants' import { useToastContext } from '@/app/components/base/toast' import { TransferMethod } from '@/types/app' import { SupportUploadFileTypes } from '@/app/components/workflow/types' import type { FileUpload } from '@/app/components/base/features/types' import { formatFileSize } from '@/utils/format' import { fetchRemoteFileInfo } from '@/service/common' +import type { FileUploadConfigResponse } from '@/models/common' + +export const useFileSizeLimit = (fileUploadConfig?: FileUploadConfigResponse) => { + const imgSizeLimit = Number(fileUploadConfig?.image_file_size_limit) * 1024 * 1024 || IMG_SIZE_LIMIT + const docSizeLimit = Number(fileUploadConfig?.file_size_limit) * 1024 * 1024 || FILE_SIZE_LIMIT + const audioSizeLimit = Number(fileUploadConfig?.audio_file_size_limit) * 1024 * 1024 || AUDIO_SIZE_LIMIT + const videoSizeLimit = Number(fileUploadConfig?.video_file_size_limit) * 1024 * 1024 || VIDEO_SIZE_LIMIT + + return { + imgSizeLimit, + docSizeLimit, + audioSizeLimit, + videoSizeLimit, + } +} export const useFile = (fileConfig: FileUpload) => { const { t } = useTranslation() const { notify } = useToastContext() const fileStore = useFileStore() const params = useParams() + const { imgSizeLimit, docSizeLimit, audioSizeLimit, videoSizeLimit } = useFileSizeLimit(fileConfig.fileUploadConfig) + + const checkSizeLimit = (fileType: string, fileSize: number) => { + switch (fileType) { + case SupportUploadFileTypes.image: { + if (fileSize > imgSizeLimit) { + notify({ + type: 'error', + message: t('common.fileUploader.uploadFromComputerLimit', { + type: SupportUploadFileTypes.image, + size: formatFileSize(imgSizeLimit), + }), + }) + return false + } + return true + } + case SupportUploadFileTypes.document: { + if (fileSize > docSizeLimit) { + notify({ + type: 'error', + message: t('common.fileUploader.uploadFromComputerLimit', { + type: SupportUploadFileTypes.document, + size: formatFileSize(docSizeLimit), + }), + }) + return false + } + return true + } + case SupportUploadFileTypes.audio: { + if (fileSize > audioSizeLimit) { + notify({ + type: 'error', + message: t('common.fileUploader.uploadFromComputerLimit', { + type: SupportUploadFileTypes.audio, + size: formatFileSize(audioSizeLimit), + }), + }) + return false + } + return true + } + case SupportUploadFileTypes.video: { + if (fileSize > videoSizeLimit) { + notify({ + type: 'error', + message: t('common.fileUploader.uploadFromComputerLimit', { + type: SupportUploadFileTypes.video, + size: formatFileSize(videoSizeLimit), + }), + }) + return false + } + return true + } + case SupportUploadFileTypes.custom: { + if (fileSize > docSizeLimit) { + notify({ + type: 'error', + message: t('common.fileUploader.uploadFromComputerLimit', { + type: SupportUploadFileTypes.document, + size: formatFileSize(docSizeLimit), + }), + }) + return false + } + return true + } + default: { + return true + } + } + } const handleAddFile = useCallback((newFile: FileEntity) => { const { @@ -117,12 +211,15 @@ export const useFile = (fileConfig: FileUpload) => { progress: 100, supportFileType: getSupportFileType(url, res.file_type, allowedFileTypes?.includes(SupportUploadFileTypes.custom)), } - handleUpdateFile(newFile) + if (!checkSizeLimit(newFile.supportFileType, newFile.size)) + handleRemoveFile(uploadingFile.id) + else + handleUpdateFile(newFile) }).catch(() => { notify({ type: 'error', message: t('common.fileUploader.pasteFileLinkInvalid') }) handleRemoveFile(uploadingFile.id) }) - }, [handleAddFile, handleUpdateFile, notify, t, handleRemoveFile, fileConfig?.allowed_file_types]) + }, [checkSizeLimit, handleAddFile, handleUpdateFile, notify, t, handleRemoveFile, fileConfig?.allowed_file_types]) const handleLoadFileFromLinkSuccess = useCallback(() => { }, []) @@ -140,13 +237,13 @@ export const useFile = (fileConfig: FileUpload) => { notify({ type: 'error', message: t('common.fileUploader.fileExtensionNotSupport') }) return } - if (file.size > FILE_SIZE_LIMIT) { - notify({ type: 'error', message: t('common.fileUploader.uploadFromComputerLimit', { size: formatFileSize(FILE_SIZE_LIMIT) }) }) + const allowedFileTypes = fileConfig.allowed_file_types + const fileType = getSupportFileType(file.name, file.type, allowedFileTypes?.includes(SupportUploadFileTypes.custom)) + if (!checkSizeLimit(fileType, file.size)) return - } + const reader = new FileReader() const isImage = file.type.startsWith('image') - const allowedFileTypes = fileConfig.allowed_file_types reader.addEventListener( 'load', @@ -187,7 +284,7 @@ export const useFile = (fileConfig: FileUpload) => { false, ) reader.readAsDataURL(file) - }, [notify, t, handleAddFile, handleUpdateFile, params.token, fileConfig?.allowed_file_types, fileConfig?.allowed_file_extensions]) + }, [checkSizeLimit, notify, t, handleAddFile, handleUpdateFile, params.token, fileConfig?.allowed_file_types, fileConfig?.allowed_file_extensions]) const handleClipboardPasteFile = useCallback((e: ClipboardEvent<HTMLTextAreaElement>) => { const file = e.clipboardData?.files[0] diff --git a/web/app/components/share/text-generation/index.tsx b/web/app/components/share/text-generation/index.tsx index a2f6864242..0860560e7c 100644 --- a/web/app/components/share/text-generation/index.tsx +++ b/web/app/components/share/text-generation/index.tsx @@ -390,6 +390,7 @@ const TextGeneration: FC<IMainProps> = ({ setVisionConfig({ ...file_upload.image, image_file_size_limit: appParams?.system_parameters?.image_file_size_limit, + fileUploadConfig: appParams?.system_parameters, }) const prompt_variables = userInputsFormToPromptVariables(user_input_form) setPromptConfig({ diff --git a/web/app/components/share/text-generation/run-once/index.tsx b/web/app/components/share/text-generation/run-once/index.tsx index 4cd56e8cef..ed2d15a36f 100644 --- a/web/app/components/share/text-generation/run-once/index.tsx +++ b/web/app/components/share/text-generation/run-once/index.tsx @@ -96,13 +96,19 @@ const RunOnce: FC<IRunOnceProps> = ({ {item.type === 'file' && ( <FileUploaderInAttachmentWrapper onChange={(files) => { onInputsChange({ ...inputs, [item.key]: getProcessedFiles(files)[0] }) }} - fileConfig={item.config as any} + fileConfig={{ + ...item.config, + fileUploadConfig: (visionConfig as any).fileUploadConfig, + }} /> )} {item.type === 'file-list' && ( <FileUploaderInAttachmentWrapper onChange={(files) => { onInputsChange({ ...inputs, [item.key]: getProcessedFiles(files) }) }} - fileConfig={item.config as any} + fileConfig={{ + ...item.config, + fileUploadConfig: (visionConfig as any).fileUploadConfig, + }} /> )} </div> diff --git a/web/app/components/workflow/index.tsx b/web/app/components/workflow/index.tsx index ed28291d69..ecd35876e7 100644 --- a/web/app/components/workflow/index.tsx +++ b/web/app/components/workflow/index.tsx @@ -9,6 +9,7 @@ import { useRef, useState, } from 'react' +import useSWR from 'swr' import { setAutoFreeze } from 'immer' import { useEventListener, @@ -93,6 +94,7 @@ import { useFeaturesStore } from '@/app/components/base/features/hooks' import { useEventEmitterContextContext } from '@/context/event-emitter' import Confirm from '@/app/components/base/confirm' import { FILE_EXTS } from '@/app/components/base/prompt-editor/constants' +import { fetchFileUploadConfig } from '@/service/common' const nodeTypes = { [CUSTOM_NODE]: CustomNode, @@ -382,6 +384,7 @@ const WorkflowWrap = memo(() => { data, isLoading, } = useWorkflowInit() + const { data: fileUploadConfigResponse } = useSWR({ url: '/files/upload' }, fetchFileUploadConfig) const nodesData = useMemo(() => { if (data) @@ -417,6 +420,7 @@ const WorkflowWrap = memo(() => { allowed_file_extensions: features.file_upload?.allowed_file_extensions || FILE_EXTS[SupportUploadFileTypes.image].map(ext => `.${ext}`), allowed_file_upload_methods: features.file_upload?.allowed_file_upload_methods || features.file_upload?.image?.transfer_methods || ['local_file', 'remote_url'], number_limits: features.file_upload?.number_limits || features.file_upload?.image?.number_limits || 3, + fileUploadConfig: fileUploadConfigResponse, }, opening: { enabled: !!features.opening_statement, diff --git a/web/app/components/workflow/nodes/_base/components/before-run-form/form-item.tsx b/web/app/components/workflow/nodes/_base/components/before-run-form/form-item.tsx index c28f402514..e2ca592a62 100644 --- a/web/app/components/workflow/nodes/_base/components/before-run-form/form-item.tsx +++ b/web/app/components/workflow/nodes/_base/components/before-run-form/form-item.tsx @@ -22,6 +22,7 @@ import { VarBlockIcon } from '@/app/components/workflow/block-icon' import { Line3 } from '@/app/components/base/icons/src/public/common' import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development' import { BubbleX } from '@/app/components/base/icons/src/vender/line/others' +import { FILE_EXTS } from '@/app/components/base/prompt-editor/constants' import cn from '@/utils/classnames' type Props = { @@ -168,10 +169,25 @@ const FormItem: FC<Props> = ({ onChange(null) }} fileConfig={{ - allowed_file_types: inStepRun ? [SupportUploadFileTypes.custom] : payload.allowed_file_types, - allowed_file_extensions: inStepRun ? [] : payload.allowed_file_extensions, + allowed_file_types: inStepRun + ? [ + SupportUploadFileTypes.image, + SupportUploadFileTypes.document, + SupportUploadFileTypes.audio, + SupportUploadFileTypes.video, + ] + : payload.allowed_file_types, + allowed_file_extensions: inStepRun + ? [ + ...FILE_EXTS[SupportUploadFileTypes.image], + ...FILE_EXTS[SupportUploadFileTypes.document], + ...FILE_EXTS[SupportUploadFileTypes.audio], + ...FILE_EXTS[SupportUploadFileTypes.video], + ] + : payload.allowed_file_extensions, allowed_file_upload_methods: inStepRun ? [TransferMethod.local_file, TransferMethod.remote_url] : payload.allowed_file_upload_methods, number_limits: 1, + fileUploadConfig: fileSettings?.fileUploadConfig, }} /> )} @@ -180,10 +196,25 @@ const FormItem: FC<Props> = ({ value={value} onChange={files => onChange(files)} fileConfig={{ - allowed_file_types: inStepRun ? [SupportUploadFileTypes.custom] : payload.allowed_file_types, - allowed_file_extensions: inStepRun ? [] : payload.allowed_file_extensions, + allowed_file_types: inStepRun + ? [ + SupportUploadFileTypes.image, + SupportUploadFileTypes.document, + SupportUploadFileTypes.audio, + SupportUploadFileTypes.video, + ] + : payload.allowed_file_types, + allowed_file_extensions: inStepRun + ? [ + ...FILE_EXTS[SupportUploadFileTypes.image], + ...FILE_EXTS[SupportUploadFileTypes.document], + ...FILE_EXTS[SupportUploadFileTypes.audio], + ...FILE_EXTS[SupportUploadFileTypes.video], + ] + : payload.allowed_file_extensions, allowed_file_upload_methods: inStepRun ? [TransferMethod.local_file, TransferMethod.remote_url] : payload.allowed_file_upload_methods, number_limits: inStepRun ? 5 : payload.max_length, + fileUploadConfig: fileSettings?.fileUploadConfig, }} /> )} diff --git a/web/app/components/workflow/nodes/_base/components/file-upload-setting.tsx b/web/app/components/workflow/nodes/_base/components/file-upload-setting.tsx index 77ff2fd5c1..82a3a906cf 100644 --- a/web/app/components/workflow/nodes/_base/components/file-upload-setting.tsx +++ b/web/app/components/workflow/nodes/_base/components/file-upload-setting.tsx @@ -1,6 +1,7 @@ 'use client' import type { FC } from 'react' import React, { useCallback } from 'react' +import useSWR from 'swr' import produce from 'immer' import { useTranslation } from 'react-i18next' import type { UploadFileSetting } from '../../../types' @@ -10,7 +11,8 @@ import FileTypeItem from './file-type-item' import InputNumberWithSlider from './input-number-with-slider' import Field from '@/app/components/app/configuration/config-var/config-modal/field' import { TransferMethod } from '@/types/app' -import { FILE_SIZE_LIMIT } from '@/app/components/base/file-uploader/constants' +import { fetchFileUploadConfig } from '@/service/common' +import { useFileSizeLimit } from '@/app/components/base/file-uploader/hooks' import { formatFileSize } from '@/utils/format' type Props = { @@ -36,6 +38,8 @@ const FileUploadSetting: FC<Props> = ({ allowed_file_types, allowed_file_extensions, } = payload + const { data: fileUploadConfigResponse } = useSWR({ url: '/files/upload' }, fetchFileUploadConfig) + const { imgSizeLimit, docSizeLimit, audioSizeLimit, videoSizeLimit } = useFileSizeLimit(fileUploadConfigResponse) const handleSupportFileTypeChange = useCallback((type: SupportUploadFileTypes) => { const newPayload = produce(payload, (draft) => { @@ -142,7 +146,13 @@ const FileUploadSetting: FC<Props> = ({ title={t('appDebug.variableConfig.maxNumberOfUploads')!} > <div> - <div className='mb-1.5 text-text-tertiary body-xs-regular'>{t('appDebug.variableConfig.maxNumberTip', { size: formatFileSize(FILE_SIZE_LIMIT) })}</div> + <div className='mb-1.5 text-text-tertiary body-xs-regular'>{t('appDebug.variableConfig.maxNumberTip', { + imgLimit: formatFileSize(imgSizeLimit), + docLimit: formatFileSize(docSizeLimit), + audioLimit: formatFileSize(audioSizeLimit), + videoLimit: formatFileSize(videoSizeLimit), + })}</div> + <InputNumberWithSlider value={max_length} min={1} diff --git a/web/i18n/en-US/app-debug.ts b/web/i18n/en-US/app-debug.ts index c0d0193c7c..b2144262f6 100644 --- a/web/i18n/en-US/app-debug.ts +++ b/web/i18n/en-US/app-debug.ts @@ -386,7 +386,7 @@ const translation = { 'localUpload': 'Local Upload', 'both': 'Both', 'maxNumberOfUploads': 'Max number of uploads', - 'maxNumberTip': 'Max {{size}} each', + 'maxNumberTip': 'Document < {{docLimit}}, image < {{imgLimit}}, audio < {{audioLimit}}, video < {{videoLimit}}', 'errorMsg': { labelNameRequired: 'Label name is required', varNameCanBeRepeat: 'Variable name can not be repeated', diff --git a/web/i18n/en-US/common.ts b/web/i18n/en-US/common.ts index 5b82ecf8be..3390280e8a 100644 --- a/web/i18n/en-US/common.ts +++ b/web/i18n/en-US/common.ts @@ -572,7 +572,7 @@ const translation = { pasteFileLinkInputPlaceholder: 'Enter URL...', uploadFromComputerReadError: 'File reading failed, please try again.', uploadFromComputerUploadError: 'File upload failed, please upload again.', - uploadFromComputerLimit: 'Upload File cannot exceed {{size}}', + uploadFromComputerLimit: 'Upload {{type}} cannot exceed {{size}}', pasteFileLinkInvalid: 'Invalid file link', fileExtensionNotSupport: 'File extension not supported', }, diff --git a/web/i18n/zh-Hans/app-debug.ts b/web/i18n/zh-Hans/app-debug.ts index ee8ff7bb29..3e801bcf62 100644 --- a/web/i18n/zh-Hans/app-debug.ts +++ b/web/i18n/zh-Hans/app-debug.ts @@ -379,7 +379,7 @@ const translation = { 'localUpload': '本地上传', 'both': '两者', 'maxNumberOfUploads': '最大上传数', - 'maxNumberTip': '最大上传文件大小为 {{size}}', + 'maxNumberTip': '文档 < {{docLimit}}, 图片 < {{imgLimit}}, 音频 < {{audioLimit}}, 视频 < {{videoLimit}}', 'content': '内容', 'errorMsg': { labelNameRequired: '显示名称必填', diff --git a/web/i18n/zh-Hans/common.ts b/web/i18n/zh-Hans/common.ts index 3cd7ece94e..58d56a8331 100644 --- a/web/i18n/zh-Hans/common.ts +++ b/web/i18n/zh-Hans/common.ts @@ -572,7 +572,7 @@ const translation = { pasteFileLinkInputPlaceholder: '输入文件链接', uploadFromComputerReadError: '文件读取失败,请重新选择。', uploadFromComputerUploadError: '文件上传失败,请重新上传。', - uploadFromComputerLimit: '上传文件不能超过 {{size}}', + uploadFromComputerLimit: '上传 {{type}} 不能超过 {{size}}', pasteFileLinkInvalid: '文件链接无效', fileExtensionNotSupport: '文件类型不支持', }, diff --git a/web/models/common.ts b/web/models/common.ts index 204e89ed9b..9ab27a6018 100644 --- a/web/models/common.ts +++ b/web/models/common.ts @@ -211,9 +211,12 @@ export type PluginProvider = { } export type FileUploadConfigResponse = { - file_size_limit: number batch_count_limit: number - image_file_size_limit?: number | string + image_file_size_limit?: number | string // default is 10MB + file_size_limit: number // default is 15MB + audio_file_size_limit?: number // default is 50MB + video_file_size_limit?: number // default is 100MB + } export type InvitationResult = { From dd1750607814a9a3c31ae20de712f7bfadedbf20 Mon Sep 17 00:00:00 2001 From: -LAN- <laipz8200@outlook.com> Date: Fri, 25 Oct 2024 09:02:06 +0800 Subject: [PATCH 208/346] feat(api): add generic file size limit parameter (#9812) --- api/controllers/console/explore/parameter.py | 2 ++ api/controllers/service_api/app/app.py | 4 +++- api/controllers/web/app.py | 2 ++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/api/controllers/console/explore/parameter.py b/api/controllers/console/explore/parameter.py index 3ad92a5436..7c7580e3c6 100644 --- a/api/controllers/console/explore/parameter.py +++ b/api/controllers/console/explore/parameter.py @@ -25,6 +25,7 @@ class AppParameterApi(InstalledAppResource): "image_file_size_limit": fields.Integer, "video_file_size_limit": fields.Integer, "audio_file_size_limit": fields.Integer, + "file_size_limit": fields.Integer, } parameters_fields = { @@ -90,6 +91,7 @@ class AppParameterApi(InstalledAppResource): "image_file_size_limit": dify_config.UPLOAD_IMAGE_FILE_SIZE_LIMIT, "video_file_size_limit": dify_config.UPLOAD_VIDEO_FILE_SIZE_LIMIT, "audio_file_size_limit": dify_config.UPLOAD_AUDIO_FILE_SIZE_LIMIT, + "file_size_limit": dify_config.UPLOAD_FILE_SIZE_LIMIT, }, } diff --git a/api/controllers/service_api/app/app.py b/api/controllers/service_api/app/app.py index 85d5388c50..9a4cdc26cd 100644 --- a/api/controllers/service_api/app/app.py +++ b/api/controllers/service_api/app/app.py @@ -22,9 +22,10 @@ class AppParameterApi(Resource): } system_parameters_fields = { - "image_file_size_limit": fields.String, + "image_file_size_limit": fields.Integer, "video_file_size_limit": fields.Integer, "audio_file_size_limit": fields.Integer, + "file_size_limit": fields.Integer, } parameters_fields = { @@ -89,6 +90,7 @@ class AppParameterApi(Resource): "image_file_size_limit": dify_config.UPLOAD_IMAGE_FILE_SIZE_LIMIT, "video_file_size_limit": dify_config.UPLOAD_VIDEO_FILE_SIZE_LIMIT, "audio_file_size_limit": dify_config.UPLOAD_AUDIO_FILE_SIZE_LIMIT, + "file_size_limit": dify_config.UPLOAD_FILE_SIZE_LIMIT, }, } diff --git a/api/controllers/web/app.py b/api/controllers/web/app.py index 62106d9893..974d2cff94 100644 --- a/api/controllers/web/app.py +++ b/api/controllers/web/app.py @@ -25,6 +25,7 @@ class AppParameterApi(WebApiResource): "image_file_size_limit": fields.Integer, "video_file_size_limit": fields.Integer, "audio_file_size_limit": fields.Integer, + "file_size_limit": fields.Integer, } parameters_fields = { @@ -88,6 +89,7 @@ class AppParameterApi(WebApiResource): "image_file_size_limit": dify_config.UPLOAD_IMAGE_FILE_SIZE_LIMIT, "video_file_size_limit": dify_config.UPLOAD_VIDEO_FILE_SIZE_LIMIT, "audio_file_size_limit": dify_config.UPLOAD_AUDIO_FILE_SIZE_LIMIT, + "file_size_limit": dify_config.UPLOAD_FILE_SIZE_LIMIT, }, } From 5bf31e7a865e12e2e6a03c27e03d8fe7aab13936 Mon Sep 17 00:00:00 2001 From: zhuhao <37029601+hwzhuhao@users.noreply.github.com> Date: Fri, 25 Oct 2024 10:11:25 +0800 Subject: [PATCH 209/346] refactor: update load_stream method to directly yield file chunks (#9806) --- api/extensions/storage/aliyun_oss_storage.py | 9 +++------ api/extensions/storage/aws_s3_storage.py | 19 ++++++++----------- api/extensions/storage/azure_blob_storage.py | 10 +++------- api/extensions/storage/baidu_obs_storage.py | 9 +++------ .../storage/google_cloud_storage.py | 13 +++++-------- api/extensions/storage/huawei_obs_storage.py | 9 +++------ api/extensions/storage/local_fs_storage.py | 14 +++++--------- api/extensions/storage/oracle_oci_storage.py | 19 ++++++++----------- api/extensions/storage/supabase_storage.py | 13 +++++-------- api/extensions/storage/tencent_cos_storage.py | 7 ++----- .../storage/volcengine_tos_storage.py | 9 +++------ 11 files changed, 48 insertions(+), 83 deletions(-) diff --git a/api/extensions/storage/aliyun_oss_storage.py b/api/extensions/storage/aliyun_oss_storage.py index 01c1000e50..67635b129e 100644 --- a/api/extensions/storage/aliyun_oss_storage.py +++ b/api/extensions/storage/aliyun_oss_storage.py @@ -36,12 +36,9 @@ class AliyunOssStorage(BaseStorage): return data def load_stream(self, filename: str) -> Generator: - def generate(filename: str = filename) -> Generator: - obj = self.client.get_object(self.__wrapper_folder_filename(filename)) - while chunk := obj.read(4096): - yield chunk - - return generate() + obj = self.client.get_object(self.__wrapper_folder_filename(filename)) + while chunk := obj.read(4096): + yield chunk def download(self, filename, target_filepath): self.client.get_object_to_file(self.__wrapper_folder_filename(filename), target_filepath) diff --git a/api/extensions/storage/aws_s3_storage.py b/api/extensions/storage/aws_s3_storage.py index cb67313bb2..ab2d0fba3b 100644 --- a/api/extensions/storage/aws_s3_storage.py +++ b/api/extensions/storage/aws_s3_storage.py @@ -62,17 +62,14 @@ class AwsS3Storage(BaseStorage): return data def load_stream(self, filename: str) -> Generator: - def generate(filename: str = filename) -> Generator: - try: - response = self.client.get_object(Bucket=self.bucket_name, Key=filename) - yield from response["Body"].iter_chunks() - except ClientError as ex: - if ex.response["Error"]["Code"] == "NoSuchKey": - raise FileNotFoundError("File not found") - else: - raise - - return generate() + try: + response = self.client.get_object(Bucket=self.bucket_name, Key=filename) + yield from response["Body"].iter_chunks() + except ClientError as ex: + if ex.response["Error"]["Code"] == "NoSuchKey": + raise FileNotFoundError("File not found") + else: + raise def download(self, filename, target_filepath): self.client.download_file(self.bucket_name, filename, target_filepath) diff --git a/api/extensions/storage/azure_blob_storage.py b/api/extensions/storage/azure_blob_storage.py index 477507feda..11a7544274 100644 --- a/api/extensions/storage/azure_blob_storage.py +++ b/api/extensions/storage/azure_blob_storage.py @@ -32,13 +32,9 @@ class AzureBlobStorage(BaseStorage): def load_stream(self, filename: str) -> Generator: client = self._sync_client() - - def generate(filename: str = filename) -> Generator: - blob = client.get_blob_client(container=self.bucket_name, blob=filename) - blob_data = blob.download_blob() - yield from blob_data.chunks() - - return generate(filename) + blob = client.get_blob_client(container=self.bucket_name, blob=filename) + blob_data = blob.download_blob() + yield from blob_data.chunks() def download(self, filename, target_filepath): client = self._sync_client() diff --git a/api/extensions/storage/baidu_obs_storage.py b/api/extensions/storage/baidu_obs_storage.py index cd69439749..e0d2140e91 100644 --- a/api/extensions/storage/baidu_obs_storage.py +++ b/api/extensions/storage/baidu_obs_storage.py @@ -39,12 +39,9 @@ class BaiduObsStorage(BaseStorage): return response.data.read() def load_stream(self, filename: str) -> Generator: - def generate(filename: str = filename) -> Generator: - response = self.client.get_object(bucket_name=self.bucket_name, key=filename).data - while chunk := response.read(4096): - yield chunk - - return generate() + response = self.client.get_object(bucket_name=self.bucket_name, key=filename).data + while chunk := response.read(4096): + yield chunk def download(self, filename, target_filepath): self.client.get_object_to_file(bucket_name=self.bucket_name, key=filename, file_name=target_filepath) diff --git a/api/extensions/storage/google_cloud_storage.py b/api/extensions/storage/google_cloud_storage.py index e90392a6ba..26b662d2f0 100644 --- a/api/extensions/storage/google_cloud_storage.py +++ b/api/extensions/storage/google_cloud_storage.py @@ -39,14 +39,11 @@ class GoogleCloudStorage(BaseStorage): return data def load_stream(self, filename: str) -> Generator: - def generate(filename: str = filename) -> Generator: - bucket = self.client.get_bucket(self.bucket_name) - blob = bucket.get_blob(filename) - with blob.open(mode="rb") as blob_stream: - while chunk := blob_stream.read(4096): - yield chunk - - return generate() + bucket = self.client.get_bucket(self.bucket_name) + blob = bucket.get_blob(filename) + with blob.open(mode="rb") as blob_stream: + while chunk := blob_stream.read(4096): + yield chunk def download(self, filename, target_filepath): bucket = self.client.get_bucket(self.bucket_name) diff --git a/api/extensions/storage/huawei_obs_storage.py b/api/extensions/storage/huawei_obs_storage.py index 3c443d87ac..20be70ef83 100644 --- a/api/extensions/storage/huawei_obs_storage.py +++ b/api/extensions/storage/huawei_obs_storage.py @@ -27,12 +27,9 @@ class HuaweiObsStorage(BaseStorage): return data def load_stream(self, filename: str) -> Generator: - def generate(filename: str = filename) -> Generator: - response = self.client.getObject(bucketName=self.bucket_name, objectKey=filename)["body"].response - while chunk := response.read(4096): - yield chunk - - return generate() + response = self.client.getObject(bucketName=self.bucket_name, objectKey=filename)["body"].response + while chunk := response.read(4096): + yield chunk def download(self, filename, target_filepath): self.client.getObject(bucketName=self.bucket_name, objectKey=filename, downloadPath=target_filepath) diff --git a/api/extensions/storage/local_fs_storage.py b/api/extensions/storage/local_fs_storage.py index b4146d7384..5a495ca4d4 100644 --- a/api/extensions/storage/local_fs_storage.py +++ b/api/extensions/storage/local_fs_storage.py @@ -40,15 +40,11 @@ class LocalFsStorage(BaseStorage): def load_stream(self, filename: str) -> Generator: filepath = self._build_filepath(filename) - - def generate() -> Generator: - if not os.path.exists(filepath): - raise FileNotFoundError("File not found") - with open(filepath, "rb") as f: - while chunk := f.read(4096): # Read in chunks of 4KB - yield chunk - - return generate() + if not os.path.exists(filepath): + raise FileNotFoundError("File not found") + with open(filepath, "rb") as f: + while chunk := f.read(4096): # Read in chunks of 4KB + yield chunk def download(self, filename, target_filepath): filepath = self._build_filepath(filename) diff --git a/api/extensions/storage/oracle_oci_storage.py b/api/extensions/storage/oracle_oci_storage.py index e4f50b34e9..b59f83b8de 100644 --- a/api/extensions/storage/oracle_oci_storage.py +++ b/api/extensions/storage/oracle_oci_storage.py @@ -36,17 +36,14 @@ class OracleOCIStorage(BaseStorage): return data def load_stream(self, filename: str) -> Generator: - def generate(filename: str = filename) -> Generator: - try: - response = self.client.get_object(Bucket=self.bucket_name, Key=filename) - yield from response["Body"].iter_chunks() - except ClientError as ex: - if ex.response["Error"]["Code"] == "NoSuchKey": - raise FileNotFoundError("File not found") - else: - raise - - return generate() + try: + response = self.client.get_object(Bucket=self.bucket_name, Key=filename) + yield from response["Body"].iter_chunks() + except ClientError as ex: + if ex.response["Error"]["Code"] == "NoSuchKey": + raise FileNotFoundError("File not found") + else: + raise def download(self, filename, target_filepath): self.client.download_file(self.bucket_name, filename, target_filepath) diff --git a/api/extensions/storage/supabase_storage.py b/api/extensions/storage/supabase_storage.py index 1119244574..9f7c69a9ae 100644 --- a/api/extensions/storage/supabase_storage.py +++ b/api/extensions/storage/supabase_storage.py @@ -36,17 +36,14 @@ class SupabaseStorage(BaseStorage): return content def load_stream(self, filename: str) -> Generator: - def generate(filename: str = filename) -> Generator: - result = self.client.storage.from_(self.bucket_name).download(filename) - byte_stream = io.BytesIO(result) - while chunk := byte_stream.read(4096): # Read in chunks of 4KB - yield chunk - - return generate() + result = self.client.storage.from_(self.bucket_name).download(filename) + byte_stream = io.BytesIO(result) + while chunk := byte_stream.read(4096): # Read in chunks of 4KB + yield chunk def download(self, filename, target_filepath): result = self.client.storage.from_(self.bucket_name).download(filename) - Path(result).write_bytes(result) + Path(target_filepath).write_bytes(result) def exists(self, filename): result = self.client.storage.from_(self.bucket_name).list(filename) diff --git a/api/extensions/storage/tencent_cos_storage.py b/api/extensions/storage/tencent_cos_storage.py index 8fd8e703a1..13a6c9239c 100644 --- a/api/extensions/storage/tencent_cos_storage.py +++ b/api/extensions/storage/tencent_cos_storage.py @@ -29,11 +29,8 @@ class TencentCosStorage(BaseStorage): return data def load_stream(self, filename: str) -> Generator: - def generate(filename: str = filename) -> Generator: - response = self.client.get_object(Bucket=self.bucket_name, Key=filename) - yield from response["Body"].get_stream(chunk_size=4096) - - return generate() + response = self.client.get_object(Bucket=self.bucket_name, Key=filename) + yield from response["Body"].get_stream(chunk_size=4096) def download(self, filename, target_filepath): response = self.client.get_object(Bucket=self.bucket_name, Key=filename) diff --git a/api/extensions/storage/volcengine_tos_storage.py b/api/extensions/storage/volcengine_tos_storage.py index 389c5630e3..de82be04ea 100644 --- a/api/extensions/storage/volcengine_tos_storage.py +++ b/api/extensions/storage/volcengine_tos_storage.py @@ -27,12 +27,9 @@ class VolcengineTosStorage(BaseStorage): return data def load_stream(self, filename: str) -> Generator: - def generate(filename: str = filename) -> Generator: - response = self.client.get_object(bucket=self.bucket_name, key=filename) - while chunk := response.read(4096): - yield chunk - - return generate() + response = self.client.get_object(bucket=self.bucket_name, key=filename) + while chunk := response.read(4096): + yield chunk def download(self, filename, target_filepath): self.client.get_object_to_file(bucket=self.bucket_name, key=filename, file_path=target_filepath) From ac9f1e9de59621e0b2cfe724ca7514681146190e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9D=9E=E6=B3=95=E6=93=8D=E4=BD=9C?= <hjlarry@163.com> Date: Fri, 25 Oct 2024 10:11:33 +0800 Subject: [PATCH 210/346] fix: duckduckgo image search not work (#9821) --- .../provider/builtin/duckduckgo/tools/ddgo_img.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/api/core/tools/provider/builtin/duckduckgo/tools/ddgo_img.py b/api/core/tools/provider/builtin/duckduckgo/tools/ddgo_img.py index 3173fb9e13..54bb38755a 100644 --- a/api/core/tools/provider/builtin/duckduckgo/tools/ddgo_img.py +++ b/api/core/tools/provider/builtin/duckduckgo/tools/ddgo_img.py @@ -2,7 +2,6 @@ from typing import Any from duckduckgo_search import DDGS -from core.file.models import FileTransferMethod from core.tools.entities.tool_entities import ToolInvokeMessage from core.tools.tool.builtin_tool import BuiltinTool @@ -20,11 +19,9 @@ class DuckDuckGoImageSearchTool(BuiltinTool): "max_results": tool_parameters.get("max_results"), } response = DDGS().images(**query_dict) - result = [] + markdown_result = "\n\n" + json_result = [] for res in response: - res["transfer_method"] = FileTransferMethod.REMOTE_URL - msg = ToolInvokeMessage( - type=ToolInvokeMessage.MessageType.IMAGE_LINK, message=res.get("image"), save_as="", meta=res - ) - result.append(msg) - return result + markdown_result += f"![{res.get('title') or ''}]({res.get('image') or ''})" + json_result.append(self.create_json_message(res)) + return [self.create_text_message(markdown_result)] + json_result From 0ef35a0ee0e2264a1cc7f3020304e8c357152c11 Mon Sep 17 00:00:00 2001 From: StyleZhang <jasonapring2015@outlook.com> Date: Fri, 25 Oct 2024 10:41:05 +0800 Subject: [PATCH 211/346] fix: enable_marketplace --- web/app/components/plugins/plugin-page/index.tsx | 4 ++-- web/app/components/tools/provider-list.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/web/app/components/plugins/plugin-page/index.tsx b/web/app/components/plugins/plugin-page/index.tsx index 9d432df664..7335dfbb16 100644 --- a/web/app/components/plugins/plugin-page/index.tsx +++ b/web/app/components/plugins/plugin-page/index.tsx @@ -100,7 +100,7 @@ const PluginPage = ({ return [ { value: 'plugins', text: t('common.menus.plugins') }, ...( - !enable_marketplace + enable_marketplace ? [{ value: 'discover', text: 'Explore Marketplace' }] : [] ), @@ -214,7 +214,7 @@ const PluginPage = ({ </> )} { - activeTab === 'discover' && !enable_marketplace && marketplace + activeTab === 'discover' && enable_marketplace && marketplace } {showPluginSettingModal && ( diff --git a/web/app/components/tools/provider-list.tsx b/web/app/components/tools/provider-list.tsx index 3f2593020e..7a8ceff0db 100644 --- a/web/app/components/tools/provider-list.tsx +++ b/web/app/components/tools/provider-list.tsx @@ -118,7 +118,7 @@ const ProviderList = () => { {!filteredCollectionList.length && <div className='absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2'><Empty /></div>} </div> { - !enable_marketplace && ( + enable_marketplace && ( <Marketplace onMarketplaceScroll={() => { containerRef.current?.scrollTo({ top: containerRef.current.scrollHeight, behavior: 'smooth' }) }} /> From 90769ac7095838d713033c73cfac7307c22773fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=83=AD=E4=BC=9F=E4=BC=9F?= <gww0426@163.com> Date: Fri, 25 Oct 2024 10:50:15 +0800 Subject: [PATCH 212/346] feat: create_empty_dataset api add the description parameter and update api docs (#9824) --- api/controllers/console/datasets/datasets.py | 8 +++++++ .../service_api/dataset/dataset.py | 8 +++++++ api/services/dataset_service.py | 2 ++ .../datasets/template/template.en.mdx | 19 +++++++++++++++ .../datasets/template/template.zh.mdx | 23 +++++++++++++++++-- 5 files changed, 58 insertions(+), 2 deletions(-) diff --git a/api/controllers/console/datasets/datasets.py b/api/controllers/console/datasets/datasets.py index 6e6792936e..b500c6c3fa 100644 --- a/api/controllers/console/datasets/datasets.py +++ b/api/controllers/console/datasets/datasets.py @@ -102,6 +102,13 @@ class DatasetListApi(Resource): help="type is required. Name must be between 1 to 40 characters.", type=_validate_name, ) + parser.add_argument( + "description", + type=str, + nullable=True, + required=False, + default="", + ) parser.add_argument( "indexing_technique", type=str, @@ -140,6 +147,7 @@ class DatasetListApi(Resource): dataset = DatasetService.create_empty_dataset( tenant_id=current_user.current_tenant_id, name=args["name"], + description=args["description"], indexing_technique=args["indexing_technique"], account=current_user, permission=DatasetPermissionEnum.ONLY_ME, diff --git a/api/controllers/service_api/dataset/dataset.py b/api/controllers/service_api/dataset/dataset.py index f076cff6c8..799fccc228 100644 --- a/api/controllers/service_api/dataset/dataset.py +++ b/api/controllers/service_api/dataset/dataset.py @@ -66,6 +66,13 @@ class DatasetListApi(DatasetApiResource): help="type is required. Name must be between 1 to 40 characters.", type=_validate_name, ) + parser.add_argument( + "description", + type=str, + nullable=True, + required=False, + default="", + ) parser.add_argument( "indexing_technique", type=str, @@ -108,6 +115,7 @@ class DatasetListApi(DatasetApiResource): dataset = DatasetService.create_empty_dataset( tenant_id=tenant_id, name=args["name"], + description=args["description"], indexing_technique=args["indexing_technique"], account=current_user, permission=args["permission"], diff --git a/api/services/dataset_service.py b/api/services/dataset_service.py index ede8764086..ca084bde56 100644 --- a/api/services/dataset_service.py +++ b/api/services/dataset_service.py @@ -140,6 +140,7 @@ class DatasetService: def create_empty_dataset( tenant_id: str, name: str, + description: Optional[str], indexing_technique: Optional[str], account: Account, permission: Optional[str] = None, @@ -158,6 +159,7 @@ class DatasetService: ) dataset = Dataset(name=name, indexing_technique=indexing_technique) # dataset = Dataset(name=name, provider=provider, config=config) + dataset.description = description dataset.created_by = account.id dataset.updated_by = account.id dataset.tenant_id = tenant_id diff --git a/web/app/(commonLayout)/datasets/template/template.en.mdx b/web/app/(commonLayout)/datasets/template/template.en.mdx index b846f6d9fb..e264fd707e 100644 --- a/web/app/(commonLayout)/datasets/template/template.en.mdx +++ b/web/app/(commonLayout)/datasets/template/template.en.mdx @@ -236,12 +236,31 @@ import { Row, Col, Properties, Property, Heading, SubProperty, Paragraph } from <Property name='name' type='string' key='name'> Knowledge name </Property> + <Property name='description' type='string' key='description'> + Knowledge description (optional) + </Property> + <Property name='indexing_technique' type='string' key='indexing_technique'> + Index Technique (optional) + - <code>high_quality</code> high_quality + - <code>economy</code> economy + </Property> <Property name='permission' type='string' key='permission'> Permission - <code>only_me</code> Only me - <code>all_team_members</code> All team members - <code>partial_members</code> Partial members </Property> + <Property name='provider' type='string' key='provider'> + Provider (optional, default: vendor) + - <code>vendor</code> vendor + - <code>external</code> external knowledge + </Property> + <Property name='external_knowledge_api_id' type='str' key='external_knowledge_api_id'> + External Knowledge api id (optional) + </Property> + <Property name='external_knowledge_id' type='str' key='external_knowledge_id'> + External Knowledge id (optional) + </Property> </Properties> </Col> <Col sticky> diff --git a/web/app/(commonLayout)/datasets/template/template.zh.mdx b/web/app/(commonLayout)/datasets/template/template.zh.mdx index ece4d3b771..5d52664db4 100644 --- a/web/app/(commonLayout)/datasets/template/template.zh.mdx +++ b/web/app/(commonLayout)/datasets/template/template.zh.mdx @@ -234,14 +234,33 @@ import { Row, Col, Properties, Property, Heading, SubProperty, Paragraph } from ### Request Body <Properties> <Property name='name' type='string' key='name'> - 知识库名称 + 知识库名称(必填) + </Property> + <Property name='description' type='string' key='description'> + 知识库描述(选填) + </Property> + <Property name='indexing_technique' type='string' key='indexing_technique'> + 索引模式(选填,建议填写) + - <code>high_quality</code> 高质量 + - <code>economy</code> 经济 </Property> <Property name='permission' type='string' key='permission'> - 权限 + 权限(选填,默认only_me) - <code>only_me</code> 仅自己 - <code>all_team_members</code> 所有团队成员 - <code>partial_members</code> 部分团队成员 </Property> + <Property name='provider' type='string' key='provider'> + provider,(选填,默认 vendor) + - <code>vendor</code> 上传文件 + - <code>external</code> 外部知识库 + </Property> + <Property name='external_knowledge_api_id' type='str' key='external_knowledge_api_id'> + 外部知识库 API_ID(选填) + </Property> + <Property name='external_knowledge_id' type='str' key='external_knowledge_id'> + 外部知识库 ID(选填) + </Property> </Properties> </Col> <Col sticky> From 5b7b7650909f3634dc441721b98dfef9fa27f323 Mon Sep 17 00:00:00 2001 From: crazywoola <100913391+crazywoola@users.noreply.github.com> Date: Fri, 25 Oct 2024 11:11:18 +0800 Subject: [PATCH 213/346] fix: yuque book id should be string (#9819) --- .../tools/provider/builtin/aliyuque/tools/base.py | 14 +++----------- .../builtin/aliyuque/tools/create_document.py | 7 ------- .../builtin/aliyuque/tools/create_document.yaml | 2 +- .../builtin/aliyuque/tools/delete_document.py | 8 -------- .../builtin/aliyuque/tools/delete_document.yaml | 2 +- .../aliyuque/tools/describe_book_index_page.py | 7 ------- .../tools/describe_book_table_of_contents.py | 8 -------- .../tools/describe_book_table_of_contents.yaml | 2 +- .../aliyuque/tools/describe_document_content.py | 10 +--------- .../builtin/aliyuque/tools/describe_documents.py | 7 ------- .../builtin/aliyuque/tools/describe_documents.yaml | 2 +- .../tools/update_book_table_of_contents.py | 8 -------- .../tools/update_book_table_of_contents.yaml | 2 +- .../builtin/aliyuque/tools/update_document.py | 7 ------- .../builtin/aliyuque/tools/update_document.yaml | 2 +- 15 files changed, 10 insertions(+), 78 deletions(-) diff --git a/api/core/tools/provider/builtin/aliyuque/tools/base.py b/api/core/tools/provider/builtin/aliyuque/tools/base.py index fb7e219bff..edfb9fea8e 100644 --- a/api/core/tools/provider/builtin/aliyuque/tools/base.py +++ b/api/core/tools/provider/builtin/aliyuque/tools/base.py @@ -1,10 +1,3 @@ -""" -语雀客户端 -""" - -__author__ = "佐井" -__created__ = "2024-06-01 09:45:20" - from typing import Any import requests @@ -29,14 +22,13 @@ class AliYuqueTool: session = requests.Session() session.headers.update({"accept": "application/json", "X-Auth-Token": token}) new_params = {**tool_parameters} - # 找出需要替换的变量 + replacements = {k: v for k, v in new_params.items() if f"{{{k}}}" in path} - # 替换 path 中的变量 for key, value in replacements.items(): path = path.replace(f"{{{key}}}", str(value)) - del new_params[key] # 从 kwargs 中删除已经替换的变量 - # 请求接口 + del new_params[key] + if method.upper() in {"POST", "PUT"}: session.headers.update( { diff --git a/api/core/tools/provider/builtin/aliyuque/tools/create_document.py b/api/core/tools/provider/builtin/aliyuque/tools/create_document.py index feadc29258..01080fd1d5 100644 --- a/api/core/tools/provider/builtin/aliyuque/tools/create_document.py +++ b/api/core/tools/provider/builtin/aliyuque/tools/create_document.py @@ -1,10 +1,3 @@ -""" -创建文档 -""" - -__author__ = "佐井" -__created__ = "2024-06-01 10:45:20" - from typing import Any, Union from core.tools.entities.tool_entities import ToolInvokeMessage diff --git a/api/core/tools/provider/builtin/aliyuque/tools/create_document.yaml b/api/core/tools/provider/builtin/aliyuque/tools/create_document.yaml index b9d1c60327..6ac8ae6696 100644 --- a/api/core/tools/provider/builtin/aliyuque/tools/create_document.yaml +++ b/api/core/tools/provider/builtin/aliyuque/tools/create_document.yaml @@ -13,7 +13,7 @@ description: parameters: - name: book_id - type: number + type: string required: true form: llm label: diff --git a/api/core/tools/provider/builtin/aliyuque/tools/delete_document.py b/api/core/tools/provider/builtin/aliyuque/tools/delete_document.py index 74c731a944..84237cec30 100644 --- a/api/core/tools/provider/builtin/aliyuque/tools/delete_document.py +++ b/api/core/tools/provider/builtin/aliyuque/tools/delete_document.py @@ -1,11 +1,3 @@ -#!/usr/bin/env python3 -""" -删除文档 -""" - -__author__ = "佐井" -__created__ = "2024-09-17 22:04" - from typing import Any, Union from core.tools.entities.tool_entities import ToolInvokeMessage diff --git a/api/core/tools/provider/builtin/aliyuque/tools/delete_document.yaml b/api/core/tools/provider/builtin/aliyuque/tools/delete_document.yaml index 87372c5350..dddd62d304 100644 --- a/api/core/tools/provider/builtin/aliyuque/tools/delete_document.yaml +++ b/api/core/tools/provider/builtin/aliyuque/tools/delete_document.yaml @@ -13,7 +13,7 @@ description: parameters: - name: book_id - type: number + type: string required: true form: llm label: diff --git a/api/core/tools/provider/builtin/aliyuque/tools/describe_book_index_page.py b/api/core/tools/provider/builtin/aliyuque/tools/describe_book_index_page.py index 02bf603a24..c23d30059a 100644 --- a/api/core/tools/provider/builtin/aliyuque/tools/describe_book_index_page.py +++ b/api/core/tools/provider/builtin/aliyuque/tools/describe_book_index_page.py @@ -1,10 +1,3 @@ -""" -获取知识库首页 -""" - -__author__ = "佐井" -__created__ = "2024-06-01 22:57:14" - from typing import Any, Union from core.tools.entities.tool_entities import ToolInvokeMessage diff --git a/api/core/tools/provider/builtin/aliyuque/tools/describe_book_table_of_contents.py b/api/core/tools/provider/builtin/aliyuque/tools/describe_book_table_of_contents.py index fcfe449c6d..36f8c10d6f 100644 --- a/api/core/tools/provider/builtin/aliyuque/tools/describe_book_table_of_contents.py +++ b/api/core/tools/provider/builtin/aliyuque/tools/describe_book_table_of_contents.py @@ -1,11 +1,3 @@ -#!/usr/bin/env python3 -""" -获取知识库目录 -""" - -__author__ = "佐井" -__created__ = "2024-09-17 15:17:11" - from typing import Any, Union from core.tools.entities.tool_entities import ToolInvokeMessage diff --git a/api/core/tools/provider/builtin/aliyuque/tools/describe_book_table_of_contents.yaml b/api/core/tools/provider/builtin/aliyuque/tools/describe_book_table_of_contents.yaml index 0c2bd22132..0a481b59eb 100644 --- a/api/core/tools/provider/builtin/aliyuque/tools/describe_book_table_of_contents.yaml +++ b/api/core/tools/provider/builtin/aliyuque/tools/describe_book_table_of_contents.yaml @@ -13,7 +13,7 @@ description: parameters: - name: book_id - type: number + type: string required: true form: llm label: diff --git a/api/core/tools/provider/builtin/aliyuque/tools/describe_document_content.py b/api/core/tools/provider/builtin/aliyuque/tools/describe_document_content.py index 1e70593879..a69bf121f7 100644 --- a/api/core/tools/provider/builtin/aliyuque/tools/describe_document_content.py +++ b/api/core/tools/provider/builtin/aliyuque/tools/describe_document_content.py @@ -1,10 +1,3 @@ -""" -获取文档 -""" - -__author__ = "佐井" -__created__ = "2024-06-02 07:11:45" - import json from typing import Any, Union from urllib.parse import urlparse @@ -37,7 +30,6 @@ class AliYuqueDescribeDocumentContentTool(AliYuqueTool, BuiltinTool): book_slug = path_parts[-2] group_id = path_parts[-3] - # 1. 请求首页信息,获取book_id new_params["group_login"] = group_id new_params["book_slug"] = book_slug index_page = json.loads( @@ -46,7 +38,7 @@ class AliYuqueDescribeDocumentContentTool(AliYuqueTool, BuiltinTool): book_id = index_page.get("data", {}).get("book", {}).get("id") if not book_id: raise Exception(f"can not parse book_id from {index_page}") - # 2. 获取文档内容 + new_params["book_id"] = book_id new_params["id"] = doc_id data = self.request("GET", token, new_params, "/api/v2/repos/{book_id}/docs/{id}") diff --git a/api/core/tools/provider/builtin/aliyuque/tools/describe_documents.py b/api/core/tools/provider/builtin/aliyuque/tools/describe_documents.py index ed1b2a8643..7a45684bed 100644 --- a/api/core/tools/provider/builtin/aliyuque/tools/describe_documents.py +++ b/api/core/tools/provider/builtin/aliyuque/tools/describe_documents.py @@ -1,10 +1,3 @@ -""" -获取文档 -""" - -__author__ = "佐井" -__created__ = "2024-06-01 10:45:20" - from typing import Any, Union from core.tools.entities.tool_entities import ToolInvokeMessage diff --git a/api/core/tools/provider/builtin/aliyuque/tools/describe_documents.yaml b/api/core/tools/provider/builtin/aliyuque/tools/describe_documents.yaml index 5156345d71..0b14c1afba 100644 --- a/api/core/tools/provider/builtin/aliyuque/tools/describe_documents.yaml +++ b/api/core/tools/provider/builtin/aliyuque/tools/describe_documents.yaml @@ -14,7 +14,7 @@ description: parameters: - name: book_id - type: number + type: string required: true form: llm label: diff --git a/api/core/tools/provider/builtin/aliyuque/tools/update_book_table_of_contents.py b/api/core/tools/provider/builtin/aliyuque/tools/update_book_table_of_contents.py index 932559445e..ca0a3909f8 100644 --- a/api/core/tools/provider/builtin/aliyuque/tools/update_book_table_of_contents.py +++ b/api/core/tools/provider/builtin/aliyuque/tools/update_book_table_of_contents.py @@ -1,11 +1,3 @@ -#!/usr/bin/env python3 -""" -获取知识库目录 -""" - -__author__ = "佐井" -__created__ = "2024-09-17 15:17:11" - from typing import Any, Union from core.tools.entities.tool_entities import ToolInvokeMessage diff --git a/api/core/tools/provider/builtin/aliyuque/tools/update_book_table_of_contents.yaml b/api/core/tools/provider/builtin/aliyuque/tools/update_book_table_of_contents.yaml index f0c0024f17..f85970348b 100644 --- a/api/core/tools/provider/builtin/aliyuque/tools/update_book_table_of_contents.yaml +++ b/api/core/tools/provider/builtin/aliyuque/tools/update_book_table_of_contents.yaml @@ -13,7 +13,7 @@ description: parameters: - name: book_id - type: number + type: string required: true form: llm label: diff --git a/api/core/tools/provider/builtin/aliyuque/tools/update_document.py b/api/core/tools/provider/builtin/aliyuque/tools/update_document.py index 0c6e0205e1..d7eba46ad9 100644 --- a/api/core/tools/provider/builtin/aliyuque/tools/update_document.py +++ b/api/core/tools/provider/builtin/aliyuque/tools/update_document.py @@ -1,10 +1,3 @@ -""" -更新文档 -""" - -__author__ = "佐井" -__created__ = "2024-06-19 16:50:07" - from typing import Any, Union from core.tools.entities.tool_entities import ToolInvokeMessage diff --git a/api/core/tools/provider/builtin/aliyuque/tools/update_document.yaml b/api/core/tools/provider/builtin/aliyuque/tools/update_document.yaml index 87f88c9b1b..c2da6b179a 100644 --- a/api/core/tools/provider/builtin/aliyuque/tools/update_document.yaml +++ b/api/core/tools/provider/builtin/aliyuque/tools/update_document.yaml @@ -12,7 +12,7 @@ description: llm: Update doc in a knowledge base via ID/path. parameters: - name: book_id - type: number + type: string required: true form: llm label: From fc2297a2ca0f0a766f9ef88bdf4765d134d40bae Mon Sep 17 00:00:00 2001 From: ice yao <yao3690093@gmail.com> Date: Fri, 25 Oct 2024 11:11:26 +0800 Subject: [PATCH 214/346] chore: add local storage test (#9827) --- api/tests/unit_tests/oss/__mock/base.py | 58 +++++++++++++++++++ api/tests/unit_tests/oss/__mock/local.py | 57 ++++++++++++++++++ .../unit_tests/oss/__mock/volcengine_tos.py | 24 +++----- .../unit_tests/oss/local/test_local_fs.py | 18 ++++++ .../oss/volcengine_tos/test_volcengine_tos.py | 58 +++---------------- 5 files changed, 148 insertions(+), 67 deletions(-) create mode 100644 api/tests/unit_tests/oss/__mock/base.py create mode 100644 api/tests/unit_tests/oss/__mock/local.py create mode 100644 api/tests/unit_tests/oss/local/test_local_fs.py diff --git a/api/tests/unit_tests/oss/__mock/base.py b/api/tests/unit_tests/oss/__mock/base.py new file mode 100644 index 0000000000..a1eaaab9c3 --- /dev/null +++ b/api/tests/unit_tests/oss/__mock/base.py @@ -0,0 +1,58 @@ +from collections.abc import Generator + +import pytest + +from extensions.storage.base_storage import BaseStorage + + +def get_example_folder() -> str: + return "/dify" + + +def get_example_bucket() -> str: + return "dify" + + +def get_example_filename() -> str: + return "test.txt" + + +def get_example_data() -> bytes: + return b"test" + + +def get_example_filepath() -> str: + return "/test" + + +class BaseStorageTest: + @pytest.fixture(autouse=True) + def setup_method(self): + """Should be implemented in child classes to setup specific storage.""" + self.storage = BaseStorage() + + def test_save(self): + """Test saving data.""" + self.storage.save(get_example_filename(), get_example_data()) + + def test_load_once(self): + """Test loading data once.""" + assert self.storage.load_once(get_example_filename()) == get_example_data() + + def test_load_stream(self): + """Test loading data as a stream.""" + generator = self.storage.load_stream(get_example_filename()) + assert isinstance(generator, Generator) + assert next(generator) == get_example_data() + + def test_download(self): + """Test downloading data.""" + self.storage.download(get_example_filename(), get_example_filepath()) + + def test_exists(self): + """Test checking if a file exists.""" + assert self.storage.exists(get_example_filename()) + + def test_delete(self): + """Test deleting a file.""" + self.storage.delete(get_example_filename()) diff --git a/api/tests/unit_tests/oss/__mock/local.py b/api/tests/unit_tests/oss/__mock/local.py new file mode 100644 index 0000000000..95cc06958c --- /dev/null +++ b/api/tests/unit_tests/oss/__mock/local.py @@ -0,0 +1,57 @@ +import os +import shutil +from pathlib import Path +from unittest.mock import MagicMock, mock_open, patch + +import pytest +from _pytest.monkeypatch import MonkeyPatch + +from tests.unit_tests.oss.__mock.base import ( + get_example_data, + get_example_filename, + get_example_filepath, + get_example_folder, +) + + +class MockLocalFSClass: + def write_bytes(self, data): + assert data == get_example_data() + + def read_bytes(self): + return get_example_data() + + @staticmethod + def copyfile(src, dst): + assert src == os.path.join(get_example_folder(), get_example_filename()) + assert dst == get_example_filepath() + + @staticmethod + def exists(path): + assert path == os.path.join(get_example_folder(), get_example_filename()) + return True + + @staticmethod + def remove(path): + assert path == os.path.join(get_example_folder(), get_example_filename()) + + +MOCK = os.getenv("MOCK_SWITCH", "false").lower() == "true" + + +@pytest.fixture +def setup_local_fs_mock(monkeypatch: MonkeyPatch): + if MOCK: + monkeypatch.setattr(Path, "write_bytes", MockLocalFSClass.write_bytes) + monkeypatch.setattr(Path, "read_bytes", MockLocalFSClass.read_bytes) + monkeypatch.setattr(shutil, "copyfile", MockLocalFSClass.copyfile) + monkeypatch.setattr(os.path, "exists", MockLocalFSClass.exists) + monkeypatch.setattr(os, "remove", MockLocalFSClass.remove) + + os.makedirs = MagicMock() + + with patch("builtins.open", mock_open(read_data=get_example_data())): + yield + + if MOCK: + monkeypatch.undo() diff --git a/api/tests/unit_tests/oss/__mock/volcengine_tos.py b/api/tests/unit_tests/oss/__mock/volcengine_tos.py index 241764c521..1194a03258 100644 --- a/api/tests/unit_tests/oss/__mock/volcengine_tos.py +++ b/api/tests/unit_tests/oss/__mock/volcengine_tos.py @@ -1,5 +1,4 @@ import os -from typing import Union from unittest.mock import MagicMock import pytest @@ -7,28 +6,19 @@ from _pytest.monkeypatch import MonkeyPatch from tos import TosClientV2 from tos.clientv2 import DeleteObjectOutput, GetObjectOutput, HeadObjectOutput, PutObjectOutput +from tests.unit_tests.oss.__mock.base import ( + get_example_bucket, + get_example_data, + get_example_filename, + get_example_filepath, +) + class AttrDict(dict): def __getattr__(self, item): return self.get(item) -def get_example_bucket() -> str: - return "dify" - - -def get_example_filename() -> str: - return "test.txt" - - -def get_example_data() -> bytes: - return b"test" - - -def get_example_filepath() -> str: - return "/test" - - class MockVolcengineTosClass: def __init__(self, ak="", sk="", endpoint="", region=""): self.bucket_name = get_example_bucket() diff --git a/api/tests/unit_tests/oss/local/test_local_fs.py b/api/tests/unit_tests/oss/local/test_local_fs.py new file mode 100644 index 0000000000..03ce7d2450 --- /dev/null +++ b/api/tests/unit_tests/oss/local/test_local_fs.py @@ -0,0 +1,18 @@ +from collections.abc import Generator + +import pytest + +from extensions.storage.local_fs_storage import LocalFsStorage +from tests.unit_tests.oss.__mock.base import ( + BaseStorageTest, + get_example_folder, +) +from tests.unit_tests.oss.__mock.local import setup_local_fs_mock + + +class TestLocalFS(BaseStorageTest): + @pytest.fixture(autouse=True) + def setup_method(self, setup_local_fs_mock): + """Executed before each test method.""" + self.storage = LocalFsStorage() + self.storage.folder = get_example_folder() diff --git a/api/tests/unit_tests/oss/volcengine_tos/test_volcengine_tos.py b/api/tests/unit_tests/oss/volcengine_tos/test_volcengine_tos.py index 545d18044d..9f8aa158a9 100644 --- a/api/tests/unit_tests/oss/volcengine_tos/test_volcengine_tos.py +++ b/api/tests/unit_tests/oss/volcengine_tos/test_volcengine_tos.py @@ -1,30 +1,20 @@ from collections.abc import Generator -from flask import Flask +import pytest from tos import TosClientV2 -from tos.clientv2 import GetObjectOutput, HeadObjectOutput, PutObjectOutput from extensions.storage.volcengine_tos_storage import VolcengineTosStorage -from tests.unit_tests.oss.__mock.volcengine_tos import ( +from tests.unit_tests.oss.__mock.base import ( + BaseStorageTest, get_example_bucket, - get_example_data, - get_example_filename, - get_example_filepath, - setup_volcengine_tos_mock, ) +from tests.unit_tests.oss.__mock.volcengine_tos import setup_volcengine_tos_mock -class VolcengineTosTest: - _instance = None - - def __new__(cls): - if cls._instance == None: - cls._instance = object.__new__(cls) - return cls._instance - else: - return cls._instance - - def __init__(self): +class TestVolcengineTos(BaseStorageTest): + @pytest.fixture(autouse=True) + def setup_method(self, setup_volcengine_tos_mock): + """Executed before each test method.""" self.storage = VolcengineTosStorage() self.storage.bucket_name = get_example_bucket() self.storage.client = TosClientV2( @@ -33,35 +23,3 @@ class VolcengineTosTest: endpoint="https://xxx.volces.com", region="cn-beijing", ) - - -def test_save(setup_volcengine_tos_mock): - volc_tos = VolcengineTosTest() - volc_tos.storage.save(get_example_filename(), get_example_data()) - - -def test_load_once(setup_volcengine_tos_mock): - volc_tos = VolcengineTosTest() - assert volc_tos.storage.load_once(get_example_filename()) == get_example_data() - - -def test_load_stream(setup_volcengine_tos_mock): - volc_tos = VolcengineTosTest() - generator = volc_tos.storage.load_stream(get_example_filename()) - assert isinstance(generator, Generator) - assert next(generator) == get_example_data() - - -def test_download(setup_volcengine_tos_mock): - volc_tos = VolcengineTosTest() - volc_tos.storage.download(get_example_filename(), get_example_filepath()) - - -def test_exists(setup_volcengine_tos_mock): - volc_tos = VolcengineTosTest() - assert volc_tos.storage.exists(get_example_filename()) - - -def test_delete(setup_volcengine_tos_mock): - volc_tos = VolcengineTosTest() - volc_tos.storage.delete(get_example_filename()) From ae00211691cf9a2cbf733665f05d1174d085f63c Mon Sep 17 00:00:00 2001 From: StyleZhang <jasonapring2015@outlook.com> Date: Fri, 25 Oct 2024 11:15:32 +0800 Subject: [PATCH 215/346] feat: marketplace types --- .../plugins/marketplace/list/index.tsx | 4 +--- .../components/plugins/marketplace/types.ts | 19 +++++++++++++++++++ web/service/plugins.ts | 12 ++++++++++++ 3 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 web/app/components/plugins/marketplace/types.ts diff --git a/web/app/components/plugins/marketplace/list/index.tsx b/web/app/components/plugins/marketplace/list/index.tsx index c3d7ff1d24..a805522b43 100644 --- a/web/app/components/plugins/marketplace/list/index.tsx +++ b/web/app/components/plugins/marketplace/list/index.tsx @@ -1,11 +1,9 @@ +'use client' import Card from '@/app/components/plugins/card' import CardMoreInfo from '@/app/components/plugins/card/card-more-info' import { toolNotion } from '@/app/components/plugins/card/card-mock' -import { getLocaleOnServer } from '@/i18n/server' const List = () => { - const locale = getLocaleOnServer() - return ( <div className='px-12 py-2 bg-background-default-subtle'> <div className='py-3'> diff --git a/web/app/components/plugins/marketplace/types.ts b/web/app/components/plugins/marketplace/types.ts new file mode 100644 index 0000000000..6af481cfb8 --- /dev/null +++ b/web/app/components/plugins/marketplace/types.ts @@ -0,0 +1,19 @@ +import type { Plugin } from '../types' + +export type MarketplaceCollection = { + name: string + description: string + rule: string + created_at: string + updated_at: string +} + +export type MarketplaceCollectionsResponse = { + collections: MarketplaceCollection[] + total: number +} + +export type MarketplaceCollectionPluginsResponse = { + plugins: Plugin[] + total: number +} diff --git a/web/service/plugins.ts b/web/service/plugins.ts index f1d6f8e223..655825004d 100644 --- a/web/service/plugins.ts +++ b/web/service/plugins.ts @@ -9,6 +9,10 @@ import type { UpdateEndpointRequest, } from '@/app/components/plugins/types' import type { DebugInfo as DebugInfoTypes } from '@/app/components/plugins/types' +import type { + MarketplaceCollectionPluginsResponse, + MarketplaceCollectionsResponse, +} from '@/app/components/plugins/marketplace/types' export const createEndpoint: Fetcher<EndpointOperationResponse, { url: string; body: CreateEndpointRequest }> = ({ url, body }) => { // url = /workspaces/current/endpoints/create @@ -64,3 +68,11 @@ export const installPackageFromLocal = async (uniqueIdentifier: string) => { body: { plugin_unique_identifiers: [uniqueIdentifier] }, }) } + +export const fetchMarketplaceCollections: Fetcher<MarketplaceCollectionsResponse, { url: string; }> = ({ url }) => { + return get<MarketplaceCollectionsResponse>(url) +} + +export const fetchMarketplaceCollectionPlugins: Fetcher<MarketplaceCollectionPluginsResponse, { url: string }> = ({ url }) => { + return get<MarketplaceCollectionPluginsResponse>(url) +} From bdb990eb909745bfcfd1d26bd1121745ad7822e0 Mon Sep 17 00:00:00 2001 From: Joel <iamjoel007@gmail.com> Date: Fri, 25 Oct 2024 11:25:04 +0800 Subject: [PATCH 216/346] merge main --- api/configs/middleware/vdb/upstash_config.py | 20 + api/core/app/segments/parser.py | 18 - api/core/entities/message_entities.py | 29 - api/core/file/constants.py | 1 + api/core/file/enums.py | 55 + api/core/file/file_manager.py | 156 ++ api/core/file/file_obj.py | 145 -- api/core/file/file_repository.py | 32 + api/core/file/helpers.py | 48 + api/core/file/message_file_parser.py | 243 -- api/core/file/models.py | 140 + api/core/file/upload_file_parser.py | 79 - .../llm/claude-3-5-sonnet-20241022.yaml | 39 + .../llm/anthropic.claude-3-sonnet-v2.yaml | 60 + .../llm/eu.anthropic.claude-3-sonnet-v2.yaml | 60 + .../llm/us.anthropic.claude-3-sonnet-v2.yaml | 60 + .../llm/llama-3.2-11b-vision-preview.yaml | 26 + .../llm/llama-3.2-90b-vision-preview.yaml | 26 + .../groq/speech2text/__init__.py | 0 .../distil-whisper-large-v3-en.yaml | 5 + .../groq/speech2text/speech2text.py | 30 + .../speech2text/whisper-large-v3-turbo.yaml | 5 + .../groq/speech2text/whisper-large-v3.yaml | 5 + .../openai/llm/gpt-4o-audio-preview.yaml | 44 + .../openai_api_compatible/rerank/__init__.py | 0 .../openai_api_compatible/rerank/rerank.py | 159 ++ .../llm/anthropic.claude-3.5-sonnet-v2.yaml | 55 + .../rag/datasource/vdb/upstash/__init__.py | 0 .../datasource/vdb/upstash/upstash_vector.py | 129 + .../unstructured_pdf_extractor.py | 47 + .../builtin/aliyuque/_assets/icon.svg | 32 + .../provider/builtin/aliyuque/aliyuque.py | 19 + .../provider/builtin/aliyuque/aliyuque.yaml | 29 + .../provider/builtin/aliyuque/tools/base.py | 50 + .../builtin/aliyuque/tools/create_document.py | 22 + .../aliyuque/tools/create_document.yaml | 99 + .../builtin/aliyuque/tools/delete_document.py | 25 + .../aliyuque/tools/delete_document.yaml | 37 + .../tools/describe_book_index_page.py | 24 + .../tools/describe_book_index_page.yaml | 38 + .../tools/describe_book_table_of_contents.py | 23 + .../describe_book_table_of_contents.yaml | 25 + .../tools/describe_document_content.py | 61 + .../tools/describe_document_content.yaml | 50 + .../aliyuque/tools/describe_documents.py | 24 + .../aliyuque/tools/describe_documents.yaml | 38 + .../tools/update_book_table_of_contents.py | 29 + .../tools/update_book_table_of_contents.yaml | 222 ++ .../builtin/aliyuque/tools/update_document.py | 24 + .../aliyuque/tools/update_document.yaml | 87 + .../builtin/feishu_base/_assets/icon.png | Bin 0 -> 7253 bytes .../builtin/feishu_base/_assets/icon.svg | 47 - .../feishu_base/tools/add_base_record.py | 56 - .../feishu_base/tools/add_base_record.yaml | 66 - .../builtin/feishu_base/tools/add_records.py | 21 + .../feishu_base/tools/add_records.yaml | 91 + .../feishu_base/tools/create_base_table.py | 48 - .../feishu_base/tools/create_base_table.yaml | 106 - .../builtin/feishu_base/tools/create_table.py | 20 + .../feishu_base/tools/create_table.yaml | 61 + .../feishu_base/tools/delete_base_records.py | 56 - .../tools/delete_base_records.yaml | 60 - .../feishu_base/tools/delete_base_tables.py | 46 - .../feishu_base/tools/delete_base_tables.yaml | 48 - .../feishu_base/tools/delete_records.py | 20 + .../feishu_base/tools/delete_records.yaml | 86 + .../feishu_base/tools/delete_tables.py | 19 + .../feishu_base/tools/delete_tables.yaml | 49 + .../tools/get_tenant_access_token.py | 48 - .../tools/get_tenant_access_token.yaml | 39 - .../feishu_base/tools/list_base_records.py | 65 - .../feishu_base/tools/list_base_records.yaml | 108 - .../feishu_base/tools/list_base_tables.py | 47 - .../feishu_base/tools/list_base_tables.yaml | 65 - .../builtin/feishu_base/tools/list_tables.py | 19 + .../feishu_base/tools/list_tables.yaml | 50 + .../feishu_base/tools/read_base_record.py | 49 - .../feishu_base/tools/read_base_record.yaml | 60 - .../builtin/feishu_base/tools/read_records.py | 21 + .../feishu_base/tools/read_records.yaml | 86 + .../feishu_base/tools/search_records.py | 39 + .../feishu_base/tools/search_records.yaml | 163 ++ .../feishu_base/tools/update_base_record.py | 60 - .../feishu_base/tools/update_base_record.yaml | 78 - .../feishu_base/tools/update_records.py | 21 + .../feishu_base/tools/update_records.yaml | 91 + .../podcast_generator/_assets/icon.svg | 24 + .../podcast_generator/podcast_generator.py | 33 + .../podcast_generator/podcast_generator.yaml | 34 + .../tools/podcast_audio_generator.py | 100 + .../tools/podcast_audio_generator.yaml | 95 + .../tools/utils/tool_parameter_converter.py | 71 - .../{app/segments => variables}/__init__.py | 12 + api/core/{app/segments => variables}/exc.py | 0 .../segments => variables}/segment_group.py | 0 .../{app/segments => variables}/segments.py | 45 +- api/core/{app/segments => variables}/types.py | 2 + .../{app/segments => variables}/variables.py | 5 + .../callbacks}/workflow_logging_callback.py | 3 +- api/core/workflow/constants.py | 3 + api/core/workflow/nodes/base/__init__.py | 4 + .../base/entities.py} | 0 .../nodes/{base_node.py => base/node.py} | 68 +- .../nodes/document_extractor/__init__.py | 4 + .../nodes/document_extractor/entities.py | 7 + .../workflow/nodes/document_extractor/exc.py | 14 + .../workflow/nodes/document_extractor/node.py | 274 ++ api/core/workflow/nodes/enums.py | 24 + api/core/workflow/nodes/event/__init__.py | 10 + api/core/workflow/nodes/{ => event}/event.py | 10 +- api/core/workflow/nodes/event/types.py | 3 + .../workflow/nodes/http_request/executor.py | 321 +++ .../nodes/http_request/http_executor.py | 343 --- .../nodes/http_request/http_request_node.py | 165 -- api/core/workflow/nodes/http_request/node.py | 174 ++ .../workflow/nodes/list_operator/__init__.py | 3 + .../workflow/nodes/list_operator/entities.py | 56 + api/core/workflow/nodes/list_operator/node.py | 259 ++ .../nodes/llm/{llm_node.py => node.py} | 375 ++- api/extensions/ext_logging.py | 45 + api/factories/file_factory.py | 251 ++ .../variable_factory.py} | 47 +- api/fields/raws.py | 17 + ...a11becb_add_name_and_size_to_tool_files.py | 49 + api/models/enums.py | 16 + api/services/errors/workspace.py | 9 + api/tasks/mail_email_code_login.py | 41 + .../email_code_login_mail_template_en-US.html | 74 + .../email_code_login_mail_template_zh-CN.html | 74 + .../vdb/__mock/upstashvectordb.py | 75 + .../integration_tests/vdb/upstash/__init__.py | 0 .../vdb/upstash/test_upstash_vector.py | 28 + .../workflow/test_sync_workflow.py | 57 + api/tests/unit_tests/core/test_file.py | 40 + .../tools/test_tool_parameter_converter.py | 56 - .../core/tools/test_tool_parameter_type.py | 49 + .../nodes/test_document_extractor_node.py | 167 ++ .../workflow/nodes/test_http_request_node.py | 369 +++ .../core/workflow/nodes/test_list_operator.py | 111 + .../nodes/test_question_classifier_node.py | 67 + .../core/workflow/test_variable_pool.py | 45 + .../utils/test_variable_template_parser.py | 28 + api/tests/unit_tests/oss/__mock/__init__.py | 0 .../unit_tests/oss/__mock/volcengine_tos.py | 100 + .../unit_tests/oss/volcengine_tos/__init__.py | 0 .../oss/volcengine_tos/test_volcengine_tos.py | 67 + web/__mocks__/mime.js | 0 .../app/app-publisher/features-wrapper.tsx | 86 + .../select-type-item/style.module.css | 40 - .../config-vision/radio-group/index.tsx | 40 - .../radio-group/style.module.css | 24 - .../config-voice/param-config-content.tsx | 220 -- .../config-voice/param-config.tsx | 41 - .../code-generator/get-code-generator-res.tsx | 220 ++ .../config/feature/add-feature-btn/index.tsx | 40 - .../choose-feature/feature-item/index.tsx | 52 - .../feature-item/preview-imgs/citation.png | Bin 29852 -> 0 bytes .../feature-item/preview-imgs/citation.svg | 150 -- .../citations-and-attributions-preview@2x.png | Bin 20827 -> 0 bytes .../conversation-opener-preview@2x.png | Bin 14409 -> 0 bytes .../more-like-this-preview@2x.png | Bin 19839 -> 0 bytes .../preview-imgs/more-like-this.png | Bin 30202 -> 0 bytes .../preview-imgs/more-like-this.svg | 188 -- .../next-question-suggestion-preview@2x.png | Bin 28325 -> 0 bytes .../preview-imgs/opening-statement.png | Bin 19955 -> 0 bytes .../opening-suggestion-preview@2x.png | Bin 24140 -> 0 bytes .../speech-to-text-preview@2x.png | Bin 16929 -> 0 bytes .../preview-imgs/speech-to-text.png | Bin 24529 -> 0 bytes .../preview-imgs/speech-to-text.svg | 100 - .../suggested-questions-after-answer.png | Bin 42447 -> 0 bytes .../suggested-questions-after-answer.svg | 163 -- .../text-to-audio-preview-assistant@2x.png | Bin 23500 -> 0 bytes .../text-to-audio-preview-completion@2x.png | Bin 18462 -> 0 bytes .../feature-item/style.module.css | 41 - .../config/feature/choose-feature/index.tsx | 172 -- .../config/feature/feature-group/index.tsx | 31 - .../configuration/debug/chat-user-input.tsx | 109 + .../features/chat-group/citation/index.tsx | 25 - .../features/chat-group/index.tsx | 65 - .../chat-group/speech-to-text/index.tsx | 25 - .../index.tsx | 34 - .../chat-group/text-to-speech/index.tsx | 55 - .../configuration/prompt-value-panel/utils.ts | 13 + .../toolbox/moderation/index.tsx | 80 - .../toolbox/score-slider/index.tsx | 46 - .../__snapshots__/utils.spec.ts.snap | 2281 +++++++++++++++++ .../chat/__tests__/branchedTestMessages.json | 42 + .../chat/__tests__/legacyTestMessages.json | 42 + .../chat/__tests__/mixedTestMessages.json | 42 + .../__tests__/multiRootNodesMessages.json | 52 + .../multiRootNodesWithLegacyTestMessages.json | 52 + .../chat/__tests__/realWorldMessages.json | 441 ++++ .../base/chat/__tests__/utils.spec.ts | 258 ++ .../base/chat/chat/answer/tool-detail.tsx | 71 + .../base/chat/chat/chat-input-area/hooks.ts | 47 + .../base/chat/chat/chat-input-area/index.tsx | 209 ++ .../chat/chat/chat-input-area/operation.tsx | 76 + .../components/base/chat/chat/chat-input.tsx | 258 -- .../base/chat/chat/check-input-forms-hooks.ts | 54 + web/app/components/base/chat/chat/utils.ts | 32 + web/app/components/base/chip/index.tsx | 109 + .../feature-choose/feature-group/index.tsx | 31 - .../feature-choose/feature-item/index.tsx | 96 - .../feature-item/preview-imgs/citation.svg | 150 -- .../citations-and-attributions-preview@2x.png | Bin 20827 -> 0 bytes .../conversation-opener-preview@2x.png | Bin 14409 -> 0 bytes .../more-like-this-preview@2x.png | Bin 19839 -> 0 bytes .../preview-imgs/more-like-this.svg | 188 -- .../next-question-suggestion-preview@2x.png | Bin 28325 -> 0 bytes .../preview-imgs/opening-statement.png | Bin 19955 -> 0 bytes .../opening-suggestion-preview@2x.png | Bin 24140 -> 0 bytes .../speech-to-text-preview@2x.png | Bin 16929 -> 0 bytes .../preview-imgs/speech-to-text.svg | 100 - .../suggested-questions-after-answer.svg | 163 -- .../text-to-audio-preview-assistant@2x.png | Bin 23500 -> 0 bytes .../text-to-audio-preview-completion@2x.png | Bin 18462 -> 0 bytes .../feature-item/style.module.css | 41 - .../features/feature-choose/feature-modal.tsx | 147 -- .../base/features/feature-choose/index.tsx | 42 - .../features/feature-panel/citation/index.tsx | 25 - .../feature-panel/file-upload/index.tsx | 63 - .../file-upload/param-config-content.tsx | 119 - .../file-upload/param-config.tsx | 49 - .../file-upload/radio-group/index.tsx | 40 - .../file-upload/radio-group/style.module.css | 24 - .../base/features/feature-panel/index.tsx | 119 - .../moderation/form-generation.tsx | 80 - .../feature-panel/moderation/index.tsx | 108 - .../moderation/moderation-content.tsx | 73 - .../moderation/moderation-setting-modal.tsx | 376 --- .../feature-panel/opening-statement/index.tsx | 328 --- .../score-slider/base-slider/index.tsx | 38 - .../score-slider/base-slider/style.module.css | 20 - .../feature-panel/speech-to-text/index.tsx | 22 - .../index.tsx | 25 - .../feature-panel/text-to-speech/index.tsx | 62 - .../text-to-speech/param-config-content.tsx | 241 -- .../text-to-speech/params-config.tsx | 48 - .../annotation-ctrl-btn/index.tsx | 0 .../annotation-reply}/config-param-modal.tsx | 2 +- .../annotation-reply/config-param.tsx | 24 + .../annotation-reply/index.tsx | 152 ++ .../score-slider/base-slider/index.tsx | 0 .../score-slider/base-slider/style.module.css | 0 .../annotation-reply}/score-slider/index.tsx | 2 +- .../annotation-reply}/type.ts | 0 .../use-annotation-config.ts | 0 .../features/new-feature-panel/citation.tsx | 56 + .../conversation-opener/index.tsx | 119 + .../conversation-opener/modal.tsx | 206 ++ .../new-feature-panel/dialog-wrapper.tsx | 59 + .../new-feature-panel/feature-bar.tsx | 145 ++ .../new-feature-panel/feature-card.tsx | 61 + .../new-feature-panel/file-upload/index.tsx | 105 + .../file-upload/setting-content.tsx | 89 + .../file-upload/setting-modal.tsx | 53 + .../features/new-feature-panel/follow-up.tsx | 56 + .../new-feature-panel/image-upload/index.tsx | 114 + .../base/features/new-feature-panel/index.tsx | 126 + .../moderation/form-generation.tsx | 7 +- .../new-feature-panel/moderation/index.tsx | 176 ++ .../moderation/moderation-content.tsx | 0 .../moderation/moderation-setting-modal.tsx | 8 +- .../new-feature-panel/more-like-this.tsx | 57 + .../new-feature-panel/speech-to-text.tsx | 56 + .../text-to-speech/index.tsx | 102 + .../text-to-speech/param-config-content.tsx | 242 ++ .../text-to-speech/voice-settings.tsx | 47 + .../base/file-uploader/constants.ts | 7 + .../file-from-link-or-local/index.tsx | 129 + .../base/file-uploader/file-image-render.tsx | 32 + .../base/file-uploader/file-input.tsx | 39 + .../base/file-uploader/file-list-in-log.tsx | 86 + .../base/file-uploader/file-type-icon.tsx | 94 + .../file-uploader-in-attachment/file-item.tsx | 139 + .../file-uploader-in-attachment/index.tsx | 133 + .../file-image-item.tsx | 109 + .../file-uploader-in-chat-input/file-item.tsx | 115 + .../file-uploader-in-chat-input/file-list.tsx | 81 + .../file-uploader-in-chat-input/index.tsx | 41 + .../components/base/file-uploader/hooks.ts | 343 +++ .../components/base/file-uploader/index.ts | 7 + .../components/base/file-uploader/store.tsx | 67 + .../components/base/file-uploader/types.ts | 32 + .../components/base/file-uploader/utils.ts | 181 ++ .../base/icons/assets/public/common/lock.svg | 5 + .../assets/vender/features/citations.svg | 3 + .../vender/features/content-moderation.svg | 3 + .../assets/vender/features/folder-upload.svg | 3 + .../assets/vender/features/love-message.svg | 3 + .../assets/vender/features/message-fast.svg | 3 + .../assets/vender/features/microphone-01.svg | 4 + .../assets/vender/features/text-to-audio.svg | 8 + .../vender/features/virtual-assistant.svg | 4 + .../icons/assets/vender/features/vision.svg | 3 + .../vender/line/others/global-variable.svg | 3 + .../icons/assets/vender/other/replay-line.svg | 5 + .../assets/vender/workflow/docs-extractor.svg | 9 + .../assets/vender/workflow/list-filter.svg | 5 + .../icons/src/vender/features/Citations.json | 26 + .../icons/src/vender/features/Citations.tsx | 16 + .../vender/features/ContentModeration.json | 28 + .../src/vender/features/ContentModeration.tsx | 16 + .../src/vender/features/FolderUpload.json | 26 + .../src/vender/features/FolderUpload.tsx | 16 + .../src/vender/features/LoveMessage.json | 26 + .../icons/src/vender/features/LoveMessage.tsx | 16 + .../src/vender/features/MessageFast.json | 28 + .../icons/src/vender/features/MessageFast.tsx | 16 + .../src/vender/features/Microphone01.json | 37 + .../src/vender/features/Microphone01.tsx | 16 + .../src/vender/features/TextToAudio.json | 77 + .../icons/src/vender/features/TextToAudio.tsx | 16 + .../src/vender/features/VirtualAssistant.json | 35 + .../src/vender/features/VirtualAssistant.tsx | 16 + .../icons/src/vender/features/Vision.json | 28 + .../base/icons/src/vender/features/Vision.tsx | 16 + .../base/icons/src/vender/features/index.ts | 9 + .../vender/line/others/GlobalVariable.json | 28 + .../src/vender/line/others/GlobalVariable.tsx | 16 + .../icons/src/vender/other/ReplayLine.json | 36 + .../icons/src/vender/other/ReplayLine.tsx | 16 + .../src/vender/workflow/DocsExtractor.json | 64 + .../src/vender/workflow/DocsExtractor.tsx | 16 + .../icons/src/vender/workflow/ListFilter.json | 38 + .../icons/src/vender/workflow/ListFilter.tsx | 16 + .../base/progress-bar/progress-circle.tsx | 64 + web/app/components/base/textarea/index.tsx | 53 + web/app/components/signin/countdown.tsx | 41 + .../header/global-variable-button.tsx | 20 + .../workflow/hooks/use-config-vision.ts | 88 + .../components/code-generator-button.tsx | 48 + .../nodes/_base/components/config-vision.tsx | 91 + .../nodes/_base/components/file-type-item.tsx | 77 + .../_base/components/file-upload-setting.tsx | 195 ++ .../components/input-number-with-slider.tsx | 65 + .../workflow/nodes/code/dependency-picker.tsx | 85 + .../nodes/document-extractor/default.ts | 36 + .../nodes/document-extractor/node.tsx | 42 + .../nodes/document-extractor/panel.tsx | 88 + .../nodes/document-extractor/types.ts | 6 + .../nodes/document-extractor/use-config.ts | 66 + .../components/condition-files-list-value.tsx | 115 + .../if-else/components/condition-wrap.tsx | 225 ++ .../if-else/use-is-var-file-attribute.ts | 45 + .../components/filter-condition.tsx | 113 + .../list-operator/components/limit-config.tsx | 80 + .../components/sub-variable-picker.tsx | 73 + .../workflow/nodes/list-operator/default.ts | 61 + .../workflow/nodes/list-operator/node.tsx | 42 + .../workflow/nodes/list-operator/panel.tsx | 153 ++ .../workflow/nodes/list-operator/types.ts | 34 + .../nodes/list-operator/use-config.ts | 168 ++ .../panel/global-variable-panel/index.tsx | 56 + .../panel/global-variable-panel/item.tsx | 30 + .../workflow/run/assets/bg-line-error.svg | 3 + .../workflow/run/assets/bg-line-running.svg | 3 + .../workflow/run/assets/bg-line-success.svg | 3 + .../workflow/run/assets/bg-line-warning.svg | 3 + .../workflow/run/assets/highlight.svg | 9 + .../workflow/run/status-container.tsx | 30 + web/app/reset-password/check-code/page.tsx | 92 + web/app/reset-password/layout.tsx | 39 + web/app/reset-password/page.tsx | 101 + web/app/reset-password/set-password/page.tsx | 193 ++ web/app/signin/check-code/page.tsx | 96 + .../signin/components/mail-and-code-auth.tsx | 71 + .../components/mail-and-password-auth.tsx | 167 ++ web/app/signin/components/social-auth.tsx | 62 + web/app/signin/components/sso-auth.tsx | 73 + web/app/signin/forms.tsx | 34 - web/app/signin/invite-settings/page.tsx | 154 ++ web/app/signin/layout.tsx | 54 + web/app/signin/userSSOForm.tsx | 107 - web/tailwind-common-config.ts | 5 + 375 files changed, 18637 insertions(+), 7426 deletions(-) create mode 100644 api/configs/middleware/vdb/upstash_config.py delete mode 100644 api/core/app/segments/parser.py delete mode 100644 api/core/entities/message_entities.py create mode 100644 api/core/file/constants.py create mode 100644 api/core/file/enums.py create mode 100644 api/core/file/file_manager.py delete mode 100644 api/core/file/file_obj.py create mode 100644 api/core/file/file_repository.py create mode 100644 api/core/file/helpers.py delete mode 100644 api/core/file/message_file_parser.py create mode 100644 api/core/file/models.py delete mode 100644 api/core/file/upload_file_parser.py create mode 100644 api/core/model_runtime/model_providers/anthropic/llm/claude-3-5-sonnet-20241022.yaml create mode 100644 api/core/model_runtime/model_providers/bedrock/llm/anthropic.claude-3-sonnet-v2.yaml create mode 100644 api/core/model_runtime/model_providers/bedrock/llm/eu.anthropic.claude-3-sonnet-v2.yaml create mode 100644 api/core/model_runtime/model_providers/bedrock/llm/us.anthropic.claude-3-sonnet-v2.yaml create mode 100644 api/core/model_runtime/model_providers/groq/llm/llama-3.2-11b-vision-preview.yaml create mode 100644 api/core/model_runtime/model_providers/groq/llm/llama-3.2-90b-vision-preview.yaml create mode 100644 api/core/model_runtime/model_providers/groq/speech2text/__init__.py create mode 100644 api/core/model_runtime/model_providers/groq/speech2text/distil-whisper-large-v3-en.yaml create mode 100644 api/core/model_runtime/model_providers/groq/speech2text/speech2text.py create mode 100644 api/core/model_runtime/model_providers/groq/speech2text/whisper-large-v3-turbo.yaml create mode 100644 api/core/model_runtime/model_providers/groq/speech2text/whisper-large-v3.yaml create mode 100644 api/core/model_runtime/model_providers/openai/llm/gpt-4o-audio-preview.yaml create mode 100644 api/core/model_runtime/model_providers/openai_api_compatible/rerank/__init__.py create mode 100644 api/core/model_runtime/model_providers/openai_api_compatible/rerank/rerank.py create mode 100644 api/core/model_runtime/model_providers/vertex_ai/llm/anthropic.claude-3.5-sonnet-v2.yaml create mode 100644 api/core/rag/datasource/vdb/upstash/__init__.py create mode 100644 api/core/rag/datasource/vdb/upstash/upstash_vector.py create mode 100644 api/core/rag/extractor/unstructured/unstructured_pdf_extractor.py create mode 100644 api/core/tools/provider/builtin/aliyuque/_assets/icon.svg create mode 100644 api/core/tools/provider/builtin/aliyuque/aliyuque.py create mode 100644 api/core/tools/provider/builtin/aliyuque/aliyuque.yaml create mode 100644 api/core/tools/provider/builtin/aliyuque/tools/base.py create mode 100644 api/core/tools/provider/builtin/aliyuque/tools/create_document.py create mode 100644 api/core/tools/provider/builtin/aliyuque/tools/create_document.yaml create mode 100644 api/core/tools/provider/builtin/aliyuque/tools/delete_document.py create mode 100644 api/core/tools/provider/builtin/aliyuque/tools/delete_document.yaml create mode 100644 api/core/tools/provider/builtin/aliyuque/tools/describe_book_index_page.py create mode 100644 api/core/tools/provider/builtin/aliyuque/tools/describe_book_index_page.yaml create mode 100644 api/core/tools/provider/builtin/aliyuque/tools/describe_book_table_of_contents.py create mode 100644 api/core/tools/provider/builtin/aliyuque/tools/describe_book_table_of_contents.yaml create mode 100644 api/core/tools/provider/builtin/aliyuque/tools/describe_document_content.py create mode 100644 api/core/tools/provider/builtin/aliyuque/tools/describe_document_content.yaml create mode 100644 api/core/tools/provider/builtin/aliyuque/tools/describe_documents.py create mode 100644 api/core/tools/provider/builtin/aliyuque/tools/describe_documents.yaml create mode 100644 api/core/tools/provider/builtin/aliyuque/tools/update_book_table_of_contents.py create mode 100644 api/core/tools/provider/builtin/aliyuque/tools/update_book_table_of_contents.yaml create mode 100644 api/core/tools/provider/builtin/aliyuque/tools/update_document.py create mode 100644 api/core/tools/provider/builtin/aliyuque/tools/update_document.yaml create mode 100644 api/core/tools/provider/builtin/feishu_base/_assets/icon.png delete mode 100644 api/core/tools/provider/builtin/feishu_base/_assets/icon.svg delete mode 100644 api/core/tools/provider/builtin/feishu_base/tools/add_base_record.py delete mode 100644 api/core/tools/provider/builtin/feishu_base/tools/add_base_record.yaml create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/add_records.py create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/add_records.yaml delete mode 100644 api/core/tools/provider/builtin/feishu_base/tools/create_base_table.py delete mode 100644 api/core/tools/provider/builtin/feishu_base/tools/create_base_table.yaml create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/create_table.py create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/create_table.yaml delete mode 100644 api/core/tools/provider/builtin/feishu_base/tools/delete_base_records.py delete mode 100644 api/core/tools/provider/builtin/feishu_base/tools/delete_base_records.yaml delete mode 100644 api/core/tools/provider/builtin/feishu_base/tools/delete_base_tables.py delete mode 100644 api/core/tools/provider/builtin/feishu_base/tools/delete_base_tables.yaml create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/delete_records.py create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/delete_records.yaml create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/delete_tables.py create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/delete_tables.yaml delete mode 100644 api/core/tools/provider/builtin/feishu_base/tools/get_tenant_access_token.py delete mode 100644 api/core/tools/provider/builtin/feishu_base/tools/get_tenant_access_token.yaml delete mode 100644 api/core/tools/provider/builtin/feishu_base/tools/list_base_records.py delete mode 100644 api/core/tools/provider/builtin/feishu_base/tools/list_base_records.yaml delete mode 100644 api/core/tools/provider/builtin/feishu_base/tools/list_base_tables.py delete mode 100644 api/core/tools/provider/builtin/feishu_base/tools/list_base_tables.yaml create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/list_tables.py create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/list_tables.yaml delete mode 100644 api/core/tools/provider/builtin/feishu_base/tools/read_base_record.py delete mode 100644 api/core/tools/provider/builtin/feishu_base/tools/read_base_record.yaml create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/read_records.py create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/read_records.yaml create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/search_records.py create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/search_records.yaml delete mode 100644 api/core/tools/provider/builtin/feishu_base/tools/update_base_record.py delete mode 100644 api/core/tools/provider/builtin/feishu_base/tools/update_base_record.yaml create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/update_records.py create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/update_records.yaml create mode 100644 api/core/tools/provider/builtin/podcast_generator/_assets/icon.svg create mode 100644 api/core/tools/provider/builtin/podcast_generator/podcast_generator.py create mode 100644 api/core/tools/provider/builtin/podcast_generator/podcast_generator.yaml create mode 100644 api/core/tools/provider/builtin/podcast_generator/tools/podcast_audio_generator.py create mode 100644 api/core/tools/provider/builtin/podcast_generator/tools/podcast_audio_generator.yaml delete mode 100644 api/core/tools/utils/tool_parameter_converter.py rename api/core/{app/segments => variables}/__init__.py (78%) rename api/core/{app/segments => variables}/exc.py (100%) rename api/core/{app/segments => variables}/segment_group.py (100%) rename api/core/{app/segments => variables}/segments.py (77%) rename api/core/{app/segments => variables}/types.py (86%) rename api/core/{app/segments => variables}/variables.py (95%) rename api/core/{app/apps => workflow/callbacks}/workflow_logging_callback.py (99%) create mode 100644 api/core/workflow/constants.py create mode 100644 api/core/workflow/nodes/base/__init__.py rename api/core/workflow/{entities/base_node_data_entities.py => nodes/base/entities.py} (100%) rename api/core/workflow/nodes/{base_node.py => base/node.py} (60%) create mode 100644 api/core/workflow/nodes/document_extractor/__init__.py create mode 100644 api/core/workflow/nodes/document_extractor/entities.py create mode 100644 api/core/workflow/nodes/document_extractor/exc.py create mode 100644 api/core/workflow/nodes/document_extractor/node.py create mode 100644 api/core/workflow/nodes/enums.py create mode 100644 api/core/workflow/nodes/event/__init__.py rename api/core/workflow/nodes/{ => event}/event.py (72%) create mode 100644 api/core/workflow/nodes/event/types.py create mode 100644 api/core/workflow/nodes/http_request/executor.py delete mode 100644 api/core/workflow/nodes/http_request/http_executor.py delete mode 100644 api/core/workflow/nodes/http_request/http_request_node.py create mode 100644 api/core/workflow/nodes/http_request/node.py create mode 100644 api/core/workflow/nodes/list_operator/__init__.py create mode 100644 api/core/workflow/nodes/list_operator/entities.py create mode 100644 api/core/workflow/nodes/list_operator/node.py rename api/core/workflow/nodes/llm/{llm_node.py => node.py} (71%) create mode 100644 api/extensions/ext_logging.py create mode 100644 api/factories/file_factory.py rename api/{core/app/segments/factory.py => factories/variable_factory.py} (73%) create mode 100644 api/fields/raws.py create mode 100644 api/migrations/versions/2024_10_10_0516-bbadea11becb_add_name_and_size_to_tool_files.py create mode 100644 api/models/enums.py create mode 100644 api/services/errors/workspace.py create mode 100644 api/tasks/mail_email_code_login.py create mode 100644 api/templates/email_code_login_mail_template_en-US.html create mode 100644 api/templates/email_code_login_mail_template_zh-CN.html create mode 100644 api/tests/integration_tests/vdb/__mock/upstashvectordb.py create mode 100644 api/tests/integration_tests/vdb/upstash/__init__.py create mode 100644 api/tests/integration_tests/vdb/upstash/test_upstash_vector.py create mode 100644 api/tests/integration_tests/workflow/test_sync_workflow.py create mode 100644 api/tests/unit_tests/core/test_file.py delete mode 100644 api/tests/unit_tests/core/tools/test_tool_parameter_converter.py create mode 100644 api/tests/unit_tests/core/tools/test_tool_parameter_type.py create mode 100644 api/tests/unit_tests/core/workflow/nodes/test_document_extractor_node.py create mode 100644 api/tests/unit_tests/core/workflow/nodes/test_http_request_node.py create mode 100644 api/tests/unit_tests/core/workflow/nodes/test_list_operator.py create mode 100644 api/tests/unit_tests/core/workflow/nodes/test_question_classifier_node.py create mode 100644 api/tests/unit_tests/core/workflow/test_variable_pool.py create mode 100644 api/tests/unit_tests/core/workflow/utils/test_variable_template_parser.py create mode 100644 api/tests/unit_tests/oss/__mock/__init__.py create mode 100644 api/tests/unit_tests/oss/__mock/volcengine_tos.py create mode 100644 api/tests/unit_tests/oss/volcengine_tos/__init__.py create mode 100644 api/tests/unit_tests/oss/volcengine_tos/test_volcengine_tos.py create mode 100644 web/__mocks__/mime.js create mode 100644 web/app/components/app/app-publisher/features-wrapper.tsx delete mode 100644 web/app/components/app/configuration/config-var/select-type-item/style.module.css delete mode 100644 web/app/components/app/configuration/config-vision/radio-group/index.tsx delete mode 100644 web/app/components/app/configuration/config-vision/radio-group/style.module.css delete mode 100644 web/app/components/app/configuration/config-voice/param-config-content.tsx delete mode 100644 web/app/components/app/configuration/config-voice/param-config.tsx create mode 100644 web/app/components/app/configuration/config/code-generator/get-code-generator-res.tsx delete mode 100644 web/app/components/app/configuration/config/feature/add-feature-btn/index.tsx delete mode 100644 web/app/components/app/configuration/config/feature/choose-feature/feature-item/index.tsx delete mode 100644 web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/citation.png delete mode 100644 web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/citation.svg delete mode 100644 web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/citations-and-attributions-preview@2x.png delete mode 100644 web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/conversation-opener-preview@2x.png delete mode 100644 web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/more-like-this-preview@2x.png delete mode 100644 web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/more-like-this.png delete mode 100644 web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/more-like-this.svg delete mode 100644 web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/next-question-suggestion-preview@2x.png delete mode 100644 web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/opening-statement.png delete mode 100644 web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/opening-suggestion-preview@2x.png delete mode 100644 web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/speech-to-text-preview@2x.png delete mode 100644 web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/speech-to-text.png delete mode 100644 web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/speech-to-text.svg delete mode 100644 web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/suggested-questions-after-answer.png delete mode 100644 web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/suggested-questions-after-answer.svg delete mode 100644 web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/text-to-audio-preview-assistant@2x.png delete mode 100644 web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/text-to-audio-preview-completion@2x.png delete mode 100644 web/app/components/app/configuration/config/feature/choose-feature/feature-item/style.module.css delete mode 100644 web/app/components/app/configuration/config/feature/choose-feature/index.tsx delete mode 100644 web/app/components/app/configuration/config/feature/feature-group/index.tsx create mode 100644 web/app/components/app/configuration/debug/chat-user-input.tsx delete mode 100644 web/app/components/app/configuration/features/chat-group/citation/index.tsx delete mode 100644 web/app/components/app/configuration/features/chat-group/index.tsx delete mode 100644 web/app/components/app/configuration/features/chat-group/speech-to-text/index.tsx delete mode 100644 web/app/components/app/configuration/features/chat-group/suggested-questions-after-answer/index.tsx delete mode 100644 web/app/components/app/configuration/features/chat-group/text-to-speech/index.tsx create mode 100644 web/app/components/app/configuration/prompt-value-panel/utils.ts delete mode 100644 web/app/components/app/configuration/toolbox/moderation/index.tsx delete mode 100644 web/app/components/app/configuration/toolbox/score-slider/index.tsx create mode 100644 web/app/components/base/chat/__tests__/__snapshots__/utils.spec.ts.snap create mode 100644 web/app/components/base/chat/__tests__/branchedTestMessages.json create mode 100644 web/app/components/base/chat/__tests__/legacyTestMessages.json create mode 100644 web/app/components/base/chat/__tests__/mixedTestMessages.json create mode 100644 web/app/components/base/chat/__tests__/multiRootNodesMessages.json create mode 100644 web/app/components/base/chat/__tests__/multiRootNodesWithLegacyTestMessages.json create mode 100644 web/app/components/base/chat/__tests__/realWorldMessages.json create mode 100644 web/app/components/base/chat/__tests__/utils.spec.ts create mode 100644 web/app/components/base/chat/chat/answer/tool-detail.tsx create mode 100644 web/app/components/base/chat/chat/chat-input-area/hooks.ts create mode 100644 web/app/components/base/chat/chat/chat-input-area/index.tsx create mode 100644 web/app/components/base/chat/chat/chat-input-area/operation.tsx delete mode 100644 web/app/components/base/chat/chat/chat-input.tsx create mode 100644 web/app/components/base/chat/chat/check-input-forms-hooks.ts create mode 100644 web/app/components/base/chat/chat/utils.ts create mode 100644 web/app/components/base/chip/index.tsx delete mode 100644 web/app/components/base/features/feature-choose/feature-group/index.tsx delete mode 100644 web/app/components/base/features/feature-choose/feature-item/index.tsx delete mode 100644 web/app/components/base/features/feature-choose/feature-item/preview-imgs/citation.svg delete mode 100644 web/app/components/base/features/feature-choose/feature-item/preview-imgs/citations-and-attributions-preview@2x.png delete mode 100644 web/app/components/base/features/feature-choose/feature-item/preview-imgs/conversation-opener-preview@2x.png delete mode 100644 web/app/components/base/features/feature-choose/feature-item/preview-imgs/more-like-this-preview@2x.png delete mode 100644 web/app/components/base/features/feature-choose/feature-item/preview-imgs/more-like-this.svg delete mode 100644 web/app/components/base/features/feature-choose/feature-item/preview-imgs/next-question-suggestion-preview@2x.png delete mode 100644 web/app/components/base/features/feature-choose/feature-item/preview-imgs/opening-statement.png delete mode 100644 web/app/components/base/features/feature-choose/feature-item/preview-imgs/opening-suggestion-preview@2x.png delete mode 100644 web/app/components/base/features/feature-choose/feature-item/preview-imgs/speech-to-text-preview@2x.png delete mode 100644 web/app/components/base/features/feature-choose/feature-item/preview-imgs/speech-to-text.svg delete mode 100644 web/app/components/base/features/feature-choose/feature-item/preview-imgs/suggested-questions-after-answer.svg delete mode 100644 web/app/components/base/features/feature-choose/feature-item/preview-imgs/text-to-audio-preview-assistant@2x.png delete mode 100644 web/app/components/base/features/feature-choose/feature-item/preview-imgs/text-to-audio-preview-completion@2x.png delete mode 100644 web/app/components/base/features/feature-choose/feature-item/style.module.css delete mode 100644 web/app/components/base/features/feature-choose/feature-modal.tsx delete mode 100644 web/app/components/base/features/feature-choose/index.tsx delete mode 100644 web/app/components/base/features/feature-panel/citation/index.tsx delete mode 100644 web/app/components/base/features/feature-panel/file-upload/index.tsx delete mode 100644 web/app/components/base/features/feature-panel/file-upload/param-config-content.tsx delete mode 100644 web/app/components/base/features/feature-panel/file-upload/param-config.tsx delete mode 100644 web/app/components/base/features/feature-panel/file-upload/radio-group/index.tsx delete mode 100644 web/app/components/base/features/feature-panel/file-upload/radio-group/style.module.css delete mode 100644 web/app/components/base/features/feature-panel/index.tsx delete mode 100644 web/app/components/base/features/feature-panel/moderation/form-generation.tsx delete mode 100644 web/app/components/base/features/feature-panel/moderation/index.tsx delete mode 100644 web/app/components/base/features/feature-panel/moderation/moderation-content.tsx delete mode 100644 web/app/components/base/features/feature-panel/moderation/moderation-setting-modal.tsx delete mode 100644 web/app/components/base/features/feature-panel/opening-statement/index.tsx delete mode 100644 web/app/components/base/features/feature-panel/score-slider/base-slider/index.tsx delete mode 100644 web/app/components/base/features/feature-panel/score-slider/base-slider/style.module.css delete mode 100644 web/app/components/base/features/feature-panel/speech-to-text/index.tsx delete mode 100644 web/app/components/base/features/feature-panel/suggested-questions-after-answer/index.tsx delete mode 100644 web/app/components/base/features/feature-panel/text-to-speech/index.tsx delete mode 100644 web/app/components/base/features/feature-panel/text-to-speech/param-config-content.tsx delete mode 100644 web/app/components/base/features/feature-panel/text-to-speech/params-config.tsx rename web/app/components/{app/configuration/toolbox/annotation => base/features/new-feature-panel/annotation-reply}/annotation-ctrl-btn/index.tsx (100%) rename web/app/components/{app/configuration/toolbox/annotation => base/features/new-feature-panel/annotation-reply}/config-param-modal.tsx (99%) create mode 100644 web/app/components/base/features/new-feature-panel/annotation-reply/config-param.tsx create mode 100644 web/app/components/base/features/new-feature-panel/annotation-reply/index.tsx rename web/app/components/{app/configuration/toolbox => base/features/new-feature-panel/annotation-reply}/score-slider/base-slider/index.tsx (100%) rename web/app/components/{app/configuration/toolbox => base/features/new-feature-panel/annotation-reply}/score-slider/base-slider/style.module.css (100%) rename web/app/components/base/features/{feature-panel => new-feature-panel/annotation-reply}/score-slider/index.tsx (90%) rename web/app/components/{app/configuration/toolbox/annotation => base/features/new-feature-panel/annotation-reply}/type.ts (100%) rename web/app/components/{app/configuration/toolbox/annotation => base/features/new-feature-panel/annotation-reply}/use-annotation-config.ts (100%) create mode 100644 web/app/components/base/features/new-feature-panel/citation.tsx create mode 100644 web/app/components/base/features/new-feature-panel/conversation-opener/index.tsx create mode 100644 web/app/components/base/features/new-feature-panel/conversation-opener/modal.tsx create mode 100644 web/app/components/base/features/new-feature-panel/dialog-wrapper.tsx create mode 100644 web/app/components/base/features/new-feature-panel/feature-bar.tsx create mode 100644 web/app/components/base/features/new-feature-panel/feature-card.tsx create mode 100644 web/app/components/base/features/new-feature-panel/file-upload/index.tsx create mode 100644 web/app/components/base/features/new-feature-panel/file-upload/setting-content.tsx create mode 100644 web/app/components/base/features/new-feature-panel/file-upload/setting-modal.tsx create mode 100644 web/app/components/base/features/new-feature-panel/follow-up.tsx create mode 100644 web/app/components/base/features/new-feature-panel/image-upload/index.tsx create mode 100644 web/app/components/base/features/new-feature-panel/index.tsx rename web/app/components/{app/configuration/toolbox => base/features/new-feature-panel}/moderation/form-generation.tsx (91%) create mode 100644 web/app/components/base/features/new-feature-panel/moderation/index.tsx rename web/app/components/{app/configuration/toolbox => base/features/new-feature-panel}/moderation/moderation-content.tsx (100%) rename web/app/components/{app/configuration/toolbox => base/features/new-feature-panel}/moderation/moderation-setting-modal.tsx (97%) create mode 100644 web/app/components/base/features/new-feature-panel/more-like-this.tsx create mode 100644 web/app/components/base/features/new-feature-panel/speech-to-text.tsx create mode 100644 web/app/components/base/features/new-feature-panel/text-to-speech/index.tsx create mode 100644 web/app/components/base/features/new-feature-panel/text-to-speech/param-config-content.tsx create mode 100644 web/app/components/base/features/new-feature-panel/text-to-speech/voice-settings.tsx create mode 100644 web/app/components/base/file-uploader/constants.ts create mode 100644 web/app/components/base/file-uploader/file-from-link-or-local/index.tsx create mode 100644 web/app/components/base/file-uploader/file-image-render.tsx create mode 100644 web/app/components/base/file-uploader/file-input.tsx create mode 100644 web/app/components/base/file-uploader/file-list-in-log.tsx create mode 100644 web/app/components/base/file-uploader/file-type-icon.tsx create mode 100644 web/app/components/base/file-uploader/file-uploader-in-attachment/file-item.tsx create mode 100644 web/app/components/base/file-uploader/file-uploader-in-attachment/index.tsx create mode 100644 web/app/components/base/file-uploader/file-uploader-in-chat-input/file-image-item.tsx create mode 100644 web/app/components/base/file-uploader/file-uploader-in-chat-input/file-item.tsx create mode 100644 web/app/components/base/file-uploader/file-uploader-in-chat-input/file-list.tsx create mode 100644 web/app/components/base/file-uploader/file-uploader-in-chat-input/index.tsx create mode 100644 web/app/components/base/file-uploader/hooks.ts create mode 100644 web/app/components/base/file-uploader/index.ts create mode 100644 web/app/components/base/file-uploader/store.tsx create mode 100644 web/app/components/base/file-uploader/types.ts create mode 100644 web/app/components/base/file-uploader/utils.ts create mode 100644 web/app/components/base/icons/assets/public/common/lock.svg create mode 100644 web/app/components/base/icons/assets/vender/features/citations.svg create mode 100644 web/app/components/base/icons/assets/vender/features/content-moderation.svg create mode 100644 web/app/components/base/icons/assets/vender/features/folder-upload.svg create mode 100644 web/app/components/base/icons/assets/vender/features/love-message.svg create mode 100644 web/app/components/base/icons/assets/vender/features/message-fast.svg create mode 100644 web/app/components/base/icons/assets/vender/features/microphone-01.svg create mode 100644 web/app/components/base/icons/assets/vender/features/text-to-audio.svg create mode 100644 web/app/components/base/icons/assets/vender/features/virtual-assistant.svg create mode 100644 web/app/components/base/icons/assets/vender/features/vision.svg create mode 100644 web/app/components/base/icons/assets/vender/line/others/global-variable.svg create mode 100644 web/app/components/base/icons/assets/vender/other/replay-line.svg create mode 100644 web/app/components/base/icons/assets/vender/workflow/docs-extractor.svg create mode 100644 web/app/components/base/icons/assets/vender/workflow/list-filter.svg create mode 100644 web/app/components/base/icons/src/vender/features/Citations.json create mode 100644 web/app/components/base/icons/src/vender/features/Citations.tsx create mode 100644 web/app/components/base/icons/src/vender/features/ContentModeration.json create mode 100644 web/app/components/base/icons/src/vender/features/ContentModeration.tsx create mode 100644 web/app/components/base/icons/src/vender/features/FolderUpload.json create mode 100644 web/app/components/base/icons/src/vender/features/FolderUpload.tsx create mode 100644 web/app/components/base/icons/src/vender/features/LoveMessage.json create mode 100644 web/app/components/base/icons/src/vender/features/LoveMessage.tsx create mode 100644 web/app/components/base/icons/src/vender/features/MessageFast.json create mode 100644 web/app/components/base/icons/src/vender/features/MessageFast.tsx create mode 100644 web/app/components/base/icons/src/vender/features/Microphone01.json create mode 100644 web/app/components/base/icons/src/vender/features/Microphone01.tsx create mode 100644 web/app/components/base/icons/src/vender/features/TextToAudio.json create mode 100644 web/app/components/base/icons/src/vender/features/TextToAudio.tsx create mode 100644 web/app/components/base/icons/src/vender/features/VirtualAssistant.json create mode 100644 web/app/components/base/icons/src/vender/features/VirtualAssistant.tsx create mode 100644 web/app/components/base/icons/src/vender/features/Vision.json create mode 100644 web/app/components/base/icons/src/vender/features/Vision.tsx create mode 100644 web/app/components/base/icons/src/vender/features/index.ts create mode 100644 web/app/components/base/icons/src/vender/line/others/GlobalVariable.json create mode 100644 web/app/components/base/icons/src/vender/line/others/GlobalVariable.tsx create mode 100644 web/app/components/base/icons/src/vender/other/ReplayLine.json create mode 100644 web/app/components/base/icons/src/vender/other/ReplayLine.tsx create mode 100644 web/app/components/base/icons/src/vender/workflow/DocsExtractor.json create mode 100644 web/app/components/base/icons/src/vender/workflow/DocsExtractor.tsx create mode 100644 web/app/components/base/icons/src/vender/workflow/ListFilter.json create mode 100644 web/app/components/base/icons/src/vender/workflow/ListFilter.tsx create mode 100644 web/app/components/base/progress-bar/progress-circle.tsx create mode 100644 web/app/components/base/textarea/index.tsx create mode 100644 web/app/components/signin/countdown.tsx create mode 100644 web/app/components/workflow/header/global-variable-button.tsx create mode 100644 web/app/components/workflow/hooks/use-config-vision.ts create mode 100644 web/app/components/workflow/nodes/_base/components/code-generator-button.tsx create mode 100644 web/app/components/workflow/nodes/_base/components/config-vision.tsx create mode 100644 web/app/components/workflow/nodes/_base/components/file-type-item.tsx create mode 100644 web/app/components/workflow/nodes/_base/components/file-upload-setting.tsx create mode 100644 web/app/components/workflow/nodes/_base/components/input-number-with-slider.tsx create mode 100644 web/app/components/workflow/nodes/code/dependency-picker.tsx create mode 100644 web/app/components/workflow/nodes/document-extractor/default.ts create mode 100644 web/app/components/workflow/nodes/document-extractor/node.tsx create mode 100644 web/app/components/workflow/nodes/document-extractor/panel.tsx create mode 100644 web/app/components/workflow/nodes/document-extractor/types.ts create mode 100644 web/app/components/workflow/nodes/document-extractor/use-config.ts create mode 100644 web/app/components/workflow/nodes/if-else/components/condition-files-list-value.tsx create mode 100644 web/app/components/workflow/nodes/if-else/components/condition-wrap.tsx create mode 100644 web/app/components/workflow/nodes/if-else/use-is-var-file-attribute.ts create mode 100644 web/app/components/workflow/nodes/list-operator/components/filter-condition.tsx create mode 100644 web/app/components/workflow/nodes/list-operator/components/limit-config.tsx create mode 100644 web/app/components/workflow/nodes/list-operator/components/sub-variable-picker.tsx create mode 100644 web/app/components/workflow/nodes/list-operator/default.ts create mode 100644 web/app/components/workflow/nodes/list-operator/node.tsx create mode 100644 web/app/components/workflow/nodes/list-operator/panel.tsx create mode 100644 web/app/components/workflow/nodes/list-operator/types.ts create mode 100644 web/app/components/workflow/nodes/list-operator/use-config.ts create mode 100644 web/app/components/workflow/panel/global-variable-panel/index.tsx create mode 100644 web/app/components/workflow/panel/global-variable-panel/item.tsx create mode 100644 web/app/components/workflow/run/assets/bg-line-error.svg create mode 100644 web/app/components/workflow/run/assets/bg-line-running.svg create mode 100644 web/app/components/workflow/run/assets/bg-line-success.svg create mode 100644 web/app/components/workflow/run/assets/bg-line-warning.svg create mode 100644 web/app/components/workflow/run/assets/highlight.svg create mode 100644 web/app/components/workflow/run/status-container.tsx create mode 100644 web/app/reset-password/check-code/page.tsx create mode 100644 web/app/reset-password/layout.tsx create mode 100644 web/app/reset-password/page.tsx create mode 100644 web/app/reset-password/set-password/page.tsx create mode 100644 web/app/signin/check-code/page.tsx create mode 100644 web/app/signin/components/mail-and-code-auth.tsx create mode 100644 web/app/signin/components/mail-and-password-auth.tsx create mode 100644 web/app/signin/components/social-auth.tsx create mode 100644 web/app/signin/components/sso-auth.tsx delete mode 100644 web/app/signin/forms.tsx create mode 100644 web/app/signin/invite-settings/page.tsx create mode 100644 web/app/signin/layout.tsx delete mode 100644 web/app/signin/userSSOForm.tsx diff --git a/api/configs/middleware/vdb/upstash_config.py b/api/configs/middleware/vdb/upstash_config.py new file mode 100644 index 0000000000..412c56374a --- /dev/null +++ b/api/configs/middleware/vdb/upstash_config.py @@ -0,0 +1,20 @@ +from typing import Optional + +from pydantic import Field +from pydantic_settings import BaseSettings + + +class UpstashConfig(BaseSettings): + """ + Configuration settings for Upstash vector database + """ + + UPSTASH_VECTOR_URL: Optional[str] = Field( + description="URL of the upstash server (e.g., 'https://vector.upstash.io')", + default=None, + ) + + UPSTASH_VECTOR_TOKEN: Optional[str] = Field( + description="Token for authenticating with the upstash server", + default=None, + ) diff --git a/api/core/app/segments/parser.py b/api/core/app/segments/parser.py deleted file mode 100644 index 3c4d7046f4..0000000000 --- a/api/core/app/segments/parser.py +++ /dev/null @@ -1,18 +0,0 @@ -import re - -from core.workflow.entities.variable_pool import VariablePool - -from . import SegmentGroup, factory - -VARIABLE_PATTERN = re.compile(r"\{\{#([a-zA-Z0-9_]{1,50}(?:\.[a-zA-Z_][a-zA-Z0-9_]{0,29}){1,10})#\}\}") - - -def convert_template(*, template: str, variable_pool: VariablePool): - parts = re.split(VARIABLE_PATTERN, template) - segments = [] - for part in filter(lambda x: x, parts): - if "." in part and (value := variable_pool.get(part.split("."))): - segments.append(value) - else: - segments.append(factory.build_segment(part)) - return SegmentGroup(value=segments) diff --git a/api/core/entities/message_entities.py b/api/core/entities/message_entities.py deleted file mode 100644 index 10bc9f6ed7..0000000000 --- a/api/core/entities/message_entities.py +++ /dev/null @@ -1,29 +0,0 @@ -import enum -from typing import Any - -from pydantic import BaseModel - - -class PromptMessageFileType(enum.Enum): - IMAGE = "image" - - @staticmethod - def value_of(value): - for member in PromptMessageFileType: - if member.value == value: - return member - raise ValueError(f"No matching enum found for value '{value}'") - - -class PromptMessageFile(BaseModel): - type: PromptMessageFileType - data: Any = None - - -class ImagePromptMessageFile(PromptMessageFile): - class DETAIL(enum.Enum): - LOW = "low" - HIGH = "high" - - type: PromptMessageFileType = PromptMessageFileType.IMAGE - detail: DETAIL = DETAIL.LOW diff --git a/api/core/file/constants.py b/api/core/file/constants.py new file mode 100644 index 0000000000..ce1d238e93 --- /dev/null +++ b/api/core/file/constants.py @@ -0,0 +1 @@ +FILE_MODEL_IDENTITY = "__dify__file__" diff --git a/api/core/file/enums.py b/api/core/file/enums.py new file mode 100644 index 0000000000..f4153f1676 --- /dev/null +++ b/api/core/file/enums.py @@ -0,0 +1,55 @@ +from enum import Enum + + +class FileType(str, Enum): + IMAGE = "image" + DOCUMENT = "document" + AUDIO = "audio" + VIDEO = "video" + CUSTOM = "custom" + + @staticmethod + def value_of(value): + for member in FileType: + if member.value == value: + return member + raise ValueError(f"No matching enum found for value '{value}'") + + +class FileTransferMethod(str, Enum): + REMOTE_URL = "remote_url" + LOCAL_FILE = "local_file" + TOOL_FILE = "tool_file" + + @staticmethod + def value_of(value): + for member in FileTransferMethod: + if member.value == value: + return member + raise ValueError(f"No matching enum found for value '{value}'") + + +class FileBelongsTo(str, Enum): + USER = "user" + ASSISTANT = "assistant" + + @staticmethod + def value_of(value): + for member in FileBelongsTo: + if member.value == value: + return member + raise ValueError(f"No matching enum found for value '{value}'") + + +class FileAttribute(str, Enum): + TYPE = "type" + SIZE = "size" + NAME = "name" + MIME_TYPE = "mime_type" + TRANSFER_METHOD = "transfer_method" + URL = "url" + EXTENSION = "extension" + + +class ArrayFileAttribute(str, Enum): + LENGTH = "length" diff --git a/api/core/file/file_manager.py b/api/core/file/file_manager.py new file mode 100644 index 0000000000..0c6ce8ce75 --- /dev/null +++ b/api/core/file/file_manager.py @@ -0,0 +1,156 @@ +import base64 + +from configs import dify_config +from core.file import file_repository +from core.helper import ssrf_proxy +from core.model_runtime.entities import AudioPromptMessageContent, ImagePromptMessageContent +from extensions.ext_database import db +from extensions.ext_storage import storage + +from . import helpers +from .enums import FileAttribute +from .models import File, FileTransferMethod, FileType +from .tool_file_parser import ToolFileParser + + +def get_attr(*, file: File, attr: FileAttribute): + match attr: + case FileAttribute.TYPE: + return file.type.value + case FileAttribute.SIZE: + return file.size + case FileAttribute.NAME: + return file.filename + case FileAttribute.MIME_TYPE: + return file.mime_type + case FileAttribute.TRANSFER_METHOD: + return file.transfer_method.value + case FileAttribute.URL: + return file.remote_url + case FileAttribute.EXTENSION: + return file.extension + case _: + raise ValueError(f"Invalid file attribute: {attr}") + + +def to_prompt_message_content(f: File, /): + """ + Convert a File object to an ImagePromptMessageContent object. + + This function takes a File object and converts it to an ImagePromptMessageContent + object, which can be used as a prompt for image-based AI models. + + Args: + file (File): The File object to convert. Must be of type FileType.IMAGE. + + Returns: + ImagePromptMessageContent: An object containing the image data and detail level. + + Raises: + ValueError: If the file is not an image or if the file data is missing. + + Note: + The detail level of the image prompt is determined by the file's extra_config. + If not specified, it defaults to ImagePromptMessageContent.DETAIL.LOW. + """ + match f.type: + case FileType.IMAGE: + if dify_config.MULTIMODAL_SEND_IMAGE_FORMAT == "url": + data = _to_url(f) + else: + data = _to_base64_data_string(f) + + if f._extra_config and f._extra_config.image_config and f._extra_config.image_config.detail: + detail = f._extra_config.image_config.detail + else: + detail = ImagePromptMessageContent.DETAIL.LOW + + return ImagePromptMessageContent(data=data, detail=detail) + case FileType.AUDIO: + encoded_string = _file_to_encoded_string(f) + if f.extension is None: + raise ValueError("Missing file extension") + return AudioPromptMessageContent(data=encoded_string, format=f.extension.lstrip(".")) + case _: + raise ValueError(f"file type {f.type} is not supported") + + +def download(f: File, /): + upload_file = file_repository.get_upload_file(session=db.session(), file=f) + return _download_file_content(upload_file.key) + + +def _download_file_content(path: str, /): + """ + Download and return the contents of a file as bytes. + + This function loads the file from storage and ensures it's in bytes format. + + Args: + path (str): The path to the file in storage. + + Returns: + bytes: The contents of the file as a bytes object. + + Raises: + ValueError: If the loaded file is not a bytes object. + """ + data = storage.load(path, stream=False) + if not isinstance(data, bytes): + raise ValueError(f"file {path} is not a bytes object") + return data + + +def _get_encoded_string(f: File, /): + match f.transfer_method: + case FileTransferMethod.REMOTE_URL: + response = ssrf_proxy.get(f.remote_url) + response.raise_for_status() + content = response.content + encoded_string = base64.b64encode(content).decode("utf-8") + return encoded_string + case FileTransferMethod.LOCAL_FILE: + upload_file = file_repository.get_upload_file(session=db.session(), file=f) + data = _download_file_content(upload_file.key) + encoded_string = base64.b64encode(data).decode("utf-8") + return encoded_string + case FileTransferMethod.TOOL_FILE: + tool_file = file_repository.get_tool_file(session=db.session(), file=f) + data = _download_file_content(tool_file.file_key) + encoded_string = base64.b64encode(data).decode("utf-8") + return encoded_string + case _: + raise ValueError(f"Unsupported transfer method: {f.transfer_method}") + + +def _to_base64_data_string(f: File, /): + encoded_string = _get_encoded_string(f) + return f"data:{f.mime_type};base64,{encoded_string}" + + +def _file_to_encoded_string(f: File, /): + match f.type: + case FileType.IMAGE: + return _to_base64_data_string(f) + case FileType.AUDIO: + return _get_encoded_string(f) + case _: + raise ValueError(f"file type {f.type} is not supported") + + +def _to_url(f: File, /): + if f.transfer_method == FileTransferMethod.REMOTE_URL: + if f.remote_url is None: + raise ValueError("Missing file remote_url") + return f.remote_url + elif f.transfer_method == FileTransferMethod.LOCAL_FILE: + if f.related_id is None: + raise ValueError("Missing file related_id") + return helpers.get_signed_file_url(upload_file_id=f.related_id) + elif f.transfer_method == FileTransferMethod.TOOL_FILE: + # add sign url + if f.related_id is None or f.extension is None: + raise ValueError("Missing file related_id or extension") + return ToolFileParser.get_tool_file_manager().sign_file(tool_file_id=f.related_id, extension=f.extension) + else: + raise ValueError(f"Unsupported transfer method: {f.transfer_method}") diff --git a/api/core/file/file_obj.py b/api/core/file/file_obj.py deleted file mode 100644 index 5c4e694025..0000000000 --- a/api/core/file/file_obj.py +++ /dev/null @@ -1,145 +0,0 @@ -import enum -from typing import Any, Optional - -from pydantic import BaseModel - -from core.file.tool_file_parser import ToolFileParser -from core.file.upload_file_parser import UploadFileParser -from core.model_runtime.entities.message_entities import ImagePromptMessageContent -from extensions.ext_database import db - - -class FileExtraConfig(BaseModel): - """ - File Upload Entity. - """ - - image_config: Optional[dict[str, Any]] = None - - -class FileType(enum.Enum): - IMAGE = "image" - - @staticmethod - def value_of(value): - for member in FileType: - if member.value == value: - return member - raise ValueError(f"No matching enum found for value '{value}'") - - -class FileTransferMethod(enum.Enum): - REMOTE_URL = "remote_url" - LOCAL_FILE = "local_file" - TOOL_FILE = "tool_file" - - @staticmethod - def value_of(value): - for member in FileTransferMethod: - if member.value == value: - return member - raise ValueError(f"No matching enum found for value '{value}'") - - -class FileBelongsTo(enum.Enum): - USER = "user" - ASSISTANT = "assistant" - - @staticmethod - def value_of(value): - for member in FileBelongsTo: - if member.value == value: - return member - raise ValueError(f"No matching enum found for value '{value}'") - - -class FileVar(BaseModel): - id: Optional[str] = None # message file id - tenant_id: str - type: FileType - transfer_method: FileTransferMethod - url: Optional[str] = None # remote url - related_id: Optional[str] = None - extra_config: Optional[FileExtraConfig] = None - filename: Optional[str] = None - extension: Optional[str] = None - mime_type: Optional[str] = None - - def to_dict(self) -> dict: - return { - "__variant": self.__class__.__name__, - "tenant_id": self.tenant_id, - "type": self.type.value, - "transfer_method": self.transfer_method.value, - "url": self.preview_url, - "remote_url": self.url, - "related_id": self.related_id, - "filename": self.filename, - "extension": self.extension, - "mime_type": self.mime_type, - } - - def to_markdown(self) -> str: - """ - Convert file to markdown - :return: - """ - preview_url = self.preview_url - if self.type == FileType.IMAGE: - text = f'![{self.filename or ""}]({preview_url})' - else: - text = f"[{self.filename or preview_url}]({preview_url})" - - return text - - @property - def data(self) -> Optional[str]: - """ - Get image data, file signed url or base64 data - depending on config MULTIMODAL_SEND_IMAGE_FORMAT - :return: - """ - return self._get_data() - - @property - def preview_url(self) -> Optional[str]: - """ - Get signed preview url - :return: - """ - return self._get_data(force_url=True) - - @property - def prompt_message_content(self) -> ImagePromptMessageContent: - if self.type == FileType.IMAGE: - image_config = self.extra_config.image_config - - return ImagePromptMessageContent( - data=self.data, - detail=ImagePromptMessageContent.DETAIL.HIGH - if image_config.get("detail") == "high" - else ImagePromptMessageContent.DETAIL.LOW, - ) - - def _get_data(self, force_url: bool = False) -> Optional[str]: - from models.model import UploadFile - - if self.type == FileType.IMAGE: - if self.transfer_method == FileTransferMethod.REMOTE_URL: - return self.url - elif self.transfer_method == FileTransferMethod.LOCAL_FILE: - upload_file = ( - db.session.query(UploadFile) - .filter(UploadFile.id == self.related_id, UploadFile.tenant_id == self.tenant_id) - .first() - ) - - return UploadFileParser.get_image_data(upload_file=upload_file, force_url=force_url) - elif self.transfer_method == FileTransferMethod.TOOL_FILE: - extension = self.extension - # add sign url - return ToolFileParser.get_tool_file_manager().sign_file( - tool_file_id=self.related_id, extension=extension - ) - - return None diff --git a/api/core/file/file_repository.py b/api/core/file/file_repository.py new file mode 100644 index 0000000000..975e1e72db --- /dev/null +++ b/api/core/file/file_repository.py @@ -0,0 +1,32 @@ +from sqlalchemy import select +from sqlalchemy.orm import Session + +from models import ToolFile, UploadFile + +from .models import File + + +def get_upload_file(*, session: Session, file: File): + if file.related_id is None: + raise ValueError("Missing file related_id") + stmt = select(UploadFile).filter( + UploadFile.id == file.related_id, + UploadFile.tenant_id == file.tenant_id, + ) + record = session.scalar(stmt) + if not record: + raise ValueError(f"upload file {file.related_id} not found") + return record + + +def get_tool_file(*, session: Session, file: File): + if file.related_id is None: + raise ValueError("Missing file related_id") + stmt = select(ToolFile).filter( + ToolFile.id == file.related_id, + ToolFile.tenant_id == file.tenant_id, + ) + record = session.scalar(stmt) + if not record: + raise ValueError(f"tool file {file.related_id} not found") + return record diff --git a/api/core/file/helpers.py b/api/core/file/helpers.py new file mode 100644 index 0000000000..12123cf3f7 --- /dev/null +++ b/api/core/file/helpers.py @@ -0,0 +1,48 @@ +import base64 +import hashlib +import hmac +import os +import time + +from configs import dify_config + + +def get_signed_file_url(upload_file_id: str) -> str: + url = f"{dify_config.FILES_URL}/files/{upload_file_id}/file-preview" + + timestamp = str(int(time.time())) + nonce = os.urandom(16).hex() + key = dify_config.SECRET_KEY.encode() + msg = f"file-preview|{upload_file_id}|{timestamp}|{nonce}" + sign = hmac.new(key, msg.encode(), hashlib.sha256).digest() + encoded_sign = base64.urlsafe_b64encode(sign).decode() + + return f"{url}?timestamp={timestamp}&nonce={nonce}&sign={encoded_sign}" + + +def verify_image_signature(*, upload_file_id: str, timestamp: str, nonce: str, sign: str) -> bool: + data_to_sign = f"image-preview|{upload_file_id}|{timestamp}|{nonce}" + secret_key = dify_config.SECRET_KEY.encode() + recalculated_sign = hmac.new(secret_key, data_to_sign.encode(), hashlib.sha256).digest() + recalculated_encoded_sign = base64.urlsafe_b64encode(recalculated_sign).decode() + + # verify signature + if sign != recalculated_encoded_sign: + return False + + current_time = int(time.time()) + return current_time - int(timestamp) <= dify_config.FILES_ACCESS_TIMEOUT + + +def verify_file_signature(*, upload_file_id: str, timestamp: str, nonce: str, sign: str) -> bool: + data_to_sign = f"file-preview|{upload_file_id}|{timestamp}|{nonce}" + secret_key = dify_config.SECRET_KEY.encode() + recalculated_sign = hmac.new(secret_key, data_to_sign.encode(), hashlib.sha256).digest() + recalculated_encoded_sign = base64.urlsafe_b64encode(recalculated_sign).decode() + + # verify signature + if sign != recalculated_encoded_sign: + return False + + current_time = int(time.time()) + return current_time - int(timestamp) <= dify_config.FILES_ACCESS_TIMEOUT diff --git a/api/core/file/message_file_parser.py b/api/core/file/message_file_parser.py deleted file mode 100644 index 641686bd7c..0000000000 --- a/api/core/file/message_file_parser.py +++ /dev/null @@ -1,243 +0,0 @@ -import re -from collections.abc import Mapping, Sequence -from typing import Any, Union -from urllib.parse import parse_qs, urlparse - -import requests - -from core.file.file_obj import FileBelongsTo, FileExtraConfig, FileTransferMethod, FileType, FileVar -from extensions.ext_database import db -from models.account import Account -from models.model import EndUser, MessageFile, UploadFile -from services.file_service import IMAGE_EXTENSIONS - - -class MessageFileParser: - def __init__(self, tenant_id: str, app_id: str) -> None: - self.tenant_id = tenant_id - self.app_id = app_id - - def validate_and_transform_files_arg( - self, files: Sequence[Mapping[str, Any]], file_extra_config: FileExtraConfig, user: Union[Account, EndUser] - ) -> list[FileVar]: - """ - validate and transform files arg - - :param files: - :param file_extra_config: - :param user: - :return: - """ - for file in files: - if not isinstance(file, dict): - raise ValueError("Invalid file format, must be dict") - if not file.get("type"): - raise ValueError("Missing file type") - FileType.value_of(file.get("type")) - if not file.get("transfer_method"): - raise ValueError("Missing file transfer method") - FileTransferMethod.value_of(file.get("transfer_method")) - if file.get("transfer_method") == FileTransferMethod.REMOTE_URL.value: - if not file.get("url"): - raise ValueError("Missing file url") - if not file.get("url").startswith("http"): - raise ValueError("Invalid file url") - if file.get("transfer_method") == FileTransferMethod.LOCAL_FILE.value and not file.get("upload_file_id"): - raise ValueError("Missing file upload_file_id") - if file.get("transform_method") == FileTransferMethod.TOOL_FILE.value and not file.get("tool_file_id"): - raise ValueError("Missing file tool_file_id") - - # transform files to file objs - type_file_objs = self._to_file_objs(files, file_extra_config) - - # validate files - new_files = [] - for file_type, file_objs in type_file_objs.items(): - if file_type == FileType.IMAGE: - # parse and validate files - image_config = file_extra_config.image_config - - # check if image file feature is enabled - if not image_config: - continue - - # Validate number of files - if len(files) > image_config["number_limits"]: - raise ValueError(f"Number of image files exceeds the maximum limit {image_config['number_limits']}") - - for file_obj in file_objs: - # Validate transfer method - if file_obj.transfer_method.value not in image_config["transfer_methods"]: - raise ValueError(f"Invalid transfer method: {file_obj.transfer_method.value}") - - # Validate file type - if file_obj.type != FileType.IMAGE: - raise ValueError(f"Invalid file type: {file_obj.type}") - - if file_obj.transfer_method == FileTransferMethod.REMOTE_URL: - # check remote url valid and is image - result, error = self._check_image_remote_url(file_obj.url) - if result is False: - raise ValueError(error) - elif file_obj.transfer_method == FileTransferMethod.LOCAL_FILE: - # get upload file from upload_file_id - upload_file = ( - db.session.query(UploadFile) - .filter( - UploadFile.id == file_obj.related_id, - UploadFile.tenant_id == self.tenant_id, - UploadFile.created_by == user.id, - UploadFile.created_by_role == ("account" if isinstance(user, Account) else "end_user"), - UploadFile.extension.in_(IMAGE_EXTENSIONS), - ) - .first() - ) - - # check upload file is belong to tenant and user - if not upload_file: - raise ValueError("Invalid upload file") - - new_files.append(file_obj) - - # return all file objs - return new_files - - def transform_message_files(self, files: list[MessageFile], file_extra_config: FileExtraConfig): - """ - transform message files - - :param files: - :param file_extra_config: - :return: - """ - # transform files to file objs - type_file_objs = self._to_file_objs(files, file_extra_config) - - # return all file objs - return [file_obj for file_objs in type_file_objs.values() for file_obj in file_objs] - - def _to_file_objs( - self, files: list[Union[dict, MessageFile]], file_extra_config: FileExtraConfig - ) -> dict[FileType, list[FileVar]]: - """ - transform files to file objs - - :param files: - :param file_extra_config: - :return: - """ - type_file_objs: dict[FileType, list[FileVar]] = { - # Currently only support image - FileType.IMAGE: [] - } - - if not files: - return type_file_objs - - # group by file type and convert file args or message files to FileObj - for file in files: - if isinstance(file, MessageFile): - if file.belongs_to == FileBelongsTo.ASSISTANT.value: - continue - - file_obj = self._to_file_obj(file, file_extra_config) - if file_obj.type not in type_file_objs: - continue - - type_file_objs[file_obj.type].append(file_obj) - - return type_file_objs - - def _to_file_obj(self, file: Union[dict, MessageFile], file_extra_config: FileExtraConfig): - """ - transform file to file obj - - :param file: - :return: - """ - if isinstance(file, dict): - transfer_method = FileTransferMethod.value_of(file.get("transfer_method")) - if transfer_method != FileTransferMethod.TOOL_FILE: - return FileVar( - tenant_id=self.tenant_id, - type=FileType.value_of(file.get("type")), - transfer_method=transfer_method, - url=file.get("url") if transfer_method == FileTransferMethod.REMOTE_URL else None, - related_id=file.get("upload_file_id") if transfer_method == FileTransferMethod.LOCAL_FILE else None, - extra_config=file_extra_config, - ) - return FileVar( - tenant_id=self.tenant_id, - type=FileType.value_of(file.get("type")), - transfer_method=transfer_method, - url=None, - related_id=file.get("tool_file_id"), - extra_config=file_extra_config, - ) - else: - return FileVar( - id=file.id, - tenant_id=self.tenant_id, - type=FileType.value_of(file.type), - transfer_method=FileTransferMethod.value_of(file.transfer_method), - url=file.url, - related_id=file.upload_file_id or None, - extra_config=file_extra_config, - ) - - def _check_image_remote_url(self, url): - try: - headers = { - "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)" - " Chrome/91.0.4472.124 Safari/537.36" - } - - def is_s3_presigned_url(url): - try: - parsed_url = urlparse(url) - if "amazonaws.com" not in parsed_url.netloc: - return False - query_params = parse_qs(parsed_url.query) - - def check_presign_v2(query_params): - required_params = ["Signature", "Expires"] - for param in required_params: - if param not in query_params: - return False - if not query_params["Expires"][0].isdigit(): - return False - signature = query_params["Signature"][0] - if not re.match(r"^[A-Za-z0-9+/]+={0,2}$", signature): - return False - - return True - - def check_presign_v4(query_params): - required_params = ["X-Amz-Signature", "X-Amz-Expires"] - for param in required_params: - if param not in query_params: - return False - if not query_params["X-Amz-Expires"][0].isdigit(): - return False - signature = query_params["X-Amz-Signature"][0] - if not re.match(r"^[A-Za-z0-9+/]+={0,2}$", signature): - return False - - return True - - return check_presign_v4(query_params) or check_presign_v2(query_params) - except Exception: - return False - - if is_s3_presigned_url(url): - response = requests.get(url, headers=headers, allow_redirects=True) - if response.status_code in {200, 304}: - return True, "" - - response = requests.head(url, headers=headers, allow_redirects=True) - if response.status_code in {200, 304}: - return True, "" - else: - return False, "URL does not exist." - except requests.RequestException as e: - return False, f"Error checking URL: {e}" diff --git a/api/core/file/models.py b/api/core/file/models.py new file mode 100644 index 0000000000..866ff3155b --- /dev/null +++ b/api/core/file/models.py @@ -0,0 +1,140 @@ +from collections.abc import Mapping, Sequence +from typing import Optional + +from pydantic import BaseModel, Field, model_validator + +from core.model_runtime.entities.message_entities import ImagePromptMessageContent + +from . import helpers +from .constants import FILE_MODEL_IDENTITY +from .enums import FileTransferMethod, FileType +from .tool_file_parser import ToolFileParser + + +class ImageConfig(BaseModel): + """ + NOTE: This part of validation is deprecated, but still used in app features "Image Upload". + """ + + number_limits: int = 0 + transfer_methods: Sequence[FileTransferMethod] = Field(default_factory=list) + detail: ImagePromptMessageContent.DETAIL | None = None + + +class FileExtraConfig(BaseModel): + """ + File Upload Entity. + """ + + image_config: Optional[ImageConfig] = None + allowed_file_types: Sequence[FileType] = Field(default_factory=list) + allowed_extensions: Sequence[str] = Field(default_factory=list) + allowed_upload_methods: Sequence[FileTransferMethod] = Field(default_factory=list) + number_limits: int = 0 + + +class File(BaseModel): + dify_model_identity: str = FILE_MODEL_IDENTITY + + id: Optional[str] = None # message file id + tenant_id: str + type: FileType + transfer_method: FileTransferMethod + remote_url: Optional[str] = None # remote url + related_id: Optional[str] = None + filename: Optional[str] = None + extension: Optional[str] = Field(default=None, description="File extension, should contains dot") + mime_type: Optional[str] = None + size: int = -1 + _extra_config: FileExtraConfig | None = None + + def to_dict(self) -> Mapping[str, str | int | None]: + data = self.model_dump(mode="json") + return { + **data, + "url": self.generate_url(), + } + + @property + def markdown(self) -> str: + url = self.generate_url() + if self.type == FileType.IMAGE: + text = f'![{self.filename or ""}]({url})' + else: + text = f"[{self.filename or url}]({url})" + + return text + + def generate_url(self) -> Optional[str]: + if self.type == FileType.IMAGE: + if self.transfer_method == FileTransferMethod.REMOTE_URL: + return self.remote_url + elif self.transfer_method == FileTransferMethod.LOCAL_FILE: + if self.related_id is None: + raise ValueError("Missing file related_id") + return helpers.get_signed_file_url(upload_file_id=self.related_id) + elif self.transfer_method == FileTransferMethod.TOOL_FILE: + assert self.related_id is not None + assert self.extension is not None + return ToolFileParser.get_tool_file_manager().sign_file( + tool_file_id=self.related_id, extension=self.extension + ) + else: + if self.transfer_method == FileTransferMethod.REMOTE_URL: + return self.remote_url + elif self.transfer_method == FileTransferMethod.LOCAL_FILE: + if self.related_id is None: + raise ValueError("Missing file related_id") + return helpers.get_signed_file_url(upload_file_id=self.related_id) + elif self.transfer_method == FileTransferMethod.TOOL_FILE: + assert self.related_id is not None + assert self.extension is not None + return ToolFileParser.get_tool_file_manager().sign_file( + tool_file_id=self.related_id, extension=self.extension + ) + + @model_validator(mode="after") + def validate_after(self): + match self.transfer_method: + case FileTransferMethod.REMOTE_URL: + if not self.remote_url: + raise ValueError("Missing file url") + if not isinstance(self.remote_url, str) or not self.remote_url.startswith("http"): + raise ValueError("Invalid file url") + case FileTransferMethod.LOCAL_FILE: + if not self.related_id: + raise ValueError("Missing file related_id") + case FileTransferMethod.TOOL_FILE: + if not self.related_id: + raise ValueError("Missing file related_id") + + # Validate the extra config. + if not self._extra_config: + return self + + if self._extra_config.allowed_file_types: + if self.type not in self._extra_config.allowed_file_types and self.type != FileType.CUSTOM: + raise ValueError(f"Invalid file type: {self.type}") + + if self._extra_config.allowed_extensions and self.extension not in self._extra_config.allowed_extensions: + raise ValueError(f"Invalid file extension: {self.extension}") + + if ( + self._extra_config.allowed_upload_methods + and self.transfer_method not in self._extra_config.allowed_upload_methods + ): + raise ValueError(f"Invalid transfer method: {self.transfer_method}") + + match self.type: + case FileType.IMAGE: + # NOTE: This part of validation is deprecated, but still used in app features "Image Upload". + if not self._extra_config.image_config: + return self + # TODO: skip check if transfer_methods is empty, because many test cases are not setting this field + if ( + self._extra_config.image_config.transfer_methods + and self.transfer_method not in self._extra_config.image_config.transfer_methods + ): + raise ValueError(f"Invalid transfer method: {self.transfer_method}") + + return self diff --git a/api/core/file/upload_file_parser.py b/api/core/file/upload_file_parser.py deleted file mode 100644 index a8c1fd4d02..0000000000 --- a/api/core/file/upload_file_parser.py +++ /dev/null @@ -1,79 +0,0 @@ -import base64 -import hashlib -import hmac -import logging -import os -import time -from typing import Optional - -from configs import dify_config -from extensions.ext_storage import storage - -IMAGE_EXTENSIONS = ["jpg", "jpeg", "png", "webp", "gif", "svg"] -IMAGE_EXTENSIONS.extend([ext.upper() for ext in IMAGE_EXTENSIONS]) - - -class UploadFileParser: - @classmethod - def get_image_data(cls, upload_file, force_url: bool = False) -> Optional[str]: - if not upload_file: - return None - - if upload_file.extension not in IMAGE_EXTENSIONS: - return None - - if dify_config.MULTIMODAL_SEND_IMAGE_FORMAT == "url" or force_url: - return cls.get_signed_temp_image_url(upload_file.id) - else: - # get image file base64 - try: - data = storage.load(upload_file.key) - except FileNotFoundError: - logging.error(f"File not found: {upload_file.key}") - return None - - encoded_string = base64.b64encode(data).decode("utf-8") - return f"data:{upload_file.mime_type};base64,{encoded_string}" - - @classmethod - def get_signed_temp_image_url(cls, upload_file_id) -> str: - """ - get signed url from upload file - - :param upload_file: UploadFile object - :return: - """ - base_url = dify_config.FILES_URL - image_preview_url = f"{base_url}/files/{upload_file_id}/image-preview" - - timestamp = str(int(time.time())) - nonce = os.urandom(16).hex() - data_to_sign = f"image-preview|{upload_file_id}|{timestamp}|{nonce}" - secret_key = dify_config.SECRET_KEY.encode() - sign = hmac.new(secret_key, data_to_sign.encode(), hashlib.sha256).digest() - encoded_sign = base64.urlsafe_b64encode(sign).decode() - - return f"{image_preview_url}?timestamp={timestamp}&nonce={nonce}&sign={encoded_sign}" - - @classmethod - def verify_image_file_signature(cls, upload_file_id: str, timestamp: str, nonce: str, sign: str) -> bool: - """ - verify signature - - :param upload_file_id: file id - :param timestamp: timestamp - :param nonce: nonce - :param sign: signature - :return: - """ - data_to_sign = f"image-preview|{upload_file_id}|{timestamp}|{nonce}" - secret_key = dify_config.SECRET_KEY.encode() - recalculated_sign = hmac.new(secret_key, data_to_sign.encode(), hashlib.sha256).digest() - recalculated_encoded_sign = base64.urlsafe_b64encode(recalculated_sign).decode() - - # verify signature - if sign != recalculated_encoded_sign: - return False - - current_time = int(time.time()) - return current_time - int(timestamp) <= dify_config.FILES_ACCESS_TIMEOUT diff --git a/api/core/model_runtime/model_providers/anthropic/llm/claude-3-5-sonnet-20241022.yaml b/api/core/model_runtime/model_providers/anthropic/llm/claude-3-5-sonnet-20241022.yaml new file mode 100644 index 0000000000..e20b8c4960 --- /dev/null +++ b/api/core/model_runtime/model_providers/anthropic/llm/claude-3-5-sonnet-20241022.yaml @@ -0,0 +1,39 @@ +model: claude-3-5-sonnet-20241022 +label: + en_US: claude-3-5-sonnet-20241022 +model_type: llm +features: + - agent-thought + - vision + - tool-call + - stream-tool-call +model_properties: + mode: chat + context_size: 200000 +parameter_rules: + - name: temperature + use_template: temperature + - name: top_p + use_template: top_p + - name: top_k + label: + zh_Hans: 取样数量 + en_US: Top k + type: int + help: + zh_Hans: 仅从每个后续标记的前 K 个选项中采样。 + en_US: Only sample from the top K options for each subsequent token. + required: false + - name: max_tokens + use_template: max_tokens + required: true + default: 8192 + min: 1 + max: 8192 + - name: response_format + use_template: response_format +pricing: + input: '3.00' + output: '15.00' + unit: '0.000001' + currency: USD diff --git a/api/core/model_runtime/model_providers/bedrock/llm/anthropic.claude-3-sonnet-v2.yaml b/api/core/model_runtime/model_providers/bedrock/llm/anthropic.claude-3-sonnet-v2.yaml new file mode 100644 index 0000000000..b1e5698375 --- /dev/null +++ b/api/core/model_runtime/model_providers/bedrock/llm/anthropic.claude-3-sonnet-v2.yaml @@ -0,0 +1,60 @@ +model: anthropic.claude-3-5-sonnet-20241022-v2:0 +label: + en_US: Claude 3.5 Sonnet V2 +model_type: llm +features: + - agent-thought + - vision + - tool-call + - stream-tool-call +model_properties: + mode: chat + context_size: 200000 +# docs: https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-anthropic-claude-messages.html +parameter_rules: + - name: max_tokens + use_template: max_tokens + required: true + type: int + default: 4096 + min: 1 + max: 4096 + help: + zh_Hans: 停止前生成的最大令牌数。请注意,Anthropic Claude 模型可能会在达到 max_tokens 的值之前停止生成令牌。不同的 Anthropic Claude 模型对此参数具有不同的最大值。 + en_US: The maximum number of tokens to generate before stopping. Note that Anthropic Claude models might stop generating tokens before reaching the value of max_tokens. Different Anthropic Claude models have different maximum values for this parameter. + - name: temperature + use_template: temperature + required: false + type: float + default: 1 + min: 0.0 + max: 1.0 + help: + zh_Hans: 生成内容的随机性。 + en_US: The amount of randomness injected into the response. + - name: top_p + required: false + type: float + default: 0.999 + min: 0.000 + max: 1.000 + help: + zh_Hans: 在核采样中,Anthropic Claude 按概率递减顺序计算每个后续标记的所有选项的累积分布,并在达到 top_p 指定的特定概率时将其切断。您应该更改温度或top_p,但不能同时更改两者。 + en_US: In nucleus sampling, Anthropic Claude computes the cumulative distribution over all the options for each subsequent token in decreasing probability order and cuts it off once it reaches a particular probability specified by top_p. You should alter either temperature or top_p, but not both. + - name: top_k + required: false + type: int + default: 0 + min: 0 + # tip docs from aws has error, max value is 500 + max: 500 + help: + zh_Hans: 对于每个后续标记,仅从前 K 个选项中进行采样。使用 top_k 删除长尾低概率响应。 + en_US: Only sample from the top K options for each subsequent token. Use top_k to remove long tail low probability responses. + - name: response_format + use_template: response_format +pricing: + input: '0.003' + output: '0.015' + unit: '0.001' + currency: USD diff --git a/api/core/model_runtime/model_providers/bedrock/llm/eu.anthropic.claude-3-sonnet-v2.yaml b/api/core/model_runtime/model_providers/bedrock/llm/eu.anthropic.claude-3-sonnet-v2.yaml new file mode 100644 index 0000000000..8d831e6fcb --- /dev/null +++ b/api/core/model_runtime/model_providers/bedrock/llm/eu.anthropic.claude-3-sonnet-v2.yaml @@ -0,0 +1,60 @@ +model: eu.anthropic.claude-3-5-sonnet-20241022-v2:0 +label: + en_US: Claude 3.5 Sonnet V2(EU.Cross Region Inference) +model_type: llm +features: + - agent-thought + - vision + - tool-call + - stream-tool-call +model_properties: + mode: chat + context_size: 200000 +# docs: https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-anthropic-claude-messages.html +parameter_rules: + - name: max_tokens + use_template: max_tokens + required: true + type: int + default: 4096 + min: 1 + max: 4096 + help: + zh_Hans: 停止前生成的最大令牌数。请注意,Anthropic Claude 模型可能会在达到 max_tokens 的值之前停止生成令牌。不同的 Anthropic Claude 模型对此参数具有不同的最大值。 + en_US: The maximum number of tokens to generate before stopping. Note that Anthropic Claude models might stop generating tokens before reaching the value of max_tokens. Different Anthropic Claude models have different maximum values for this parameter. + - name: temperature + use_template: temperature + required: false + type: float + default: 1 + min: 0.0 + max: 1.0 + help: + zh_Hans: 生成内容的随机性。 + en_US: The amount of randomness injected into the response. + - name: top_p + required: false + type: float + default: 0.999 + min: 0.000 + max: 1.000 + help: + zh_Hans: 在核采样中,Anthropic Claude 按概率递减顺序计算每个后续标记的所有选项的累积分布,并在达到 top_p 指定的特定概率时将其切断。您应该更改温度或top_p,但不能同时更改两者。 + en_US: In nucleus sampling, Anthropic Claude computes the cumulative distribution over all the options for each subsequent token in decreasing probability order and cuts it off once it reaches a particular probability specified by top_p. You should alter either temperature or top_p, but not both. + - name: top_k + required: false + type: int + default: 0 + min: 0 + # tip docs from aws has error, max value is 500 + max: 500 + help: + zh_Hans: 对于每个后续标记,仅从前 K 个选项中进行采样。使用 top_k 删除长尾低概率响应。 + en_US: Only sample from the top K options for each subsequent token. Use top_k to remove long tail low probability responses. + - name: response_format + use_template: response_format +pricing: + input: '0.003' + output: '0.015' + unit: '0.001' + currency: USD diff --git a/api/core/model_runtime/model_providers/bedrock/llm/us.anthropic.claude-3-sonnet-v2.yaml b/api/core/model_runtime/model_providers/bedrock/llm/us.anthropic.claude-3-sonnet-v2.yaml new file mode 100644 index 0000000000..31a403289b --- /dev/null +++ b/api/core/model_runtime/model_providers/bedrock/llm/us.anthropic.claude-3-sonnet-v2.yaml @@ -0,0 +1,60 @@ +model: us.anthropic.claude-3-5-sonnet-20241022-v2:0 +label: + en_US: Claude 3.5 Sonnet V2(US.Cross Region Inference) +model_type: llm +features: + - agent-thought + - vision + - tool-call + - stream-tool-call +model_properties: + mode: chat + context_size: 200000 +# docs: https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-anthropic-claude-messages.html +parameter_rules: + - name: max_tokens + use_template: max_tokens + required: true + type: int + default: 4096 + min: 1 + max: 4096 + help: + zh_Hans: 停止前生成的最大令牌数。请注意,Anthropic Claude 模型可能会在达到 max_tokens 的值之前停止生成令牌。不同的 Anthropic Claude 模型对此参数具有不同的最大值。 + en_US: The maximum number of tokens to generate before stopping. Note that Anthropic Claude models might stop generating tokens before reaching the value of max_tokens. Different Anthropic Claude models have different maximum values for this parameter. + - name: temperature + use_template: temperature + required: false + type: float + default: 1 + min: 0.0 + max: 1.0 + help: + zh_Hans: 生成内容的随机性。 + en_US: The amount of randomness injected into the response. + - name: top_p + required: false + type: float + default: 0.999 + min: 0.000 + max: 1.000 + help: + zh_Hans: 在核采样中,Anthropic Claude 按概率递减顺序计算每个后续标记的所有选项的累积分布,并在达到 top_p 指定的特定概率时将其切断。您应该更改温度或top_p,但不能同时更改两者。 + en_US: In nucleus sampling, Anthropic Claude computes the cumulative distribution over all the options for each subsequent token in decreasing probability order and cuts it off once it reaches a particular probability specified by top_p. You should alter either temperature or top_p, but not both. + - name: top_k + required: false + type: int + default: 0 + min: 0 + # tip docs from aws has error, max value is 500 + max: 500 + help: + zh_Hans: 对于每个后续标记,仅从前 K 个选项中进行采样。使用 top_k 删除长尾低概率响应。 + en_US: Only sample from the top K options for each subsequent token. Use top_k to remove long tail low probability responses. + - name: response_format + use_template: response_format +pricing: + input: '0.003' + output: '0.015' + unit: '0.001' + currency: USD diff --git a/api/core/model_runtime/model_providers/groq/llm/llama-3.2-11b-vision-preview.yaml b/api/core/model_runtime/model_providers/groq/llm/llama-3.2-11b-vision-preview.yaml new file mode 100644 index 0000000000..5632218797 --- /dev/null +++ b/api/core/model_runtime/model_providers/groq/llm/llama-3.2-11b-vision-preview.yaml @@ -0,0 +1,26 @@ +model: llama-3.2-11b-vision-preview +label: + zh_Hans: Llama 3.2 11B Vision (Preview) + en_US: Llama 3.2 11B Vision (Preview) +model_type: llm +features: + - agent-thought + - vision +model_properties: + mode: chat + context_size: 131072 +parameter_rules: + - name: temperature + use_template: temperature + - name: top_p + use_template: top_p + - name: max_tokens + use_template: max_tokens + default: 512 + min: 1 + max: 8192 +pricing: + input: '0.05' + output: '0.1' + unit: '0.000001' + currency: USD diff --git a/api/core/model_runtime/model_providers/groq/llm/llama-3.2-90b-vision-preview.yaml b/api/core/model_runtime/model_providers/groq/llm/llama-3.2-90b-vision-preview.yaml new file mode 100644 index 0000000000..e7b93101e8 --- /dev/null +++ b/api/core/model_runtime/model_providers/groq/llm/llama-3.2-90b-vision-preview.yaml @@ -0,0 +1,26 @@ +model: llama-3.2-90b-vision-preview +label: + zh_Hans: Llama 3.2 90B Vision (Preview) + en_US: Llama 3.2 90B Vision (Preview) +model_type: llm +features: + - agent-thought + - vision +model_properties: + mode: chat + context_size: 131072 +parameter_rules: + - name: temperature + use_template: temperature + - name: top_p + use_template: top_p + - name: max_tokens + use_template: max_tokens + default: 512 + min: 1 + max: 8192 +pricing: + input: '0.05' + output: '0.1' + unit: '0.000001' + currency: USD diff --git a/api/core/model_runtime/model_providers/groq/speech2text/__init__.py b/api/core/model_runtime/model_providers/groq/speech2text/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/api/core/model_runtime/model_providers/groq/speech2text/distil-whisper-large-v3-en.yaml b/api/core/model_runtime/model_providers/groq/speech2text/distil-whisper-large-v3-en.yaml new file mode 100644 index 0000000000..202d006a66 --- /dev/null +++ b/api/core/model_runtime/model_providers/groq/speech2text/distil-whisper-large-v3-en.yaml @@ -0,0 +1,5 @@ +model: distil-whisper-large-v3-en +model_type: speech2text +model_properties: + file_upload_limit: 1 + supported_file_extensions: flac,mp3,mp4,mpeg,mpga,m4a,ogg,wav,webm diff --git a/api/core/model_runtime/model_providers/groq/speech2text/speech2text.py b/api/core/model_runtime/model_providers/groq/speech2text/speech2text.py new file mode 100644 index 0000000000..75feeb9cb9 --- /dev/null +++ b/api/core/model_runtime/model_providers/groq/speech2text/speech2text.py @@ -0,0 +1,30 @@ +from typing import IO, Optional + +from core.model_runtime.model_providers.openai_api_compatible.speech2text.speech2text import OAICompatSpeech2TextModel + + +class GroqSpeech2TextModel(OAICompatSpeech2TextModel): + """ + Model class for Groq Speech to text model. + """ + + def _invoke(self, model: str, credentials: dict, file: IO[bytes], user: Optional[str] = None) -> str: + """ + Invoke speech2text model + + :param model: model name + :param credentials: model credentials + :param file: audio file + :param user: unique user id + :return: text for given audio file + """ + self._add_custom_parameters(credentials) + return super()._invoke(model, credentials, file) + + def validate_credentials(self, model: str, credentials: dict) -> None: + self._add_custom_parameters(credentials) + return super().validate_credentials(model, credentials) + + @classmethod + def _add_custom_parameters(cls, credentials: dict) -> None: + credentials["endpoint_url"] = "https://api.groq.com/openai/v1" diff --git a/api/core/model_runtime/model_providers/groq/speech2text/whisper-large-v3-turbo.yaml b/api/core/model_runtime/model_providers/groq/speech2text/whisper-large-v3-turbo.yaml new file mode 100644 index 0000000000..3882a3f4f2 --- /dev/null +++ b/api/core/model_runtime/model_providers/groq/speech2text/whisper-large-v3-turbo.yaml @@ -0,0 +1,5 @@ +model: whisper-large-v3-turbo +model_type: speech2text +model_properties: + file_upload_limit: 1 + supported_file_extensions: flac,mp3,mp4,mpeg,mpga,m4a,ogg,wav,webm diff --git a/api/core/model_runtime/model_providers/groq/speech2text/whisper-large-v3.yaml b/api/core/model_runtime/model_providers/groq/speech2text/whisper-large-v3.yaml new file mode 100644 index 0000000000..ed02477d70 --- /dev/null +++ b/api/core/model_runtime/model_providers/groq/speech2text/whisper-large-v3.yaml @@ -0,0 +1,5 @@ +model: whisper-large-v3 +model_type: speech2text +model_properties: + file_upload_limit: 1 + supported_file_extensions: flac,mp3,mp4,mpeg,mpga,m4a,ogg,wav,webm diff --git a/api/core/model_runtime/model_providers/openai/llm/gpt-4o-audio-preview.yaml b/api/core/model_runtime/model_providers/openai/llm/gpt-4o-audio-preview.yaml new file mode 100644 index 0000000000..256e87edbe --- /dev/null +++ b/api/core/model_runtime/model_providers/openai/llm/gpt-4o-audio-preview.yaml @@ -0,0 +1,44 @@ +model: gpt-4o-audio-preview +label: + zh_Hans: gpt-4o-audio-preview + en_US: gpt-4o-audio-preview +model_type: llm +features: + - multi-tool-call + - agent-thought + - stream-tool-call + - vision +model_properties: + mode: chat + context_size: 128000 +parameter_rules: + - name: temperature + use_template: temperature + - name: top_p + use_template: top_p + - name: presence_penalty + use_template: presence_penalty + - name: frequency_penalty + use_template: frequency_penalty + - name: max_tokens + use_template: max_tokens + default: 512 + min: 1 + max: 4096 + - name: response_format + label: + zh_Hans: 回复格式 + en_US: Response Format + type: string + help: + zh_Hans: 指定模型必须输出的格式 + en_US: specifying the format that the model must output + required: false + options: + - text + - json_object +pricing: + input: '5.00' + output: '15.00' + unit: '0.000001' + currency: USD diff --git a/api/core/model_runtime/model_providers/openai_api_compatible/rerank/__init__.py b/api/core/model_runtime/model_providers/openai_api_compatible/rerank/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/api/core/model_runtime/model_providers/openai_api_compatible/rerank/rerank.py b/api/core/model_runtime/model_providers/openai_api_compatible/rerank/rerank.py new file mode 100644 index 0000000000..508da4bf20 --- /dev/null +++ b/api/core/model_runtime/model_providers/openai_api_compatible/rerank/rerank.py @@ -0,0 +1,159 @@ +from json import dumps +from typing import Optional + +import httpx +from requests import post +from yarl import URL + +from core.model_runtime.entities.common_entities import I18nObject +from core.model_runtime.entities.model_entities import AIModelEntity, FetchFrom, ModelType +from core.model_runtime.entities.rerank_entities import RerankDocument, RerankResult +from core.model_runtime.errors.invoke import ( + InvokeAuthorizationError, + InvokeBadRequestError, + InvokeConnectionError, + InvokeError, + InvokeRateLimitError, + InvokeServerUnavailableError, +) +from core.model_runtime.errors.validate import CredentialsValidateFailedError +from core.model_runtime.model_providers.__base.rerank_model import RerankModel + + +class OAICompatRerankModel(RerankModel): + """ + rerank model API is compatible with Jina rerank model API. So copy the JinaRerankModel class code here. + we need enhance for llama.cpp , which return raw score, not normalize score 0~1. It seems Dify need it + """ + + def _invoke( + self, + model: str, + credentials: dict, + query: str, + docs: list[str], + score_threshold: Optional[float] = None, + top_n: Optional[int] = None, + user: Optional[str] = None, + ) -> RerankResult: + """ + Invoke rerank model + + :param model: model name + :param credentials: model credentials + :param query: search query + :param docs: docs for reranking + :param score_threshold: score threshold + :param top_n: top n documents to return + :param user: unique user id + :return: rerank result + """ + if len(docs) == 0: + return RerankResult(model=model, docs=[]) + + server_url = credentials["endpoint_url"] + model_name = model + + if not server_url: + raise CredentialsValidateFailedError("server_url is required") + if not model_name: + raise CredentialsValidateFailedError("model_name is required") + + url = server_url + headers = {"Authorization": f"Bearer {credentials.get('api_key')}", "Content-Type": "application/json"} + + # TODO: Do we need truncate docs to avoid llama.cpp return error? + + data = {"model": model_name, "query": query, "documents": docs, "top_n": top_n} + + try: + response = post(str(URL(url) / "rerank"), headers=headers, data=dumps(data), timeout=60) + response.raise_for_status() + results = response.json() + + rerank_documents = [] + scores = [result["relevance_score"] for result in results["results"]] + + # Min-Max Normalization: Normalize scores to 0 ~ 1.0 range + min_score = min(scores) + max_score = max(scores) + score_range = max_score - min_score if max_score != min_score else 1.0 # Avoid division by zero + + for result in results["results"]: + index = result["index"] + + # Retrieve document text (fallback if llama.cpp rerank doesn't return it) + text = result.get("document", {}).get("text", docs[index]) + + # Normalize the score + normalized_score = (result["relevance_score"] - min_score) / score_range + + # Create RerankDocument object with normalized score + rerank_document = RerankDocument( + index=index, + text=text, + score=normalized_score, + ) + + # Apply threshold (if defined) + if score_threshold is None or normalized_score >= score_threshold: + rerank_documents.append(rerank_document) + + # Sort rerank_documents by normalized score in descending order + rerank_documents.sort(key=lambda doc: doc.score, reverse=True) + + return RerankResult(model=model, docs=rerank_documents) + + except httpx.HTTPStatusError as e: + raise InvokeServerUnavailableError(str(e)) + + def validate_credentials(self, model: str, credentials: dict) -> None: + """ + Validate model credentials + + :param model: model name + :param credentials: model credentials + :return: + """ + try: + self._invoke( + model=model, + credentials=credentials, + query="What is the capital of the United States?", + docs=[ + "Carson City is the capital city of the American state of Nevada. At the 2010 United States " + "Census, Carson City had a population of 55,274.", + "The Commonwealth of the Northern Mariana Islands is a group of islands in the Pacific Ocean that " + "are a political division controlled by the United States. Its capital is Saipan.", + ], + score_threshold=0.8, + ) + except Exception as ex: + raise CredentialsValidateFailedError(str(ex)) + + @property + def _invoke_error_mapping(self) -> dict[type[InvokeError], list[type[Exception]]]: + """ + Map model invoke error to unified error + """ + return { + InvokeConnectionError: [httpx.ConnectError], + InvokeServerUnavailableError: [httpx.RemoteProtocolError], + InvokeRateLimitError: [], + InvokeAuthorizationError: [httpx.HTTPStatusError], + InvokeBadRequestError: [httpx.RequestError], + } + + def get_customizable_model_schema(self, model: str, credentials: dict) -> AIModelEntity: + """ + generate custom model entities from credentials + """ + entity = AIModelEntity( + model=model, + label=I18nObject(en_US=model), + model_type=ModelType.RERANK, + fetch_from=FetchFrom.CUSTOMIZABLE_MODEL, + model_properties={}, + ) + + return entity diff --git a/api/core/model_runtime/model_providers/vertex_ai/llm/anthropic.claude-3.5-sonnet-v2.yaml b/api/core/model_runtime/model_providers/vertex_ai/llm/anthropic.claude-3.5-sonnet-v2.yaml new file mode 100644 index 0000000000..0be3e26e7a --- /dev/null +++ b/api/core/model_runtime/model_providers/vertex_ai/llm/anthropic.claude-3.5-sonnet-v2.yaml @@ -0,0 +1,55 @@ +model: claude-3-5-sonnet-v2@20241022 +label: + en_US: Claude 3.5 Sonnet v2 +model_type: llm +features: + - agent-thought + - vision +model_properties: + mode: chat + context_size: 200000 +parameter_rules: + - name: max_tokens + use_template: max_tokens + required: true + type: int + default: 4096 + min: 1 + max: 4096 + help: + zh_Hans: 停止前生成的最大令牌数。请注意,Anthropic Claude 模型可能会在达到 max_tokens 的值之前停止生成令牌。不同的 Anthropic Claude 模型对此参数具有不同的最大值。 + en_US: The maximum number of tokens to generate before stopping. Note that Anthropic Claude models might stop generating tokens before reaching the value of max_tokens. Different Anthropic Claude models have different maximum values for this parameter. + - name: temperature + use_template: temperature + required: false + type: float + default: 1 + min: 0.0 + max: 1.0 + help: + zh_Hans: 生成内容的随机性。 + en_US: The amount of randomness injected into the response. + - name: top_p + required: false + type: float + default: 0.999 + min: 0.000 + max: 1.000 + help: + zh_Hans: 在核采样中,Anthropic Claude 按概率递减顺序计算每个后续标记的所有选项的累积分布,并在达到 top_p 指定的特定概率时将其切断。您应该更改温度或top_p,但不能同时更改两者。 + en_US: In nucleus sampling, Anthropic Claude computes the cumulative distribution over all the options for each subsequent token in decreasing probability order and cuts it off once it reaches a particular probability specified by top_p. You should alter either temperature or top_p, but not both. + - name: top_k + required: false + type: int + default: 0 + min: 0 + # tip docs from aws has error, max value is 500 + max: 500 + help: + zh_Hans: 对于每个后续标记,仅从前 K 个选项中进行采样。使用 top_k 删除长尾低概率响应。 + en_US: Only sample from the top K options for each subsequent token. Use top_k to remove long tail low probability responses. +pricing: + input: '0.003' + output: '0.015' + unit: '0.001' + currency: USD diff --git a/api/core/rag/datasource/vdb/upstash/__init__.py b/api/core/rag/datasource/vdb/upstash/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/api/core/rag/datasource/vdb/upstash/upstash_vector.py b/api/core/rag/datasource/vdb/upstash/upstash_vector.py new file mode 100644 index 0000000000..df1b550b40 --- /dev/null +++ b/api/core/rag/datasource/vdb/upstash/upstash_vector.py @@ -0,0 +1,129 @@ +import json +from typing import Any +from uuid import uuid4 + +from pydantic import BaseModel, model_validator +from upstash_vector import Index, Vector + +from configs import dify_config +from core.rag.datasource.vdb.vector_base import BaseVector +from core.rag.datasource.vdb.vector_factory import AbstractVectorFactory +from core.rag.datasource.vdb.vector_type import VectorType +from core.rag.embedding.embedding_base import Embeddings +from core.rag.models.document import Document +from models.dataset import Dataset + + +class UpstashVectorConfig(BaseModel): + url: str + token: str + + @model_validator(mode="before") + @classmethod + def validate_config(cls, values: dict) -> dict: + if not values["url"]: + raise ValueError("Upstash URL is required") + if not values["token"]: + raise ValueError("Upstash Token is required") + return values + + +class UpstashVector(BaseVector): + def __init__(self, collection_name: str, config: UpstashVectorConfig): + super().__init__(collection_name) + self._table_name = collection_name + self.index = Index(url=config.url, token=config.token) + + def _get_index_dimension(self) -> int: + index_info = self.index.info() + if index_info and index_info.dimension: + return index_info.dimension + else: + return 1536 + + def create(self, texts: list[Document], embeddings: list[list[float]], **kwargs): + self.add_texts(texts, embeddings) + + def add_texts(self, documents: list[Document], embeddings: list[list[float]], **kwargs): + vectors = [ + Vector( + id=str(uuid4()), + vector=embedding, + metadata=doc.metadata, + data=doc.page_content, + ) + for doc, embedding in zip(documents, embeddings) + ] + self.index.upsert(vectors=vectors) + + def text_exists(self, id: str) -> bool: + response = self.get_ids_by_metadata_field("doc_id", id) + return len(response) > 0 + + def delete_by_ids(self, ids: list[str]) -> None: + item_ids = [] + for doc_id in ids: + ids = self.get_ids_by_metadata_field("doc_id", doc_id) + if id: + item_ids += ids + self._delete_by_ids(ids=item_ids) + + def _delete_by_ids(self, ids: list[str]) -> None: + if ids: + self.index.delete(ids=ids) + + def get_ids_by_metadata_field(self, key: str, value: str) -> list[str]: + query_result = self.index.query( + vector=[1.001 * i for i in range(self._get_index_dimension())], + include_metadata=True, + top_k=1000, + filter=f"{key} = '{value}'", + ) + return [result.id for result in query_result] + + def delete_by_metadata_field(self, key: str, value: str) -> None: + ids = self.get_ids_by_metadata_field(key, value) + if ids: + self._delete_by_ids(ids) + + def search_by_vector(self, query_vector: list[float], **kwargs: Any) -> list[Document]: + top_k = kwargs.get("top_k", 4) + result = self.index.query(vector=query_vector, top_k=top_k, include_metadata=True, include_data=True) + docs = [] + score_threshold = float(kwargs.get("score_threshold") or 0.0) + for record in result: + metadata = record.metadata + text = record.data + score = record.score + metadata["score"] = score + if score > score_threshold: + docs.append(Document(page_content=text, metadata=metadata)) + return docs + + def search_by_full_text(self, query: str, **kwargs: Any) -> list[Document]: + return [] + + def delete(self) -> None: + self.index.reset() + + def get_type(self) -> str: + return VectorType.UPSTASH + + +class UpstashVectorFactory(AbstractVectorFactory): + def init_vector(self, dataset: Dataset, attributes: list, embeddings: Embeddings) -> UpstashVector: + if dataset.index_struct_dict: + class_prefix: str = dataset.index_struct_dict["vector_store"]["class_prefix"] + collection_name = class_prefix.lower() + else: + dataset_id = dataset.id + collection_name = Dataset.gen_collection_name_by_id(dataset_id).lower() + dataset.index_struct = json.dumps(self.gen_index_struct_dict(VectorType.UPSTASH, collection_name)) + + return UpstashVector( + collection_name=collection_name, + config=UpstashVectorConfig( + url=dify_config.UPSTASH_VECTOR_URL, + token=dify_config.UPSTASH_VECTOR_TOKEN, + ), + ) diff --git a/api/core/rag/extractor/unstructured/unstructured_pdf_extractor.py b/api/core/rag/extractor/unstructured/unstructured_pdf_extractor.py new file mode 100644 index 0000000000..dd8a979e70 --- /dev/null +++ b/api/core/rag/extractor/unstructured/unstructured_pdf_extractor.py @@ -0,0 +1,47 @@ +import logging + +from core.rag.extractor.extractor_base import BaseExtractor +from core.rag.models.document import Document + +logger = logging.getLogger(__name__) + + +class UnstructuredPDFExtractor(BaseExtractor): + """Load pdf files. + + + Args: + file_path: Path to the file to load. + + api_url: Unstructured API URL + + api_key: Unstructured API Key + """ + + def __init__(self, file_path: str, api_url: str, api_key: str): + """Initialize with file path.""" + self._file_path = file_path + self._api_url = api_url + self._api_key = api_key + + def extract(self) -> list[Document]: + if self._api_url: + from unstructured.partition.api import partition_via_api + + elements = partition_via_api( + filename=self._file_path, api_url=self._api_url, api_key=self._api_key, strategy="auto" + ) + else: + from unstructured.partition.pdf import partition_pdf + + elements = partition_pdf(filename=self._file_path, strategy="auto") + + from unstructured.chunking.title import chunk_by_title + + chunks = chunk_by_title(elements, max_characters=2000, combine_text_under_n_chars=2000) + documents = [] + for chunk in chunks: + text = chunk.text.strip() + documents.append(Document(page_content=text)) + + return documents diff --git a/api/core/tools/provider/builtin/aliyuque/_assets/icon.svg b/api/core/tools/provider/builtin/aliyuque/_assets/icon.svg new file mode 100644 index 0000000000..82b23ebbc6 --- /dev/null +++ b/api/core/tools/provider/builtin/aliyuque/_assets/icon.svg @@ -0,0 +1,32 @@ +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="26" height="26" viewBox="0 0 26 26" version="1.1"> + <title>绿 lgo + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/api/core/tools/provider/builtin/aliyuque/aliyuque.py b/api/core/tools/provider/builtin/aliyuque/aliyuque.py new file mode 100644 index 0000000000..56eac1a4b5 --- /dev/null +++ b/api/core/tools/provider/builtin/aliyuque/aliyuque.py @@ -0,0 +1,19 @@ +from core.tools.errors import ToolProviderCredentialValidationError +from core.tools.provider.builtin.aliyuque.tools.base import AliYuqueTool +from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController + + +class AliYuqueProvider(BuiltinToolProviderController): + def _validate_credentials(self, credentials: dict) -> None: + token = credentials.get("token") + if not token: + raise ToolProviderCredentialValidationError("token is required") + + try: + resp = AliYuqueTool.auth(token) + if resp and resp.get("data", {}).get("id"): + return + + raise ToolProviderCredentialValidationError(resp) + except Exception as e: + raise ToolProviderCredentialValidationError(str(e)) diff --git a/api/core/tools/provider/builtin/aliyuque/aliyuque.yaml b/api/core/tools/provider/builtin/aliyuque/aliyuque.yaml new file mode 100644 index 0000000000..73d39aa96c --- /dev/null +++ b/api/core/tools/provider/builtin/aliyuque/aliyuque.yaml @@ -0,0 +1,29 @@ +identity: + author: 佐井 + name: aliyuque + label: + en_US: yuque + zh_Hans: 语雀 + pt_BR: yuque + description: + en_US: Yuque, https://www.yuque.com. + zh_Hans: 语雀,https://www.yuque.com。 + pt_BR: Yuque, https://www.yuque.com. + icon: icon.svg + tags: + - productivity + - search +credentials_for_provider: + token: + type: secret-input + required: true + label: + en_US: Yuque Team Token + zh_Hans: 语雀团队Token + placeholder: + en_US: Please input your Yuque team token + zh_Hans: 请输入你的语雀团队Token + help: + en_US: Get Alibaba Yuque team token + zh_Hans: 先获取语雀团队Token + url: https://www.yuque.com/settings/tokens diff --git a/api/core/tools/provider/builtin/aliyuque/tools/base.py b/api/core/tools/provider/builtin/aliyuque/tools/base.py new file mode 100644 index 0000000000..fb7e219bff --- /dev/null +++ b/api/core/tools/provider/builtin/aliyuque/tools/base.py @@ -0,0 +1,50 @@ +""" +语雀客户端 +""" + +__author__ = "佐井" +__created__ = "2024-06-01 09:45:20" + +from typing import Any + +import requests + + +class AliYuqueTool: + # yuque service url + server_url = "https://www.yuque.com" + + @staticmethod + def auth(token): + session = requests.Session() + session.headers.update({"Accept": "application/json", "X-Auth-Token": token}) + login = session.request("GET", AliYuqueTool.server_url + "/api/v2/user") + login.raise_for_status() + resp = login.json() + return resp + + def request(self, method: str, token, tool_parameters: dict[str, Any], path: str) -> str: + if not token: + raise Exception("token is required") + session = requests.Session() + session.headers.update({"accept": "application/json", "X-Auth-Token": token}) + new_params = {**tool_parameters} + # 找出需要替换的变量 + replacements = {k: v for k, v in new_params.items() if f"{{{k}}}" in path} + + # 替换 path 中的变量 + for key, value in replacements.items(): + path = path.replace(f"{{{key}}}", str(value)) + del new_params[key] # 从 kwargs 中删除已经替换的变量 + # 请求接口 + if method.upper() in {"POST", "PUT"}: + session.headers.update( + { + "Content-Type": "application/json", + } + ) + response = session.request(method.upper(), self.server_url + path, json=new_params) + else: + response = session.request(method, self.server_url + path, params=new_params) + response.raise_for_status() + return response.text diff --git a/api/core/tools/provider/builtin/aliyuque/tools/create_document.py b/api/core/tools/provider/builtin/aliyuque/tools/create_document.py new file mode 100644 index 0000000000..feadc29258 --- /dev/null +++ b/api/core/tools/provider/builtin/aliyuque/tools/create_document.py @@ -0,0 +1,22 @@ +""" +创建文档 +""" + +__author__ = "佐井" +__created__ = "2024-06-01 10:45:20" + +from typing import Any, Union + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.provider.builtin.aliyuque.tools.base import AliYuqueTool +from core.tools.tool.builtin_tool import BuiltinTool + + +class AliYuqueCreateDocumentTool(AliYuqueTool, BuiltinTool): + def _invoke( + self, user_id: str, tool_parameters: dict[str, Any] + ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: + token = self.runtime.credentials.get("token", None) + if not token: + raise Exception("token is required") + return self.create_text_message(self.request("POST", token, tool_parameters, "/api/v2/repos/{book_id}/docs")) diff --git a/api/core/tools/provider/builtin/aliyuque/tools/create_document.yaml b/api/core/tools/provider/builtin/aliyuque/tools/create_document.yaml new file mode 100644 index 0000000000..b9d1c60327 --- /dev/null +++ b/api/core/tools/provider/builtin/aliyuque/tools/create_document.yaml @@ -0,0 +1,99 @@ +identity: + name: aliyuque_create_document + author: 佐井 + label: + en_US: Create Document + zh_Hans: 创建文档 + icon: icon.svg +description: + human: + en_US: Creates a new document within a knowledge base without automatic addition to the table of contents. Requires a subsequent call to the "knowledge base directory update API". Supports setting visibility, format, and content. # 接口英文描述 + zh_Hans: 在知识库中创建新文档,但不会自动加入目录,需额外调用“知识库目录更新接口”。允许设置公开性、格式及正文内容。 + llm: Creates docs in a KB. + +parameters: + - name: book_id + type: number + required: true + form: llm + label: + en_US: Knowledge Base ID + zh_Hans: 知识库ID + human_description: + en_US: The unique identifier of the knowledge base where the document will be created. + zh_Hans: 文档将被创建的知识库的唯一标识。 + llm_description: ID of the target knowledge base. + + - name: title + type: string + required: false + form: llm + label: + en_US: Title + zh_Hans: 标题 + human_description: + en_US: The title of the document, defaults to 'Untitled' if not provided. + zh_Hans: 文档标题,默认为'无标题'如未提供。 + llm_description: Title of the document, defaults to 'Untitled'. + + - name: public + type: select + required: false + form: llm + options: + - value: 0 + label: + en_US: Private + zh_Hans: 私密 + - value: 1 + label: + en_US: Public + zh_Hans: 公开 + - value: 2 + label: + en_US: Enterprise-only + zh_Hans: 企业内公开 + label: + en_US: Visibility + zh_Hans: 公开性 + human_description: + en_US: Document visibility (0 Private, 1 Public, 2 Enterprise-only). + zh_Hans: 文档可见性(0 私密, 1 公开, 2 企业内公开)。 + llm_description: Doc visibility options, 0-private, 1-public, 2-enterprise. + + - name: format + type: select + required: false + form: llm + options: + - value: markdown + label: + en_US: markdown + zh_Hans: markdown + - value: html + label: + en_US: html + zh_Hans: html + - value: lake + label: + en_US: lake + zh_Hans: lake + label: + en_US: Content Format + zh_Hans: 内容格式 + human_description: + en_US: Format of the document content (markdown, HTML, Lake). + zh_Hans: 文档内容格式(markdown, HTML, Lake)。 + llm_description: Content format choices, markdown, HTML, Lake. + + - name: body + type: string + required: true + form: llm + label: + en_US: Body Content + zh_Hans: 正文内容 + human_description: + en_US: The actual content of the document. + zh_Hans: 文档的实际内容。 + llm_description: Content of the document. diff --git a/api/core/tools/provider/builtin/aliyuque/tools/delete_document.py b/api/core/tools/provider/builtin/aliyuque/tools/delete_document.py new file mode 100644 index 0000000000..74c731a944 --- /dev/null +++ b/api/core/tools/provider/builtin/aliyuque/tools/delete_document.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python3 +""" +删除文档 +""" + +__author__ = "佐井" +__created__ = "2024-09-17 22:04" + +from typing import Any, Union + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.provider.builtin.aliyuque.tools.base import AliYuqueTool +from core.tools.tool.builtin_tool import BuiltinTool + + +class AliYuqueDeleteDocumentTool(AliYuqueTool, BuiltinTool): + def _invoke( + self, user_id: str, tool_parameters: dict[str, Any] + ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: + token = self.runtime.credentials.get("token", None) + if not token: + raise Exception("token is required") + return self.create_text_message( + self.request("DELETE", token, tool_parameters, "/api/v2/repos/{book_id}/docs/{id}") + ) diff --git a/api/core/tools/provider/builtin/aliyuque/tools/delete_document.yaml b/api/core/tools/provider/builtin/aliyuque/tools/delete_document.yaml new file mode 100644 index 0000000000..87372c5350 --- /dev/null +++ b/api/core/tools/provider/builtin/aliyuque/tools/delete_document.yaml @@ -0,0 +1,37 @@ +identity: + name: aliyuque_delete_document + author: 佐井 + label: + en_US: Delete Document + zh_Hans: 删除文档 + icon: icon.svg +description: + human: + en_US: Delete Document + zh_Hans: 根据id删除文档 + llm: Delete document. + +parameters: + - name: book_id + type: number + required: true + form: llm + label: + en_US: Knowledge Base ID + zh_Hans: 知识库ID + human_description: + en_US: The unique identifier of the knowledge base where the document will be created. + zh_Hans: 文档将被创建的知识库的唯一标识。 + llm_description: ID of the target knowledge base. + + - name: id + type: string + required: true + form: llm + label: + en_US: Document ID or Path + zh_Hans: 文档 ID or 路径 + human_description: + en_US: Document ID or path. + zh_Hans: 文档 ID or 路径。 + llm_description: Document ID or path. diff --git a/api/core/tools/provider/builtin/aliyuque/tools/describe_book_index_page.py b/api/core/tools/provider/builtin/aliyuque/tools/describe_book_index_page.py new file mode 100644 index 0000000000..02bf603a24 --- /dev/null +++ b/api/core/tools/provider/builtin/aliyuque/tools/describe_book_index_page.py @@ -0,0 +1,24 @@ +""" +获取知识库首页 +""" + +__author__ = "佐井" +__created__ = "2024-06-01 22:57:14" + +from typing import Any, Union + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.provider.builtin.aliyuque.tools.base import AliYuqueTool +from core.tools.tool.builtin_tool import BuiltinTool + + +class AliYuqueDescribeBookIndexPageTool(AliYuqueTool, BuiltinTool): + def _invoke( + self, user_id: str, tool_parameters: dict[str, Any] + ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: + token = self.runtime.credentials.get("token", None) + if not token: + raise Exception("token is required") + return self.create_text_message( + self.request("GET", token, tool_parameters, "/api/v2/repos/{group_login}/{book_slug}/index_page") + ) diff --git a/api/core/tools/provider/builtin/aliyuque/tools/describe_book_index_page.yaml b/api/core/tools/provider/builtin/aliyuque/tools/describe_book_index_page.yaml new file mode 100644 index 0000000000..5e490725d1 --- /dev/null +++ b/api/core/tools/provider/builtin/aliyuque/tools/describe_book_index_page.yaml @@ -0,0 +1,38 @@ +identity: + name: aliyuque_describe_book_index_page + author: 佐井 + label: + en_US: Get Repo Index Page + zh_Hans: 获取知识库首页 + icon: icon.svg + +description: + human: + en_US: Retrieves the homepage of a knowledge base within a group, supporting both book ID and group login with book slug access. + zh_Hans: 获取团队中知识库的首页信息,可通过书籍ID或团队登录名与书籍路径访问。 + llm: Fetches the knowledge base homepage using group and book identifiers with support for alternate access paths. + +parameters: + - name: group_login + type: string + required: true + form: llm + label: + en_US: Group Login + zh_Hans: 团队登录名 + human_description: + en_US: The login name of the group that owns the knowledge base. + zh_Hans: 拥有该知识库的团队登录名。 + llm_description: Team login identifier for the knowledge base owner. + + - name: book_slug + type: string + required: true + form: llm + label: + en_US: Book Slug + zh_Hans: 知识库路径 + human_description: + en_US: The unique slug representing the path of the knowledge base. + zh_Hans: 知识库的唯一路径标识。 + llm_description: Unique path identifier for the knowledge base. diff --git a/api/core/tools/provider/builtin/aliyuque/tools/describe_book_table_of_contents.py b/api/core/tools/provider/builtin/aliyuque/tools/describe_book_table_of_contents.py new file mode 100644 index 0000000000..fcfe449c6d --- /dev/null +++ b/api/core/tools/provider/builtin/aliyuque/tools/describe_book_table_of_contents.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python3 +""" +获取知识库目录 +""" + +__author__ = "佐井" +__created__ = "2024-09-17 15:17:11" + +from typing import Any, Union + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.provider.builtin.aliyuque.tools.base import AliYuqueTool +from core.tools.tool.builtin_tool import BuiltinTool + + +class YuqueDescribeBookTableOfContentsTool(AliYuqueTool, BuiltinTool): + def _invoke( + self, user_id: str, tool_parameters: dict[str, Any] + ) -> (Union)[ToolInvokeMessage, list[ToolInvokeMessage]]: + token = self.runtime.credentials.get("token", None) + if not token: + raise Exception("token is required") + return self.create_text_message(self.request("GET", token, tool_parameters, "/api/v2/repos/{book_id}/toc")) diff --git a/api/core/tools/provider/builtin/aliyuque/tools/describe_book_table_of_contents.yaml b/api/core/tools/provider/builtin/aliyuque/tools/describe_book_table_of_contents.yaml new file mode 100644 index 0000000000..0c2bd22132 --- /dev/null +++ b/api/core/tools/provider/builtin/aliyuque/tools/describe_book_table_of_contents.yaml @@ -0,0 +1,25 @@ +identity: + name: aliyuque_describe_book_table_of_contents + author: 佐井 + label: + en_US: Get Book's Table of Contents + zh_Hans: 获取知识库的目录 + icon: icon.svg +description: + human: + en_US: Get Book's Table of Contents. + zh_Hans: 获取知识库的目录。 + llm: Get Book's Table of Contents. + +parameters: + - name: book_id + type: number + required: true + form: llm + label: + en_US: Book ID + zh_Hans: 知识库 ID + human_description: + en_US: Book ID. + zh_Hans: 知识库 ID。 + llm_description: Book ID. diff --git a/api/core/tools/provider/builtin/aliyuque/tools/describe_document_content.py b/api/core/tools/provider/builtin/aliyuque/tools/describe_document_content.py new file mode 100644 index 0000000000..1e70593879 --- /dev/null +++ b/api/core/tools/provider/builtin/aliyuque/tools/describe_document_content.py @@ -0,0 +1,61 @@ +""" +获取文档 +""" + +__author__ = "佐井" +__created__ = "2024-06-02 07:11:45" + +import json +from typing import Any, Union +from urllib.parse import urlparse + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.provider.builtin.aliyuque.tools.base import AliYuqueTool +from core.tools.tool.builtin_tool import BuiltinTool + + +class AliYuqueDescribeDocumentContentTool(AliYuqueTool, BuiltinTool): + def _invoke( + self, user_id: str, tool_parameters: dict[str, Any] + ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: + new_params = {**tool_parameters} + token = new_params.pop("token") + if not token or token.lower() == "none": + token = self.runtime.credentials.get("token", None) + if not token: + raise Exception("token is required") + new_params = {**tool_parameters} + url = new_params.pop("url") + if not url or not url.startswith("http"): + raise Exception("url is not valid") + + parsed_url = urlparse(url) + path_parts = parsed_url.path.strip("/").split("/") + if len(path_parts) < 3: + raise Exception("url is not correct") + doc_id = path_parts[-1] + book_slug = path_parts[-2] + group_id = path_parts[-3] + + # 1. 请求首页信息,获取book_id + new_params["group_login"] = group_id + new_params["book_slug"] = book_slug + index_page = json.loads( + self.request("GET", token, new_params, "/api/v2/repos/{group_login}/{book_slug}/index_page") + ) + book_id = index_page.get("data", {}).get("book", {}).get("id") + if not book_id: + raise Exception(f"can not parse book_id from {index_page}") + # 2. 获取文档内容 + new_params["book_id"] = book_id + new_params["id"] = doc_id + data = self.request("GET", token, new_params, "/api/v2/repos/{book_id}/docs/{id}") + data = json.loads(data) + body_only = tool_parameters.get("body_only") or "" + if body_only.lower() == "true": + return self.create_text_message(data.get("data").get("body")) + else: + raw = data.get("data") + del raw["body_lake"] + del raw["body_html"] + return self.create_text_message(json.dumps(data)) diff --git a/api/core/tools/provider/builtin/aliyuque/tools/describe_document_content.yaml b/api/core/tools/provider/builtin/aliyuque/tools/describe_document_content.yaml new file mode 100644 index 0000000000..6116886a96 --- /dev/null +++ b/api/core/tools/provider/builtin/aliyuque/tools/describe_document_content.yaml @@ -0,0 +1,50 @@ +identity: + name: aliyuque_describe_document_content + author: 佐井 + label: + en_US: Fetch Document Content + zh_Hans: 获取文档内容 + icon: icon.svg + +description: + human: + en_US: Retrieves document content from Yuque based on the provided document URL, which can be a normal or shared link. + zh_Hans: 根据提供的语雀文档地址(支持正常链接或分享链接)获取文档内容。 + llm: Fetches Yuque document content given a URL. + +parameters: + - name: url + type: string + required: true + form: llm + label: + en_US: Document URL + zh_Hans: 文档地址 + human_description: + en_US: The URL of the document to retrieve content from, can be normal or shared. + zh_Hans: 需要获取内容的文档地址,可以是正常链接或分享链接。 + llm_description: URL of the Yuque document to fetch content. + + - name: body_only + type: string + required: false + form: llm + label: + en_US: return body content only + zh_Hans: 仅返回body内容 + human_description: + en_US: true:Body content only, false:Full response with metadata. + zh_Hans: true:仅返回body内容,不返回其他元数据,false:返回所有元数据。 + llm_description: true:Body content only, false:Full response with metadata. + + - name: token + type: secret-input + required: false + form: llm + label: + en_US: Yuque API Token + zh_Hans: 语雀接口Token + human_description: + en_US: The token for calling the Yuque API defaults to the Yuque token bound to the current tool if not provided. + zh_Hans: 调用语雀接口的token,如果不传则默认为当前工具绑定的语雀Token。 + llm_description: If the token for calling the Yuque API is not provided, it will default to the Yuque token bound to the current tool. diff --git a/api/core/tools/provider/builtin/aliyuque/tools/describe_documents.py b/api/core/tools/provider/builtin/aliyuque/tools/describe_documents.py new file mode 100644 index 0000000000..ed1b2a8643 --- /dev/null +++ b/api/core/tools/provider/builtin/aliyuque/tools/describe_documents.py @@ -0,0 +1,24 @@ +""" +获取文档 +""" + +__author__ = "佐井" +__created__ = "2024-06-01 10:45:20" + +from typing import Any, Union + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.provider.builtin.aliyuque.tools.base import AliYuqueTool +from core.tools.tool.builtin_tool import BuiltinTool + + +class AliYuqueDescribeDocumentsTool(AliYuqueTool, BuiltinTool): + def _invoke( + self, user_id: str, tool_parameters: dict[str, Any] + ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: + token = self.runtime.credentials.get("token", None) + if not token: + raise Exception("token is required") + return self.create_text_message( + self.request("GET", token, tool_parameters, "/api/v2/repos/{book_id}/docs/{id}") + ) diff --git a/api/core/tools/provider/builtin/aliyuque/tools/describe_documents.yaml b/api/core/tools/provider/builtin/aliyuque/tools/describe_documents.yaml new file mode 100644 index 0000000000..5156345d71 --- /dev/null +++ b/api/core/tools/provider/builtin/aliyuque/tools/describe_documents.yaml @@ -0,0 +1,38 @@ +identity: + name: aliyuque_describe_documents + author: 佐井 + label: + en_US: Get Doc Detail + zh_Hans: 获取文档详情 + icon: icon.svg + +description: + human: + en_US: Retrieves detailed information of a specific document identified by its ID or path within a knowledge base. + zh_Hans: 根据知识库ID和文档ID或路径获取文档详细信息。 + llm: Fetches detailed doc info using ID/path from a knowledge base; supports doc lookup in Yuque. + +parameters: + - name: book_id + type: number + required: true + form: llm + label: + en_US: Knowledge Base ID + zh_Hans: 知识库 ID + human_description: + en_US: Identifier for the knowledge base where the document resides. + zh_Hans: 文档所属知识库的唯一标识。 + llm_description: ID of the knowledge base holding the document. + + - name: id + type: string + required: true + form: llm + label: + en_US: Document ID or Path + zh_Hans: 文档 ID 或路径 + human_description: + en_US: The unique identifier or path of the document to retrieve. + zh_Hans: 需要获取的文档的ID或其在知识库中的路径。 + llm_description: Unique doc ID or its path for retrieval. diff --git a/api/core/tools/provider/builtin/aliyuque/tools/update_book_table_of_contents.py b/api/core/tools/provider/builtin/aliyuque/tools/update_book_table_of_contents.py new file mode 100644 index 0000000000..932559445e --- /dev/null +++ b/api/core/tools/provider/builtin/aliyuque/tools/update_book_table_of_contents.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python3 +""" +获取知识库目录 +""" + +__author__ = "佐井" +__created__ = "2024-09-17 15:17:11" + +from typing import Any, Union + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.provider.builtin.aliyuque.tools.base import AliYuqueTool +from core.tools.tool.builtin_tool import BuiltinTool + + +class YuqueDescribeBookTableOfContentsTool(AliYuqueTool, BuiltinTool): + def _invoke( + self, user_id: str, tool_parameters: dict[str, Any] + ) -> (Union)[ToolInvokeMessage, list[ToolInvokeMessage]]: + token = self.runtime.credentials.get("token", None) + if not token: + raise Exception("token is required") + + doc_ids = tool_parameters.get("doc_ids") + if doc_ids: + doc_ids = [int(doc_id.strip()) for doc_id in doc_ids.split(",")] + tool_parameters["doc_ids"] = doc_ids + + return self.create_text_message(self.request("PUT", token, tool_parameters, "/api/v2/repos/{book_id}/toc")) diff --git a/api/core/tools/provider/builtin/aliyuque/tools/update_book_table_of_contents.yaml b/api/core/tools/provider/builtin/aliyuque/tools/update_book_table_of_contents.yaml new file mode 100644 index 0000000000..f0c0024f17 --- /dev/null +++ b/api/core/tools/provider/builtin/aliyuque/tools/update_book_table_of_contents.yaml @@ -0,0 +1,222 @@ +identity: + name: aliyuque_update_book_table_of_contents + author: 佐井 + label: + en_US: Update Book's Table of Contents + zh_Hans: 更新知识库目录 + icon: icon.svg +description: + human: + en_US: Update Book's Table of Contents. + zh_Hans: 更新知识库目录。 + llm: Update Book's Table of Contents. + +parameters: + - name: book_id + type: number + required: true + form: llm + label: + en_US: Book ID + zh_Hans: 知识库 ID + human_description: + en_US: Book ID. + zh_Hans: 知识库 ID。 + llm_description: Book ID. + + - name: action + type: select + required: true + form: llm + options: + - value: appendNode + label: + en_US: appendNode + zh_Hans: appendNode + pt_BR: appendNode + - value: prependNode + label: + en_US: prependNode + zh_Hans: prependNode + pt_BR: prependNode + - value: editNode + label: + en_US: editNode + zh_Hans: editNode + pt_BR: editNode + - value: editNode + label: + en_US: removeNode + zh_Hans: removeNode + pt_BR: removeNode + label: + en_US: Action Type + zh_Hans: 操作 + human_description: + en_US: In the operation scenario, sibling node prepending is not supported, deleting a node doesn't remove associated documents, and node deletion has two modes, 'sibling' (delete current node) and 'child' (delete current node and its children). + zh_Hans: 操作,创建场景下不支持同级头插 prependNode,删除节点不会删除关联文档,删除节点时action_mode=sibling (删除当前节点), action_mode=child (删除当前节点及子节点) + llm_description: In the operation scenario, sibling node prepending is not supported, deleting a node doesn't remove associated documents, and node deletion has two modes, 'sibling' (delete current node) and 'child' (delete current node and its children). + + + - name: action_mode + type: select + required: false + form: llm + options: + - value: sibling + label: + en_US: sibling + zh_Hans: 同级 + pt_BR: sibling + - value: child + label: + en_US: child + zh_Hans: 子集 + pt_BR: child + label: + en_US: Action Type + zh_Hans: 操作 + human_description: + en_US: Operation mode (sibling:same level, child:child level). + zh_Hans: 操作模式 (sibling:同级, child:子级)。 + llm_description: Operation mode (sibling:same level, child:child level). + + - name: target_uuid + type: string + required: false + form: llm + label: + en_US: Target node UUID + zh_Hans: 目标节点 UUID + human_description: + en_US: Target node UUID, defaults to root node if left empty. + zh_Hans: 目标节点 UUID, 不填默认为根节点。 + llm_description: Target node UUID, defaults to root node if left empty. + + - name: node_uuid + type: string + required: false + form: llm + label: + en_US: Node UUID + zh_Hans: 操作节点 UUID + human_description: + en_US: Operation node UUID [required for move/update/delete]. + zh_Hans: 操作节点 UUID [移动/更新/删除必填]。 + llm_description: Operation node UUID [required for move/update/delete]. + + - name: doc_ids + type: string + required: false + form: llm + label: + en_US: Document IDs + zh_Hans: 文档id列表 + human_description: + en_US: Document IDs [required for creating documents], separate multiple IDs with ','. + zh_Hans: 文档 IDs [创建文档必填],多个用','分隔。 + llm_description: Document IDs [required for creating documents], separate multiple IDs with ','. + + + - name: type + type: select + required: false + form: llm + default: DOC + options: + - value: DOC + label: + en_US: DOC + zh_Hans: 文档 + pt_BR: DOC + - value: LINK + label: + en_US: LINK + zh_Hans: 链接 + pt_BR: LINK + - value: TITLE + label: + en_US: TITLE + zh_Hans: 分组 + pt_BR: TITLE + label: + en_US: Node type + zh_Hans: 操节点类型 + human_description: + en_US: Node type [required for creation] (DOC:document, LINK:external link, TITLE:group). + zh_Hans: 操节点类型 [创建必填] (DOC:文档, LINK:外链, TITLE:分组)。 + llm_description: Node type [required for creation] (DOC:document, LINK:external link, TITLE:group). + + - name: title + type: string + required: false + form: llm + label: + en_US: Node Name + zh_Hans: 节点名称 + human_description: + en_US: Node name [required for creating groups/external links]. + zh_Hans: 节点名称 [创建分组/外链必填]。 + llm_description: Node name [required for creating groups/external links]. + + - name: url + type: string + required: false + form: llm + label: + en_US: Node URL + zh_Hans: 节点URL + human_description: + en_US: Node URL [required for creating external links]. + zh_Hans: 节点 URL [创建外链必填]。 + llm_description: Node URL [required for creating external links]. + + + - name: open_window + type: select + required: false + form: llm + default: 0 + options: + - value: 0 + label: + en_US: DOC + zh_Hans: Current Page + pt_BR: DOC + - value: 1 + label: + en_US: LINK + zh_Hans: New Page + pt_BR: LINK + label: + en_US: Open in new window + zh_Hans: 是否新窗口打开 + human_description: + en_US: Open in new window [optional for external links] (0:open in current page, 1:open in new window). + zh_Hans: 是否新窗口打开 [外链选填] (0:当前页打开, 1:新窗口打开)。 + llm_description: Open in new window [optional for external links] (0:open in current page, 1:open in new window). + + + - name: visible + type: select + required: false + form: llm + default: 1 + options: + - value: 0 + label: + en_US: Invisible + zh_Hans: 隐藏 + pt_BR: Invisible + - value: 1 + label: + en_US: Visible + zh_Hans: 可见 + pt_BR: Visible + label: + en_US: Visibility + zh_Hans: 是否可见 + human_description: + en_US: Visibility (0:invisible, 1:visible). + zh_Hans: 是否可见 (0:不可见, 1:可见)。 + llm_description: Visibility (0:invisible, 1:visible). diff --git a/api/core/tools/provider/builtin/aliyuque/tools/update_document.py b/api/core/tools/provider/builtin/aliyuque/tools/update_document.py new file mode 100644 index 0000000000..0c6e0205e1 --- /dev/null +++ b/api/core/tools/provider/builtin/aliyuque/tools/update_document.py @@ -0,0 +1,24 @@ +""" +更新文档 +""" + +__author__ = "佐井" +__created__ = "2024-06-19 16:50:07" + +from typing import Any, Union + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.provider.builtin.aliyuque.tools.base import AliYuqueTool +from core.tools.tool.builtin_tool import BuiltinTool + + +class AliYuqueUpdateDocumentTool(AliYuqueTool, BuiltinTool): + def _invoke( + self, user_id: str, tool_parameters: dict[str, Any] + ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: + token = self.runtime.credentials.get("token", None) + if not token: + raise Exception("token is required") + return self.create_text_message( + self.request("PUT", token, tool_parameters, "/api/v2/repos/{book_id}/docs/{id}") + ) diff --git a/api/core/tools/provider/builtin/aliyuque/tools/update_document.yaml b/api/core/tools/provider/builtin/aliyuque/tools/update_document.yaml new file mode 100644 index 0000000000..87f88c9b1b --- /dev/null +++ b/api/core/tools/provider/builtin/aliyuque/tools/update_document.yaml @@ -0,0 +1,87 @@ +identity: + name: aliyuque_update_document + author: 佐井 + label: + en_US: Update Document + zh_Hans: 更新文档 + icon: icon.svg +description: + human: + en_US: Update an existing document within a specified knowledge base by providing the document ID or path. + zh_Hans: 通过提供文档ID或路径,更新指定知识库中的现有文档。 + llm: Update doc in a knowledge base via ID/path. +parameters: + - name: book_id + type: number + required: true + form: llm + label: + en_US: Knowledge Base ID + zh_Hans: 知识库 ID + human_description: + en_US: The unique identifier of the knowledge base where the document resides. + zh_Hans: 文档所属知识库的ID。 + llm_description: ID of the knowledge base holding the doc. + - name: id + type: string + required: true + form: llm + label: + en_US: Document ID or Path + zh_Hans: 文档 ID 或 路径 + human_description: + en_US: The unique identifier or the path of the document to be updated. + zh_Hans: 要更新的文档的唯一ID或路径。 + llm_description: Doc's ID or path for update. + + - name: title + type: string + required: false + form: llm + label: + en_US: Title + zh_Hans: 标题 + human_description: + en_US: The title of the document, defaults to 'Untitled' if not provided. + zh_Hans: 文档标题,默认为'无标题'如未提供。 + llm_description: Title of the document, defaults to 'Untitled'. + + - name: format + type: select + required: false + form: llm + options: + - value: markdown + label: + en_US: markdown + zh_Hans: markdown + pt_BR: markdown + - value: html + label: + en_US: html + zh_Hans: html + pt_BR: html + - value: lake + label: + en_US: lake + zh_Hans: lake + pt_BR: lake + label: + en_US: Content Format + zh_Hans: 内容格式 + human_description: + en_US: Format of the document content (markdown, HTML, Lake). + zh_Hans: 文档内容格式(markdown, HTML, Lake)。 + llm_description: Content format choices, markdown, HTML, Lake. + + - name: body + type: string + required: true + form: llm + label: + en_US: Body Content + zh_Hans: 正文内容 + human_description: + en_US: The actual content of the document. + zh_Hans: 文档的实际内容。 + llm_description: Content of the document. diff --git a/api/core/tools/provider/builtin/feishu_base/_assets/icon.png b/api/core/tools/provider/builtin/feishu_base/_assets/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..787427e7218058678986333768b33a0aafd1eb58 GIT binary patch literal 7253 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 literal 0 HcmV?d00001 diff --git a/api/core/tools/provider/builtin/feishu_base/_assets/icon.svg b/api/core/tools/provider/builtin/feishu_base/_assets/icon.svg deleted file mode 100644 index 2663a0f59e..0000000000 --- a/api/core/tools/provider/builtin/feishu_base/_assets/icon.svg +++ /dev/null @@ -1,47 +0,0 @@ - - - - diff --git a/api/core/tools/provider/builtin/feishu_base/tools/add_base_record.py b/api/core/tools/provider/builtin/feishu_base/tools/add_base_record.py deleted file mode 100644 index 4a605fbffe..0000000000 --- a/api/core/tools/provider/builtin/feishu_base/tools/add_base_record.py +++ /dev/null @@ -1,56 +0,0 @@ -import json -from typing import Any, Union - -import httpx - -from core.tools.entities.tool_entities import ToolInvokeMessage -from core.tools.tool.builtin_tool import BuiltinTool - - -class AddBaseRecordTool(BuiltinTool): - def _invoke( - self, user_id: str, tool_parameters: dict[str, Any] - ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: - url = "https://open.feishu.cn/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/records" - - access_token = tool_parameters.get("Authorization", "") - if not access_token: - return self.create_text_message("Invalid parameter access_token") - - app_token = tool_parameters.get("app_token", "") - if not app_token: - return self.create_text_message("Invalid parameter app_token") - - table_id = tool_parameters.get("table_id", "") - if not table_id: - return self.create_text_message("Invalid parameter table_id") - - fields = tool_parameters.get("fields", "") - if not fields: - return self.create_text_message("Invalid parameter fields") - - headers = { - "Content-Type": "application/json", - "Authorization": f"Bearer {access_token}", - } - - params = {} - payload = {"fields": json.loads(fields)} - - try: - res = httpx.post( - url.format(app_token=app_token, table_id=table_id), - headers=headers, - params=params, - json=payload, - timeout=30, - ) - res_json = res.json() - if res.is_success: - return self.create_text_message(text=json.dumps(res_json)) - else: - return self.create_text_message( - f"Failed to add base record, status code: {res.status_code}, response: {res.text}" - ) - except Exception as e: - return self.create_text_message("Failed to add base record. {}".format(e)) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/add_base_record.yaml b/api/core/tools/provider/builtin/feishu_base/tools/add_base_record.yaml deleted file mode 100644 index 3ce0154efd..0000000000 --- a/api/core/tools/provider/builtin/feishu_base/tools/add_base_record.yaml +++ /dev/null @@ -1,66 +0,0 @@ -identity: - name: add_base_record - author: Doug Lea - label: - en_US: Add Base Record - zh_Hans: 在多维表格数据表中新增一条记录 -description: - human: - en_US: Add Base Record - zh_Hans: | - 在多维表格数据表中新增一条记录,详细请参考:https://open.larkoffice.com/document/server-docs/docs/bitable-v1/app-table-record/create - llm: Add a new record in the multidimensional table data table. -parameters: - - name: Authorization - type: string - required: true - label: - en_US: token - zh_Hans: 凭证 - human_description: - en_US: API access token parameter, tenant_access_token or user_access_token - zh_Hans: API 的访问凭证参数,tenant_access_token 或 user_access_token - llm_description: API access token parameter, tenant_access_token or user_access_token - form: llm - - - name: app_token - type: string - required: true - label: - en_US: app_token - zh_Hans: 多维表格 - human_description: - en_US: bitable app token - zh_Hans: 多维表格的唯一标识符 app_token - llm_description: bitable app token - form: llm - - - name: table_id - type: string - required: true - label: - en_US: table_id - zh_Hans: 多维表格的数据表 - human_description: - en_US: bitable table id - zh_Hans: 多维表格数据表的唯一标识符 table_id - llm_description: bitable table id - form: llm - - - name: fields - type: string - required: true - label: - en_US: fields - zh_Hans: 数据表的列字段内容 - human_description: - en_US: The fields of the Base data table are the columns of the data table. - zh_Hans: | - 要增加一行多维表格记录,字段结构拼接如下:{"多行文本":"多行文本内容","单选":"选项1","多选":["选项1","选项2"],"复选框":true,"人员":[{"id":"ou_2910013f1e6456f16a0ce75ede950a0a"}],"群组":[{"id":"oc_cd07f55f14d6f4a4f1b51504e7e97f48"}],"电话号码":"13026162666"} - 当前接口支持的字段类型为:多行文本、单选、条码、多选、日期、人员、附件、复选框、超链接、数字、单向关联、双向关联、电话号码、地理位置。 - 不同类型字段的数据结构请参考数据结构概述:https://open.larkoffice.com/document/server-docs/docs/bitable-v1/bitable-structure - llm_description: | - 要增加一行多维表格记录,字段结构拼接如下:{"多行文本":"多行文本内容","单选":"选项1","多选":["选项1","选项2"],"复选框":true,"人员":[{"id":"ou_2910013f1e6456f16a0ce75ede950a0a"}],"群组":[{"id":"oc_cd07f55f14d6f4a4f1b51504e7e97f48"}],"电话号码":"13026162666"} - 当前接口支持的字段类型为:多行文本、单选、条码、多选、日期、人员、附件、复选框、超链接、数字、单向关联、双向关联、电话号码、地理位置。 - 不同类型字段的数据结构请参考数据结构概述:https://open.larkoffice.com/document/server-docs/docs/bitable-v1/bitable-structure - form: llm diff --git a/api/core/tools/provider/builtin/feishu_base/tools/add_records.py b/api/core/tools/provider/builtin/feishu_base/tools/add_records.py new file mode 100644 index 0000000000..905f8b7880 --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/add_records.py @@ -0,0 +1,21 @@ +from typing import Any + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.tool.builtin_tool import BuiltinTool +from core.tools.utils.feishu_api_utils import FeishuRequest + + +class AddRecordsTool(BuiltinTool): + def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage: + app_id = self.runtime.credentials.get("app_id") + app_secret = self.runtime.credentials.get("app_secret") + client = FeishuRequest(app_id, app_secret) + + app_token = tool_parameters.get("app_token") + table_id = tool_parameters.get("table_id") + table_name = tool_parameters.get("table_name") + records = tool_parameters.get("records") + user_id_type = tool_parameters.get("user_id_type", "open_id") + + res = client.add_records(app_token, table_id, table_name, records, user_id_type) + return self.create_json_message(res) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/add_records.yaml b/api/core/tools/provider/builtin/feishu_base/tools/add_records.yaml new file mode 100644 index 0000000000..f2a93490dc --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/add_records.yaml @@ -0,0 +1,91 @@ +identity: + name: add_records + author: Doug Lea + label: + en_US: Add Records + zh_Hans: 新增多条记录 +description: + human: + en_US: Add Multiple Records to Multidimensional Table + zh_Hans: 在多维表格数据表中新增多条记录 + llm: A tool for adding multiple records to a multidimensional table. (在多维表格数据表中新增多条记录) +parameters: + - name: app_token + type: string + required: true + label: + en_US: app_token + zh_Hans: app_token + human_description: + en_US: Unique identifier for the multidimensional table, supports inputting document URL. + zh_Hans: 多维表格的唯一标识符,支持输入文档 URL。 + llm_description: 多维表格的唯一标识符,支持输入文档 URL。 + form: llm + + - name: table_id + type: string + required: false + label: + en_US: table_id + zh_Hans: table_id + human_description: + en_US: Unique identifier for the multidimensional table data, either table_id or table_name must be provided, cannot be empty simultaneously. + zh_Hans: 多维表格数据表的唯一标识符,table_id 和 table_name 至少需要提供一个,不能同时为空。 + llm_description: 多维表格数据表的唯一标识符,table_id 和 table_name 至少需要提供一个,不能同时为空。 + form: llm + + - name: table_name + type: string + required: false + label: + en_US: table_name + zh_Hans: table_name + human_description: + en_US: Name of the multidimensional table data, either table_name or table_id must be provided, cannot be empty simultaneously. + zh_Hans: 多维表格数据表的名称,table_name 和 table_id 至少需要提供一个,不能同时为空。 + llm_description: 多维表格数据表的名称,table_name 和 table_id 至少需要提供一个,不能同时为空。 + form: llm + + - name: records + type: string + required: true + label: + en_US: records + zh_Hans: 记录列表 + human_description: + en_US: | + List of records to be added in this request. Example value: [{"multi-line-text":"text content","single_select":"option 1","date":1674206443000}] + For supported field types, refer to the integration guide (https://open.larkoffice.com/document/server-docs/docs/bitable-v1/notification). For data structures of different field types, refer to the data structure overview (https://open.larkoffice.com/document/server-docs/docs/bitable-v1/bitable-structure). + zh_Hans: | + 本次请求将要新增的记录列表,示例值:[{"多行文本":"文本内容","单选":"选项 1","日期":1674206443000}]。 + 当前接口支持的字段类型请参考接入指南(https://open.larkoffice.com/document/server-docs/docs/bitable-v1/notification),不同类型字段的数据结构请参考数据结构概述(https://open.larkoffice.com/document/server-docs/docs/bitable-v1/bitable-structure)。 + llm_description: | + 本次请求将要新增的记录列表,示例值:[{"多行文本":"文本内容","单选":"选项 1","日期":1674206443000}]。 + 当前接口支持的字段类型请参考接入指南(https://open.larkoffice.com/document/server-docs/docs/bitable-v1/notification),不同类型字段的数据结构请参考数据结构概述(https://open.larkoffice.com/document/server-docs/docs/bitable-v1/bitable-structure)。 + form: llm + + - name: user_id_type + type: select + required: false + options: + - value: open_id + label: + en_US: open_id + zh_Hans: open_id + - value: union_id + label: + en_US: union_id + zh_Hans: union_id + - value: user_id + label: + en_US: user_id + zh_Hans: user_id + default: "open_id" + label: + en_US: user_id_type + zh_Hans: 用户 ID 类型 + human_description: + en_US: User ID type, optional values are open_id, union_id, user_id, with a default value of open_id. + zh_Hans: 用户 ID 类型,可选值有 open_id、union_id、user_id,默认值为 open_id。 + llm_description: 用户 ID 类型,可选值有 open_id、union_id、user_id,默认值为 open_id。 + form: form diff --git a/api/core/tools/provider/builtin/feishu_base/tools/create_base_table.py b/api/core/tools/provider/builtin/feishu_base/tools/create_base_table.py deleted file mode 100644 index b05d700113..0000000000 --- a/api/core/tools/provider/builtin/feishu_base/tools/create_base_table.py +++ /dev/null @@ -1,48 +0,0 @@ -import json -from typing import Any, Union - -import httpx - -from core.tools.entities.tool_entities import ToolInvokeMessage -from core.tools.tool.builtin_tool import BuiltinTool - - -class CreateBaseTableTool(BuiltinTool): - def _invoke( - self, user_id: str, tool_parameters: dict[str, Any] - ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: - url = "https://open.feishu.cn/open-apis/bitable/v1/apps/{app_token}/tables" - - access_token = tool_parameters.get("Authorization", "") - if not access_token: - return self.create_text_message("Invalid parameter access_token") - - app_token = tool_parameters.get("app_token", "") - if not app_token: - return self.create_text_message("Invalid parameter app_token") - - name = tool_parameters.get("name", "") - - fields = tool_parameters.get("fields", "") - if not fields: - return self.create_text_message("Invalid parameter fields") - - headers = { - "Content-Type": "application/json", - "Authorization": f"Bearer {access_token}", - } - - params = {} - payload = {"table": {"name": name, "fields": json.loads(fields)}} - - try: - res = httpx.post(url.format(app_token=app_token), headers=headers, params=params, json=payload, timeout=30) - res_json = res.json() - if res.is_success: - return self.create_text_message(text=json.dumps(res_json)) - else: - return self.create_text_message( - f"Failed to create base table, status code: {res.status_code}, response: {res.text}" - ) - except Exception as e: - return self.create_text_message("Failed to create base table. {}".format(e)) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/create_base_table.yaml b/api/core/tools/provider/builtin/feishu_base/tools/create_base_table.yaml deleted file mode 100644 index 48c46bec14..0000000000 --- a/api/core/tools/provider/builtin/feishu_base/tools/create_base_table.yaml +++ /dev/null @@ -1,106 +0,0 @@ -identity: - name: create_base_table - author: Doug Lea - label: - en_US: Create Base Table - zh_Hans: 多维表格新增一个数据表 -description: - human: - en_US: Create base table - zh_Hans: | - 多维表格新增一个数据表,详细请参考:https://open.larkoffice.com/document/server-docs/docs/bitable-v1/app-table/create - llm: A tool for add a new data table to the multidimensional table. -parameters: - - name: Authorization - type: string - required: true - label: - en_US: token - zh_Hans: 凭证 - human_description: - en_US: API access token parameter, tenant_access_token or user_access_token - zh_Hans: API 的访问凭证参数,tenant_access_token 或 user_access_token - llm_description: API access token parameter, tenant_access_token or user_access_token - form: llm - - - name: app_token - type: string - required: true - label: - en_US: app_token - zh_Hans: 多维表格 - human_description: - en_US: bitable app token - zh_Hans: 多维表格的唯一标识符 app_token - llm_description: bitable app token - form: llm - - - name: name - type: string - required: false - label: - en_US: name - zh_Hans: name - human_description: - en_US: Multidimensional table data table name - zh_Hans: 多维表格数据表名称 - llm_description: Multidimensional table data table name - form: llm - - - name: fields - type: string - required: true - label: - en_US: fields - zh_Hans: fields - human_description: - en_US: Initial fields of the data table - zh_Hans: | - 数据表的初始字段,格式为:[{"field_name":"多行文本","type":1},{"field_name":"数字","type":2},{"field_name":"单选","type":3},{"field_name":"多选","type":4},{"field_name":"日期","type":5}]。 - field_name:字段名; - type: 字段类型;可选值有 - 1:多行文本 - 2:数字 - 3:单选 - 4:多选 - 5:日期 - 7:复选框 - 11:人员 - 13:电话号码 - 15:超链接 - 17:附件 - 18:单向关联 - 20:公式 - 21:双向关联 - 22:地理位置 - 23:群组 - 1001:创建时间 - 1002:最后更新时间 - 1003:创建人 - 1004:修改人 - 1005:自动编号 - llm_description: | - 数据表的初始字段,格式为:[{"field_name":"多行文本","type":1},{"field_name":"数字","type":2},{"field_name":"单选","type":3},{"field_name":"多选","type":4},{"field_name":"日期","type":5}]。 - field_name:字段名; - type: 字段类型;可选值有 - 1:多行文本 - 2:数字 - 3:单选 - 4:多选 - 5:日期 - 7:复选框 - 11:人员 - 13:电话号码 - 15:超链接 - 17:附件 - 18:单向关联 - 20:公式 - 21:双向关联 - 22:地理位置 - 23:群组 - 1001:创建时间 - 1002:最后更新时间 - 1003:创建人 - 1004:修改人 - 1005:自动编号 - form: llm diff --git a/api/core/tools/provider/builtin/feishu_base/tools/create_table.py b/api/core/tools/provider/builtin/feishu_base/tools/create_table.py new file mode 100644 index 0000000000..81f2617545 --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/create_table.py @@ -0,0 +1,20 @@ +from typing import Any + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.tool.builtin_tool import BuiltinTool +from core.tools.utils.feishu_api_utils import FeishuRequest + + +class CreateTableTool(BuiltinTool): + def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage: + app_id = self.runtime.credentials.get("app_id") + app_secret = self.runtime.credentials.get("app_secret") + client = FeishuRequest(app_id, app_secret) + + app_token = tool_parameters.get("app_token") + table_name = tool_parameters.get("table_name") + default_view_name = tool_parameters.get("default_view_name") + fields = tool_parameters.get("fields") + + res = client.create_table(app_token, table_name, default_view_name, fields) + return self.create_json_message(res) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/create_table.yaml b/api/core/tools/provider/builtin/feishu_base/tools/create_table.yaml new file mode 100644 index 0000000000..8b1007b9a5 --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/create_table.yaml @@ -0,0 +1,61 @@ +identity: + name: create_table + author: Doug Lea + label: + en_US: Create Table + zh_Hans: 新增数据表 +description: + human: + en_US: Add a Data Table to Multidimensional Table + zh_Hans: 在多维表格中新增一个数据表 + llm: A tool for adding a data table to a multidimensional table. (在多维表格中新增一个数据表) +parameters: + - name: app_token + type: string + required: true + label: + en_US: app_token + zh_Hans: app_token + human_description: + en_US: Unique identifier for the multidimensional table, supports inputting document URL. + zh_Hans: 多维表格的唯一标识符,支持输入文档 URL。 + llm_description: 多维表格的唯一标识符,支持输入文档 URL。 + form: llm + + - name: table_name + type: string + required: true + label: + en_US: Table Name + zh_Hans: 数据表名称 + human_description: + en_US: | + The name of the data table, length range: 1 character to 100 characters. + zh_Hans: 数据表名称,长度范围:1 字符 ~ 100 字符。 + llm_description: 数据表名称,长度范围:1 字符 ~ 100 字符。 + form: llm + + - name: default_view_name + type: string + required: false + label: + en_US: Default View Name + zh_Hans: 默认表格视图的名称 + human_description: + en_US: The name of the default table view, defaults to "Table" if not filled. + zh_Hans: 默认表格视图的名称,不填则默认为"表格"。 + llm_description: 默认表格视图的名称,不填则默认为"表格"。 + form: llm + + - name: fields + type: string + required: true + label: + en_US: Initial Fields + zh_Hans: 初始字段 + human_description: + en_US: | + Initial fields of the data table, format: [ { "field_name": "Multi-line Text","type": 1 },{ "field_name": "Number","type": 2 },{ "field_name": "Single Select","type": 3 },{ "field_name": "Multiple Select","type": 4 },{ "field_name": "Date","type": 5 } ]. For field details, refer to: https://open.larkoffice.com/document/server-docs/docs/bitable-v1/app-table-field/guide + zh_Hans: 数据表的初始字段,格式为:[{"field_name":"多行文本","type":1},{"field_name":"数字","type":2},{"field_name":"单选","type":3},{"field_name":"多选","type":4},{"field_name":"日期","type":5}]。字段详情参考:https://open.larkoffice.com/document/server-docs/docs/bitable-v1/app-table-field/guide + llm_description: 数据表的初始字段,格式为:[{"field_name":"多行文本","type":1},{"field_name":"数字","type":2},{"field_name":"单选","type":3},{"field_name":"多选","type":4},{"field_name":"日期","type":5}]。字段详情参考:https://open.larkoffice.com/document/server-docs/docs/bitable-v1/app-table-field/guide + form: llm diff --git a/api/core/tools/provider/builtin/feishu_base/tools/delete_base_records.py b/api/core/tools/provider/builtin/feishu_base/tools/delete_base_records.py deleted file mode 100644 index 862eb2171b..0000000000 --- a/api/core/tools/provider/builtin/feishu_base/tools/delete_base_records.py +++ /dev/null @@ -1,56 +0,0 @@ -import json -from typing import Any, Union - -import httpx - -from core.tools.entities.tool_entities import ToolInvokeMessage -from core.tools.tool.builtin_tool import BuiltinTool - - -class DeleteBaseRecordsTool(BuiltinTool): - def _invoke( - self, user_id: str, tool_parameters: dict[str, Any] - ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: - url = "https://open.feishu.cn/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/records/batch_delete" - - access_token = tool_parameters.get("Authorization", "") - if not access_token: - return self.create_text_message("Invalid parameter access_token") - - app_token = tool_parameters.get("app_token", "") - if not app_token: - return self.create_text_message("Invalid parameter app_token") - - table_id = tool_parameters.get("table_id", "") - if not table_id: - return self.create_text_message("Invalid parameter table_id") - - record_ids = tool_parameters.get("record_ids", "") - if not record_ids: - return self.create_text_message("Invalid parameter record_ids") - - headers = { - "Content-Type": "application/json", - "Authorization": f"Bearer {access_token}", - } - - params = {} - payload = {"records": json.loads(record_ids)} - - try: - res = httpx.post( - url.format(app_token=app_token, table_id=table_id), - headers=headers, - params=params, - json=payload, - timeout=30, - ) - res_json = res.json() - if res.is_success: - return self.create_text_message(text=json.dumps(res_json)) - else: - return self.create_text_message( - f"Failed to delete base records, status code: {res.status_code}, response: {res.text}" - ) - except Exception as e: - return self.create_text_message("Failed to delete base records. {}".format(e)) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/delete_base_records.yaml b/api/core/tools/provider/builtin/feishu_base/tools/delete_base_records.yaml deleted file mode 100644 index 595b287029..0000000000 --- a/api/core/tools/provider/builtin/feishu_base/tools/delete_base_records.yaml +++ /dev/null @@ -1,60 +0,0 @@ -identity: - name: delete_base_records - author: Doug Lea - label: - en_US: Delete Base Records - zh_Hans: 在多维表格数据表中删除多条记录 -description: - human: - en_US: Delete base records - zh_Hans: | - 该接口用于删除多维表格数据表中的多条记录,单次调用中最多删除 500 条记录。 - llm: A tool for delete multiple records in a multidimensional table data table, up to 500 records can be deleted in a single call. -parameters: - - name: Authorization - type: string - required: true - label: - en_US: token - zh_Hans: 凭证 - human_description: - en_US: API access token parameter, tenant_access_token or user_access_token - zh_Hans: API 的访问凭证参数,tenant_access_token 或 user_access_token - llm_description: API access token parameter, tenant_access_token or user_access_token - form: llm - - - name: app_token - type: string - required: true - label: - en_US: app_token - zh_Hans: 多维表格 - human_description: - en_US: bitable app token - zh_Hans: 多维表格的唯一标识符 app_token - llm_description: bitable app token - form: llm - - - name: table_id - type: string - required: true - label: - en_US: table_id - zh_Hans: 多维表格的数据表 - human_description: - en_US: bitable table id - zh_Hans: 多维表格数据表的唯一标识符 table_id - llm_description: bitable table id - form: llm - - - name: record_ids - type: string - required: true - label: - en_US: record_ids - zh_Hans: record_ids - human_description: - en_US: A list of multiple record IDs to be deleted, for example ["recwNXzPQv","recpCsf4ME"] - zh_Hans: 待删除的多条记录id列表,示例为 ["recwNXzPQv","recpCsf4ME"] - llm_description: A list of multiple record IDs to be deleted, for example ["recwNXzPQv","recpCsf4ME"] - form: llm diff --git a/api/core/tools/provider/builtin/feishu_base/tools/delete_base_tables.py b/api/core/tools/provider/builtin/feishu_base/tools/delete_base_tables.py deleted file mode 100644 index f512186303..0000000000 --- a/api/core/tools/provider/builtin/feishu_base/tools/delete_base_tables.py +++ /dev/null @@ -1,46 +0,0 @@ -import json -from typing import Any, Union - -import httpx - -from core.tools.entities.tool_entities import ToolInvokeMessage -from core.tools.tool.builtin_tool import BuiltinTool - - -class DeleteBaseTablesTool(BuiltinTool): - def _invoke( - self, user_id: str, tool_parameters: dict[str, Any] - ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: - url = "https://open.feishu.cn/open-apis/bitable/v1/apps/{app_token}/tables/batch_delete" - - access_token = tool_parameters.get("Authorization", "") - if not access_token: - return self.create_text_message("Invalid parameter access_token") - - app_token = tool_parameters.get("app_token", "") - if not app_token: - return self.create_text_message("Invalid parameter app_token") - - table_ids = tool_parameters.get("table_ids", "") - if not table_ids: - return self.create_text_message("Invalid parameter table_ids") - - headers = { - "Content-Type": "application/json", - "Authorization": f"Bearer {access_token}", - } - - params = {} - payload = {"table_ids": json.loads(table_ids)} - - try: - res = httpx.post(url.format(app_token=app_token), headers=headers, params=params, json=payload, timeout=30) - res_json = res.json() - if res.is_success: - return self.create_text_message(text=json.dumps(res_json)) - else: - return self.create_text_message( - f"Failed to delete base tables, status code: {res.status_code}, response: {res.text}" - ) - except Exception as e: - return self.create_text_message("Failed to delete base tables. {}".format(e)) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/delete_base_tables.yaml b/api/core/tools/provider/builtin/feishu_base/tools/delete_base_tables.yaml deleted file mode 100644 index 5d72814363..0000000000 --- a/api/core/tools/provider/builtin/feishu_base/tools/delete_base_tables.yaml +++ /dev/null @@ -1,48 +0,0 @@ -identity: - name: delete_base_tables - author: Doug Lea - label: - en_US: Delete Base Tables - zh_Hans: 删除多维表格中的数据表 -description: - human: - en_US: Delete base tables - zh_Hans: | - 删除多维表格中的数据表 - llm: A tool for deleting a data table in a multidimensional table -parameters: - - name: Authorization - type: string - required: true - label: - en_US: token - zh_Hans: 凭证 - human_description: - en_US: API access token parameter, tenant_access_token or user_access_token - zh_Hans: API 的访问凭证参数,tenant_access_token 或 user_access_token - llm_description: API access token parameter, tenant_access_token or user_access_token - form: llm - - - name: app_token - type: string - required: true - label: - en_US: app_token - zh_Hans: 多维表格 - human_description: - en_US: bitable app token - zh_Hans: 多维表格的唯一标识符 app_token - llm_description: bitable app token - form: llm - - - name: table_ids - type: string - required: true - label: - en_US: table_ids - zh_Hans: table_ids - human_description: - en_US: The ID list of the data tables to be deleted. Currently, a maximum of 50 data tables can be deleted at a time. The example is ["tbl1TkhyTWDkSoZ3","tblsRc9GRRXKqhvW"] - zh_Hans: 待删除数据表的id列表,当前一次操作最多支持50个数据表,示例为 ["tbl1TkhyTWDkSoZ3","tblsRc9GRRXKqhvW"] - llm_description: The ID list of the data tables to be deleted. Currently, a maximum of 50 data tables can be deleted at a time. The example is ["tbl1TkhyTWDkSoZ3","tblsRc9GRRXKqhvW"] - form: llm diff --git a/api/core/tools/provider/builtin/feishu_base/tools/delete_records.py b/api/core/tools/provider/builtin/feishu_base/tools/delete_records.py new file mode 100644 index 0000000000..c896a2c81b --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/delete_records.py @@ -0,0 +1,20 @@ +from typing import Any + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.tool.builtin_tool import BuiltinTool +from core.tools.utils.feishu_api_utils import FeishuRequest + + +class DeleteRecordsTool(BuiltinTool): + def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage: + app_id = self.runtime.credentials.get("app_id") + app_secret = self.runtime.credentials.get("app_secret") + client = FeishuRequest(app_id, app_secret) + + app_token = tool_parameters.get("app_token") + table_id = tool_parameters.get("table_id") + table_name = tool_parameters.get("table_name") + record_ids = tool_parameters.get("record_ids") + + res = client.delete_records(app_token, table_id, table_name, record_ids) + return self.create_json_message(res) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/delete_records.yaml b/api/core/tools/provider/builtin/feishu_base/tools/delete_records.yaml new file mode 100644 index 0000000000..c30ebd630c --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/delete_records.yaml @@ -0,0 +1,86 @@ +identity: + name: delete_records + author: Doug Lea + label: + en_US: Delete Records + zh_Hans: 删除多条记录 +description: + human: + en_US: Delete Multiple Records from Multidimensional Table + zh_Hans: 删除多维表格数据表中的多条记录 + llm: A tool for deleting multiple records from a multidimensional table. (删除多维表格数据表中的多条记录) +parameters: + - name: app_token + type: string + required: true + label: + en_US: app_token + zh_Hans: app_token + human_description: + en_US: Unique identifier for the multidimensional table, supports inputting document URL. + zh_Hans: 多维表格的唯一标识符,支持输入文档 URL。 + llm_description: 多维表格的唯一标识符,支持输入文档 URL。 + form: llm + + - name: table_id + type: string + required: false + label: + en_US: table_id + zh_Hans: table_id + human_description: + en_US: Unique identifier for the multidimensional table data, either table_id or table_name must be provided, cannot be empty simultaneously. + zh_Hans: 多维表格数据表的唯一标识符,table_id 和 table_name 至少需要提供一个,不能同时为空。 + llm_description: 多维表格数据表的唯一标识符,table_id 和 table_name 至少需要提供一个,不能同时为空。 + form: llm + + - name: table_name + type: string + required: false + label: + en_US: table_name + zh_Hans: table_name + human_description: + en_US: Name of the multidimensional table data, either table_name or table_id must be provided, cannot be empty simultaneously. + zh_Hans: 多维表格数据表的名称,table_name 和 table_id 至少需要提供一个,不能同时为空。 + llm_description: 多维表格数据表的名称,table_name 和 table_id 至少需要提供一个,不能同时为空。 + form: llm + + - name: record_ids + type: string + required: true + label: + en_US: Record IDs + zh_Hans: 记录 ID 列表 + human_description: + en_US: | + List of IDs for the records to be deleted, example value: ["recwNXzPQv"]. + zh_Hans: 删除的多条记录 ID 列表,示例值:["recwNXzPQv"]。 + llm_description: 删除的多条记录 ID 列表,示例值:["recwNXzPQv"]。 + form: llm + + - name: user_id_type + type: select + required: false + options: + - value: open_id + label: + en_US: open_id + zh_Hans: open_id + - value: union_id + label: + en_US: union_id + zh_Hans: union_id + - value: user_id + label: + en_US: user_id + zh_Hans: user_id + default: "open_id" + label: + en_US: user_id_type + zh_Hans: 用户 ID 类型 + human_description: + en_US: User ID type, optional values are open_id, union_id, user_id, with a default value of open_id. + zh_Hans: 用户 ID 类型,可选值有 open_id、union_id、user_id,默认值为 open_id。 + llm_description: 用户 ID 类型,可选值有 open_id、union_id、user_id,默认值为 open_id。 + form: form diff --git a/api/core/tools/provider/builtin/feishu_base/tools/delete_tables.py b/api/core/tools/provider/builtin/feishu_base/tools/delete_tables.py new file mode 100644 index 0000000000..f732a16da6 --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/delete_tables.py @@ -0,0 +1,19 @@ +from typing import Any + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.tool.builtin_tool import BuiltinTool +from core.tools.utils.feishu_api_utils import FeishuRequest + + +class DeleteTablesTool(BuiltinTool): + def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage: + app_id = self.runtime.credentials.get("app_id") + app_secret = self.runtime.credentials.get("app_secret") + client = FeishuRequest(app_id, app_secret) + + app_token = tool_parameters.get("app_token") + table_ids = tool_parameters.get("table_ids") + table_names = tool_parameters.get("table_names") + + res = client.delete_tables(app_token, table_ids, table_names) + return self.create_json_message(res) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/delete_tables.yaml b/api/core/tools/provider/builtin/feishu_base/tools/delete_tables.yaml new file mode 100644 index 0000000000..498126eae5 --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/delete_tables.yaml @@ -0,0 +1,49 @@ +identity: + name: delete_tables + author: Doug Lea + label: + en_US: Delete Tables + zh_Hans: 删除数据表 +description: + human: + en_US: Batch Delete Data Tables from Multidimensional Table + zh_Hans: 批量删除多维表格中的数据表 + llm: A tool for batch deleting data tables from a multidimensional table. (批量删除多维表格中的数据表) +parameters: + - name: app_token + type: string + required: true + label: + en_US: app_token + zh_Hans: app_token + human_description: + en_US: Unique identifier for the multidimensional table, supports inputting document URL. + zh_Hans: 多维表格的唯一标识符,支持输入文档 URL。 + llm_description: 多维表格的唯一标识符,支持输入文档 URL。 + form: llm + + - name: table_ids + type: string + required: false + label: + en_US: Table IDs + zh_Hans: 数据表 ID + human_description: + en_US: | + IDs of the tables to be deleted. Each operation supports deleting up to 50 tables. Example: ["tbl1TkhyTWDkSoZ3"]. Ensure that either table_ids or table_names is not empty. + zh_Hans: 待删除的数据表的 ID,每次操作最多支持删除 50 个数据表。示例值:["tbl1TkhyTWDkSoZ3"]。请确保 table_ids 和 table_names 至少有一个不为空。 + llm_description: 待删除的数据表的 ID,每次操作最多支持删除 50 个数据表。示例值:["tbl1TkhyTWDkSoZ3"]。请确保 table_ids 和 table_names 至少有一个不为空。 + form: llm + + - name: table_names + type: string + required: false + label: + en_US: Table Names + zh_Hans: 数据表名称 + human_description: + en_US: | + Names of the tables to be deleted. Each operation supports deleting up to 50 tables. Example: ["Table1", "Table2"]. Ensure that either table_names or table_ids is not empty. + zh_Hans: 待删除的数据表的名称,每次操作最多支持删除 50 个数据表。示例值:["数据表1", "数据表2"]。请确保 table_names 和 table_ids 至少有一个不为空。 + llm_description: 待删除的数据表的名称,每次操作最多支持删除 50 个数据表。示例值:["数据表1", "数据表2"]。请确保 table_names 和 table_ids 至少有一个不为空。 + form: llm diff --git a/api/core/tools/provider/builtin/feishu_base/tools/get_tenant_access_token.py b/api/core/tools/provider/builtin/feishu_base/tools/get_tenant_access_token.py deleted file mode 100644 index 2ea61d0068..0000000000 --- a/api/core/tools/provider/builtin/feishu_base/tools/get_tenant_access_token.py +++ /dev/null @@ -1,48 +0,0 @@ -import json -from typing import Any, Union - -import httpx - -from core.tools.entities.tool_entities import ToolInvokeMessage -from core.tools.tool.builtin_tool import BuiltinTool - - -class GetTenantAccessTokenTool(BuiltinTool): - def _invoke( - self, user_id: str, tool_parameters: dict[str, Any] - ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: - url = "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal" - - app_id = tool_parameters.get("app_id", "") - if not app_id: - return self.create_text_message("Invalid parameter app_id") - - app_secret = tool_parameters.get("app_secret", "") - if not app_secret: - return self.create_text_message("Invalid parameter app_secret") - - headers = { - "Content-Type": "application/json", - } - params = {} - payload = {"app_id": app_id, "app_secret": app_secret} - - """ - { - "code": 0, - "msg": "ok", - "tenant_access_token": "t-caecc734c2e3328a62489fe0648c4b98779515d3", - "expire": 7200 - } - """ - try: - res = httpx.post(url, headers=headers, params=params, json=payload, timeout=30) - res_json = res.json() - if res.is_success: - return self.create_text_message(text=json.dumps(res_json)) - else: - return self.create_text_message( - f"Failed to get tenant access token, status code: {res.status_code}, response: {res.text}" - ) - except Exception as e: - return self.create_text_message("Failed to get tenant access token. {}".format(e)) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/get_tenant_access_token.yaml b/api/core/tools/provider/builtin/feishu_base/tools/get_tenant_access_token.yaml deleted file mode 100644 index 88acc27e06..0000000000 --- a/api/core/tools/provider/builtin/feishu_base/tools/get_tenant_access_token.yaml +++ /dev/null @@ -1,39 +0,0 @@ -identity: - name: get_tenant_access_token - author: Doug Lea - label: - en_US: Get Tenant Access Token - zh_Hans: 获取飞书自建应用的 tenant_access_token -description: - human: - en_US: Get tenant access token - zh_Hans: | - 获取飞书自建应用的 tenant_access_token,响应体示例: - {"code":0,"msg":"ok","tenant_access_token":"t-caecc734c2e3328a62489fe0648c4b98779515d3","expire":7200} - tenant_access_token: 租户访问凭证; - expire: tenant_access_token 的过期时间,单位为秒; - llm: A tool for obtaining a tenant access token. The input parameters must include app_id and app_secret. -parameters: - - name: app_id - type: string - required: true - label: - en_US: app_id - zh_Hans: 应用唯一标识 - human_description: - en_US: app_id is the unique identifier of the Lark Open Platform application - zh_Hans: app_id 是飞书开放平台应用的唯一标识 - llm_description: app_id is the unique identifier of the Lark Open Platform application - form: llm - - - name: app_secret - type: secret-input - required: true - label: - en_US: app_secret - zh_Hans: 应用秘钥 - human_description: - en_US: app_secret is the secret key of the application - zh_Hans: app_secret 是应用的秘钥 - llm_description: app_secret is the secret key of the application - form: llm diff --git a/api/core/tools/provider/builtin/feishu_base/tools/list_base_records.py b/api/core/tools/provider/builtin/feishu_base/tools/list_base_records.py deleted file mode 100644 index e579d02f69..0000000000 --- a/api/core/tools/provider/builtin/feishu_base/tools/list_base_records.py +++ /dev/null @@ -1,65 +0,0 @@ -import json -from typing import Any, Union - -import httpx - -from core.tools.entities.tool_entities import ToolInvokeMessage -from core.tools.tool.builtin_tool import BuiltinTool - - -class ListBaseRecordsTool(BuiltinTool): - def _invoke( - self, user_id: str, tool_parameters: dict[str, Any] - ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: - url = "https://open.feishu.cn/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/records/search" - - access_token = tool_parameters.get("Authorization", "") - if not access_token: - return self.create_text_message("Invalid parameter access_token") - - app_token = tool_parameters.get("app_token", "") - if not app_token: - return self.create_text_message("Invalid parameter app_token") - - table_id = tool_parameters.get("table_id", "") - if not table_id: - return self.create_text_message("Invalid parameter table_id") - - page_token = tool_parameters.get("page_token", "") - page_size = tool_parameters.get("page_size", "") - sort_condition = tool_parameters.get("sort_condition", "") - filter_condition = tool_parameters.get("filter_condition", "") - - headers = { - "Content-Type": "application/json", - "Authorization": f"Bearer {access_token}", - } - - params = { - "page_token": page_token, - "page_size": page_size, - } - - payload = {"automatic_fields": True} - if sort_condition: - payload["sort"] = json.loads(sort_condition) - if filter_condition: - payload["filter"] = json.loads(filter_condition) - - try: - res = httpx.post( - url.format(app_token=app_token, table_id=table_id), - headers=headers, - params=params, - json=payload, - timeout=30, - ) - res_json = res.json() - if res.is_success: - return self.create_text_message(text=json.dumps(res_json)) - else: - return self.create_text_message( - f"Failed to list base records, status code: {res.status_code}, response: {res.text}" - ) - except Exception as e: - return self.create_text_message("Failed to list base records. {}".format(e)) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/list_base_records.yaml b/api/core/tools/provider/builtin/feishu_base/tools/list_base_records.yaml deleted file mode 100644 index 8647c880a6..0000000000 --- a/api/core/tools/provider/builtin/feishu_base/tools/list_base_records.yaml +++ /dev/null @@ -1,108 +0,0 @@ -identity: - name: list_base_records - author: Doug Lea - label: - en_US: List Base Records - zh_Hans: 查询多维表格数据表中的现有记录 -description: - human: - en_US: List base records - zh_Hans: | - 查询多维表格数据表中的现有记录,单次最多查询 500 行记录,支持分页获取。 - llm: Query existing records in a multidimensional table data table. A maximum of 500 rows of records can be queried at a time, and paging retrieval is supported. -parameters: - - name: Authorization - type: string - required: true - label: - en_US: token - zh_Hans: 凭证 - human_description: - en_US: API access token parameter, tenant_access_token or user_access_token - zh_Hans: API 的访问凭证参数,tenant_access_token 或 user_access_token - llm_description: API access token parameter, tenant_access_token or user_access_token - form: llm - - - name: app_token - type: string - required: true - label: - en_US: app_token - zh_Hans: 多维表格 - human_description: - en_US: bitable app token - zh_Hans: 多维表格的唯一标识符 app_token - llm_description: bitable app token - form: llm - - - name: table_id - type: string - required: true - label: - en_US: table_id - zh_Hans: 多维表格的数据表 - human_description: - en_US: bitable table id - zh_Hans: 多维表格数据表的唯一标识符 table_id - llm_description: bitable table id - form: llm - - - name: page_token - type: string - required: false - label: - en_US: page_token - zh_Hans: 分页标记 - human_description: - en_US: Pagination mark. If it is not filled in the first request, it means to traverse from the beginning. - zh_Hans: 分页标记,第一次请求不填,表示从头开始遍历。 - llm_description: 分页标记,第一次请求不填,表示从头开始遍历;分页查询结果还有更多项时会同时返回新的 page_token,下次遍历可采用该 page_token 获取查询结果。 - form: llm - - - name: page_size - type: number - required: false - default: 20 - label: - en_US: page_size - zh_Hans: 分页大小 - human_description: - en_US: paging size - zh_Hans: 分页大小,默认值为 20,最大值为 100。 - llm_description: The default value of paging size is 20 and the maximum value is 100. - form: llm - - - name: sort_condition - type: string - required: false - label: - en_US: sort_condition - zh_Hans: 排序条件 - human_description: - en_US: sort condition - zh_Hans: | - 排序条件,格式为:[{"field_name":"多行文本","desc":true}]。 - field_name: 字段名称; - desc: 是否倒序排序; - llm_description: | - Sorting conditions, the format is: [{"field_name":"multi-line text","desc":true}]. - form: llm - - - name: filter_condition - type: string - required: false - label: - en_US: filter_condition - zh_Hans: 筛选条件 - human_description: - en_US: filter condition - zh_Hans: | - 筛选条件,格式为:{"conjunction":"and","conditions":[{"field_name":"字段1","operator":"is","value":["文本内容"]}]}。 - conjunction:条件逻辑连接词; - conditions:筛选条件集合; - field_name:筛选条件的左值,值为字段的名称; - operator:条件运算符; - value:目标值; - llm_description: | - The format of the filter condition is: {"conjunction":"and","conditions":[{"field_name":"Field 1","operator":"is","value":["text content"]}]}. - form: llm diff --git a/api/core/tools/provider/builtin/feishu_base/tools/list_base_tables.py b/api/core/tools/provider/builtin/feishu_base/tools/list_base_tables.py deleted file mode 100644 index 4ec9a476bc..0000000000 --- a/api/core/tools/provider/builtin/feishu_base/tools/list_base_tables.py +++ /dev/null @@ -1,47 +0,0 @@ -import json -from typing import Any, Union - -import httpx - -from core.tools.entities.tool_entities import ToolInvokeMessage -from core.tools.tool.builtin_tool import BuiltinTool - - -class ListBaseTablesTool(BuiltinTool): - def _invoke( - self, user_id: str, tool_parameters: dict[str, Any] - ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: - url = "https://open.feishu.cn/open-apis/bitable/v1/apps/{app_token}/tables" - - access_token = tool_parameters.get("Authorization", "") - if not access_token: - return self.create_text_message("Invalid parameter access_token") - - app_token = tool_parameters.get("app_token", "") - if not app_token: - return self.create_text_message("Invalid parameter app_token") - - page_token = tool_parameters.get("page_token", "") - page_size = tool_parameters.get("page_size", "") - - headers = { - "Content-Type": "application/json", - "Authorization": f"Bearer {access_token}", - } - - params = { - "page_token": page_token, - "page_size": page_size, - } - - try: - res = httpx.get(url.format(app_token=app_token), headers=headers, params=params, timeout=30) - res_json = res.json() - if res.is_success: - return self.create_text_message(text=json.dumps(res_json)) - else: - return self.create_text_message( - f"Failed to list base tables, status code: {res.status_code}, response: {res.text}" - ) - except Exception as e: - return self.create_text_message("Failed to list base tables. {}".format(e)) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/list_base_tables.yaml b/api/core/tools/provider/builtin/feishu_base/tools/list_base_tables.yaml deleted file mode 100644 index 9887124a28..0000000000 --- a/api/core/tools/provider/builtin/feishu_base/tools/list_base_tables.yaml +++ /dev/null @@ -1,65 +0,0 @@ -identity: - name: list_base_tables - author: Doug Lea - label: - en_US: List Base Tables - zh_Hans: 根据 app_token 获取多维表格下的所有数据表 -description: - human: - en_US: List base tables - zh_Hans: | - 根据 app_token 获取多维表格下的所有数据表 - llm: A tool for getting all data tables under a multidimensional table based on app_token. -parameters: - - name: Authorization - type: string - required: true - label: - en_US: token - zh_Hans: 凭证 - human_description: - en_US: API access token parameter, tenant_access_token or user_access_token - zh_Hans: API 的访问凭证参数,tenant_access_token 或 user_access_token - llm_description: API access token parameter, tenant_access_token or user_access_token - form: llm - - - name: app_token - type: string - required: true - label: - en_US: app_token - zh_Hans: 多维表格 - human_description: - en_US: bitable app token - zh_Hans: 多维表格的唯一标识符 app_token - llm_description: bitable app token - form: llm - - - name: page_token - type: string - required: false - label: - en_US: page_token - zh_Hans: 分页标记 - human_description: - en_US: Pagination mark. If it is not filled in the first request, it means to traverse from the beginning. - zh_Hans: 分页标记,第一次请求不填,表示从头开始遍历。 - llm_description: | - Pagination token. If it is not filled in the first request, it means to start traversal from the beginning. - If there are more items in the pagination query result, a new page_token will be returned at the same time. - The page_token can be used to obtain the query result in the next traversal. - 分页标记,第一次请求不填,表示从头开始遍历;分页查询结果还有更多项时会同时返回新的 page_token,下次遍历可采用该 page_token 获取查询结果。 - form: llm - - - name: page_size - type: number - required: false - default: 20 - label: - en_US: page_size - zh_Hans: 分页大小 - human_description: - en_US: paging size - zh_Hans: 分页大小,默认值为 20,最大值为 100。 - llm_description: The default value of paging size is 20 and the maximum value is 100. - form: llm diff --git a/api/core/tools/provider/builtin/feishu_base/tools/list_tables.py b/api/core/tools/provider/builtin/feishu_base/tools/list_tables.py new file mode 100644 index 0000000000..c7768a496d --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/list_tables.py @@ -0,0 +1,19 @@ +from typing import Any + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.tool.builtin_tool import BuiltinTool +from core.tools.utils.feishu_api_utils import FeishuRequest + + +class ListTablesTool(BuiltinTool): + def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage: + app_id = self.runtime.credentials.get("app_id") + app_secret = self.runtime.credentials.get("app_secret") + client = FeishuRequest(app_id, app_secret) + + app_token = tool_parameters.get("app_token") + page_token = tool_parameters.get("page_token") + page_size = tool_parameters.get("page_size", 20) + + res = client.list_tables(app_token, page_token, page_size) + return self.create_json_message(res) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/list_tables.yaml b/api/core/tools/provider/builtin/feishu_base/tools/list_tables.yaml new file mode 100644 index 0000000000..5a3891bd45 --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/list_tables.yaml @@ -0,0 +1,50 @@ +identity: + name: list_tables + author: Doug Lea + label: + en_US: List Tables + zh_Hans: 列出数据表 +description: + human: + en_US: Get All Data Tables under Multidimensional Table + zh_Hans: 获取多维表格下的所有数据表 + llm: A tool for getting all data tables under a multidimensional table. (获取多维表格下的所有数据表) +parameters: + - name: app_token + type: string + required: true + label: + en_US: app_token + zh_Hans: app_token + human_description: + en_US: Unique identifier for the multidimensional table, supports inputting document URL. + zh_Hans: 多维表格的唯一标识符,支持输入文档 URL。 + llm_description: 多维表格的唯一标识符,支持输入文档 URL。 + form: llm + + - name: page_size + type: number + required: false + default: 20 + label: + en_US: page_size + zh_Hans: 分页大小 + human_description: + en_US: | + Page size, default value: 20, maximum value: 100. + zh_Hans: 分页大小,默认值:20,最大值:100。 + llm_description: 分页大小,默认值:20,最大值:100。 + form: llm + + - name: page_token + type: string + required: false + label: + en_US: page_token + zh_Hans: 分页标记 + human_description: + en_US: | + Page token, leave empty for the first request to start from the beginning; a new page_token will be returned if there are more items in the paginated query results, which can be used for the next traversal. Example value: "tblsRc9GRRXKqhvW". + zh_Hans: 分页标记,第一次请求不填,表示从头开始遍历;分页查询结果还有更多项时会同时返回新的 page_token,下次遍历可采用该 page_token 获取查询结果。示例值:"tblsRc9GRRXKqhvW"。 + llm_description: 分页标记,第一次请求不填,表示从头开始遍历;分页查询结果还有更多项时会同时返回新的 page_token,下次遍历可采用该 page_token 获取查询结果。示例值:"tblsRc9GRRXKqhvW"。 + form: llm diff --git a/api/core/tools/provider/builtin/feishu_base/tools/read_base_record.py b/api/core/tools/provider/builtin/feishu_base/tools/read_base_record.py deleted file mode 100644 index fb818f8380..0000000000 --- a/api/core/tools/provider/builtin/feishu_base/tools/read_base_record.py +++ /dev/null @@ -1,49 +0,0 @@ -import json -from typing import Any, Union - -import httpx - -from core.tools.entities.tool_entities import ToolInvokeMessage -from core.tools.tool.builtin_tool import BuiltinTool - - -class ReadBaseRecordTool(BuiltinTool): - def _invoke( - self, user_id: str, tool_parameters: dict[str, Any] - ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: - url = "https://open.feishu.cn/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/records/{record_id}" - - access_token = tool_parameters.get("Authorization", "") - if not access_token: - return self.create_text_message("Invalid parameter access_token") - - app_token = tool_parameters.get("app_token", "") - if not app_token: - return self.create_text_message("Invalid parameter app_token") - - table_id = tool_parameters.get("table_id", "") - if not table_id: - return self.create_text_message("Invalid parameter table_id") - - record_id = tool_parameters.get("record_id", "") - if not record_id: - return self.create_text_message("Invalid parameter record_id") - - headers = { - "Content-Type": "application/json", - "Authorization": f"Bearer {access_token}", - } - - try: - res = httpx.get( - url.format(app_token=app_token, table_id=table_id, record_id=record_id), headers=headers, timeout=30 - ) - res_json = res.json() - if res.is_success: - return self.create_text_message(text=json.dumps(res_json)) - else: - return self.create_text_message( - f"Failed to read base record, status code: {res.status_code}, response: {res.text}" - ) - except Exception as e: - return self.create_text_message("Failed to read base record. {}".format(e)) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/read_base_record.yaml b/api/core/tools/provider/builtin/feishu_base/tools/read_base_record.yaml deleted file mode 100644 index 400e9a1021..0000000000 --- a/api/core/tools/provider/builtin/feishu_base/tools/read_base_record.yaml +++ /dev/null @@ -1,60 +0,0 @@ -identity: - name: read_base_record - author: Doug Lea - label: - en_US: Read Base Record - zh_Hans: 根据 record_id 的值检索多维表格数据表的记录 -description: - human: - en_US: Read base record - zh_Hans: | - 根据 record_id 的值检索多维表格数据表的记录 - llm: Retrieve records from a multidimensional table based on the value of record_id -parameters: - - name: Authorization - type: string - required: true - label: - en_US: token - zh_Hans: 凭证 - human_description: - en_US: API access token parameter, tenant_access_token or user_access_token - zh_Hans: API 的访问凭证参数,tenant_access_token 或 user_access_token - llm_description: API access token parameter, tenant_access_token or user_access_token - form: llm - - - name: app_token - type: string - required: true - label: - en_US: app_token - zh_Hans: 多维表格 - human_description: - en_US: bitable app token - zh_Hans: 多维表格的唯一标识符 app_token - llm_description: bitable app token - form: llm - - - name: table_id - type: string - required: true - label: - en_US: table_id - zh_Hans: 多维表格的数据表 - human_description: - en_US: bitable table id - zh_Hans: 多维表格数据表的唯一标识符 table_id - llm_description: bitable table id - form: llm - - - name: record_id - type: string - required: true - label: - en_US: record_id - zh_Hans: 单条记录的 id - human_description: - en_US: The id of a single record - zh_Hans: 单条记录的 id - llm_description: The id of a single record - form: llm diff --git a/api/core/tools/provider/builtin/feishu_base/tools/read_records.py b/api/core/tools/provider/builtin/feishu_base/tools/read_records.py new file mode 100644 index 0000000000..46f3df4ff0 --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/read_records.py @@ -0,0 +1,21 @@ +from typing import Any + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.tool.builtin_tool import BuiltinTool +from core.tools.utils.feishu_api_utils import FeishuRequest + + +class ReadRecordsTool(BuiltinTool): + def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage: + app_id = self.runtime.credentials.get("app_id") + app_secret = self.runtime.credentials.get("app_secret") + client = FeishuRequest(app_id, app_secret) + + app_token = tool_parameters.get("app_token") + table_id = tool_parameters.get("table_id") + table_name = tool_parameters.get("table_name") + record_ids = tool_parameters.get("record_ids") + user_id_type = tool_parameters.get("user_id_type", "open_id") + + res = client.read_records(app_token, table_id, table_name, record_ids, user_id_type) + return self.create_json_message(res) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/read_records.yaml b/api/core/tools/provider/builtin/feishu_base/tools/read_records.yaml new file mode 100644 index 0000000000..911e667cfc --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/read_records.yaml @@ -0,0 +1,86 @@ +identity: + name: read_records + author: Doug Lea + label: + en_US: Read Records + zh_Hans: 批量获取记录 +description: + human: + en_US: Batch Retrieve Records from Multidimensional Table + zh_Hans: 批量获取多维表格数据表中的记录信息 + llm: A tool for batch retrieving records from a multidimensional table, supporting up to 100 records per call. (批量获取多维表格数据表中的记录信息,单次调用最多支持查询 100 条记录) + +parameters: + - name: app_token + type: string + required: true + label: + en_US: app_token + zh_Hans: app_token + human_description: + en_US: Unique identifier for the multidimensional table, supports inputting document URL. + zh_Hans: 多维表格的唯一标识符,支持输入文档 URL。 + llm_description: 多维表格的唯一标识符,支持输入文档 URL。 + form: llm + + - name: table_id + type: string + required: false + label: + en_US: table_id + zh_Hans: table_id + human_description: + en_US: Unique identifier for the multidimensional table data, either table_id or table_name must be provided, cannot be empty simultaneously. + zh_Hans: 多维表格数据表的唯一标识符,table_id 和 table_name 至少需要提供一个,不能同时为空。 + llm_description: 多维表格数据表的唯一标识符,table_id 和 table_name 至少需要提供一个,不能同时为空。 + form: llm + + - name: table_name + type: string + required: false + label: + en_US: table_name + zh_Hans: table_name + human_description: + en_US: Name of the multidimensional table data, either table_name or table_id must be provided, cannot be empty simultaneously. + zh_Hans: 多维表格数据表的名称,table_name 和 table_id 至少需要提供一个,不能同时为空。 + llm_description: 多维表格数据表的名称,table_name 和 table_id 至少需要提供一个,不能同时为空。 + form: llm + + - name: record_ids + type: string + required: true + label: + en_US: record_ids + zh_Hans: 记录 ID 列表 + human_description: + en_US: List of record IDs, which can be obtained by calling the "Query Records API". + zh_Hans: 记录 ID 列表,可以通过调用"查询记录接口"获取。 + llm_description: 记录 ID 列表,可以通过调用"查询记录接口"获取。 + form: llm + + - name: user_id_type + type: select + required: false + options: + - value: open_id + label: + en_US: open_id + zh_Hans: open_id + - value: union_id + label: + en_US: union_id + zh_Hans: union_id + - value: user_id + label: + en_US: user_id + zh_Hans: user_id + default: "open_id" + label: + en_US: user_id_type + zh_Hans: 用户 ID 类型 + human_description: + en_US: User ID type, optional values are open_id, union_id, user_id, with a default value of open_id. + zh_Hans: 用户 ID 类型,可选值有 open_id、union_id、user_id,默认值为 open_id。 + llm_description: 用户 ID 类型,可选值有 open_id、union_id、user_id,默认值为 open_id。 + form: form diff --git a/api/core/tools/provider/builtin/feishu_base/tools/search_records.py b/api/core/tools/provider/builtin/feishu_base/tools/search_records.py new file mode 100644 index 0000000000..c959496735 --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/search_records.py @@ -0,0 +1,39 @@ +from typing import Any + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.tool.builtin_tool import BuiltinTool +from core.tools.utils.feishu_api_utils import FeishuRequest + + +class SearchRecordsTool(BuiltinTool): + def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage: + app_id = self.runtime.credentials.get("app_id") + app_secret = self.runtime.credentials.get("app_secret") + client = FeishuRequest(app_id, app_secret) + + app_token = tool_parameters.get("app_token") + table_id = tool_parameters.get("table_id") + table_name = tool_parameters.get("table_name") + view_id = tool_parameters.get("view_id") + field_names = tool_parameters.get("field_names") + sort = tool_parameters.get("sort") + filters = tool_parameters.get("filter") + page_token = tool_parameters.get("page_token") + automatic_fields = tool_parameters.get("automatic_fields", False) + user_id_type = tool_parameters.get("user_id_type", "open_id") + page_size = tool_parameters.get("page_size", 20) + + res = client.search_record( + app_token, + table_id, + table_name, + view_id, + field_names, + sort, + filters, + page_token, + automatic_fields, + user_id_type, + page_size, + ) + return self.create_json_message(res) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/search_records.yaml b/api/core/tools/provider/builtin/feishu_base/tools/search_records.yaml new file mode 100644 index 0000000000..6cac4b0524 --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/search_records.yaml @@ -0,0 +1,163 @@ +identity: + name: search_records + author: Doug Lea + label: + en_US: Search Records + zh_Hans: 查询记录 +description: + human: + en_US: Query records in a multidimensional table, up to 500 rows per query. + zh_Hans: 查询多维表格数据表中的记录,单次最多查询 500 行记录。 + llm: A tool for querying records in a multidimensional table, up to 500 rows per query. (查询多维表格数据表中的记录,单次最多查询 500 行记录) +parameters: + - name: app_token + type: string + required: true + label: + en_US: app_token + zh_Hans: app_token + human_description: + en_US: Unique identifier for the multidimensional table, supports inputting document URL. + zh_Hans: 多维表格的唯一标识符,支持输入文档 URL。 + llm_description: 多维表格的唯一标识符,支持输入文档 URL。 + form: llm + + - name: table_id + type: string + required: false + label: + en_US: table_id + zh_Hans: table_id + human_description: + en_US: Unique identifier for the multidimensional table data, either table_id or table_name must be provided, cannot be empty simultaneously. + zh_Hans: 多维表格数据表的唯一标识符,table_id 和 table_name 至少需要提供一个,不能同时为空。 + llm_description: 多维表格数据表的唯一标识符,table_id 和 table_name 至少需要提供一个,不能同时为空。 + form: llm + + - name: table_name + type: string + required: false + label: + en_US: table_name + zh_Hans: table_name + human_description: + en_US: Name of the multidimensional table data, either table_name or table_id must be provided, cannot be empty simultaneously. + zh_Hans: 多维表格数据表的名称,table_name 和 table_id 至少需要提供一个,不能同时为空。 + llm_description: 多维表格数据表的名称,table_name 和 table_id 至少需要提供一个,不能同时为空。 + form: llm + + - name: view_id + type: string + required: false + label: + en_US: view_id + zh_Hans: 视图唯一标识 + human_description: + en_US: | + Unique identifier for a view in a multidimensional table. It can be found in the URL's query parameter with the key 'view'. For example: https://svi136aogf123.feishu.cn/base/KWC8bYsYXahYqGsTtqectNn9n3e?table=tblE8a2fmBIEflaE&view=vewlkAVpRx. + zh_Hans: 多维表格中视图的唯一标识,可在多维表格的 URL 地址栏中找到,query 参数中 key 为 view 的部分。例如:https://svi136aogf123.feishu.cn/base/KWC8bYsYXahYqGsTtqectNn9n3e?table=tblE8a2fmBIEflaE&view=vewlkAVpRx。 + llm_description: 多维表格中视图的唯一标识,可在多维表格的 URL 地址栏中找到,query 参数中 key 为 view 的部分。例如:https://svi136aogf123.feishu.cn/base/KWC8bYsYXahYqGsTtqectNn9n3e?table=tblE8a2fmBIEflaE&view=vewlkAVpRx。 + form: llm + + - name: field_names + type: string + required: false + label: + en_US: field_names + zh_Hans: 字段名称 + human_description: + en_US: | + Field names to specify which fields to include in the returned records. Example value: ["Field1", "Field2"]. + zh_Hans: 字段名称,用于指定本次查询返回记录中包含的字段。示例值:["字段1","字段2"]。 + llm_description: 字段名称,用于指定本次查询返回记录中包含的字段。示例值:["字段1","字段2"]。 + form: llm + + - name: sort + type: string + required: false + label: + en_US: sort + zh_Hans: 排序条件 + human_description: + en_US: | + Sorting conditions, for example: [{"field_name":"Multiline Text","desc":true}]. + zh_Hans: 排序条件,例如:[{"field_name":"多行文本","desc":true}]。 + llm_description: 排序条件,例如:[{"field_name":"多行文本","desc":true}]。 + form: llm + + - name: filter + type: string + required: false + label: + en_US: filter + zh_Hans: 筛选条件 + human_description: + en_US: Object containing filter information. For details on how to fill in the filter, refer to the record filter parameter guide (https://open.larkoffice.com/document/uAjLw4CM/ukTMukTMukTM/reference/bitable-v1/app-table-record/record-filter-guide). + zh_Hans: 包含条件筛选信息的对象。了解如何填写 filter,参考记录筛选参数填写指南(https://open.larkoffice.com/document/uAjLw4CM/ukTMukTMukTM/reference/bitable-v1/app-table-record/record-filter-guide)。 + llm_description: 包含条件筛选信息的对象。了解如何填写 filter,参考记录筛选参数填写指南(https://open.larkoffice.com/document/uAjLw4CM/ukTMukTMukTM/reference/bitable-v1/app-table-record/record-filter-guide)。 + form: llm + + - name: automatic_fields + type: boolean + required: false + label: + en_US: automatic_fields + zh_Hans: automatic_fields + human_description: + en_US: Whether to return automatically calculated fields. Default is false, meaning they are not returned. + zh_Hans: 是否返回自动计算的字段。默认为 false,表示不返回。 + llm_description: 是否返回自动计算的字段。默认为 false,表示不返回。 + form: form + + - name: user_id_type + type: select + required: false + options: + - value: open_id + label: + en_US: open_id + zh_Hans: open_id + - value: union_id + label: + en_US: union_id + zh_Hans: union_id + - value: user_id + label: + en_US: user_id + zh_Hans: user_id + default: "open_id" + label: + en_US: user_id_type + zh_Hans: 用户 ID 类型 + human_description: + en_US: User ID type, optional values are open_id, union_id, user_id, with a default value of open_id. + zh_Hans: 用户 ID 类型,可选值有 open_id、union_id、user_id,默认值为 open_id。 + llm_description: 用户 ID 类型,可选值有 open_id、union_id、user_id,默认值为 open_id。 + form: form + + - name: page_size + type: number + required: false + default: 20 + label: + en_US: page_size + zh_Hans: 分页大小 + human_description: + en_US: | + Page size, default value: 20, maximum value: 500. + zh_Hans: 分页大小,默认值:20,最大值:500。 + llm_description: 分页大小,默认值:20,最大值:500。 + form: llm + + - name: page_token + type: string + required: false + label: + en_US: page_token + zh_Hans: 分页标记 + human_description: + en_US: | + Page token, leave empty for the first request to start from the beginning; a new page_token will be returned if there are more items in the paginated query results, which can be used for the next traversal. Example value: "tblsRc9GRRXKqhvW". + zh_Hans: 分页标记,第一次请求不填,表示从头开始遍历;分页查询结果还有更多项时会同时返回新的 page_token,下次遍历可采用该 page_token 获取查询结果。示例值:"tblsRc9GRRXKqhvW"。 + llm_description: 分页标记,第一次请求不填,表示从头开始遍历;分页查询结果还有更多项时会同时返回新的 page_token,下次遍历可采用该 page_token 获取查询结果。示例值:"tblsRc9GRRXKqhvW"。 + form: llm diff --git a/api/core/tools/provider/builtin/feishu_base/tools/update_base_record.py b/api/core/tools/provider/builtin/feishu_base/tools/update_base_record.py deleted file mode 100644 index 6d7e33f3ff..0000000000 --- a/api/core/tools/provider/builtin/feishu_base/tools/update_base_record.py +++ /dev/null @@ -1,60 +0,0 @@ -import json -from typing import Any, Union - -import httpx - -from core.tools.entities.tool_entities import ToolInvokeMessage -from core.tools.tool.builtin_tool import BuiltinTool - - -class UpdateBaseRecordTool(BuiltinTool): - def _invoke( - self, user_id: str, tool_parameters: dict[str, Any] - ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: - url = "https://open.feishu.cn/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/records/{record_id}" - - access_token = tool_parameters.get("Authorization", "") - if not access_token: - return self.create_text_message("Invalid parameter access_token") - - app_token = tool_parameters.get("app_token", "") - if not app_token: - return self.create_text_message("Invalid parameter app_token") - - table_id = tool_parameters.get("table_id", "") - if not table_id: - return self.create_text_message("Invalid parameter table_id") - - record_id = tool_parameters.get("record_id", "") - if not record_id: - return self.create_text_message("Invalid parameter record_id") - - fields = tool_parameters.get("fields", "") - if not fields: - return self.create_text_message("Invalid parameter fields") - - headers = { - "Content-Type": "application/json", - "Authorization": f"Bearer {access_token}", - } - - params = {} - payload = {"fields": json.loads(fields)} - - try: - res = httpx.put( - url.format(app_token=app_token, table_id=table_id, record_id=record_id), - headers=headers, - params=params, - json=payload, - timeout=30, - ) - res_json = res.json() - if res.is_success: - return self.create_text_message(text=json.dumps(res_json)) - else: - return self.create_text_message( - f"Failed to update base record, status code: {res.status_code}, response: {res.text}" - ) - except Exception as e: - return self.create_text_message("Failed to update base record. {}".format(e)) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/update_base_record.yaml b/api/core/tools/provider/builtin/feishu_base/tools/update_base_record.yaml deleted file mode 100644 index 788798c4b3..0000000000 --- a/api/core/tools/provider/builtin/feishu_base/tools/update_base_record.yaml +++ /dev/null @@ -1,78 +0,0 @@ -identity: - name: update_base_record - author: Doug Lea - label: - en_US: Update Base Record - zh_Hans: 更新多维表格数据表中的一条记录 -description: - human: - en_US: Update base record - zh_Hans: | - 更新多维表格数据表中的一条记录,详细请参考:https://open.larkoffice.com/document/server-docs/docs/bitable-v1/app-table-record/update - llm: Update a record in a multidimensional table data table -parameters: - - name: Authorization - type: string - required: true - label: - en_US: token - zh_Hans: 凭证 - human_description: - en_US: API access token parameter, tenant_access_token or user_access_token - zh_Hans: API 的访问凭证参数,tenant_access_token 或 user_access_token - llm_description: API access token parameter, tenant_access_token or user_access_token - form: llm - - - name: app_token - type: string - required: true - label: - en_US: app_token - zh_Hans: 多维表格 - human_description: - en_US: bitable app token - zh_Hans: 多维表格的唯一标识符 app_token - llm_description: bitable app token - form: llm - - - name: table_id - type: string - required: true - label: - en_US: table_id - zh_Hans: 多维表格的数据表 - human_description: - en_US: bitable table id - zh_Hans: 多维表格数据表的唯一标识符 table_id - llm_description: bitable table id - form: llm - - - name: record_id - type: string - required: true - label: - en_US: record_id - zh_Hans: 单条记录的 id - human_description: - en_US: The id of a single record - zh_Hans: 单条记录的 id - llm_description: The id of a single record - form: llm - - - name: fields - type: string - required: true - label: - en_US: fields - zh_Hans: 数据表的列字段内容 - human_description: - en_US: The fields of a multidimensional table data table, that is, the columns of the data table. - zh_Hans: | - 要更新一行多维表格记录,字段结构拼接如下:{"多行文本":"多行文本内容","单选":"选项1","多选":["选项1","选项2"],"复选框":true,"人员":[{"id":"ou_2910013f1e6456f16a0ce75ede950a0a"}],"群组":[{"id":"oc_cd07f55f14d6f4a4f1b51504e7e97f48"}],"电话号码":"13026162666"} - 当前接口支持的字段类型为:多行文本、单选、条码、多选、日期、人员、附件、复选框、超链接、数字、单向关联、双向关联、电话号码、地理位置。 - 不同类型字段的数据结构请参考数据结构概述:https://open.larkoffice.com/document/server-docs/docs/bitable-v1/bitable-structure - llm_description: | - 要更新一行多维表格记录,字段结构拼接如下:{"多行文本":"多行文本内容","单选":"选项1","多选":["选项1","选项2"],"复选框":true,"人员":[{"id":"ou_2910013f1e6456f16a0ce75ede950a0a"}],"群组":[{"id":"oc_cd07f55f14d6f4a4f1b51504e7e97f48"}],"电话号码":"13026162666"} - 当前接口支持的字段类型为:多行文本、单选、条码、多选、日期、人员、附件、复选框、超链接、数字、单向关联、双向关联、电话号码、地理位置。 - 不同类型字段的数据结构请参考数据结构概述:https://open.larkoffice.com/document/server-docs/docs/bitable-v1/bitable-structure - form: llm diff --git a/api/core/tools/provider/builtin/feishu_base/tools/update_records.py b/api/core/tools/provider/builtin/feishu_base/tools/update_records.py new file mode 100644 index 0000000000..a7b0363875 --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/update_records.py @@ -0,0 +1,21 @@ +from typing import Any + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.tool.builtin_tool import BuiltinTool +from core.tools.utils.feishu_api_utils import FeishuRequest + + +class UpdateRecordsTool(BuiltinTool): + def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage: + app_id = self.runtime.credentials.get("app_id") + app_secret = self.runtime.credentials.get("app_secret") + client = FeishuRequest(app_id, app_secret) + + app_token = tool_parameters.get("app_token") + table_id = tool_parameters.get("table_id") + table_name = tool_parameters.get("table_name") + records = tool_parameters.get("records") + user_id_type = tool_parameters.get("user_id_type", "open_id") + + res = client.update_records(app_token, table_id, table_name, records, user_id_type) + return self.create_json_message(res) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/update_records.yaml b/api/core/tools/provider/builtin/feishu_base/tools/update_records.yaml new file mode 100644 index 0000000000..68117e7136 --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/update_records.yaml @@ -0,0 +1,91 @@ +identity: + name: update_records + author: Doug Lea + label: + en_US: Update Records + zh_Hans: 更新多条记录 +description: + human: + en_US: Update Multiple Records in Multidimensional Table + zh_Hans: 更新多维表格数据表中的多条记录 + llm: A tool for updating multiple records in a multidimensional table. (更新多维表格数据表中的多条记录) +parameters: + - name: app_token + type: string + required: true + label: + en_US: app_token + zh_Hans: app_token + human_description: + en_US: Unique identifier for the multidimensional table, supports inputting document URL. + zh_Hans: 多维表格的唯一标识符,支持输入文档 URL。 + llm_description: 多维表格的唯一标识符,支持输入文档 URL。 + form: llm + + - name: table_id + type: string + required: false + label: + en_US: table_id + zh_Hans: table_id + human_description: + en_US: Unique identifier for the multidimensional table data, either table_id or table_name must be provided, cannot be empty simultaneously. + zh_Hans: 多维表格数据表的唯一标识符,table_id 和 table_name 至少需要提供一个,不能同时为空。 + llm_description: 多维表格数据表的唯一标识符,table_id 和 table_name 至少需要提供一个,不能同时为空。 + form: llm + + - name: table_name + type: string + required: false + label: + en_US: table_name + zh_Hans: table_name + human_description: + en_US: Name of the multidimensional table data, either table_name or table_id must be provided, cannot be empty simultaneously. + zh_Hans: 多维表格数据表的名称,table_name 和 table_id 至少需要提供一个,不能同时为空。 + llm_description: 多维表格数据表的名称,table_name 和 table_id 至少需要提供一个,不能同时为空。 + form: llm + + - name: records + type: string + required: true + label: + en_US: records + zh_Hans: 记录列表 + human_description: + en_US: | + List of records to be updated in this request. Example value: [{"fields":{"multi-line-text":"text content","single_select":"option 1","date":1674206443000},"record_id":"recupK4f4RM5RX"}]. + For supported field types, refer to the integration guide (https://open.larkoffice.com/document/server-docs/docs/bitable-v1/notification). For data structures of different field types, refer to the data structure overview (https://open.larkoffice.com/document/server-docs/docs/bitable-v1/bitable-structure). + zh_Hans: | + 本次请求将要更新的记录列表,示例值:[{"fields":{"多行文本":"文本内容","单选":"选项 1","日期":1674206443000},"record_id":"recupK4f4RM5RX"}]。 + 当前接口支持的字段类型请参考接入指南(https://open.larkoffice.com/document/server-docs/docs/bitable-v1/notification),不同类型字段的数据结构请参考数据结构概述(https://open.larkoffice.com/document/server-docs/docs/bitable-v1/bitable-structure)。 + llm_description: | + 本次请求将要更新的记录列表,示例值:[{"fields":{"多行文本":"文本内容","单选":"选项 1","日期":1674206443000},"record_id":"recupK4f4RM5RX"}]。 + 当前接口支持的字段类型请参考接入指南(https://open.larkoffice.com/document/server-docs/docs/bitable-v1/notification),不同类型字段的数据结构请参考数据结构概述(https://open.larkoffice.com/document/server-docs/docs/bitable-v1/bitable-structure)。 + form: llm + + - name: user_id_type + type: select + required: false + options: + - value: open_id + label: + en_US: open_id + zh_Hans: open_id + - value: union_id + label: + en_US: union_id + zh_Hans: union_id + - value: user_id + label: + en_US: user_id + zh_Hans: user_id + default: "open_id" + label: + en_US: user_id_type + zh_Hans: 用户 ID 类型 + human_description: + en_US: User ID type, optional values are open_id, union_id, user_id, with a default value of open_id. + zh_Hans: 用户 ID 类型,可选值有 open_id、union_id、user_id,默认值为 open_id。 + llm_description: 用户 ID 类型,可选值有 open_id、union_id、user_id,默认值为 open_id。 + form: form diff --git a/api/core/tools/provider/builtin/podcast_generator/_assets/icon.svg b/api/core/tools/provider/builtin/podcast_generator/_assets/icon.svg new file mode 100644 index 0000000000..01743c9cd3 --- /dev/null +++ b/api/core/tools/provider/builtin/podcast_generator/_assets/icon.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/api/core/tools/provider/builtin/podcast_generator/podcast_generator.py b/api/core/tools/provider/builtin/podcast_generator/podcast_generator.py new file mode 100644 index 0000000000..0b9c025834 --- /dev/null +++ b/api/core/tools/provider/builtin/podcast_generator/podcast_generator.py @@ -0,0 +1,33 @@ +from typing import Any + +import openai + +from core.tools.errors import ToolProviderCredentialValidationError +from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController + + +class PodcastGeneratorProvider(BuiltinToolProviderController): + def _validate_credentials(self, credentials: dict[str, Any]) -> None: + tts_service = credentials.get("tts_service") + api_key = credentials.get("api_key") + + if not tts_service: + raise ToolProviderCredentialValidationError("TTS service is not specified") + + if not api_key: + raise ToolProviderCredentialValidationError("API key is missing") + + if tts_service == "openai": + self._validate_openai_credentials(api_key) + else: + raise ToolProviderCredentialValidationError(f"Unsupported TTS service: {tts_service}") + + def _validate_openai_credentials(self, api_key: str) -> None: + client = openai.OpenAI(api_key=api_key) + try: + # We're using a simple API call to validate the credentials + client.models.list() + except openai.AuthenticationError: + raise ToolProviderCredentialValidationError("Invalid OpenAI API key") + except Exception as e: + raise ToolProviderCredentialValidationError(f"Error validating OpenAI API key: {str(e)}") diff --git a/api/core/tools/provider/builtin/podcast_generator/podcast_generator.yaml b/api/core/tools/provider/builtin/podcast_generator/podcast_generator.yaml new file mode 100644 index 0000000000..bd02b32020 --- /dev/null +++ b/api/core/tools/provider/builtin/podcast_generator/podcast_generator.yaml @@ -0,0 +1,34 @@ +identity: + author: Dify + name: podcast_generator + label: + en_US: Podcast Generator + zh_Hans: 播客生成器 + description: + en_US: Generate podcast audio using Text-to-Speech services + zh_Hans: 使用文字转语音服务生成播客音频 + icon: icon.svg +credentials_for_provider: + tts_service: + type: select + required: true + label: + en_US: TTS Service + zh_Hans: TTS 服务 + placeholder: + en_US: Select a TTS service + zh_Hans: 选择一个 TTS 服务 + options: + - label: + en_US: OpenAI TTS + zh_Hans: OpenAI TTS + value: openai + api_key: + type: secret-input + required: true + label: + en_US: API Key + zh_Hans: API 密钥 + placeholder: + en_US: Enter your TTS service API key + zh_Hans: 输入您的 TTS 服务 API 密钥 diff --git a/api/core/tools/provider/builtin/podcast_generator/tools/podcast_audio_generator.py b/api/core/tools/provider/builtin/podcast_generator/tools/podcast_audio_generator.py new file mode 100644 index 0000000000..8c8dd9bf68 --- /dev/null +++ b/api/core/tools/provider/builtin/podcast_generator/tools/podcast_audio_generator.py @@ -0,0 +1,100 @@ +import concurrent.futures +import io +import random +from typing import Any, Literal, Optional, Union + +import openai +from pydub import AudioSegment + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.errors import ToolParameterValidationError, ToolProviderCredentialValidationError +from core.tools.tool.builtin_tool import BuiltinTool + + +class PodcastAudioGeneratorTool(BuiltinTool): + @staticmethod + def _generate_silence(duration: float): + # Generate silent WAV data using pydub + silence = AudioSegment.silent(duration=int(duration * 1000)) # pydub uses milliseconds + return silence + + @staticmethod + def _generate_audio_segment( + client: openai.OpenAI, + line: str, + voice: Literal["alloy", "echo", "fable", "onyx", "nova", "shimmer"], + index: int, + ) -> tuple[int, Union[AudioSegment, str], Optional[AudioSegment]]: + try: + response = client.audio.speech.create(model="tts-1", voice=voice, input=line.strip(), response_format="wav") + audio = AudioSegment.from_wav(io.BytesIO(response.content)) + silence_duration = random.uniform(0.1, 1.5) + silence = PodcastAudioGeneratorTool._generate_silence(silence_duration) + return index, audio, silence + except Exception as e: + return index, f"Error generating audio: {str(e)}", None + + def _invoke( + self, user_id: str, tool_parameters: dict[str, Any] + ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: + # Extract parameters + script = tool_parameters.get("script", "") + host1_voice = tool_parameters.get("host1_voice") + host2_voice = tool_parameters.get("host2_voice") + + # Split the script into lines + script_lines = [line for line in script.split("\n") if line.strip()] + + # Ensure voices are provided + if not host1_voice or not host2_voice: + raise ToolParameterValidationError("Host voices are required") + + # Get OpenAI API key from credentials + if not self.runtime or not self.runtime.credentials: + raise ToolProviderCredentialValidationError("Tool runtime or credentials are missing") + api_key = self.runtime.credentials.get("api_key") + if not api_key: + raise ToolProviderCredentialValidationError("OpenAI API key is missing") + + # Initialize OpenAI client + client = openai.OpenAI(api_key=api_key) + + # Create a thread pool + max_workers = 5 + with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor: + futures = [] + for i, line in enumerate(script_lines): + voice = host1_voice if i % 2 == 0 else host2_voice + future = executor.submit(self._generate_audio_segment, client, line, voice, i) + futures.append(future) + + # Collect results + audio_segments: list[Any] = [None] * len(script_lines) + for future in concurrent.futures.as_completed(futures): + index, audio, silence = future.result() + if isinstance(audio, str): # Error occurred + return self.create_text_message(audio) + audio_segments[index] = (audio, silence) + + # Combine audio segments in the correct order + combined_audio = AudioSegment.empty() + for i, (audio, silence) in enumerate(audio_segments): + if audio: + combined_audio += audio + if i < len(audio_segments) - 1 and silence: + combined_audio += silence + + # Export the combined audio to a WAV file in memory + buffer = io.BytesIO() + combined_audio.export(buffer, format="wav") + wav_bytes = buffer.getvalue() + + # Create a blob message with the combined audio + return [ + self.create_text_message("Audio generated successfully"), + self.create_blob_message( + blob=wav_bytes, + meta={"mime_type": "audio/x-wav"}, + save_as=self.VariableKey.AUDIO, + ), + ] diff --git a/api/core/tools/provider/builtin/podcast_generator/tools/podcast_audio_generator.yaml b/api/core/tools/provider/builtin/podcast_generator/tools/podcast_audio_generator.yaml new file mode 100644 index 0000000000..d6ae98f595 --- /dev/null +++ b/api/core/tools/provider/builtin/podcast_generator/tools/podcast_audio_generator.yaml @@ -0,0 +1,95 @@ +identity: + name: podcast_audio_generator + author: Dify + label: + en_US: Podcast Audio Generator + zh_Hans: 播客音频生成器 +description: + human: + en_US: Generate a podcast audio file from a script with two alternating voices using OpenAI's TTS service. + zh_Hans: 使用 OpenAI 的 TTS 服务,从包含两个交替声音的脚本生成播客音频文件。 + llm: This tool converts a prepared podcast script into an audio file using OpenAI's Text-to-Speech service, with two specified voices for alternating hosts. +parameters: + - name: script + type: string + required: true + label: + en_US: Podcast Script + zh_Hans: 播客脚本 + human_description: + en_US: A string containing alternating lines for two hosts, separated by newline characters. + zh_Hans: 包含两位主持人交替台词的字符串,每行用换行符分隔。 + llm_description: A string representing the script, with alternating lines for two hosts separated by newline characters. + form: llm + - name: host1_voice + type: select + required: true + label: + en_US: Host 1 Voice + zh_Hans: 主持人1 音色 + human_description: + en_US: The voice for the first host. + zh_Hans: 第一位主持人的音色。 + llm_description: The voice identifier for the first host's voice. + options: + - label: + en_US: Alloy + zh_Hans: Alloy + value: alloy + - label: + en_US: Echo + zh_Hans: Echo + value: echo + - label: + en_US: Fable + zh_Hans: Fable + value: fable + - label: + en_US: Onyx + zh_Hans: Onyx + value: onyx + - label: + en_US: Nova + zh_Hans: Nova + value: nova + - label: + en_US: Shimmer + zh_Hans: Shimmer + value: shimmer + form: form + - name: host2_voice + type: select + required: true + label: + en_US: Host 2 Voice + zh_Hans: 主持人2 音色 + human_description: + en_US: The voice for the second host. + zh_Hans: 第二位主持人的音色。 + llm_description: The voice identifier for the second host's voice. + options: + - label: + en_US: Alloy + zh_Hans: Alloy + value: alloy + - label: + en_US: Echo + zh_Hans: Echo + value: echo + - label: + en_US: Fable + zh_Hans: Fable + value: fable + - label: + en_US: Onyx + zh_Hans: Onyx + value: onyx + - label: + en_US: Nova + zh_Hans: Nova + value: nova + - label: + en_US: Shimmer + zh_Hans: Shimmer + value: shimmer + form: form diff --git a/api/core/tools/utils/tool_parameter_converter.py b/api/core/tools/utils/tool_parameter_converter.py deleted file mode 100644 index 6f7610651c..0000000000 --- a/api/core/tools/utils/tool_parameter_converter.py +++ /dev/null @@ -1,71 +0,0 @@ -from typing import Any - -from core.tools.entities.tool_entities import ToolParameter - - -class ToolParameterConverter: - @staticmethod - def get_parameter_type(parameter_type: str | ToolParameter.ToolParameterType) -> str: - match parameter_type: - case ( - ToolParameter.ToolParameterType.STRING - | ToolParameter.ToolParameterType.SECRET_INPUT - | ToolParameter.ToolParameterType.SELECT - ): - return "string" - - case ToolParameter.ToolParameterType.BOOLEAN: - return "boolean" - - case ToolParameter.ToolParameterType.NUMBER: - return "number" - - case _: - raise ValueError(f"Unsupported parameter type {parameter_type}") - - @staticmethod - def cast_parameter_by_type(value: Any, parameter_type: str) -> Any: - # convert tool parameter config to correct type - try: - match parameter_type: - case ( - ToolParameter.ToolParameterType.STRING - | ToolParameter.ToolParameterType.SECRET_INPUT - | ToolParameter.ToolParameterType.SELECT - ): - if value is None: - return "" - else: - return value if isinstance(value, str) else str(value) - - case ToolParameter.ToolParameterType.BOOLEAN: - if value is None: - return False - elif isinstance(value, str): - # Allowed YAML boolean value strings: https://yaml.org/type/bool.html - # and also '0' for False and '1' for True - match value.lower(): - case "true" | "yes" | "y" | "1": - return True - case "false" | "no" | "n" | "0": - return False - case _: - return bool(value) - else: - return value if isinstance(value, bool) else bool(value) - - case ToolParameter.ToolParameterType.NUMBER: - if isinstance(value, int) | isinstance(value, float): - return value - elif isinstance(value, str) and value != "": - if "." in value: - return float(value) - else: - return int(value) - case ToolParameter.ToolParameterType.FILE: - return value - case _: - return str(value) - - except Exception: - raise ValueError(f"The tool parameter value {value} is not in correct type of {parameter_type}.") diff --git a/api/core/app/segments/__init__.py b/api/core/variables/__init__.py similarity index 78% rename from api/core/app/segments/__init__.py rename to api/core/variables/__init__.py index 652ef243b4..87f9e3ed45 100644 --- a/api/core/app/segments/__init__.py +++ b/api/core/variables/__init__.py @@ -1,7 +1,12 @@ from .segment_group import SegmentGroup from .segments import ( ArrayAnySegment, + ArrayFileSegment, + ArrayNumberSegment, + ArrayObjectSegment, ArraySegment, + ArrayStringSegment, + FileSegment, FloatSegment, IntegerSegment, NoneSegment, @@ -15,6 +20,7 @@ from .variables import ( ArrayNumberVariable, ArrayObjectVariable, ArrayStringVariable, + FileVariable, FloatVariable, IntegerVariable, NoneVariable, @@ -46,4 +52,10 @@ __all__ = [ "ArrayNumberVariable", "ArrayObjectVariable", "ArraySegment", + "ArrayFileSegment", + "ArrayNumberSegment", + "ArrayObjectSegment", + "ArrayStringSegment", + "FileSegment", + "FileVariable", ] diff --git a/api/core/app/segments/exc.py b/api/core/variables/exc.py similarity index 100% rename from api/core/app/segments/exc.py rename to api/core/variables/exc.py diff --git a/api/core/app/segments/segment_group.py b/api/core/variables/segment_group.py similarity index 100% rename from api/core/app/segments/segment_group.py rename to api/core/variables/segment_group.py diff --git a/api/core/app/segments/segments.py b/api/core/variables/segments.py similarity index 77% rename from api/core/app/segments/segments.py rename to api/core/variables/segments.py index b26b3c8291..b71882b043 100644 --- a/api/core/app/segments/segments.py +++ b/api/core/variables/segments.py @@ -5,6 +5,8 @@ from typing import Any from pydantic import BaseModel, ConfigDict, field_validator +from core.file import File + from .types import SegmentType @@ -39,6 +41,9 @@ class Segment(BaseModel): @property def size(self) -> int: + """ + Return the size of the value in bytes. + """ return sys.getsizeof(self.value) def to_object(self) -> Any: @@ -51,15 +56,15 @@ class NoneSegment(Segment): @property def text(self) -> str: - return "null" + return "" @property def log(self) -> str: - return "null" + return "" @property def markdown(self) -> str: - return "null" + return "" class StringSegment(Segment): @@ -99,13 +104,27 @@ class ArraySegment(Segment): def markdown(self) -> str: items = [] for item in self.value: - if hasattr(item, "to_markdown"): - items.append(item.to_markdown()) - else: - items.append(str(item)) + items.append(str(item)) return "\n".join(items) +class FileSegment(Segment): + value_type: SegmentType = SegmentType.FILE + value: File + + @property + def markdown(self) -> str: + return self.value.markdown + + @property + def log(self) -> str: + return str(self.value) + + @property + def text(self) -> str: + return str(self.value) + + class ArrayAnySegment(ArraySegment): value_type: SegmentType = SegmentType.ARRAY_ANY value: Sequence[Any] @@ -124,3 +143,15 @@ class ArrayNumberSegment(ArraySegment): class ArrayObjectSegment(ArraySegment): value_type: SegmentType = SegmentType.ARRAY_OBJECT value: Sequence[Mapping[str, Any]] + + +class ArrayFileSegment(ArraySegment): + value_type: SegmentType = SegmentType.ARRAY_FILE + value: Sequence[File] + + @property + def markdown(self) -> str: + items = [] + for item in self.value: + items.append(item.markdown) + return "\n".join(items) diff --git a/api/core/app/segments/types.py b/api/core/variables/types.py similarity index 86% rename from api/core/app/segments/types.py rename to api/core/variables/types.py index 9cf0856df5..53c2e8a3aa 100644 --- a/api/core/app/segments/types.py +++ b/api/core/variables/types.py @@ -11,5 +11,7 @@ class SegmentType(str, Enum): ARRAY_NUMBER = "array[number]" ARRAY_OBJECT = "array[object]" OBJECT = "object" + FILE = "file" + ARRAY_FILE = "array[file]" GROUP = "group" diff --git a/api/core/app/segments/variables.py b/api/core/variables/variables.py similarity index 95% rename from api/core/app/segments/variables.py rename to api/core/variables/variables.py index f0e403ab8d..ddc6914192 100644 --- a/api/core/app/segments/variables.py +++ b/api/core/variables/variables.py @@ -7,6 +7,7 @@ from .segments import ( ArrayNumberSegment, ArrayObjectSegment, ArrayStringSegment, + FileSegment, FloatSegment, IntegerSegment, NoneSegment, @@ -73,3 +74,7 @@ class SecretVariable(StringVariable): class NoneVariable(NoneSegment, Variable): value_type: SegmentType = SegmentType.NONE value: None = None + + +class FileVariable(FileSegment, Variable): + pass diff --git a/api/core/app/apps/workflow_logging_callback.py b/api/core/workflow/callbacks/workflow_logging_callback.py similarity index 99% rename from api/core/app/apps/workflow_logging_callback.py rename to api/core/workflow/callbacks/workflow_logging_callback.py index 60683b0f21..17913de7b0 100644 --- a/api/core/app/apps/workflow_logging_callback.py +++ b/api/core/workflow/callbacks/workflow_logging_callback.py @@ -1,7 +1,6 @@ from typing import Optional from core.model_runtime.utils.encoders import jsonable_encoder -from core.workflow.callbacks.base_workflow_callback import WorkflowCallback from core.workflow.graph_engine.entities.event import ( GraphEngineEvent, GraphRunFailedEvent, @@ -20,6 +19,8 @@ from core.workflow.graph_engine.entities.event import ( ParallelBranchRunSucceededEvent, ) +from .base_workflow_callback import WorkflowCallback + _TEXT_COLOR_MAPPING = { "blue": "36;1", "yellow": "33;1", diff --git a/api/core/workflow/constants.py b/api/core/workflow/constants.py new file mode 100644 index 0000000000..e3fe17c284 --- /dev/null +++ b/api/core/workflow/constants.py @@ -0,0 +1,3 @@ +SYSTEM_VARIABLE_NODE_ID = "sys" +ENVIRONMENT_VARIABLE_NODE_ID = "env" +CONVERSATION_VARIABLE_NODE_ID = "conversation" diff --git a/api/core/workflow/nodes/base/__init__.py b/api/core/workflow/nodes/base/__init__.py new file mode 100644 index 0000000000..61f727740c --- /dev/null +++ b/api/core/workflow/nodes/base/__init__.py @@ -0,0 +1,4 @@ +from .entities import BaseIterationNodeData, BaseIterationState, BaseNodeData +from .node import BaseNode + +__all__ = ["BaseNode", "BaseNodeData", "BaseIterationNodeData", "BaseIterationState"] diff --git a/api/core/workflow/entities/base_node_data_entities.py b/api/core/workflow/nodes/base/entities.py similarity index 100% rename from api/core/workflow/entities/base_node_data_entities.py rename to api/core/workflow/nodes/base/entities.py diff --git a/api/core/workflow/nodes/base_node.py b/api/core/workflow/nodes/base/node.py similarity index 60% rename from api/core/workflow/nodes/base_node.py rename to api/core/workflow/nodes/base/node.py index 7bfe45a13c..053a339ba7 100644 --- a/api/core/workflow/nodes/base_node.py +++ b/api/core/workflow/nodes/base/node.py @@ -1,17 +1,27 @@ -from abc import ABC, abstractmethod +import logging +from abc import abstractmethod from collections.abc import Generator, Mapping, Sequence -from typing import Any, Optional +from typing import TYPE_CHECKING, Any, Generic, Optional, TypeVar, Union, cast -from core.workflow.entities.base_node_data_entities import BaseNodeData -from core.workflow.entities.node_entities import NodeRunResult, NodeType -from core.workflow.graph_engine.entities.event import InNodeEvent -from core.workflow.graph_engine.entities.graph import Graph -from core.workflow.graph_engine.entities.graph_init_params import GraphInitParams -from core.workflow.graph_engine.entities.graph_runtime_state import GraphRuntimeState -from core.workflow.nodes.event import RunCompletedEvent, RunEvent +from core.workflow.entities.node_entities import NodeRunResult +from core.workflow.nodes.enums import NodeType +from core.workflow.nodes.event import NodeEvent, RunCompletedEvent +from models.workflow import WorkflowNodeExecutionStatus + +from .entities import BaseNodeData + +if TYPE_CHECKING: + from core.workflow.graph_engine.entities.event import InNodeEvent + from core.workflow.graph_engine.entities.graph import Graph + from core.workflow.graph_engine.entities.graph_init_params import GraphInitParams + from core.workflow.graph_engine.entities.graph_runtime_state import GraphRuntimeState + +logger = logging.getLogger(__name__) + +GenericNodeData = TypeVar("GenericNodeData", bound=BaseNodeData) -class BaseNode(ABC): +class BaseNode(Generic[GenericNodeData]): _node_data_cls: type[BaseNodeData] _node_type: NodeType @@ -19,9 +29,9 @@ class BaseNode(ABC): self, id: str, config: Mapping[str, Any], - graph_init_params: GraphInitParams, - graph: Graph, - graph_runtime_state: GraphRuntimeState, + graph_init_params: "GraphInitParams", + graph: "Graph", + graph_runtime_state: "GraphRuntimeState", previous_node_id: Optional[str] = None, thread_pool_id: Optional[str] = None, ) -> None: @@ -45,22 +55,25 @@ class BaseNode(ABC): raise ValueError("Node ID is required.") self.node_id = node_id - self.node_data = self._node_data_cls(**config.get("data", {})) + self.node_data: GenericNodeData = cast(GenericNodeData, self._node_data_cls(**config.get("data", {}))) @abstractmethod - def _run(self) -> NodeRunResult | Generator[RunEvent | InNodeEvent, None, None]: + def _run(self) -> NodeRunResult | Generator[Union[NodeEvent, "InNodeEvent"], None, None]: """ Run node :return: """ raise NotImplementedError - def run(self) -> Generator[RunEvent | InNodeEvent, None, None]: - """ - Run node entry - :return: - """ - result = self._run() + def run(self) -> Generator[Union[NodeEvent, "InNodeEvent"], None, None]: + try: + result = self._run() + except Exception as e: + logger.error(f"Node {self.node_id} failed to run: {e}") + result = NodeRunResult( + status=WorkflowNodeExecutionStatus.FAILED, + error=str(e), + ) if isinstance(result, NodeRunResult): yield RunCompletedEvent(run_result=result) @@ -69,7 +82,10 @@ class BaseNode(ABC): @classmethod def extract_variable_selector_to_variable_mapping( - cls, graph_config: Mapping[str, Any], config: dict + cls, + *, + graph_config: Mapping[str, Any], + config: Mapping[str, Any], ) -> Mapping[str, Sequence[str]]: """ Extract variable selector to variable mapping @@ -83,12 +99,16 @@ class BaseNode(ABC): node_data = cls._node_data_cls(**config.get("data", {})) return cls._extract_variable_selector_to_variable_mapping( - graph_config=graph_config, node_id=node_id, node_data=node_data + graph_config=graph_config, node_id=node_id, node_data=cast(GenericNodeData, node_data) ) @classmethod def _extract_variable_selector_to_variable_mapping( - cls, graph_config: Mapping[str, Any], node_id: str, node_data: BaseNodeData + cls, + *, + graph_config: Mapping[str, Any], + node_id: str, + node_data: GenericNodeData, ) -> Mapping[str, Sequence[str]]: """ Extract variable selector to variable mapping diff --git a/api/core/workflow/nodes/document_extractor/__init__.py b/api/core/workflow/nodes/document_extractor/__init__.py new file mode 100644 index 0000000000..3cc5fae187 --- /dev/null +++ b/api/core/workflow/nodes/document_extractor/__init__.py @@ -0,0 +1,4 @@ +from .entities import DocumentExtractorNodeData +from .node import DocumentExtractorNode + +__all__ = ["DocumentExtractorNode", "DocumentExtractorNodeData"] diff --git a/api/core/workflow/nodes/document_extractor/entities.py b/api/core/workflow/nodes/document_extractor/entities.py new file mode 100644 index 0000000000..7e9ffaa889 --- /dev/null +++ b/api/core/workflow/nodes/document_extractor/entities.py @@ -0,0 +1,7 @@ +from collections.abc import Sequence + +from core.workflow.nodes.base import BaseNodeData + + +class DocumentExtractorNodeData(BaseNodeData): + variable_selector: Sequence[str] diff --git a/api/core/workflow/nodes/document_extractor/exc.py b/api/core/workflow/nodes/document_extractor/exc.py new file mode 100644 index 0000000000..c9d4bb8ef6 --- /dev/null +++ b/api/core/workflow/nodes/document_extractor/exc.py @@ -0,0 +1,14 @@ +class DocumentExtractorError(Exception): + """Base exception for errors related to the DocumentExtractorNode.""" + + +class FileDownloadError(DocumentExtractorError): + """Exception raised when there's an error downloading a file.""" + + +class UnsupportedFileTypeError(DocumentExtractorError): + """Exception raised when trying to extract text from an unsupported file type.""" + + +class TextExtractionError(DocumentExtractorError): + """Exception raised when there's an error during text extraction from a file.""" diff --git a/api/core/workflow/nodes/document_extractor/node.py b/api/core/workflow/nodes/document_extractor/node.py new file mode 100644 index 0000000000..b4ffee1f13 --- /dev/null +++ b/api/core/workflow/nodes/document_extractor/node.py @@ -0,0 +1,274 @@ +import csv +import io + +import docx +import pandas as pd +import pypdfium2 +from unstructured.partition.email import partition_email +from unstructured.partition.epub import partition_epub +from unstructured.partition.msg import partition_msg +from unstructured.partition.ppt import partition_ppt +from unstructured.partition.pptx import partition_pptx + +from core.file import File, FileTransferMethod, file_manager +from core.helper import ssrf_proxy +from core.variables import ArrayFileSegment +from core.variables.segments import FileSegment +from core.workflow.entities.node_entities import NodeRunResult +from core.workflow.nodes.base import BaseNode +from core.workflow.nodes.enums import NodeType +from models.workflow import WorkflowNodeExecutionStatus + +from .entities import DocumentExtractorNodeData +from .exc import DocumentExtractorError, FileDownloadError, TextExtractionError, UnsupportedFileTypeError + + +class DocumentExtractorNode(BaseNode[DocumentExtractorNodeData]): + """ + Extracts text content from various file types. + Supports plain text, PDF, and DOC/DOCX files. + """ + + _node_data_cls = DocumentExtractorNodeData + _node_type = NodeType.DOCUMENT_EXTRACTOR + + def _run(self): + variable_selector = self.node_data.variable_selector + variable = self.graph_runtime_state.variable_pool.get(variable_selector) + + if variable is None: + error_message = f"File variable not found for selector: {variable_selector}" + return NodeRunResult(status=WorkflowNodeExecutionStatus.FAILED, error=error_message) + if variable.value and not isinstance(variable, ArrayFileSegment | FileSegment): + error_message = f"Variable {variable_selector} is not an ArrayFileSegment" + return NodeRunResult(status=WorkflowNodeExecutionStatus.FAILED, error=error_message) + + value = variable.value + inputs = {"variable_selector": variable_selector} + process_data = {"documents": value if isinstance(value, list) else [value]} + + try: + if isinstance(value, list): + extracted_text_list = list(map(_extract_text_from_file, value)) + return NodeRunResult( + status=WorkflowNodeExecutionStatus.SUCCEEDED, + inputs=inputs, + process_data=process_data, + outputs={"text": extracted_text_list}, + ) + elif isinstance(value, File): + extracted_text = _extract_text_from_file(value) + return NodeRunResult( + status=WorkflowNodeExecutionStatus.SUCCEEDED, + inputs=inputs, + process_data=process_data, + outputs={"text": extracted_text}, + ) + else: + raise DocumentExtractorError(f"Unsupported variable type: {type(value)}") + except DocumentExtractorError as e: + return NodeRunResult( + status=WorkflowNodeExecutionStatus.FAILED, + error=str(e), + inputs=inputs, + process_data=process_data, + ) + + +def _extract_text_by_mime_type(*, file_content: bytes, mime_type: str) -> str: + """Extract text from a file based on its MIME type.""" + if mime_type.startswith("text/plain") or mime_type in {"text/html", "text/htm", "text/markdown", "text/xml"}: + return _extract_text_from_plain_text(file_content) + elif mime_type == "application/pdf": + return _extract_text_from_pdf(file_content) + elif mime_type in { + "application/vnd.openxmlformats-officedocument.wordprocessingml.document", + "application/msword", + }: + return _extract_text_from_doc(file_content) + elif mime_type == "text/csv": + return _extract_text_from_csv(file_content) + elif mime_type in { + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + "application/vnd.ms-excel", + }: + return _extract_text_from_excel(file_content) + elif mime_type == "application/vnd.ms-powerpoint": + return _extract_text_from_ppt(file_content) + elif mime_type == "application/vnd.openxmlformats-officedocument.presentationml.presentation": + return _extract_text_from_pptx(file_content) + elif mime_type == "application/epub+zip": + return _extract_text_from_epub(file_content) + elif mime_type == "message/rfc822": + return _extract_text_from_eml(file_content) + elif mime_type == "application/vnd.ms-outlook": + return _extract_text_from_msg(file_content) + else: + raise UnsupportedFileTypeError(f"Unsupported MIME type: {mime_type}") + + +def _extract_text_by_file_extension(*, file_content: bytes, file_extension: str) -> str: + """Extract text from a file based on its file extension.""" + match file_extension: + case ".txt" | ".markdown" | ".md" | ".html" | ".htm" | ".xml": + return _extract_text_from_plain_text(file_content) + case ".pdf": + return _extract_text_from_pdf(file_content) + case ".doc" | ".docx": + return _extract_text_from_doc(file_content) + case ".csv": + return _extract_text_from_csv(file_content) + case ".xls" | ".xlsx": + return _extract_text_from_excel(file_content) + case ".ppt": + return _extract_text_from_ppt(file_content) + case ".pptx": + return _extract_text_from_pptx(file_content) + case ".epub": + return _extract_text_from_epub(file_content) + case ".eml": + return _extract_text_from_eml(file_content) + case ".msg": + return _extract_text_from_msg(file_content) + case _: + raise UnsupportedFileTypeError(f"Unsupported Extension Type: {file_extension}") + + +def _extract_text_from_plain_text(file_content: bytes) -> str: + try: + return file_content.decode("utf-8") + except UnicodeDecodeError as e: + raise TextExtractionError("Failed to decode plain text file") from e + + +def _extract_text_from_pdf(file_content: bytes) -> str: + try: + pdf_file = io.BytesIO(file_content) + pdf_document = pypdfium2.PdfDocument(pdf_file, autoclose=True) + text = "" + for page in pdf_document: + text_page = page.get_textpage() + text += text_page.get_text_range() + text_page.close() + page.close() + return text + except Exception as e: + raise TextExtractionError(f"Failed to extract text from PDF: {str(e)}") from e + + +def _extract_text_from_doc(file_content: bytes) -> str: + try: + doc_file = io.BytesIO(file_content) + doc = docx.Document(doc_file) + return "\n".join([paragraph.text for paragraph in doc.paragraphs]) + except Exception as e: + raise TextExtractionError(f"Failed to extract text from DOC/DOCX: {str(e)}") from e + + +def _download_file_content(file: File) -> bytes: + """Download the content of a file based on its transfer method.""" + try: + if file.transfer_method == FileTransferMethod.REMOTE_URL: + if file.remote_url is None: + raise FileDownloadError("Missing URL for remote file") + response = ssrf_proxy.get(file.remote_url) + response.raise_for_status() + return response.content + elif file.transfer_method == FileTransferMethod.LOCAL_FILE: + return file_manager.download(file) + else: + raise ValueError(f"Unsupported transfer method: {file.transfer_method}") + except Exception as e: + raise FileDownloadError(f"Error downloading file: {str(e)}") from e + + +def _extract_text_from_file(file: File): + if file.mime_type is None: + raise UnsupportedFileTypeError("Unable to determine file type: MIME type is missing") + file_content = _download_file_content(file) + if file.transfer_method == FileTransferMethod.REMOTE_URL: + extracted_text = _extract_text_by_mime_type(file_content=file_content, mime_type=file.mime_type) + else: + extracted_text = _extract_text_by_file_extension(file_content=file_content, file_extension=file.extension) + return extracted_text + + +def _extract_text_from_csv(file_content: bytes) -> str: + try: + csv_file = io.StringIO(file_content.decode("utf-8")) + csv_reader = csv.reader(csv_file) + rows = list(csv_reader) + + if not rows: + return "" + + # Create Markdown table + markdown_table = "| " + " | ".join(rows[0]) + " |\n" + markdown_table += "| " + " | ".join(["---"] * len(rows[0])) + " |\n" + for row in rows[1:]: + markdown_table += "| " + " | ".join(row) + " |\n" + + return markdown_table.strip() + except Exception as e: + raise TextExtractionError(f"Failed to extract text from CSV: {str(e)}") from e + + +def _extract_text_from_excel(file_content: bytes) -> str: + """Extract text from an Excel file using pandas.""" + + try: + df = pd.read_excel(io.BytesIO(file_content)) + + # Drop rows where all elements are NaN + df.dropna(how="all", inplace=True) + + # Convert DataFrame to Markdown table + markdown_table = df.to_markdown(index=False) + return markdown_table + except Exception as e: + raise TextExtractionError(f"Failed to extract text from Excel file: {str(e)}") from e + + +def _extract_text_from_ppt(file_content: bytes) -> str: + try: + with io.BytesIO(file_content) as file: + elements = partition_ppt(file=file) + return "\n".join([getattr(element, "text", "") for element in elements]) + except Exception as e: + raise TextExtractionError(f"Failed to extract text from PPT: {str(e)}") from e + + +def _extract_text_from_pptx(file_content: bytes) -> str: + try: + with io.BytesIO(file_content) as file: + elements = partition_pptx(file=file) + return "\n".join([getattr(element, "text", "") for element in elements]) + except Exception as e: + raise TextExtractionError(f"Failed to extract text from PPTX: {str(e)}") from e + + +def _extract_text_from_epub(file_content: bytes) -> str: + try: + with io.BytesIO(file_content) as file: + elements = partition_epub(file=file) + return "\n".join([str(element) for element in elements]) + except Exception as e: + raise TextExtractionError(f"Failed to extract text from EPUB: {str(e)}") from e + + +def _extract_text_from_eml(file_content: bytes) -> str: + try: + with io.BytesIO(file_content) as file: + elements = partition_email(file=file) + return "\n".join([str(element) for element in elements]) + except Exception as e: + raise TextExtractionError(f"Failed to extract text from EML: {str(e)}") from e + + +def _extract_text_from_msg(file_content: bytes) -> str: + try: + with io.BytesIO(file_content) as file: + elements = partition_msg(file=file) + return "\n".join([str(element) for element in elements]) + except Exception as e: + raise TextExtractionError(f"Failed to extract text from MSG: {str(e)}") from e diff --git a/api/core/workflow/nodes/enums.py b/api/core/workflow/nodes/enums.py new file mode 100644 index 0000000000..208144655b --- /dev/null +++ b/api/core/workflow/nodes/enums.py @@ -0,0 +1,24 @@ +from enum import Enum + + +class NodeType(str, Enum): + START = "start" + END = "end" + ANSWER = "answer" + LLM = "llm" + KNOWLEDGE_RETRIEVAL = "knowledge-retrieval" + IF_ELSE = "if-else" + CODE = "code" + TEMPLATE_TRANSFORM = "template-transform" + QUESTION_CLASSIFIER = "question-classifier" + HTTP_REQUEST = "http-request" + TOOL = "tool" + VARIABLE_AGGREGATOR = "variable-aggregator" + VARIABLE_ASSIGNER = "variable-assigner" # TODO: Merge this into VARIABLE_AGGREGATOR in the database. + LOOP = "loop" + ITERATION = "iteration" + ITERATION_START = "iteration-start" # Fake start node for iteration. + PARAMETER_EXTRACTOR = "parameter-extractor" + CONVERSATION_VARIABLE_ASSIGNER = "assigner" + DOCUMENT_EXTRACTOR = "document-extractor" + LIST_OPERATOR = "list-operator" diff --git a/api/core/workflow/nodes/event/__init__.py b/api/core/workflow/nodes/event/__init__.py new file mode 100644 index 0000000000..581def9553 --- /dev/null +++ b/api/core/workflow/nodes/event/__init__.py @@ -0,0 +1,10 @@ +from .event import ModelInvokeCompletedEvent, RunCompletedEvent, RunRetrieverResourceEvent, RunStreamChunkEvent +from .types import NodeEvent + +__all__ = [ + "RunCompletedEvent", + "RunRetrieverResourceEvent", + "RunStreamChunkEvent", + "NodeEvent", + "ModelInvokeCompletedEvent", +] diff --git a/api/core/workflow/nodes/event.py b/api/core/workflow/nodes/event/event.py similarity index 72% rename from api/core/workflow/nodes/event.py rename to api/core/workflow/nodes/event/event.py index 276c13a6d4..b7034561bf 100644 --- a/api/core/workflow/nodes/event.py +++ b/api/core/workflow/nodes/event/event.py @@ -1,5 +1,6 @@ from pydantic import BaseModel, Field +from core.model_runtime.entities.llm_entities import LLMUsage from core.workflow.entities.node_entities import NodeRunResult @@ -17,4 +18,11 @@ class RunRetrieverResourceEvent(BaseModel): context: str = Field(..., description="context") -RunEvent = RunCompletedEvent | RunStreamChunkEvent | RunRetrieverResourceEvent +class ModelInvokeCompletedEvent(BaseModel): + """ + Model invoke completed + """ + + text: str + usage: LLMUsage + finish_reason: str | None = None diff --git a/api/core/workflow/nodes/event/types.py b/api/core/workflow/nodes/event/types.py new file mode 100644 index 0000000000..b19a91022d --- /dev/null +++ b/api/core/workflow/nodes/event/types.py @@ -0,0 +1,3 @@ +from .event import ModelInvokeCompletedEvent, RunCompletedEvent, RunRetrieverResourceEvent, RunStreamChunkEvent + +NodeEvent = RunCompletedEvent | RunStreamChunkEvent | RunRetrieverResourceEvent | ModelInvokeCompletedEvent diff --git a/api/core/workflow/nodes/http_request/executor.py b/api/core/workflow/nodes/http_request/executor.py new file mode 100644 index 0000000000..0270d7e0fd --- /dev/null +++ b/api/core/workflow/nodes/http_request/executor.py @@ -0,0 +1,321 @@ +import json +from collections.abc import Mapping +from copy import deepcopy +from random import randint +from typing import Any, Literal +from urllib.parse import urlencode, urlparse + +import httpx + +from configs import dify_config +from core.file import file_manager +from core.helper import ssrf_proxy +from core.workflow.entities.variable_pool import VariablePool + +from .entities import ( + HttpRequestNodeAuthorization, + HttpRequestNodeData, + HttpRequestNodeTimeout, + Response, +) + +BODY_TYPE_TO_CONTENT_TYPE = { + "json": "application/json", + "x-www-form-urlencoded": "application/x-www-form-urlencoded", + "form-data": "multipart/form-data", + "raw-text": "text/plain", +} + + +class Executor: + method: Literal["get", "head", "post", "put", "delete", "patch"] + url: str + params: Mapping[str, str] | None + content: str | bytes | None + data: Mapping[str, Any] | None + files: Mapping[str, bytes] | None + json: Any + headers: dict[str, str] + auth: HttpRequestNodeAuthorization + timeout: HttpRequestNodeTimeout + + boundary: str + + def __init__( + self, + *, + node_data: HttpRequestNodeData, + timeout: HttpRequestNodeTimeout, + variable_pool: VariablePool, + ): + # If authorization API key is present, convert the API key using the variable pool + if node_data.authorization.type == "api-key": + if node_data.authorization.config is None: + raise ValueError("authorization config is required") + node_data.authorization.config.api_key = variable_pool.convert_template( + node_data.authorization.config.api_key + ).text + + self.url: str = node_data.url + self.method = node_data.method + self.auth = node_data.authorization + self.timeout = timeout + self.params = {} + self.headers = {} + self.content = None + self.files = None + self.data = None + self.json = None + + # init template + self.variable_pool = variable_pool + self.node_data = node_data + self._initialize() + + def _initialize(self): + self._init_url() + self._init_params() + self._init_headers() + self._init_body() + + def _init_url(self): + self.url = self.variable_pool.convert_template(self.node_data.url).text + + def _init_params(self): + params = self.variable_pool.convert_template(self.node_data.params).text + self.params = _plain_text_to_dict(params) + + def _init_headers(self): + headers = self.variable_pool.convert_template(self.node_data.headers).text + self.headers = _plain_text_to_dict(headers) + + body = self.node_data.body + if body is None: + return + if "content-type" not in (k.lower() for k in self.headers) and body.type in BODY_TYPE_TO_CONTENT_TYPE: + self.headers["Content-Type"] = BODY_TYPE_TO_CONTENT_TYPE[body.type] + if body.type == "form-data": + self.boundary = f"----WebKitFormBoundary{_generate_random_string(16)}" + self.headers["Content-Type"] = f"multipart/form-data; boundary={self.boundary}" + + def _init_body(self): + body = self.node_data.body + if body is not None: + data = body.data + match body.type: + case "none": + self.content = "" + case "raw-text": + self.content = self.variable_pool.convert_template(data[0].value).text + case "json": + json_string = self.variable_pool.convert_template(data[0].value).text + json_object = json.loads(json_string) + self.json = json_object + # self.json = self._parse_object_contains_variables(json_object) + case "binary": + file_selector = data[0].file + file_variable = self.variable_pool.get_file(file_selector) + if file_variable is None: + raise ValueError(f"cannot fetch file with selector {file_selector}") + file = file_variable.value + self.content = file_manager.download(file) + case "x-www-form-urlencoded": + form_data = { + self.variable_pool.convert_template(item.key).text: self.variable_pool.convert_template( + item.value + ).text + for item in data + } + self.data = form_data + case "form-data": + form_data = { + self.variable_pool.convert_template(item.key).text: self.variable_pool.convert_template( + item.value + ).text + for item in filter(lambda item: item.type == "text", data) + } + file_selectors = { + self.variable_pool.convert_template(item.key).text: item.file + for item in filter(lambda item: item.type == "file", data) + } + files = {k: self.variable_pool.get_file(selector) for k, selector in file_selectors.items()} + files = {k: v for k, v in files.items() if v is not None} + files = {k: variable.value for k, variable in files.items()} + files = {k: file_manager.download(v) for k, v in files.items() if v.related_id is not None} + + self.data = form_data + self.files = files + + def _assembling_headers(self) -> dict[str, Any]: + authorization = deepcopy(self.auth) + headers = deepcopy(self.headers) or {} + if self.auth.type == "api-key": + if self.auth.config is None: + raise ValueError("self.authorization config is required") + if authorization.config is None: + raise ValueError("authorization config is required") + + if self.auth.config.api_key is None: + raise ValueError("api_key is required") + + if not authorization.config.header: + authorization.config.header = "Authorization" + + if self.auth.config.type == "bearer": + headers[authorization.config.header] = f"Bearer {authorization.config.api_key}" + elif self.auth.config.type == "basic": + headers[authorization.config.header] = f"Basic {authorization.config.api_key}" + elif self.auth.config.type == "custom": + headers[authorization.config.header] = authorization.config.api_key or "" + + return headers + + def _validate_and_parse_response(self, response: httpx.Response) -> Response: + executor_response = Response(response) + + threshold_size = ( + dify_config.HTTP_REQUEST_NODE_MAX_BINARY_SIZE + if executor_response.is_file + else dify_config.HTTP_REQUEST_NODE_MAX_TEXT_SIZE + ) + if executor_response.size > threshold_size: + raise ValueError( + f'{"File" if executor_response.is_file else "Text"} size is too large,' + f' max size is {threshold_size / 1024 / 1024:.2f} MB,' + f' but current size is {executor_response.readable_size}.' + ) + + return executor_response + + def _do_http_request(self, headers: dict[str, Any]) -> httpx.Response: + """ + do http request depending on api bundle + """ + if self.method not in {"get", "head", "post", "put", "delete", "patch"}: + raise ValueError(f"Invalid http method {self.method}") + + request_args = { + "url": self.url, + "data": self.data, + "files": self.files, + "json": self.json, + "content": self.content, + "headers": headers, + "params": self.params, + "timeout": (self.timeout.connect, self.timeout.read, self.timeout.write), + "follow_redirects": True, + } + + response = getattr(ssrf_proxy, self.method)(**request_args) + return response + + def invoke(self) -> Response: + # assemble headers + headers = self._assembling_headers() + # do http request + response = self._do_http_request(headers) + # validate response + return self._validate_and_parse_response(response) + + def to_log(self): + url_parts = urlparse(self.url) + path = url_parts.path or "/" + + # Add query parameters + if self.params: + query_string = urlencode(self.params) + path += f"?{query_string}" + elif url_parts.query: + path += f"?{url_parts.query}" + + raw = f"{self.method.upper()} {path} HTTP/1.1\r\n" + raw += f"Host: {url_parts.netloc}\r\n" + + headers = self._assembling_headers() + for k, v in headers.items(): + if self.auth.type == "api-key": + authorization_header = "Authorization" + if self.auth.config and self.auth.config.header: + authorization_header = self.auth.config.header + if k.lower() == authorization_header.lower(): + raw += f'{k}: {"*" * len(v)}\r\n' + continue + raw += f"{k}: {v}\r\n" + + body = "" + if self.files: + boundary = self.boundary + for k, v in self.files.items(): + body += f"--{boundary}\r\n" + body += f'Content-Disposition: form-data; name="{k}"\r\n\r\n' + body += f"{v[1]}\r\n" + body += f"--{boundary}--\r\n" + elif self.node_data.body: + if self.content: + if isinstance(self.content, str): + body = self.content + elif isinstance(self.content, bytes): + body = self.content.decode("utf-8", errors="replace") + elif self.data and self.node_data.body.type == "x-www-form-urlencoded": + body = urlencode(self.data) + elif self.data and self.node_data.body.type == "form-data": + boundary = self.boundary + for key, value in self.data.items(): + body += f"--{boundary}\r\n" + body += f'Content-Disposition: form-data; name="{key}"\r\n\r\n' + body += f"{value}\r\n" + body += f"--{boundary}--\r\n" + elif self.json: + body = json.dumps(self.json) + elif self.node_data.body.type == "raw-text": + body = self.node_data.body.data[0].value + if body: + raw += f"Content-Length: {len(body)}\r\n" + raw += "\r\n" # Empty line between headers and body + raw += body + + return raw + + +def _plain_text_to_dict(text: str, /) -> dict[str, str]: + """ + Convert a string of key-value pairs to a dictionary. + + Each line in the input string represents a key-value pair. + Keys and values are separated by ':'. + Empty values are allowed. + + Examples: + 'aa:bb\n cc:dd' -> {'aa': 'bb', 'cc': 'dd'} + 'aa:\n cc:dd\n' -> {'aa': '', 'cc': 'dd'} + 'aa\n cc : dd' -> {'aa': '', 'cc': 'dd'} + + Args: + convert_text (str): The input string to convert. + + Returns: + dict[str, str]: A dictionary of key-value pairs. + """ + return { + key.strip(): (value[0].strip() if value else "") + for line in text.splitlines() + if line.strip() + for key, *value in [line.split(":", 1)] + } + + +def _generate_random_string(n: int) -> str: + """ + Generate a random string of lowercase ASCII letters. + + Args: + n (int): The length of the random string to generate. + + Returns: + str: A random string of lowercase ASCII letters with length n. + + Example: + >>> _generate_random_string(5) + 'abcde' + """ + return "".join([chr(randint(97, 122)) for _ in range(n)]) diff --git a/api/core/workflow/nodes/http_request/http_executor.py b/api/core/workflow/nodes/http_request/http_executor.py deleted file mode 100644 index f8ab4e3132..0000000000 --- a/api/core/workflow/nodes/http_request/http_executor.py +++ /dev/null @@ -1,343 +0,0 @@ -import json -from copy import deepcopy -from random import randint -from typing import Any, Optional, Union -from urllib.parse import urlencode - -import httpx - -from configs import dify_config -from core.helper import ssrf_proxy -from core.workflow.entities.variable_entities import VariableSelector -from core.workflow.entities.variable_pool import VariablePool -from core.workflow.nodes.http_request.entities import ( - HttpRequestNodeAuthorization, - HttpRequestNodeBody, - HttpRequestNodeData, - HttpRequestNodeTimeout, -) -from core.workflow.utils.variable_template_parser import VariableTemplateParser - - -class HttpExecutorResponse: - headers: dict[str, str] - response: httpx.Response - - def __init__(self, response: httpx.Response): - self.response = response - self.headers = dict(response.headers) if isinstance(self.response, httpx.Response) else {} - - @property - def is_file(self) -> bool: - """ - check if response is file - """ - content_type = self.get_content_type() - file_content_types = ["image", "audio", "video"] - - return any(v in content_type for v in file_content_types) - - def get_content_type(self) -> str: - return self.headers.get("content-type", "") - - def extract_file(self) -> tuple[str, bytes]: - """ - extract file from response if content type is file related - """ - if self.is_file: - return self.get_content_type(), self.body - - return "", b"" - - @property - def content(self) -> str: - if isinstance(self.response, httpx.Response): - return self.response.text - else: - raise ValueError(f"Invalid response type {type(self.response)}") - - @property - def body(self) -> bytes: - if isinstance(self.response, httpx.Response): - return self.response.content - else: - raise ValueError(f"Invalid response type {type(self.response)}") - - @property - def status_code(self) -> int: - if isinstance(self.response, httpx.Response): - return self.response.status_code - else: - raise ValueError(f"Invalid response type {type(self.response)}") - - @property - def size(self) -> int: - return len(self.body) - - @property - def readable_size(self) -> str: - if self.size < 1024: - return f"{self.size} bytes" - elif self.size < 1024 * 1024: - return f"{(self.size / 1024):.2f} KB" - else: - return f"{(self.size / 1024 / 1024):.2f} MB" - - -class HttpExecutor: - server_url: str - method: str - authorization: HttpRequestNodeAuthorization - params: dict[str, Any] - headers: dict[str, Any] - body: Union[None, str] - files: Union[None, dict[str, Any]] - boundary: str - variable_selectors: list[VariableSelector] - timeout: HttpRequestNodeTimeout - - def __init__( - self, - node_data: HttpRequestNodeData, - timeout: HttpRequestNodeTimeout, - variable_pool: Optional[VariablePool] = None, - ): - self.server_url = node_data.url - self.method = node_data.method - self.authorization = node_data.authorization - self.timeout = timeout - self.params = {} - self.headers = {} - self.body = None - self.files = None - - # init template - self.variable_selectors = [] - self._init_template(node_data, variable_pool) - - @staticmethod - def _is_json_body(body: HttpRequestNodeBody): - """ - check if body is json - """ - if body and body.type == "json" and body.data: - try: - json.loads(body.data) - return True - except: - return False - - return False - - @staticmethod - def _to_dict(convert_text: str): - """ - Convert the string like `aa:bb\n cc:dd` to dict `{aa:bb, cc:dd}` - """ - kv_paris = convert_text.split("\n") - result = {} - for kv in kv_paris: - if not kv.strip(): - continue - - kv = kv.split(":", maxsplit=1) - if len(kv) == 1: - k, v = kv[0], "" - else: - k, v = kv - result[k.strip()] = v - return result - - def _init_template(self, node_data: HttpRequestNodeData, variable_pool: Optional[VariablePool] = None): - # extract all template in url - self.server_url, server_url_variable_selectors = self._format_template(node_data.url, variable_pool) - - # extract all template in params - params, params_variable_selectors = self._format_template(node_data.params, variable_pool) - self.params = self._to_dict(params) - - # extract all template in headers - headers, headers_variable_selectors = self._format_template(node_data.headers, variable_pool) - self.headers = self._to_dict(headers) - - # extract all template in body - body_data_variable_selectors = [] - if node_data.body: - # check if it's a valid JSON - is_valid_json = self._is_json_body(node_data.body) - - body_data = node_data.body.data or "" - if body_data: - body_data, body_data_variable_selectors = self._format_template(body_data, variable_pool, is_valid_json) - - content_type_is_set = any(key.lower() == "content-type" for key in self.headers) - if node_data.body.type == "json" and not content_type_is_set: - self.headers["Content-Type"] = "application/json" - elif node_data.body.type == "x-www-form-urlencoded" and not content_type_is_set: - self.headers["Content-Type"] = "application/x-www-form-urlencoded" - - if node_data.body.type in {"form-data", "x-www-form-urlencoded"}: - body = self._to_dict(body_data) - - if node_data.body.type == "form-data": - self.files = {k: ("", v) for k, v in body.items()} - random_str = lambda n: "".join([chr(randint(97, 122)) for _ in range(n)]) - self.boundary = f"----WebKitFormBoundary{random_str(16)}" - - self.headers["Content-Type"] = f"multipart/form-data; boundary={self.boundary}" - else: - self.body = urlencode(body) - elif node_data.body.type in {"json", "raw-text"}: - self.body = body_data - elif node_data.body.type == "none": - self.body = "" - - self.variable_selectors = ( - server_url_variable_selectors - + params_variable_selectors - + headers_variable_selectors - + body_data_variable_selectors - ) - - def _assembling_headers(self) -> dict[str, Any]: - authorization = deepcopy(self.authorization) - headers = deepcopy(self.headers) or {} - if self.authorization.type == "api-key": - if self.authorization.config is None: - raise ValueError("self.authorization config is required") - if authorization.config is None: - raise ValueError("authorization config is required") - - if self.authorization.config.api_key is None: - raise ValueError("api_key is required") - - if not authorization.config.header: - authorization.config.header = "Authorization" - - if self.authorization.config.type == "bearer": - headers[authorization.config.header] = f"Bearer {authorization.config.api_key}" - elif self.authorization.config.type == "basic": - headers[authorization.config.header] = f"Basic {authorization.config.api_key}" - elif self.authorization.config.type == "custom": - headers[authorization.config.header] = authorization.config.api_key - - return headers - - def _validate_and_parse_response(self, response: httpx.Response) -> HttpExecutorResponse: - """ - validate the response - """ - if isinstance(response, httpx.Response): - executor_response = HttpExecutorResponse(response) - else: - raise ValueError(f"Invalid response type {type(response)}") - - threshold_size = ( - dify_config.HTTP_REQUEST_NODE_MAX_BINARY_SIZE - if executor_response.is_file - else dify_config.HTTP_REQUEST_NODE_MAX_TEXT_SIZE - ) - if executor_response.size > threshold_size: - raise ValueError( - f'{"File" if executor_response.is_file else "Text"} size is too large,' - f' max size is {threshold_size / 1024 / 1024:.2f} MB,' - f' but current size is {executor_response.readable_size}.' - ) - - return executor_response - - def _do_http_request(self, headers: dict[str, Any]) -> httpx.Response: - """ - do http request depending on api bundle - """ - kwargs = { - "url": self.server_url, - "headers": headers, - "params": self.params, - "timeout": (self.timeout.connect, self.timeout.read, self.timeout.write), - "follow_redirects": True, - } - - if self.method in {"get", "head", "post", "put", "delete", "patch"}: - response = getattr(ssrf_proxy, self.method)(data=self.body, files=self.files, **kwargs) - else: - raise ValueError(f"Invalid http method {self.method}") - return response - - def invoke(self) -> HttpExecutorResponse: - """ - invoke http request - """ - # assemble headers - headers = self._assembling_headers() - - # do http request - response = self._do_http_request(headers) - - # validate response - return self._validate_and_parse_response(response) - - def to_raw_request(self) -> str: - """ - convert to raw request - """ - server_url = self.server_url - if self.params: - server_url += f"?{urlencode(self.params)}" - - raw_request = f"{self.method.upper()} {server_url} HTTP/1.1\n" - - headers = self._assembling_headers() - for k, v in headers.items(): - # get authorization header - if self.authorization.type == "api-key": - authorization_header = "Authorization" - if self.authorization.config and self.authorization.config.header: - authorization_header = self.authorization.config.header - - if k.lower() == authorization_header.lower(): - raw_request += f'{k}: {"*" * len(v)}\n' - continue - - raw_request += f"{k}: {v}\n" - - raw_request += "\n" - - # if files, use multipart/form-data with boundary - if self.files: - boundary = self.boundary - raw_request += f"--{boundary}" - for k, v in self.files.items(): - raw_request += f'\nContent-Disposition: form-data; name="{k}"\n\n' - raw_request += f"{v[1]}\n" - raw_request += f"--{boundary}" - raw_request += "--" - else: - raw_request += self.body or "" - - return raw_request - - def _format_template( - self, template: str, variable_pool: Optional[VariablePool], escape_quotes: bool = False - ) -> tuple[str, list[VariableSelector]]: - """ - format template - """ - variable_template_parser = VariableTemplateParser(template=template) - variable_selectors = variable_template_parser.extract_variable_selectors() - - if variable_pool: - variable_value_mapping = {} - for variable_selector in variable_selectors: - variable = variable_pool.get_any(variable_selector.value_selector) - if variable is None: - raise ValueError(f"Variable {variable_selector.variable} not found") - if escape_quotes and isinstance(variable, str): - value = variable.replace('"', '\\"').replace("\n", "\\n") - else: - value = variable - variable_value_mapping[variable_selector.variable] = value - - return variable_template_parser.format(variable_value_mapping), variable_selectors - else: - return template, variable_selectors diff --git a/api/core/workflow/nodes/http_request/http_request_node.py b/api/core/workflow/nodes/http_request/http_request_node.py deleted file mode 100644 index cd40819126..0000000000 --- a/api/core/workflow/nodes/http_request/http_request_node.py +++ /dev/null @@ -1,165 +0,0 @@ -import logging -from collections.abc import Mapping, Sequence -from mimetypes import guess_extension -from os import path -from typing import Any, cast - -from configs import dify_config -from core.app.segments import parser -from core.file.file_obj import FileTransferMethod, FileType, FileVar -from core.tools.tool_file_manager import ToolFileManager -from core.workflow.entities.node_entities import NodeRunResult, NodeType -from core.workflow.nodes.base_node import BaseNode -from core.workflow.nodes.http_request.entities import ( - HttpRequestNodeData, - HttpRequestNodeTimeout, -) -from core.workflow.nodes.http_request.http_executor import HttpExecutor, HttpExecutorResponse -from models.workflow import WorkflowNodeExecutionStatus - -HTTP_REQUEST_DEFAULT_TIMEOUT = HttpRequestNodeTimeout( - connect=dify_config.HTTP_REQUEST_MAX_CONNECT_TIMEOUT, - read=dify_config.HTTP_REQUEST_MAX_READ_TIMEOUT, - write=dify_config.HTTP_REQUEST_MAX_WRITE_TIMEOUT, -) - - -class HttpRequestNode(BaseNode): - _node_data_cls = HttpRequestNodeData - _node_type = NodeType.HTTP_REQUEST - - @classmethod - def get_default_config(cls, filters: dict | None = None) -> dict: - return { - "type": "http-request", - "config": { - "method": "get", - "authorization": { - "type": "no-auth", - }, - "body": {"type": "none"}, - "timeout": { - **HTTP_REQUEST_DEFAULT_TIMEOUT.model_dump(), - "max_connect_timeout": dify_config.HTTP_REQUEST_MAX_CONNECT_TIMEOUT, - "max_read_timeout": dify_config.HTTP_REQUEST_MAX_READ_TIMEOUT, - "max_write_timeout": dify_config.HTTP_REQUEST_MAX_WRITE_TIMEOUT, - }, - }, - } - - def _run(self) -> NodeRunResult: - node_data: HttpRequestNodeData = cast(HttpRequestNodeData, self.node_data) - # TODO: Switch to use segment directly - if node_data.authorization.config and node_data.authorization.config.api_key: - node_data.authorization.config.api_key = parser.convert_template( - template=node_data.authorization.config.api_key, variable_pool=self.graph_runtime_state.variable_pool - ).text - - # init http executor - http_executor = None - try: - http_executor = HttpExecutor( - node_data=node_data, - timeout=self._get_request_timeout(node_data), - variable_pool=self.graph_runtime_state.variable_pool, - ) - - # invoke http executor - response = http_executor.invoke() - except Exception as e: - process_data = {} - if http_executor: - process_data = { - "request": http_executor.to_raw_request(), - } - return NodeRunResult( - status=WorkflowNodeExecutionStatus.FAILED, - error=str(e), - process_data=process_data, - ) - - files = self.extract_files(http_executor.server_url, response) - - return NodeRunResult( - status=WorkflowNodeExecutionStatus.SUCCEEDED, - outputs={ - "status_code": response.status_code, - "body": response.content if not files else "", - "headers": response.headers, - "files": files, - }, - process_data={ - "request": http_executor.to_raw_request(), - }, - ) - - @staticmethod - def _get_request_timeout(node_data: HttpRequestNodeData) -> HttpRequestNodeTimeout: - timeout = node_data.timeout - if timeout is None: - return HTTP_REQUEST_DEFAULT_TIMEOUT - - timeout.connect = timeout.connect or HTTP_REQUEST_DEFAULT_TIMEOUT.connect - timeout.read = timeout.read or HTTP_REQUEST_DEFAULT_TIMEOUT.read - timeout.write = timeout.write or HTTP_REQUEST_DEFAULT_TIMEOUT.write - return timeout - - @classmethod - def _extract_variable_selector_to_variable_mapping( - cls, graph_config: Mapping[str, Any], node_id: str, node_data: HttpRequestNodeData - ) -> Mapping[str, Sequence[str]]: - """ - Extract variable selector to variable mapping - :param graph_config: graph config - :param node_id: node id - :param node_data: node data - :return: - """ - try: - http_executor = HttpExecutor(node_data=node_data, timeout=HTTP_REQUEST_DEFAULT_TIMEOUT) - - variable_selectors = http_executor.variable_selectors - - variable_mapping = {} - for variable_selector in variable_selectors: - variable_mapping[node_id + "." + variable_selector.variable] = variable_selector.value_selector - - return variable_mapping - except Exception as e: - logging.exception(f"Failed to extract variable selector to variable mapping: {e}") - return {} - - def extract_files(self, url: str, response: HttpExecutorResponse) -> list[FileVar]: - """ - Extract files from response - """ - files = [] - mimetype, file_binary = response.extract_file() - - if mimetype: - # extract filename from url - filename = path.basename(url) - # extract extension if possible - extension = guess_extension(mimetype) or ".bin" - - tool_file = ToolFileManager.create_file_by_raw( - user_id=self.user_id, - tenant_id=self.tenant_id, - conversation_id=None, - file_binary=file_binary, - mimetype=mimetype, - ) - - files.append( - FileVar( - tenant_id=self.tenant_id, - type=FileType.IMAGE, - transfer_method=FileTransferMethod.TOOL_FILE, - related_id=tool_file.id, - filename=filename, - extension=extension, - mime_type=mimetype, - ) - ) - - return files diff --git a/api/core/workflow/nodes/http_request/node.py b/api/core/workflow/nodes/http_request/node.py new file mode 100644 index 0000000000..483d0e2b7e --- /dev/null +++ b/api/core/workflow/nodes/http_request/node.py @@ -0,0 +1,174 @@ +import logging +from collections.abc import Mapping, Sequence +from mimetypes import guess_extension +from os import path +from typing import Any + +from configs import dify_config +from core.file import File, FileTransferMethod, FileType +from core.tools.tool_file_manager import ToolFileManager +from core.workflow.entities.node_entities import NodeRunResult +from core.workflow.entities.variable_entities import VariableSelector +from core.workflow.nodes.base import BaseNode +from core.workflow.nodes.enums import NodeType +from core.workflow.nodes.http_request.executor import Executor +from core.workflow.utils import variable_template_parser +from models.workflow import WorkflowNodeExecutionStatus + +from .entities import ( + HttpRequestNodeData, + HttpRequestNodeTimeout, + Response, +) + +HTTP_REQUEST_DEFAULT_TIMEOUT = HttpRequestNodeTimeout( + connect=dify_config.HTTP_REQUEST_MAX_CONNECT_TIMEOUT, + read=dify_config.HTTP_REQUEST_MAX_READ_TIMEOUT, + write=dify_config.HTTP_REQUEST_MAX_WRITE_TIMEOUT, +) + +logger = logging.getLogger(__name__) + + +class HttpRequestNode(BaseNode[HttpRequestNodeData]): + _node_data_cls = HttpRequestNodeData + _node_type = NodeType.HTTP_REQUEST + + @classmethod + def get_default_config(cls, filters: dict | None = None) -> dict: + return { + "type": "http-request", + "config": { + "method": "get", + "authorization": { + "type": "no-auth", + }, + "body": {"type": "none"}, + "timeout": { + **HTTP_REQUEST_DEFAULT_TIMEOUT.model_dump(), + "max_connect_timeout": dify_config.HTTP_REQUEST_MAX_CONNECT_TIMEOUT, + "max_read_timeout": dify_config.HTTP_REQUEST_MAX_READ_TIMEOUT, + "max_write_timeout": dify_config.HTTP_REQUEST_MAX_WRITE_TIMEOUT, + }, + }, + } + + def _run(self) -> NodeRunResult: + process_data = {} + try: + http_executor = Executor( + node_data=self.node_data, + timeout=self._get_request_timeout(self.node_data), + variable_pool=self.graph_runtime_state.variable_pool, + ) + process_data["request"] = http_executor.to_log() + + response = http_executor.invoke() + files = self.extract_files(url=http_executor.url, response=response) + return NodeRunResult( + status=WorkflowNodeExecutionStatus.SUCCEEDED, + outputs={ + "status_code": response.status_code, + "body": response.text if not files else "", + "headers": response.headers, + "files": files, + }, + process_data={ + "request": http_executor.to_log(), + }, + ) + except Exception as e: + logger.warning(f"http request node {self.node_id} failed to run: {e}") + return NodeRunResult( + status=WorkflowNodeExecutionStatus.FAILED, + error=str(e), + process_data=process_data, + ) + + @staticmethod + def _get_request_timeout(node_data: HttpRequestNodeData) -> HttpRequestNodeTimeout: + timeout = node_data.timeout + if timeout is None: + return HTTP_REQUEST_DEFAULT_TIMEOUT + + timeout.connect = timeout.connect or HTTP_REQUEST_DEFAULT_TIMEOUT.connect + timeout.read = timeout.read or HTTP_REQUEST_DEFAULT_TIMEOUT.read + timeout.write = timeout.write or HTTP_REQUEST_DEFAULT_TIMEOUT.write + return timeout + + @classmethod + def _extract_variable_selector_to_variable_mapping( + cls, + *, + graph_config: Mapping[str, Any], + node_id: str, + node_data: HttpRequestNodeData, + ) -> Mapping[str, Sequence[str]]: + selectors: list[VariableSelector] = [] + selectors += variable_template_parser.extract_selectors_from_template(node_data.headers) + selectors += variable_template_parser.extract_selectors_from_template(node_data.params) + if node_data.body: + body_type = node_data.body.type + data = node_data.body.data + match body_type: + case "binary": + selector = data[0].file + selectors.append(VariableSelector(variable="#" + ".".join(selector) + "#", value_selector=selector)) + case "json" | "raw-text": + selectors += variable_template_parser.extract_selectors_from_template(data[0].key) + selectors += variable_template_parser.extract_selectors_from_template(data[0].value) + case "x-www-form-urlencoded": + for item in data: + selectors += variable_template_parser.extract_selectors_from_template(item.key) + selectors += variable_template_parser.extract_selectors_from_template(item.value) + case "form-data": + for item in data: + selectors += variable_template_parser.extract_selectors_from_template(item.key) + if item.type == "text": + selectors += variable_template_parser.extract_selectors_from_template(item.value) + elif item.type == "file": + selectors.append( + VariableSelector(variable="#" + ".".join(item.file) + "#", value_selector=item.file) + ) + + mapping = {} + for selector in selectors: + mapping[node_id + "." + selector.variable] = selector.value_selector + + return mapping + + def extract_files(self, url: str, response: Response) -> list[File]: + """ + Extract files from response + """ + files = [] + content_type = response.content_type + content = response.content + + if content_type: + # extract filename from url + filename = path.basename(url) + # extract extension if possible + extension = guess_extension(content_type) or ".bin" + + tool_file = ToolFileManager.create_file_by_raw( + user_id=self.user_id, + tenant_id=self.tenant_id, + conversation_id=None, + file_binary=content, + mimetype=content_type, + ) + + files.append( + File( + tenant_id=self.tenant_id, + type=FileType.IMAGE, + transfer_method=FileTransferMethod.TOOL_FILE, + related_id=tool_file.id, + filename=filename, + extension=extension, + mime_type=content_type, + ) + ) + + return files diff --git a/api/core/workflow/nodes/list_operator/__init__.py b/api/core/workflow/nodes/list_operator/__init__.py new file mode 100644 index 0000000000..1877586ef4 --- /dev/null +++ b/api/core/workflow/nodes/list_operator/__init__.py @@ -0,0 +1,3 @@ +from .node import ListOperatorNode + +__all__ = ["ListOperatorNode"] diff --git a/api/core/workflow/nodes/list_operator/entities.py b/api/core/workflow/nodes/list_operator/entities.py new file mode 100644 index 0000000000..79cef1c27a --- /dev/null +++ b/api/core/workflow/nodes/list_operator/entities.py @@ -0,0 +1,56 @@ +from collections.abc import Sequence +from typing import Literal + +from pydantic import BaseModel, Field + +from core.workflow.nodes.base import BaseNodeData + +_Condition = Literal[ + # string conditions + "contains", + "start with", + "end with", + "is", + "in", + "empty", + "not contains", + "is not", + "not in", + "not empty", + # number conditions + "=", + "≠", + "<", + ">", + "≥", + "≤", +] + + +class FilterCondition(BaseModel): + key: str = "" + comparison_operator: _Condition = "contains" + value: str | Sequence[str] = "" + + +class FilterBy(BaseModel): + enabled: bool = False + conditions: Sequence[FilterCondition] = Field(default_factory=list) + + +class OrderBy(BaseModel): + enabled: bool = False + key: str = "" + value: Literal["asc", "desc"] = "asc" + + +class Limit(BaseModel): + enabled: bool = False + size: int = -1 + + +class ListOperatorNodeData(BaseNodeData): + variable: Sequence[str] = Field(default_factory=list) + filter_by: FilterBy + order_by: OrderBy + limit: Limit diff --git a/api/core/workflow/nodes/list_operator/node.py b/api/core/workflow/nodes/list_operator/node.py new file mode 100644 index 0000000000..d7e4c64313 --- /dev/null +++ b/api/core/workflow/nodes/list_operator/node.py @@ -0,0 +1,259 @@ +from collections.abc import Callable, Sequence +from typing import Literal + +from core.file import File +from core.variables import ArrayFileSegment, ArrayNumberSegment, ArrayStringSegment +from core.workflow.entities.node_entities import NodeRunResult +from core.workflow.nodes.base import BaseNode +from core.workflow.nodes.enums import NodeType +from models.workflow import WorkflowNodeExecutionStatus + +from .entities import ListOperatorNodeData + + +class ListOperatorNode(BaseNode[ListOperatorNodeData]): + _node_data_cls = ListOperatorNodeData + _node_type = NodeType.LIST_OPERATOR + + def _run(self): + inputs = {} + process_data = {} + outputs = {} + + variable = self.graph_runtime_state.variable_pool.get(self.node_data.variable) + if variable is None: + error_message = f"Variable not found for selector: {self.node_data.variable}" + return NodeRunResult( + status=WorkflowNodeExecutionStatus.FAILED, error=error_message, inputs=inputs, outputs=outputs + ) + if variable.value and not isinstance(variable, ArrayFileSegment | ArrayNumberSegment | ArrayStringSegment): + error_message = ( + f"Variable {self.node_data.variable} is not an ArrayFileSegment, ArrayNumberSegment " + "or ArrayStringSegment" + ) + return NodeRunResult( + status=WorkflowNodeExecutionStatus.FAILED, error=error_message, inputs=inputs, outputs=outputs + ) + + if isinstance(variable, ArrayFileSegment): + process_data["variable"] = [item.to_dict() for item in variable.value] + else: + process_data["variable"] = variable.value + + # Filter + if self.node_data.filter_by.enabled: + for condition in self.node_data.filter_by.conditions: + if isinstance(variable, ArrayStringSegment): + if not isinstance(condition.value, str): + raise ValueError(f"Invalid filter value: {condition.value}") + value = self.graph_runtime_state.variable_pool.convert_template(condition.value).text + filter_func = _get_string_filter_func(condition=condition.comparison_operator, value=value) + result = list(filter(filter_func, variable.value)) + variable = variable.model_copy(update={"value": result}) + elif isinstance(variable, ArrayNumberSegment): + if not isinstance(condition.value, str): + raise ValueError(f"Invalid filter value: {condition.value}") + value = self.graph_runtime_state.variable_pool.convert_template(condition.value).text + filter_func = _get_number_filter_func(condition=condition.comparison_operator, value=float(value)) + result = list(filter(filter_func, variable.value)) + variable = variable.model_copy(update={"value": result}) + elif isinstance(variable, ArrayFileSegment): + if isinstance(condition.value, str): + value = self.graph_runtime_state.variable_pool.convert_template(condition.value).text + else: + value = condition.value + filter_func = _get_file_filter_func( + key=condition.key, + condition=condition.comparison_operator, + value=value, + ) + result = list(filter(filter_func, variable.value)) + variable = variable.model_copy(update={"value": result}) + + # Order + if self.node_data.order_by.enabled: + if isinstance(variable, ArrayStringSegment): + result = _order_string(order=self.node_data.order_by.value, array=variable.value) + variable = variable.model_copy(update={"value": result}) + elif isinstance(variable, ArrayNumberSegment): + result = _order_number(order=self.node_data.order_by.value, array=variable.value) + variable = variable.model_copy(update={"value": result}) + elif isinstance(variable, ArrayFileSegment): + result = _order_file( + order=self.node_data.order_by.value, order_by=self.node_data.order_by.key, array=variable.value + ) + variable = variable.model_copy(update={"value": result}) + + # Slice + if self.node_data.limit.enabled: + result = variable.value[: self.node_data.limit.size] + variable = variable.model_copy(update={"value": result}) + + outputs = { + "result": variable.value, + "first_record": variable.value[0] if variable.value else None, + "last_record": variable.value[-1] if variable.value else None, + } + return NodeRunResult( + status=WorkflowNodeExecutionStatus.SUCCEEDED, + inputs=inputs, + process_data=process_data, + outputs=outputs, + ) + + +def _get_file_extract_number_func(*, key: str) -> Callable[[File], int]: + match key: + case "size": + return lambda x: x.size + case _: + raise ValueError(f"Invalid key: {key}") + + +def _get_file_extract_string_func(*, key: str) -> Callable[[File], str]: + match key: + case "name": + return lambda x: x.filename or "" + case "type": + return lambda x: x.type + case "extension": + return lambda x: x.extension or "" + case "mimetype": + return lambda x: x.mime_type or "" + case "transfer_method": + return lambda x: x.transfer_method + case "url": + return lambda x: x.remote_url or "" + case _: + raise ValueError(f"Invalid key: {key}") + + +def _get_string_filter_func(*, condition: str, value: str) -> Callable[[str], bool]: + match condition: + case "contains": + return _contains(value) + case "start with": + return _startswith(value) + case "end with": + return _endswith(value) + case "is": + return _is(value) + case "in": + return _in(value) + case "empty": + return lambda x: x == "" + case "not contains": + return lambda x: not _contains(value)(x) + case "is not": + return lambda x: not _is(value)(x) + case "not in": + return lambda x: not _in(value)(x) + case "not empty": + return lambda x: x != "" + case _: + raise ValueError(f"Invalid condition: {condition}") + + +def _get_sequence_filter_func(*, condition: str, value: Sequence[str]) -> Callable[[str], bool]: + match condition: + case "in": + return _in(value) + case "not in": + return lambda x: not _in(value)(x) + case _: + raise ValueError(f"Invalid condition: {condition}") + + +def _get_number_filter_func(*, condition: str, value: int | float) -> Callable[[int | float], bool]: + match condition: + case "=": + return _eq(value) + case "≠": + return _ne(value) + case "<": + return _lt(value) + case "≤": + return _le(value) + case ">": + return _gt(value) + case "≥": + return _ge(value) + case _: + raise ValueError(f"Invalid condition: {condition}") + + +def _get_file_filter_func(*, key: str, condition: str, value: str | Sequence[str]) -> Callable[[File], bool]: + if key in {"name", "extension", "mime_type", "url"} and isinstance(value, str): + extract_func = _get_file_extract_string_func(key=key) + return lambda x: _get_string_filter_func(condition=condition, value=value)(extract_func(x)) + if key in {"type", "transfer_method"} and isinstance(value, Sequence): + extract_func = _get_file_extract_string_func(key=key) + return lambda x: _get_sequence_filter_func(condition=condition, value=value)(extract_func(x)) + elif key == "size" and isinstance(value, str): + extract_func = _get_file_extract_number_func(key=key) + return lambda x: _get_number_filter_func(condition=condition, value=float(value))(extract_func(x)) + else: + raise ValueError(f"Invalid key: {key}") + + +def _contains(value: str): + return lambda x: value in x + + +def _startswith(value: str): + return lambda x: x.startswith(value) + + +def _endswith(value: str): + return lambda x: x.endswith(value) + + +def _is(value: str): + return lambda x: x is value + + +def _in(value: str | Sequence[str]): + return lambda x: x in value + + +def _eq(value: int | float): + return lambda x: x == value + + +def _ne(value: int | float): + return lambda x: x != value + + +def _lt(value: int | float): + return lambda x: x < value + + +def _le(value: int | float): + return lambda x: x <= value + + +def _gt(value: int | float): + return lambda x: x > value + + +def _ge(value: int | float): + return lambda x: x >= value + + +def _order_number(*, order: Literal["asc", "desc"], array: Sequence[int | float]): + return sorted(array, key=lambda x: x, reverse=order == "desc") + + +def _order_string(*, order: Literal["asc", "desc"], array: Sequence[str]): + return sorted(array, key=lambda x: x, reverse=order == "desc") + + +def _order_file(*, order: Literal["asc", "desc"], order_by: str = "", array: Sequence[File]): + if order_by in {"name", "type", "extension", "mime_type", "transfer_method", "url"}: + extract_func = _get_file_extract_string_func(key=order_by) + return sorted(array, key=lambda x: extract_func(x), reverse=order == "desc") + elif order_by == "size": + extract_func = _get_file_extract_number_func(key=order_by) + return sorted(array, key=lambda x: extract_func(x), reverse=order == "desc") + else: + raise ValueError(f"Invalid order key: {order_by}") diff --git a/api/core/workflow/nodes/llm/llm_node.py b/api/core/workflow/nodes/llm/node.py similarity index 71% rename from api/core/workflow/nodes/llm/llm_node.py rename to api/core/workflow/nodes/llm/node.py index 3d336b0b0b..abf77f3339 100644 --- a/api/core/workflow/nodes/llm/llm_node.py +++ b/api/core/workflow/nodes/llm/node.py @@ -1,39 +1,48 @@ import json from collections.abc import Generator, Mapping, Sequence -from copy import deepcopy from typing import TYPE_CHECKING, Any, Optional, cast -from pydantic import BaseModel - from core.app.entities.app_invoke_entities import ModelConfigWithCredentialsEntity from core.entities.model_entities import ModelStatus from core.entities.provider_entities import QuotaUnit from core.errors.error import ModelCurrentlyNotSupportError, ProviderTokenNotInitError, QuotaExceededError from core.memory.token_buffer_memory import TokenBufferMemory from core.model_manager import ModelInstance, ModelManager -from core.model_runtime.entities.llm_entities import LLMResult, LLMUsage -from core.model_runtime.entities.message_entities import ( +from core.model_runtime.entities import ( + AudioPromptMessageContent, ImagePromptMessageContent, PromptMessage, PromptMessageContentType, + TextPromptMessageContent, ) +from core.model_runtime.entities.llm_entities import LLMResult, LLMUsage from core.model_runtime.entities.model_entities import ModelType from core.model_runtime.model_providers.__base.large_language_model import LargeLanguageModel from core.model_runtime.utils.encoders import jsonable_encoder from core.prompt.advanced_prompt_transform import AdvancedPromptTransform from core.prompt.entities.advanced_prompt_entities import CompletionModelPromptTemplate, MemoryConfig from core.prompt.utils.prompt_message_util import PromptMessageUtil -from core.workflow.entities.node_entities import NodeRunMetadataKey, NodeRunResult, NodeType -from core.workflow.entities.variable_pool import VariablePool +from core.variables import ( + ArrayAnySegment, + ArrayFileSegment, + ArraySegment, + FileSegment, + NoneSegment, + ObjectSegment, + StringSegment, +) +from core.workflow.constants import SYSTEM_VARIABLE_NODE_ID +from core.workflow.entities.node_entities import NodeRunMetadataKey, NodeRunResult from core.workflow.enums import SystemVariableKey from core.workflow.graph_engine.entities.event import InNodeEvent -from core.workflow.nodes.base_node import BaseNode -from core.workflow.nodes.event import RunCompletedEvent, RunEvent, RunRetrieverResourceEvent, RunStreamChunkEvent -from core.workflow.nodes.llm.entities import ( - LLMNodeChatModelMessage, - LLMNodeCompletionModelPromptTemplate, - LLMNodeData, - ModelConfig, +from core.workflow.nodes.base import BaseNode +from core.workflow.nodes.enums import NodeType +from core.workflow.nodes.event import ( + ModelInvokeCompletedEvent, + NodeEvent, + RunCompletedEvent, + RunRetrieverResourceEvent, + RunStreamChunkEvent, ) from core.workflow.utils.variable_template_parser import VariableTemplateParser from extensions.ext_database import db @@ -41,44 +50,34 @@ from models.model import Conversation from models.provider import Provider, ProviderType from models.workflow import WorkflowNodeExecutionStatus +from .entities import ( + LLMNodeChatModelMessage, + LLMNodeCompletionModelPromptTemplate, + LLMNodeData, + ModelConfig, +) + if TYPE_CHECKING: - from core.file.file_obj import FileVar + from core.file.models import File -class ModelInvokeCompleted(BaseModel): - """ - Model invoke completed - """ - - text: str - usage: LLMUsage - finish_reason: Optional[str] = None - - -class LLMNode(BaseNode): +class LLMNode(BaseNode[LLMNodeData]): _node_data_cls = LLMNodeData _node_type = NodeType.LLM - def _run(self) -> Generator[RunEvent | InNodeEvent, None, None]: - """ - Run node - :return: - """ - node_data = cast(LLMNodeData, deepcopy(self.node_data)) - variable_pool = self.graph_runtime_state.variable_pool - + def _run(self) -> NodeRunResult | Generator[NodeEvent | InNodeEvent, None, None]: node_inputs = None process_data = None try: # init messages template - node_data.prompt_template = self._transform_chat_messages(node_data.prompt_template) + self.node_data.prompt_template = self._transform_chat_messages(self.node_data.prompt_template) # fetch variables and fetch values from variable pool - inputs = self._fetch_inputs(node_data, variable_pool) + inputs = self._fetch_inputs(node_data=self.node_data) # fetch jinja2 inputs - jinja_inputs = self._fetch_jinja_inputs(node_data, variable_pool) + jinja_inputs = self._fetch_jinja_inputs(node_data=self.node_data) # merge inputs inputs.update(jinja_inputs) @@ -86,13 +85,17 @@ class LLMNode(BaseNode): node_inputs = {} # fetch files - files = self._fetch_files(node_data, variable_pool) + files = ( + self._fetch_files(selector=self.node_data.vision.configs.variable_selector) + if self.node_data.vision.enabled + else [] + ) if files: node_inputs["#files#"] = [file.to_dict() for file in files] # fetch context value - generator = self._fetch_context(node_data, variable_pool) + generator = self._fetch_context(node_data=self.node_data) context = None for event in generator: if isinstance(event, RunRetrieverResourceEvent): @@ -103,21 +106,31 @@ class LLMNode(BaseNode): node_inputs["#context#"] = context # type: ignore # fetch model config - model_instance, model_config = self._fetch_model_config(node_data.model) + model_instance, model_config = self._fetch_model_config(self.node_data.model) # fetch memory - memory = self._fetch_memory(node_data.memory, variable_pool, model_instance) + memory = self._fetch_memory(node_data_memory=self.node_data.memory, model_instance=model_instance) # fetch prompt messages + if self.node_data.memory: + query = self.graph_runtime_state.variable_pool.get((SYSTEM_VARIABLE_NODE_ID, SystemVariableKey.QUERY)) + if not query: + raise ValueError("Query not found") + query = query.text + else: + query = None + prompt_messages, stop = self._fetch_prompt_messages( - node_data=node_data, - query=variable_pool.get_any(["sys", SystemVariableKey.QUERY.value]) if node_data.memory else None, - query_prompt_template=node_data.memory.query_prompt_template if node_data.memory else None, + system_query=query, inputs=inputs, files=files, context=context, memory=memory, model_config=model_config, + prompt_template=self.node_data.prompt_template, + memory_config=self.node_data.memory, + vision_enabled=self.node_data.vision.enabled, + vision_detail=self.node_data.vision.configs.detail, ) process_data = { @@ -131,7 +144,7 @@ class LLMNode(BaseNode): # handle invoke result generator = self._invoke_llm( - node_data_model=node_data.model, + node_data_model=self.node_data.model, model_instance=model_instance, prompt_messages=prompt_messages, stop=stop, @@ -143,7 +156,7 @@ class LLMNode(BaseNode): for event in generator: if isinstance(event, RunStreamChunkEvent): yield event - elif isinstance(event, ModelInvokeCompleted): + elif isinstance(event, ModelInvokeCompletedEvent): result_text = event.text usage = event.usage finish_reason = event.finish_reason @@ -182,15 +195,7 @@ class LLMNode(BaseNode): model_instance: ModelInstance, prompt_messages: list[PromptMessage], stop: Optional[list[str]] = None, - ) -> Generator[RunEvent | ModelInvokeCompleted, None, None]: - """ - Invoke large language model - :param node_data_model: node data model - :param model_instance: model instance - :param prompt_messages: prompt messages - :param stop: stop - :return: - """ + ) -> Generator[NodeEvent, None, None]: db.session.close() invoke_result = model_instance.invoke_llm( @@ -207,20 +212,13 @@ class LLMNode(BaseNode): usage = LLMUsage.empty_usage() for event in generator: yield event - if isinstance(event, ModelInvokeCompleted): + if isinstance(event, ModelInvokeCompletedEvent): usage = event.usage # deduct quota self.deduct_llm_quota(tenant_id=self.tenant_id, model_instance=model_instance, usage=usage) - def _handle_invoke_result( - self, invoke_result: LLMResult | Generator - ) -> Generator[RunEvent | ModelInvokeCompleted, None, None]: - """ - Handle invoke result - :param invoke_result: invoke result - :return: - """ + def _handle_invoke_result(self, invoke_result: LLMResult | Generator) -> Generator[NodeEvent, None, None]: if isinstance(invoke_result, LLMResult): return @@ -250,18 +248,11 @@ class LLMNode(BaseNode): if not usage: usage = LLMUsage.empty_usage() - yield ModelInvokeCompleted(text=full_text, usage=usage, finish_reason=finish_reason) + yield ModelInvokeCompletedEvent(text=full_text, usage=usage, finish_reason=finish_reason) def _transform_chat_messages( - self, messages: list[LLMNodeChatModelMessage] | LLMNodeCompletionModelPromptTemplate - ) -> list[LLMNodeChatModelMessage] | LLMNodeCompletionModelPromptTemplate: - """ - Transform chat messages - - :param messages: chat messages - :return: - """ - + self, messages: Sequence[LLMNodeChatModelMessage] | LLMNodeCompletionModelPromptTemplate, / + ) -> Sequence[LLMNodeChatModelMessage] | LLMNodeCompletionModelPromptTemplate: if isinstance(messages, LLMNodeCompletionModelPromptTemplate): if messages.edition_type == "jinja2" and messages.jinja2_text: messages.text = messages.jinja2_text @@ -274,69 +265,51 @@ class LLMNode(BaseNode): return messages - def _fetch_jinja_inputs(self, node_data: LLMNodeData, variable_pool: VariablePool) -> dict[str, str]: - """ - Fetch jinja inputs - :param node_data: node data - :param variable_pool: variable pool - :return: - """ + def _fetch_jinja_inputs(self, node_data: LLMNodeData) -> dict[str, str]: variables = {} if not node_data.prompt_config: return variables for variable_selector in node_data.prompt_config.jinja2_variables or []: - variable = variable_selector.variable - value = variable_pool.get_any(variable_selector.value_selector) + variable_name = variable_selector.variable + variable = self.graph_runtime_state.variable_pool.get(variable_selector.value_selector) + if variable is None: + raise ValueError(f"Variable {variable_selector.variable} not found") - def parse_dict(d: dict) -> str: + def parse_dict(input_dict: Mapping[str, Any]) -> str: """ Parse dict into string """ # check if it's a context structure - if "metadata" in d and "_source" in d["metadata"] and "content" in d: - return d["content"] + if "metadata" in input_dict and "_source" in input_dict["metadata"] and "content" in input_dict: + return input_dict["content"] # else, parse the dict try: - return json.dumps(d, ensure_ascii=False) + return json.dumps(input_dict, ensure_ascii=False) except Exception: - return str(d) + return str(input_dict) - if isinstance(value, str): - value = value - elif isinstance(value, list): + if isinstance(variable, ArraySegment): result = "" - for item in value: + for item in variable.value: if isinstance(item, dict): result += parse_dict(item) - elif isinstance(item, str): - result += item - elif isinstance(item, int | float): - result += str(item) else: result += str(item) result += "\n" value = result.strip() - elif isinstance(value, dict): - value = parse_dict(value) - elif isinstance(value, int | float): - value = str(value) + elif isinstance(variable, ObjectSegment): + value = parse_dict(variable.value) else: - value = str(value) + value = variable.text - variables[variable] = value + variables[variable_name] = value return variables - def _fetch_inputs(self, node_data: LLMNodeData, variable_pool: VariablePool) -> dict[str, str]: - """ - Fetch inputs - :param node_data: node data - :param variable_pool: variable pool - :return: - """ + def _fetch_inputs(self, node_data: LLMNodeData) -> dict[str, Any]: inputs = {} prompt_template = node_data.prompt_template @@ -350,11 +323,12 @@ class LLMNode(BaseNode): variable_selectors = variable_template_parser.extract_variable_selectors() for variable_selector in variable_selectors: - variable_value = variable_pool.get_any(variable_selector.value_selector) - if variable_value is None: + variable = self.graph_runtime_state.variable_pool.get(variable_selector.value_selector) + if variable is None: raise ValueError(f"Variable {variable_selector.variable} not found") - - inputs[variable_selector.variable] = variable_value + if isinstance(variable, NoneSegment): + continue + inputs[variable_selector.variable] = variable.to_object() memory = node_data.memory if memory and memory.query_prompt_template: @@ -362,51 +336,44 @@ class LLMNode(BaseNode): template=memory.query_prompt_template ).extract_variable_selectors() for variable_selector in query_variable_selectors: - variable_value = variable_pool.get_any(variable_selector.value_selector) - if variable_value is None: + variable = self.graph_runtime_state.variable_pool.get(variable_selector.value_selector) + if variable is None: raise ValueError(f"Variable {variable_selector.variable} not found") - - inputs[variable_selector.variable] = variable_value + if isinstance(variable, NoneSegment): + continue + inputs[variable_selector.variable] = variable.to_object() return inputs - def _fetch_files(self, node_data: LLMNodeData, variable_pool: VariablePool) -> list["FileVar"]: - """ - Fetch files - :param node_data: node data - :param variable_pool: variable pool - :return: - """ - if not node_data.vision.enabled: + def _fetch_files(self, *, selector: Sequence[str]) -> Sequence["File"]: + variable = self.graph_runtime_state.variable_pool.get(selector) + if variable is None: return [] - - files = variable_pool.get_any(["sys", SystemVariableKey.FILES.value]) - if not files: + if isinstance(variable, FileSegment): + return [variable.value] + if isinstance(variable, ArrayFileSegment): + return variable.value + # FIXME: Temporary fix for empty array, + # all variables added to variable pool should be a Segment instance. + if isinstance(variable, ArrayAnySegment) and len(variable.value) == 0: return [] + raise ValueError(f"Invalid variable type: {type(variable)}") - return files - - def _fetch_context(self, node_data: LLMNodeData, variable_pool: VariablePool) -> Generator[RunEvent, None, None]: - """ - Fetch context - :param node_data: node data - :param variable_pool: variable pool - :return: - """ + def _fetch_context(self, node_data: LLMNodeData): if not node_data.context.enabled: return if not node_data.context.variable_selector: return - context_value = variable_pool.get_any(node_data.context.variable_selector) - if context_value: - if isinstance(context_value, str): - yield RunRetrieverResourceEvent(retriever_resources=[], context=context_value) - elif isinstance(context_value, list): + context_value_variable = self.graph_runtime_state.variable_pool.get(node_data.context.variable_selector) + if context_value_variable: + if isinstance(context_value_variable, StringSegment): + yield RunRetrieverResourceEvent(retriever_resources=[], context=context_value_variable.value) + elif isinstance(context_value_variable, ArraySegment): context_str = "" original_retriever_resource = [] - for item in context_value: + for item in context_value_variable.value: if isinstance(item, str): context_str += item + "\n" else: @@ -424,11 +391,6 @@ class LLMNode(BaseNode): ) def _convert_to_original_retriever_resource(self, context_dict: dict) -> Optional[dict]: - """ - Convert to original retriever resource, temp. - :param context_dict: context dict - :return: - """ if ( "metadata" in context_dict and "_source" in context_dict["metadata"] @@ -451,6 +413,7 @@ class LLMNode(BaseNode): "segment_position": metadata.get("segment_position"), "index_node_hash": metadata.get("segment_index_node_hash"), "content": context_dict.get("content"), + "page": metadata.get("page"), } return source @@ -460,11 +423,6 @@ class LLMNode(BaseNode): def _fetch_model_config( self, node_data_model: ModelConfig ) -> tuple[ModelInstance, ModelConfigWithCredentialsEntity]: - """ - Fetch model config - :param node_data_model: node data model - :return: - """ model_name = node_data_model.name provider_name = node_data_model.provider @@ -523,21 +481,18 @@ class LLMNode(BaseNode): ) def _fetch_memory( - self, node_data_memory: Optional[MemoryConfig], variable_pool: VariablePool, model_instance: ModelInstance + self, node_data_memory: Optional[MemoryConfig], model_instance: ModelInstance ) -> Optional[TokenBufferMemory]: - """ - Fetch memory - :param node_data_memory: node data memory - :param variable_pool: variable pool - :return: - """ if not node_data_memory: return None # get conversation id - conversation_id = variable_pool.get_any(["sys", SystemVariableKey.CONVERSATION_ID.value]) - if conversation_id is None: + conversation_id_variable = self.graph_runtime_state.variable_pool.get( + ["sys", SystemVariableKey.CONVERSATION_ID.value] + ) + if not isinstance(conversation_id_variable, StringSegment): return None + conversation_id = conversation_id_variable.value # get conversation conversation = ( @@ -555,43 +510,32 @@ class LLMNode(BaseNode): def _fetch_prompt_messages( self, - node_data: LLMNodeData, - query: Optional[str], - query_prompt_template: Optional[str], - inputs: dict[str, str], - files: list["FileVar"], - context: Optional[str], - memory: Optional[TokenBufferMemory], + *, + system_query: str | None = None, + inputs: dict[str, str] | None = None, + files: Sequence["File"], + context: str | None = None, + memory: TokenBufferMemory | None = None, model_config: ModelConfigWithCredentialsEntity, + prompt_template: Sequence[LLMNodeChatModelMessage] | LLMNodeCompletionModelPromptTemplate, + memory_config: MemoryConfig | None = None, + vision_enabled: bool = False, + vision_detail: ImagePromptMessageContent.DETAIL, ) -> tuple[list[PromptMessage], Optional[list[str]]]: - """ - Fetch prompt messages - :param node_data: node data - :param query: query - :param query_prompt_template: query prompt template - :param inputs: inputs - :param files: files - :param context: context - :param memory: memory - :param model_config: model config - :return: - """ + inputs = inputs or {} + prompt_transform = AdvancedPromptTransform(with_variable_tmpl=True) prompt_messages = prompt_transform.get_prompt( - prompt_template=node_data.prompt_template, + prompt_template=prompt_template, inputs=inputs, - query=query or "", + query=system_query or "", files=files, context=context, - memory_config=node_data.memory, + memory_config=memory_config, memory=memory, model_config=model_config, - query_prompt_template=query_prompt_template, ) stop = model_config.stop - - vision_enabled = node_data.vision.enabled - vision_detail = node_data.vision.configs.detail if node_data.vision.configs else None filtered_prompt_messages = [] for prompt_message in prompt_messages: if prompt_message.is_empty(): @@ -599,17 +543,17 @@ class LLMNode(BaseNode): if not isinstance(prompt_message.content, str): prompt_message_content = [] - for content_item in prompt_message.content: - if ( - vision_enabled - and content_item.type == PromptMessageContentType.IMAGE - and isinstance(content_item, ImagePromptMessageContent) - ): - # Override vision config if LLM node has vision config - if vision_detail: - content_item.detail = ImagePromptMessageContent.DETAIL(vision_detail) + for content_item in prompt_message.content or []: + # Skip image if vision is disabled + if not vision_enabled and content_item.type == PromptMessageContentType.IMAGE: + continue + + if isinstance(content_item, ImagePromptMessageContent): + # Override vision config if LLM node has vision config, + # cuz vision detail is related to the configuration from FileUpload feature. + content_item.detail = vision_detail prompt_message_content.append(content_item) - elif content_item.type == PromptMessageContentType.TEXT: + elif isinstance(content_item, TextPromptMessageContent | AudioPromptMessageContent): prompt_message_content.append(content_item) if len(prompt_message_content) > 1: @@ -631,13 +575,6 @@ class LLMNode(BaseNode): @classmethod def deduct_llm_quota(cls, tenant_id: str, model_instance: ModelInstance, usage: LLMUsage) -> None: - """ - Deduct LLM quota - :param tenant_id: tenant id - :param model_instance: model instance - :param usage: usage - :return: - """ provider_model_bundle = model_instance.provider_model_bundle provider_configuration = provider_model_bundle.configuration @@ -668,7 +605,7 @@ class LLMNode(BaseNode): else: used_quota = 1 - if used_quota is not None: + if used_quota is not None and system_configuration.current_quota_type is not None: db.session.query(Provider).filter( Provider.tenant_id == tenant_id, Provider.provider_name == model_instance.provider, @@ -680,27 +617,28 @@ class LLMNode(BaseNode): @classmethod def _extract_variable_selector_to_variable_mapping( - cls, graph_config: Mapping[str, Any], node_id: str, node_data: LLMNodeData + cls, + *, + graph_config: Mapping[str, Any], + node_id: str, + node_data: LLMNodeData, ) -> Mapping[str, Sequence[str]]: - """ - Extract variable selector to variable mapping - :param graph_config: graph config - :param node_id: node id - :param node_data: node data - :return: - """ prompt_template = node_data.prompt_template variable_selectors = [] - if isinstance(prompt_template, list): + if isinstance(prompt_template, list) and all( + isinstance(prompt, LLMNodeChatModelMessage) for prompt in prompt_template + ): for prompt in prompt_template: if prompt.edition_type != "jinja2": variable_template_parser = VariableTemplateParser(template=prompt.text) variable_selectors.extend(variable_template_parser.extract_variable_selectors()) - else: + elif isinstance(prompt_template, LLMNodeCompletionModelPromptTemplate): if prompt_template.edition_type != "jinja2": variable_template_parser = VariableTemplateParser(template=prompt_template.text) variable_selectors = variable_template_parser.extract_variable_selectors() + else: + raise ValueError(f"Invalid prompt template type: {type(prompt_template)}") variable_mapping = {} for variable_selector in variable_selectors: @@ -745,11 +683,6 @@ class LLMNode(BaseNode): @classmethod def get_default_config(cls, filters: Optional[dict] = None) -> dict: - """ - Get default config of node. - :param filters: filter by node config parameters. - :return: - """ return { "type": "llm", "config": { diff --git a/api/extensions/ext_logging.py b/api/extensions/ext_logging.py new file mode 100644 index 0000000000..56b1d6bd28 --- /dev/null +++ b/api/extensions/ext_logging.py @@ -0,0 +1,45 @@ +import logging +import os +import sys +from logging.handlers import RotatingFileHandler + +from flask import Flask + +from configs import dify_config + + +def init_app(app: Flask): + log_handlers = None + log_file = dify_config.LOG_FILE + if log_file: + log_dir = os.path.dirname(log_file) + os.makedirs(log_dir, exist_ok=True) + log_handlers = [ + RotatingFileHandler( + filename=log_file, + maxBytes=dify_config.LOG_FILE_MAX_SIZE * 1024 * 1024, + backupCount=dify_config.LOG_FILE_BACKUP_COUNT, + ), + logging.StreamHandler(sys.stdout), + ] + + logging.basicConfig( + level=dify_config.LOG_LEVEL, + format=dify_config.LOG_FORMAT, + datefmt=dify_config.LOG_DATEFORMAT, + handlers=log_handlers, + force=True, + ) + log_tz = dify_config.LOG_TZ + if log_tz: + from datetime import datetime + + import pytz + + timezone = pytz.timezone(log_tz) + + def time_converter(seconds): + return datetime.utcfromtimestamp(seconds).astimezone(timezone).timetuple() + + for handler in logging.root.handlers: + handler.formatter.converter = time_converter diff --git a/api/factories/file_factory.py b/api/factories/file_factory.py new file mode 100644 index 0000000000..ead7b9a8b3 --- /dev/null +++ b/api/factories/file_factory.py @@ -0,0 +1,251 @@ +import mimetypes +from collections.abc import Mapping, Sequence +from typing import Any + +import httpx +from sqlalchemy import select + +from constants import AUDIO_EXTENSIONS, DOCUMENT_EXTENSIONS, IMAGE_EXTENSIONS, VIDEO_EXTENSIONS +from core.file import File, FileBelongsTo, FileExtraConfig, FileTransferMethod, FileType +from core.helper import ssrf_proxy +from extensions.ext_database import db +from models import MessageFile, ToolFile, UploadFile +from models.enums import CreatedByRole + + +def build_from_message_files( + *, + message_files: Sequence["MessageFile"], + tenant_id: str, + config: FileExtraConfig, +) -> Sequence[File]: + results = [ + build_from_message_file(message_file=file, tenant_id=tenant_id, config=config) + for file in message_files + if file.belongs_to != FileBelongsTo.ASSISTANT + ] + return results + + +def build_from_message_file( + *, + message_file: "MessageFile", + tenant_id: str, + config: FileExtraConfig, +): + mapping = { + "transfer_method": message_file.transfer_method, + "url": message_file.url, + "id": message_file.id, + "type": message_file.type, + "upload_file_id": message_file.upload_file_id, + } + return build_from_mapping( + mapping=mapping, + tenant_id=tenant_id, + user_id=message_file.created_by, + role=CreatedByRole(message_file.created_by_role), + config=config, + ) + + +def build_from_mapping( + *, + mapping: Mapping[str, Any], + tenant_id: str, + user_id: str, + role: "CreatedByRole", + config: FileExtraConfig, +): + transfer_method = FileTransferMethod.value_of(mapping.get("transfer_method")) + match transfer_method: + case FileTransferMethod.REMOTE_URL: + file = _build_from_remote_url( + mapping=mapping, + tenant_id=tenant_id, + config=config, + transfer_method=transfer_method, + ) + case FileTransferMethod.LOCAL_FILE: + file = _build_from_local_file( + mapping=mapping, + tenant_id=tenant_id, + user_id=user_id, + role=role, + config=config, + transfer_method=transfer_method, + ) + case FileTransferMethod.TOOL_FILE: + file = _build_from_tool_file( + mapping=mapping, + tenant_id=tenant_id, + user_id=user_id, + config=config, + transfer_method=transfer_method, + ) + case _: + raise ValueError(f"Invalid file transfer method: {transfer_method}") + + return file + + +def build_from_mappings( + *, + mappings: Sequence[Mapping[str, Any]], + config: FileExtraConfig | None, + tenant_id: str, + user_id: str, + role: "CreatedByRole", +) -> Sequence[File]: + if not config: + return [] + + files = [ + build_from_mapping( + mapping=mapping, + tenant_id=tenant_id, + user_id=user_id, + role=role, + config=config, + ) + for mapping in mappings + ] + + if ( + # If image config is set. + config.image_config + # And the number of image files exceeds the maximum limit + and sum(1 for _ in (filter(lambda x: x.type == FileType.IMAGE, files))) > config.image_config.number_limits + ): + raise ValueError(f"Number of image files exceeds the maximum limit {config.image_config.number_limits}") + if config.number_limits and len(files) > config.number_limits: + raise ValueError(f"Number of files exceeds the maximum limit {config.number_limits}") + + return files + + +def _build_from_local_file( + *, + mapping: Mapping[str, Any], + tenant_id: str, + user_id: str, + role: "CreatedByRole", + config: FileExtraConfig, + transfer_method: FileTransferMethod, +): + # check if the upload file exists. + file_type = FileType.value_of(mapping.get("type")) + stmt = select(UploadFile).where( + UploadFile.id == mapping.get("upload_file_id"), + UploadFile.tenant_id == tenant_id, + UploadFile.created_by == user_id, + UploadFile.created_by_role == role, + ) + if file_type == FileType.IMAGE: + stmt = stmt.where(UploadFile.extension.in_(IMAGE_EXTENSIONS)) + elif file_type == FileType.VIDEO: + stmt = stmt.where(UploadFile.extension.in_(VIDEO_EXTENSIONS)) + elif file_type == FileType.AUDIO: + stmt = stmt.where(UploadFile.extension.in_(AUDIO_EXTENSIONS)) + elif file_type == FileType.DOCUMENT: + stmt = stmt.where(UploadFile.extension.in_(DOCUMENT_EXTENSIONS)) + row = db.session.scalar(stmt) + if row is None: + raise ValueError("Invalid upload file") + file = File( + id=mapping.get("id"), + filename=row.name, + extension="." + row.extension, + mime_type=row.mime_type, + tenant_id=tenant_id, + type=file_type, + transfer_method=transfer_method, + remote_url=None, + related_id=mapping.get("upload_file_id"), + _extra_config=config, + size=row.size, + ) + return file + + +def _build_from_remote_url( + *, + mapping: Mapping[str, Any], + tenant_id: str, + config: FileExtraConfig, + transfer_method: FileTransferMethod, +): + url = mapping.get("url") + if not url: + raise ValueError("Invalid file url") + + mime_type = mimetypes.guess_type(url)[0] or "" + file_size = -1 + filename = url.split("/")[-1].split("?")[0] or "unknown_file" + + resp = ssrf_proxy.head(url, follow_redirects=True) + if resp.status_code == httpx.codes.OK: + if content_disposition := resp.headers.get("Content-Disposition"): + filename = content_disposition.split("filename=")[-1].strip('"') + file_size = int(resp.headers.get("Content-Length", file_size)) + mime_type = mime_type or str(resp.headers.get("Content-Type", "")) + + # Determine file extension + extension = mimetypes.guess_extension(mime_type) or "." + filename.split(".")[-1] if "." in filename else ".bin" + + if not mime_type: + mime_type, _ = mimetypes.guess_type(url) + file = File( + id=mapping.get("id"), + filename=filename, + tenant_id=tenant_id, + type=FileType.value_of(mapping.get("type")), + transfer_method=transfer_method, + remote_url=url, + _extra_config=config, + mime_type=mime_type, + extension=extension, + size=file_size, + ) + return file + + +def _build_from_tool_file( + *, + mapping: Mapping[str, Any], + tenant_id: str, + user_id: str, + config: FileExtraConfig, + transfer_method: FileTransferMethod, +): + tool_file = ( + db.session.query(ToolFile) + .filter( + ToolFile.id == mapping.get("tool_file_id"), + ToolFile.tenant_id == tenant_id, + ToolFile.user_id == user_id, + ) + .first() + ) + if tool_file is None: + raise ValueError(f"ToolFile {mapping.get('tool_file_id')} not found") + + path = tool_file.file_key + if "." in path: + extension = "." + path.split("/")[-1].split(".")[-1] + else: + extension = ".bin" + file = File( + id=mapping.get("id"), + tenant_id=tenant_id, + filename=tool_file.name, + type=FileType.value_of(mapping.get("type")), + transfer_method=transfer_method, + remote_url=tool_file.original_url, + related_id=tool_file.id, + extension=extension, + mime_type=tool_file.mimetype, + size=tool_file.size, + _extra_config=config, + ) + return file diff --git a/api/core/app/segments/factory.py b/api/factories/variable_factory.py similarity index 73% rename from api/core/app/segments/factory.py rename to api/factories/variable_factory.py index 40a69ed4eb..a758f9981f 100644 --- a/api/core/app/segments/factory.py +++ b/api/factories/variable_factory.py @@ -2,29 +2,32 @@ from collections.abc import Mapping from typing import Any from configs import dify_config - -from .exc import VariableError -from .segments import ( +from core.file import File +from core.variables import ( ArrayAnySegment, + ArrayFileSegment, + ArrayNumberSegment, + ArrayNumberVariable, + ArrayObjectSegment, + ArrayObjectVariable, + ArrayStringSegment, + ArrayStringVariable, + FileSegment, FloatSegment, + FloatVariable, IntegerSegment, + IntegerVariable, NoneSegment, ObjectSegment, - Segment, - StringSegment, -) -from .types import SegmentType -from .variables import ( - ArrayNumberVariable, - ArrayObjectVariable, - ArrayStringVariable, - FloatVariable, - IntegerVariable, ObjectVariable, SecretVariable, + Segment, + SegmentType, + StringSegment, StringVariable, Variable, ) +from core.variables.exc import VariableError def build_variable_from_mapping(mapping: Mapping[str, Any], /) -> Variable: @@ -71,6 +74,22 @@ def build_segment(value: Any, /) -> Segment: return FloatSegment(value=value) if isinstance(value, dict): return ObjectSegment(value=value) + if isinstance(value, File): + return FileSegment(value=value) if isinstance(value, list): - return ArrayAnySegment(value=value) + items = [build_segment(item) for item in value] + types = {item.value_type for item in items} + if len(types) != 1: + return ArrayAnySegment(value=value) + match types.pop(): + case SegmentType.STRING: + return ArrayStringSegment(value=value) + case SegmentType.NUMBER: + return ArrayNumberSegment(value=value) + case SegmentType.OBJECT: + return ArrayObjectSegment(value=value) + case SegmentType.FILE: + return ArrayFileSegment(value=value) + case _: + raise ValueError(f"not supported value {value}") raise ValueError(f"not supported value {value}") diff --git a/api/fields/raws.py b/api/fields/raws.py new file mode 100644 index 0000000000..15ec16ab13 --- /dev/null +++ b/api/fields/raws.py @@ -0,0 +1,17 @@ +from flask_restful import fields + +from core.file import File + + +class FilesContainedField(fields.Raw): + def format(self, value): + return self._format_file_object(value) + + def _format_file_object(self, v): + if isinstance(v, File): + return v.model_dump() + if isinstance(v, dict): + return {k: self._format_file_object(vv) for k, vv in v.items()} + if isinstance(v, list): + return [self._format_file_object(vv) for vv in v] + return v diff --git a/api/migrations/versions/2024_10_10_0516-bbadea11becb_add_name_and_size_to_tool_files.py b/api/migrations/versions/2024_10_10_0516-bbadea11becb_add_name_and_size_to_tool_files.py new file mode 100644 index 0000000000..c17d1db77a --- /dev/null +++ b/api/migrations/versions/2024_10_10_0516-bbadea11becb_add_name_and_size_to_tool_files.py @@ -0,0 +1,49 @@ +"""add name and size to tool_files + +Revision ID: bbadea11becb +Revises: 33f5fac87f29 +Create Date: 2024-10-10 05:16:14.764268 + +""" +from alembic import op +import models as models +import sqlalchemy as sa +from sqlalchemy.dialects import postgresql + +# revision identifiers, used by Alembic. +revision = 'bbadea11becb' +down_revision = 'd8e744d88ed6' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + # Get the database connection + conn = op.get_bind() + + # Use SQLAlchemy inspector to get the columns of the 'tool_files' table + inspector = sa.inspect(conn) + columns = [col['name'] for col in inspector.get_columns('tool_files')] + + # If 'name' or 'size' columns already exist, exit the upgrade function + if 'name' in columns or 'size' in columns: + return + + with op.batch_alter_table('tool_files', schema=None) as batch_op: + batch_op.add_column(sa.Column('name', sa.String(), nullable=True)) + batch_op.add_column(sa.Column('size', sa.Integer(), nullable=True)) + op.execute("UPDATE tool_files SET name = '' WHERE name IS NULL") + op.execute("UPDATE tool_files SET size = -1 WHERE size IS NULL") + with op.batch_alter_table('tool_files', schema=None) as batch_op: + batch_op.alter_column('name', existing_type=sa.String(), nullable=False) + batch_op.alter_column('size', existing_type=sa.Integer(), nullable=False) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('tool_files', schema=None) as batch_op: + batch_op.drop_column('size') + batch_op.drop_column('name') + # ### end Alembic commands ### diff --git a/api/models/enums.py b/api/models/enums.py new file mode 100644 index 0000000000..a83d35e042 --- /dev/null +++ b/api/models/enums.py @@ -0,0 +1,16 @@ +from enum import Enum + + +class CreatedByRole(str, Enum): + ACCOUNT = "account" + END_USER = "end_user" + + +class UserFrom(str, Enum): + ACCOUNT = "account" + END_USER = "end-user" + + +class WorkflowRunTriggeredFrom(str, Enum): + DEBUGGING = "debugging" + APP_RUN = "app-run" diff --git a/api/services/errors/workspace.py b/api/services/errors/workspace.py new file mode 100644 index 0000000000..714064ffdf --- /dev/null +++ b/api/services/errors/workspace.py @@ -0,0 +1,9 @@ +from services.errors.base import BaseServiceError + + +class WorkSpaceNotAllowedCreateError(BaseServiceError): + pass + + +class WorkSpaceNotFoundError(BaseServiceError): + pass diff --git a/api/tasks/mail_email_code_login.py b/api/tasks/mail_email_code_login.py new file mode 100644 index 0000000000..d78fc2b891 --- /dev/null +++ b/api/tasks/mail_email_code_login.py @@ -0,0 +1,41 @@ +import logging +import time + +import click +from celery import shared_task +from flask import render_template + +from extensions.ext_mail import mail + + +@shared_task(queue="mail") +def send_email_code_login_mail_task(language: str, to: str, code: str): + """ + Async Send email code login mail + :param language: Language in which the email should be sent (e.g., 'en', 'zh') + :param to: Recipient email address + :param code: Email code to be included in the email + """ + if not mail.is_inited(): + return + + logging.info(click.style("Start email code login mail to {}".format(to), fg="green")) + start_at = time.perf_counter() + + # send email code login mail using different languages + try: + if language == "zh-Hans": + html_content = render_template("email_code_login_mail_template_zh-CN.html", to=to, code=code) + mail.send(to=to, subject="邮箱验证码", html=html_content) + else: + html_content = render_template("email_code_login_mail_template_en-US.html", to=to, code=code) + mail.send(to=to, subject="Email Code", html=html_content) + + end_at = time.perf_counter() + logging.info( + click.style( + "Send email code login mail to {} succeeded: latency: {}".format(to, end_at - start_at), fg="green" + ) + ) + except Exception: + logging.exception("Send email code login mail to {} failed".format(to)) diff --git a/api/templates/email_code_login_mail_template_en-US.html b/api/templates/email_code_login_mail_template_en-US.html new file mode 100644 index 0000000000..066818d10c --- /dev/null +++ b/api/templates/email_code_login_mail_template_en-US.html @@ -0,0 +1,74 @@ + + + + + + +
+
+ + Dify Logo +
+

Your login code for Dify

+

Copy and paste this code, this code will only be valid for the next 5 minutes.

+
+ {{code}} +
+

If you didn't request a login, don't worry. You can safely ignore this email.

+
+ + diff --git a/api/templates/email_code_login_mail_template_zh-CN.html b/api/templates/email_code_login_mail_template_zh-CN.html new file mode 100644 index 0000000000..0c2b63a1f1 --- /dev/null +++ b/api/templates/email_code_login_mail_template_zh-CN.html @@ -0,0 +1,74 @@ + + + + + + +
+
+ + Dify Logo +
+

Dify 的登录验证码

+

复制并粘贴此验证码,注意验证码仅在接下来的 5 分钟内有效。

+
+ {{code}} +
+

如果您没有请求登录,请不要担心。您可以安全地忽略此电子邮件。

+
+ + diff --git a/api/tests/integration_tests/vdb/__mock/upstashvectordb.py b/api/tests/integration_tests/vdb/__mock/upstashvectordb.py new file mode 100644 index 0000000000..c93292bd8a --- /dev/null +++ b/api/tests/integration_tests/vdb/__mock/upstashvectordb.py @@ -0,0 +1,75 @@ +import os +from typing import Optional + +import pytest +from _pytest.monkeypatch import MonkeyPatch +from upstash_vector import Index + + +# Mocking the Index class from upstash_vector +class MockIndex: + def __init__(self, url="", token=""): + self.url = url + self.token = token + self.vectors = [] + + def upsert(self, vectors): + for vector in vectors: + vector.score = 0.5 + self.vectors.append(vector) + return {"code": 0, "msg": "operation success", "affectedCount": len(vectors)} + + def fetch(self, ids): + return [vector for vector in self.vectors if vector.id in ids] + + def delete(self, ids): + self.vectors = [vector for vector in self.vectors if vector.id not in ids] + return {"code": 0, "msg": "Success"} + + def query( + self, + vector: None, + top_k: int = 10, + include_vectors: bool = False, + include_metadata: bool = False, + filter: str = "", + data: Optional[str] = None, + namespace: str = "", + include_data: bool = False, + ): + # Simple mock query, in real scenario you would calculate similarity + mock_result = [] + for vector_data in self.vectors: + mock_result.append(vector_data) + return mock_result[:top_k] + + def reset(self): + self.vectors = [] + + def info(self): + return AttrDict({"dimension": 1024}) + + +class AttrDict(dict): + def __getattr__(self, item): + return self.get(item) + + +MOCK = os.getenv("MOCK_SWITCH", "false").lower() == "true" + + +@pytest.fixture +def setup_upstashvector_mock(request, monkeypatch: MonkeyPatch): + if MOCK: + monkeypatch.setattr(Index, "__init__", MockIndex.__init__) + monkeypatch.setattr(Index, "upsert", MockIndex.upsert) + monkeypatch.setattr(Index, "fetch", MockIndex.fetch) + monkeypatch.setattr(Index, "delete", MockIndex.delete) + monkeypatch.setattr(Index, "query", MockIndex.query) + monkeypatch.setattr(Index, "reset", MockIndex.reset) + monkeypatch.setattr(Index, "info", MockIndex.info) + + yield + + if MOCK: + monkeypatch.undo() diff --git a/api/tests/integration_tests/vdb/upstash/__init__.py b/api/tests/integration_tests/vdb/upstash/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/api/tests/integration_tests/vdb/upstash/test_upstash_vector.py b/api/tests/integration_tests/vdb/upstash/test_upstash_vector.py new file mode 100644 index 0000000000..23470474ff --- /dev/null +++ b/api/tests/integration_tests/vdb/upstash/test_upstash_vector.py @@ -0,0 +1,28 @@ +from core.rag.datasource.vdb.upstash.upstash_vector import UpstashVector, UpstashVectorConfig +from core.rag.models.document import Document +from tests.integration_tests.vdb.__mock.upstashvectordb import setup_upstashvector_mock +from tests.integration_tests.vdb.test_vector_store import AbstractVectorTest, get_example_text + + +class UpstashVectorTest(AbstractVectorTest): + def __init__(self): + super().__init__() + self.vector = UpstashVector( + collection_name="test_collection", + config=UpstashVectorConfig( + url="your-server-url", + token="your-access-token", + ), + ) + + def get_ids_by_metadata_field(self): + ids = self.vector.get_ids_by_metadata_field(key="document_id", value=self.example_doc_id) + assert len(ids) != 0 + + def search_by_full_text(self): + hits_by_full_text: list[Document] = self.vector.search_by_full_text(query=get_example_text()) + assert len(hits_by_full_text) == 0 + + +def test_upstash_vector(setup_upstashvector_mock): + UpstashVectorTest().run_all_tests() diff --git a/api/tests/integration_tests/workflow/test_sync_workflow.py b/api/tests/integration_tests/workflow/test_sync_workflow.py new file mode 100644 index 0000000000..df2ec95ebc --- /dev/null +++ b/api/tests/integration_tests/workflow/test_sync_workflow.py @@ -0,0 +1,57 @@ +""" +This test file is used to verify the compatibility of Workflow before and after supporting multiple file types. +""" + +import json + +from models import Workflow + +OLD_VERSION_WORKFLOW_FEATURES = { + "file_upload": { + "image": { + "enabled": True, + "number_limits": 6, + "transfer_methods": ["remote_url", "local_file"], + } + }, + "opening_statement": "", + "retriever_resource": {"enabled": True}, + "sensitive_word_avoidance": {"enabled": False}, + "speech_to_text": {"enabled": False}, + "suggested_questions": [], + "suggested_questions_after_answer": {"enabled": False}, + "text_to_speech": {"enabled": False, "language": "", "voice": ""}, +} + +NEW_VERSION_WORKFLOW_FEATURES = { + "file_upload": { + "enabled": True, + "allowed_file_types": ["image"], + "allowed_extensions": [], + "allowed_upload_methods": ["remote_url", "local_file"], + "number_limits": 6, + }, + "opening_statement": "", + "retriever_resource": {"enabled": True}, + "sensitive_word_avoidance": {"enabled": False}, + "speech_to_text": {"enabled": False}, + "suggested_questions": [], + "suggested_questions_after_answer": {"enabled": False}, + "text_to_speech": {"enabled": False, "language": "", "voice": ""}, +} + + +def test_workflow_features(): + workflow = Workflow( + tenant_id="", + app_id="", + type="", + version="", + graph="", + features=json.dumps(OLD_VERSION_WORKFLOW_FEATURES), + created_by="", + environment_variables=[], + conversation_variables=[], + ) + + assert workflow.features_dict == NEW_VERSION_WORKFLOW_FEATURES diff --git a/api/tests/unit_tests/core/test_file.py b/api/tests/unit_tests/core/test_file.py new file mode 100644 index 0000000000..aa61c1c6f7 --- /dev/null +++ b/api/tests/unit_tests/core/test_file.py @@ -0,0 +1,40 @@ +from core.file import FILE_MODEL_IDENTITY, File, FileTransferMethod, FileType + + +def test_file_loads_and_dumps(): + file = File( + id="file1", + tenant_id="tenant1", + type=FileType.IMAGE, + transfer_method=FileTransferMethod.REMOTE_URL, + remote_url="https://example.com/image1.jpg", + ) + + file_dict = file.model_dump() + assert file_dict["dify_model_identity"] == FILE_MODEL_IDENTITY + assert file_dict["type"] == file.type.value + assert isinstance(file_dict["type"], str) + assert file_dict["transfer_method"] == file.transfer_method.value + assert isinstance(file_dict["transfer_method"], str) + assert "_extra_config" not in file_dict + + file_obj = File.model_validate(file_dict) + assert file_obj.id == file.id + assert file_obj.tenant_id == file.tenant_id + assert file_obj.type == file.type + assert file_obj.transfer_method == file.transfer_method + assert file_obj.remote_url == file.remote_url + + +def test_file_to_dict(): + file = File( + id="file1", + tenant_id="tenant1", + type=FileType.IMAGE, + transfer_method=FileTransferMethod.REMOTE_URL, + remote_url="https://example.com/image1.jpg", + ) + + file_dict = file.to_dict() + assert "_extra_config" not in file_dict + assert "url" in file_dict diff --git a/api/tests/unit_tests/core/tools/test_tool_parameter_converter.py b/api/tests/unit_tests/core/tools/test_tool_parameter_converter.py deleted file mode 100644 index 279a6cdbc3..0000000000 --- a/api/tests/unit_tests/core/tools/test_tool_parameter_converter.py +++ /dev/null @@ -1,56 +0,0 @@ -import pytest - -from core.tools.entities.tool_entities import ToolParameter -from core.tools.utils.tool_parameter_converter import ToolParameterConverter - - -def test_get_parameter_type(): - assert ToolParameterConverter.get_parameter_type(ToolParameter.ToolParameterType.STRING) == "string" - assert ToolParameterConverter.get_parameter_type(ToolParameter.ToolParameterType.SELECT) == "string" - assert ToolParameterConverter.get_parameter_type(ToolParameter.ToolParameterType.BOOLEAN) == "boolean" - assert ToolParameterConverter.get_parameter_type(ToolParameter.ToolParameterType.NUMBER) == "number" - with pytest.raises(ValueError): - ToolParameterConverter.get_parameter_type("unsupported_type") - - -def test_cast_parameter_by_type(): - # string - assert ToolParameterConverter.cast_parameter_by_type("test", ToolParameter.ToolParameterType.STRING) == "test" - assert ToolParameterConverter.cast_parameter_by_type(1, ToolParameter.ToolParameterType.STRING) == "1" - assert ToolParameterConverter.cast_parameter_by_type(1.0, ToolParameter.ToolParameterType.STRING) == "1.0" - assert ToolParameterConverter.cast_parameter_by_type(None, ToolParameter.ToolParameterType.STRING) == "" - - # secret input - assert ToolParameterConverter.cast_parameter_by_type("test", ToolParameter.ToolParameterType.SECRET_INPUT) == "test" - assert ToolParameterConverter.cast_parameter_by_type(1, ToolParameter.ToolParameterType.SECRET_INPUT) == "1" - assert ToolParameterConverter.cast_parameter_by_type(1.0, ToolParameter.ToolParameterType.SECRET_INPUT) == "1.0" - assert ToolParameterConverter.cast_parameter_by_type(None, ToolParameter.ToolParameterType.SECRET_INPUT) == "" - - # select - assert ToolParameterConverter.cast_parameter_by_type("test", ToolParameter.ToolParameterType.SELECT) == "test" - assert ToolParameterConverter.cast_parameter_by_type(1, ToolParameter.ToolParameterType.SELECT) == "1" - assert ToolParameterConverter.cast_parameter_by_type(1.0, ToolParameter.ToolParameterType.SELECT) == "1.0" - assert ToolParameterConverter.cast_parameter_by_type(None, ToolParameter.ToolParameterType.SELECT) == "" - - # boolean - true_values = [True, "True", "true", "1", "YES", "Yes", "yes", "y", "something"] - for value in true_values: - assert ToolParameterConverter.cast_parameter_by_type(value, ToolParameter.ToolParameterType.BOOLEAN) is True - - false_values = [False, "False", "false", "0", "NO", "No", "no", "n", None, ""] - for value in false_values: - assert ToolParameterConverter.cast_parameter_by_type(value, ToolParameter.ToolParameterType.BOOLEAN) is False - - # number - assert ToolParameterConverter.cast_parameter_by_type("1", ToolParameter.ToolParameterType.NUMBER) == 1 - assert ToolParameterConverter.cast_parameter_by_type("1.0", ToolParameter.ToolParameterType.NUMBER) == 1.0 - assert ToolParameterConverter.cast_parameter_by_type("-1.0", ToolParameter.ToolParameterType.NUMBER) == -1.0 - assert ToolParameterConverter.cast_parameter_by_type(1, ToolParameter.ToolParameterType.NUMBER) == 1 - assert ToolParameterConverter.cast_parameter_by_type(1.0, ToolParameter.ToolParameterType.NUMBER) == 1.0 - assert ToolParameterConverter.cast_parameter_by_type(-1.0, ToolParameter.ToolParameterType.NUMBER) == -1.0 - assert ToolParameterConverter.cast_parameter_by_type(None, ToolParameter.ToolParameterType.NUMBER) is None - - # unknown - assert ToolParameterConverter.cast_parameter_by_type("1", "unknown_type") == "1" - assert ToolParameterConverter.cast_parameter_by_type(1, "unknown_type") == "1" - assert ToolParameterConverter.cast_parameter_by_type(None, ToolParameter.ToolParameterType.NUMBER) is None diff --git a/api/tests/unit_tests/core/tools/test_tool_parameter_type.py b/api/tests/unit_tests/core/tools/test_tool_parameter_type.py new file mode 100644 index 0000000000..8a41678267 --- /dev/null +++ b/api/tests/unit_tests/core/tools/test_tool_parameter_type.py @@ -0,0 +1,49 @@ +from core.tools.entities.tool_entities import ToolParameter + + +def test_get_parameter_type(): + assert ToolParameter.ToolParameterType.STRING.as_normal_type() == "string" + assert ToolParameter.ToolParameterType.SELECT.as_normal_type() == "string" + assert ToolParameter.ToolParameterType.SECRET_INPUT.as_normal_type() == "string" + assert ToolParameter.ToolParameterType.BOOLEAN.as_normal_type() == "boolean" + assert ToolParameter.ToolParameterType.NUMBER.as_normal_type() == "number" + assert ToolParameter.ToolParameterType.FILE.as_normal_type() == "file" + assert ToolParameter.ToolParameterType.FILES.as_normal_type() == "files" + + +def test_cast_parameter_by_type(): + # string + assert ToolParameter.ToolParameterType.STRING.cast_value("test") == "test" + assert ToolParameter.ToolParameterType.STRING.cast_value(1) == "1" + assert ToolParameter.ToolParameterType.STRING.cast_value(1.0) == "1.0" + assert ToolParameter.ToolParameterType.STRING.cast_value(None) == "" + + # secret input + assert ToolParameter.ToolParameterType.SECRET_INPUT.cast_value("test") == "test" + assert ToolParameter.ToolParameterType.SECRET_INPUT.cast_value(1) == "1" + assert ToolParameter.ToolParameterType.SECRET_INPUT.cast_value(1.0) == "1.0" + assert ToolParameter.ToolParameterType.SECRET_INPUT.cast_value(None) == "" + + # select + assert ToolParameter.ToolParameterType.SELECT.cast_value("test") == "test" + assert ToolParameter.ToolParameterType.SELECT.cast_value(1) == "1" + assert ToolParameter.ToolParameterType.SELECT.cast_value(1.0) == "1.0" + assert ToolParameter.ToolParameterType.SELECT.cast_value(None) == "" + + # boolean + true_values = [True, "True", "true", "1", "YES", "Yes", "yes", "y", "something"] + for value in true_values: + assert ToolParameter.ToolParameterType.BOOLEAN.cast_value(value) is True + + false_values = [False, "False", "false", "0", "NO", "No", "no", "n", None, ""] + for value in false_values: + assert ToolParameter.ToolParameterType.BOOLEAN.cast_value(value) is False + + # number + assert ToolParameter.ToolParameterType.NUMBER.cast_value("1") == 1 + assert ToolParameter.ToolParameterType.NUMBER.cast_value("1.0") == 1.0 + assert ToolParameter.ToolParameterType.NUMBER.cast_value("-1.0") == -1.0 + assert ToolParameter.ToolParameterType.NUMBER.cast_value(1) == 1 + assert ToolParameter.ToolParameterType.NUMBER.cast_value(1.0) == 1.0 + assert ToolParameter.ToolParameterType.NUMBER.cast_value(-1.0) == -1.0 + assert ToolParameter.ToolParameterType.NUMBER.cast_value(None) is None diff --git a/api/tests/unit_tests/core/workflow/nodes/test_document_extractor_node.py b/api/tests/unit_tests/core/workflow/nodes/test_document_extractor_node.py new file mode 100644 index 0000000000..a141fa9a13 --- /dev/null +++ b/api/tests/unit_tests/core/workflow/nodes/test_document_extractor_node.py @@ -0,0 +1,167 @@ +from unittest.mock import Mock, patch + +import pytest + +from core.file import File, FileTransferMethod +from core.variables import ArrayFileSegment +from core.variables.variables import StringVariable +from core.workflow.entities.node_entities import NodeRunResult +from core.workflow.nodes.document_extractor import DocumentExtractorNode, DocumentExtractorNodeData +from core.workflow.nodes.document_extractor.node import ( + _extract_text_from_doc, + _extract_text_from_pdf, + _extract_text_from_plain_text, +) +from core.workflow.nodes.enums import NodeType +from models.workflow import WorkflowNodeExecutionStatus + + +@pytest.fixture +def document_extractor_node(): + node_data = DocumentExtractorNodeData( + title="Test Document Extractor", + variable_selector=["node_id", "variable_name"], + ) + return DocumentExtractorNode( + id="test_node_id", + config={"id": "test_node_id", "data": node_data.model_dump()}, + graph_init_params=Mock(), + graph=Mock(), + graph_runtime_state=Mock(), + ) + + +@pytest.fixture +def mock_graph_runtime_state(): + return Mock() + + +def test_run_variable_not_found(document_extractor_node, mock_graph_runtime_state): + document_extractor_node.graph_runtime_state = mock_graph_runtime_state + mock_graph_runtime_state.variable_pool.get.return_value = None + + result = document_extractor_node._run() + + assert isinstance(result, NodeRunResult) + assert result.status == WorkflowNodeExecutionStatus.FAILED + assert result.error is not None + assert "File variable not found" in result.error + + +def test_run_invalid_variable_type(document_extractor_node, mock_graph_runtime_state): + document_extractor_node.graph_runtime_state = mock_graph_runtime_state + mock_graph_runtime_state.variable_pool.get.return_value = StringVariable( + value="Not an ArrayFileSegment", name="test" + ) + + result = document_extractor_node._run() + + assert isinstance(result, NodeRunResult) + assert result.status == WorkflowNodeExecutionStatus.FAILED + assert result.error is not None + assert "is not an ArrayFileSegment" in result.error + + +@pytest.mark.parametrize( + ("mime_type", "file_content", "expected_text", "transfer_method", "extension"), + [ + ("text/plain", b"Hello, world!", ["Hello, world!"], FileTransferMethod.LOCAL_FILE, ".txt"), + ( + "application/pdf", + b"%PDF-1.5\n%Test PDF content", + ["Mocked PDF content"], + FileTransferMethod.LOCAL_FILE, + ".pdf", + ), + ( + "application/vnd.openxmlformats-officedocument.wordprocessingml.document", + b"PK\x03\x04", + ["Mocked DOCX content"], + FileTransferMethod.REMOTE_URL, + "", + ), + ("text/plain", b"Remote content", ["Remote content"], FileTransferMethod.REMOTE_URL, None), + ], +) +def test_run_extract_text( + document_extractor_node, + mock_graph_runtime_state, + mime_type, + file_content, + expected_text, + transfer_method, + extension, + monkeypatch, +): + document_extractor_node.graph_runtime_state = mock_graph_runtime_state + + mock_file = Mock(spec=File) + mock_file.mime_type = mime_type + mock_file.transfer_method = transfer_method + mock_file.related_id = "test_file_id" if transfer_method == FileTransferMethod.LOCAL_FILE else None + mock_file.remote_url = "https://example.com/file.txt" if transfer_method == FileTransferMethod.REMOTE_URL else None + mock_file.extension = extension + + mock_array_file_segment = Mock(spec=ArrayFileSegment) + mock_array_file_segment.value = [mock_file] + + mock_graph_runtime_state.variable_pool.get.return_value = mock_array_file_segment + + mock_download = Mock(return_value=file_content) + mock_ssrf_proxy_get = Mock() + mock_ssrf_proxy_get.return_value.content = file_content + mock_ssrf_proxy_get.return_value.raise_for_status = Mock() + + monkeypatch.setattr("core.file.file_manager.download", mock_download) + monkeypatch.setattr("core.helper.ssrf_proxy.get", mock_ssrf_proxy_get) + + if mime_type == "application/pdf": + mock_pdf_extract = Mock(return_value=expected_text[0]) + monkeypatch.setattr("core.workflow.nodes.document_extractor.node._extract_text_from_pdf", mock_pdf_extract) + elif mime_type.startswith("application/vnd.openxmlformats"): + mock_docx_extract = Mock(return_value=expected_text[0]) + monkeypatch.setattr("core.workflow.nodes.document_extractor.node._extract_text_from_doc", mock_docx_extract) + + result = document_extractor_node._run() + + assert isinstance(result, NodeRunResult) + assert result.status == WorkflowNodeExecutionStatus.SUCCEEDED + assert result.outputs is not None + assert result.outputs["text"] == expected_text + + if transfer_method == FileTransferMethod.REMOTE_URL: + mock_ssrf_proxy_get.assert_called_once_with("https://example.com/file.txt") + elif transfer_method == FileTransferMethod.LOCAL_FILE: + mock_download.assert_called_once_with(mock_file) + + +def test_extract_text_from_plain_text(): + text = _extract_text_from_plain_text(b"Hello, world!") + assert text == "Hello, world!" + + +@patch("pypdfium2.PdfDocument") +def test_extract_text_from_pdf(mock_pdf_document): + mock_page = Mock() + mock_text_page = Mock() + mock_text_page.get_text_range.return_value = "PDF content" + mock_page.get_textpage.return_value = mock_text_page + mock_pdf_document.return_value = [mock_page] + text = _extract_text_from_pdf(b"%PDF-1.5\n%Test PDF content") + assert text == "PDF content" + + +@patch("docx.Document") +def test_extract_text_from_doc(mock_document): + mock_paragraph1 = Mock() + mock_paragraph1.text = "Paragraph 1" + mock_paragraph2 = Mock() + mock_paragraph2.text = "Paragraph 2" + mock_document.return_value.paragraphs = [mock_paragraph1, mock_paragraph2] + + text = _extract_text_from_doc(b"PK\x03\x04") + assert text == "Paragraph 1\nParagraph 2" + + +def test_node_type(document_extractor_node): + assert document_extractor_node._node_type == NodeType.DOCUMENT_EXTRACTOR diff --git a/api/tests/unit_tests/core/workflow/nodes/test_http_request_node.py b/api/tests/unit_tests/core/workflow/nodes/test_http_request_node.py new file mode 100644 index 0000000000..2a5fda48b1 --- /dev/null +++ b/api/tests/unit_tests/core/workflow/nodes/test_http_request_node.py @@ -0,0 +1,369 @@ +import json + +import httpx + +from core.app.entities.app_invoke_entities import InvokeFrom +from core.file import File, FileTransferMethod, FileType +from core.variables import FileVariable +from core.workflow.entities.variable_pool import VariablePool +from core.workflow.graph_engine import Graph, GraphInitParams, GraphRuntimeState +from core.workflow.nodes.answer import AnswerStreamGenerateRoute +from core.workflow.nodes.end import EndStreamParam +from core.workflow.nodes.http_request import ( + BodyData, + HttpRequestNode, + HttpRequestNodeAuthorization, + HttpRequestNodeBody, + HttpRequestNodeData, +) +from core.workflow.nodes.http_request.entities import HttpRequestNodeTimeout +from core.workflow.nodes.http_request.executor import Executor, _plain_text_to_dict +from models.enums import UserFrom +from models.workflow import WorkflowNodeExecutionStatus, WorkflowType + + +def test_plain_text_to_dict(): + assert _plain_text_to_dict("aa\n cc:") == {"aa": "", "cc": ""} + assert _plain_text_to_dict("aa:bb\n cc:dd") == {"aa": "bb", "cc": "dd"} + assert _plain_text_to_dict("aa:bb\n cc:dd\n") == {"aa": "bb", "cc": "dd"} + assert _plain_text_to_dict("aa:bb\n\n cc : dd\n\n") == {"aa": "bb", "cc": "dd"} + + +def test_http_request_node_binary_file(monkeypatch): + data = HttpRequestNodeData( + title="test", + method="post", + url="http://example.org/post", + authorization=HttpRequestNodeAuthorization(type="no-auth"), + headers="", + params="", + body=HttpRequestNodeBody( + type="binary", + data=[ + BodyData( + key="file", + type="file", + value="", + file=["1111", "file"], + ) + ], + ), + ) + variable_pool = VariablePool( + system_variables={}, + user_inputs={}, + ) + variable_pool.add( + ["1111", "file"], + FileVariable( + name="file", + value=File( + tenant_id="1", + type=FileType.IMAGE, + transfer_method=FileTransferMethod.LOCAL_FILE, + related_id="1111", + ), + ), + ) + node = HttpRequestNode( + id="1", + config={ + "id": "1", + "data": data.model_dump(), + }, + graph_init_params=GraphInitParams( + tenant_id="1", + app_id="1", + workflow_type=WorkflowType.WORKFLOW, + workflow_id="1", + graph_config={}, + user_id="1", + user_from=UserFrom.ACCOUNT, + invoke_from=InvokeFrom.SERVICE_API, + call_depth=0, + ), + graph=Graph( + root_node_id="1", + answer_stream_generate_routes=AnswerStreamGenerateRoute( + answer_dependencies={}, + answer_generate_route={}, + ), + end_stream_param=EndStreamParam( + end_dependencies={}, + end_stream_variable_selector_mapping={}, + ), + ), + graph_runtime_state=GraphRuntimeState( + variable_pool=variable_pool, + start_at=0, + ), + ) + monkeypatch.setattr( + "core.workflow.nodes.http_request.executor.file_manager.download", + lambda *args, **kwargs: b"test", + ) + monkeypatch.setattr( + "core.helper.ssrf_proxy.post", + lambda *args, **kwargs: httpx.Response(200, content=kwargs["content"]), + ) + result = node._run() + assert result.status == WorkflowNodeExecutionStatus.SUCCEEDED + assert result.outputs is not None + assert result.outputs["body"] == "test" + + +def test_http_request_node_form_with_file(monkeypatch): + data = HttpRequestNodeData( + title="test", + method="post", + url="http://example.org/post", + authorization=HttpRequestNodeAuthorization(type="no-auth"), + headers="", + params="", + body=HttpRequestNodeBody( + type="form-data", + data=[ + BodyData( + key="file", + type="file", + file=["1111", "file"], + ), + BodyData( + key="name", + type="text", + value="test", + ), + ], + ), + ) + variable_pool = VariablePool( + system_variables={}, + user_inputs={}, + ) + variable_pool.add( + ["1111", "file"], + FileVariable( + name="file", + value=File( + tenant_id="1", + type=FileType.IMAGE, + transfer_method=FileTransferMethod.LOCAL_FILE, + related_id="1111", + ), + ), + ) + node = HttpRequestNode( + id="1", + config={ + "id": "1", + "data": data.model_dump(), + }, + graph_init_params=GraphInitParams( + tenant_id="1", + app_id="1", + workflow_type=WorkflowType.WORKFLOW, + workflow_id="1", + graph_config={}, + user_id="1", + user_from=UserFrom.ACCOUNT, + invoke_from=InvokeFrom.SERVICE_API, + call_depth=0, + ), + graph=Graph( + root_node_id="1", + answer_stream_generate_routes=AnswerStreamGenerateRoute( + answer_dependencies={}, + answer_generate_route={}, + ), + end_stream_param=EndStreamParam( + end_dependencies={}, + end_stream_variable_selector_mapping={}, + ), + ), + graph_runtime_state=GraphRuntimeState( + variable_pool=variable_pool, + start_at=0, + ), + ) + monkeypatch.setattr( + "core.workflow.nodes.http_request.executor.file_manager.download", + lambda *args, **kwargs: b"test", + ) + + def attr_checker(*args, **kwargs): + assert kwargs["data"] == {"name": "test"} + assert kwargs["files"] == {"file": b"test"} + return httpx.Response(200, content=b"") + + monkeypatch.setattr( + "core.helper.ssrf_proxy.post", + attr_checker, + ) + result = node._run() + assert result.status == WorkflowNodeExecutionStatus.SUCCEEDED + assert result.outputs is not None + assert result.outputs["body"] == "" + + +def test_executor_with_json_body_and_number_variable(): + # Prepare the variable pool + variable_pool = VariablePool( + system_variables={}, + user_inputs={}, + ) + variable_pool.add(["pre_node_id", "number"], 42) + + # Prepare the node data + node_data = HttpRequestNodeData( + title="Test JSON Body with Number Variable", + method="post", + url="https://api.example.com/data", + authorization=HttpRequestNodeAuthorization(type="no-auth"), + headers="Content-Type: application/json", + params="", + body=HttpRequestNodeBody( + type="json", + data=[ + BodyData( + key="", + type="text", + value='{"number": {{#pre_node_id.number#}}}', + ) + ], + ), + ) + + # Initialize the Executor + executor = Executor( + node_data=node_data, + timeout=HttpRequestNodeTimeout(connect=10, read=30, write=30), + variable_pool=variable_pool, + ) + + # Check the executor's data + assert executor.method == "post" + assert executor.url == "https://api.example.com/data" + assert executor.headers == {"Content-Type": "application/json"} + assert executor.params == {} + assert executor.json == {"number": 42} + assert executor.data is None + assert executor.files is None + assert executor.content is None + + # Check the raw request (to_log method) + raw_request = executor.to_log() + assert "POST /data HTTP/1.1" in raw_request + assert "Host: api.example.com" in raw_request + assert "Content-Type: application/json" in raw_request + assert '{"number": 42}' in raw_request + + +def test_executor_with_json_body_and_object_variable(): + # Prepare the variable pool + variable_pool = VariablePool( + system_variables={}, + user_inputs={}, + ) + variable_pool.add(["pre_node_id", "object"], {"name": "John Doe", "age": 30, "email": "john@example.com"}) + + # Prepare the node data + node_data = HttpRequestNodeData( + title="Test JSON Body with Object Variable", + method="post", + url="https://api.example.com/data", + authorization=HttpRequestNodeAuthorization(type="no-auth"), + headers="Content-Type: application/json", + params="", + body=HttpRequestNodeBody( + type="json", + data=[ + BodyData( + key="", + type="text", + value="{{#pre_node_id.object#}}", + ) + ], + ), + ) + + # Initialize the Executor + executor = Executor( + node_data=node_data, + timeout=HttpRequestNodeTimeout(connect=10, read=30, write=30), + variable_pool=variable_pool, + ) + + # Check the executor's data + assert executor.method == "post" + assert executor.url == "https://api.example.com/data" + assert executor.headers == {"Content-Type": "application/json"} + assert executor.params == {} + assert executor.json == {"name": "John Doe", "age": 30, "email": "john@example.com"} + assert executor.data is None + assert executor.files is None + assert executor.content is None + + # Check the raw request (to_log method) + raw_request = executor.to_log() + assert "POST /data HTTP/1.1" in raw_request + assert "Host: api.example.com" in raw_request + assert "Content-Type: application/json" in raw_request + assert '"name": "John Doe"' in raw_request + assert '"age": 30' in raw_request + assert '"email": "john@example.com"' in raw_request + + +def test_executor_with_json_body_and_nested_object_variable(): + # Prepare the variable pool + variable_pool = VariablePool( + system_variables={}, + user_inputs={}, + ) + variable_pool.add(["pre_node_id", "object"], {"name": "John Doe", "age": 30, "email": "john@example.com"}) + + # Prepare the node data + node_data = HttpRequestNodeData( + title="Test JSON Body with Nested Object Variable", + method="post", + url="https://api.example.com/data", + authorization=HttpRequestNodeAuthorization(type="no-auth"), + headers="Content-Type: application/json", + params="", + body=HttpRequestNodeBody( + type="json", + data=[ + BodyData( + key="", + type="text", + value='{"object": {{#pre_node_id.object#}}}', + ) + ], + ), + ) + + # Initialize the Executor + executor = Executor( + node_data=node_data, + timeout=HttpRequestNodeTimeout(connect=10, read=30, write=30), + variable_pool=variable_pool, + ) + + # Check the executor's data + assert executor.method == "post" + assert executor.url == "https://api.example.com/data" + assert executor.headers == {"Content-Type": "application/json"} + assert executor.params == {} + assert executor.json == {"object": {"name": "John Doe", "age": 30, "email": "john@example.com"}} + assert executor.data is None + assert executor.files is None + assert executor.content is None + + # Check the raw request (to_log method) + raw_request = executor.to_log() + assert "POST /data HTTP/1.1" in raw_request + assert "Host: api.example.com" in raw_request + assert "Content-Type: application/json" in raw_request + assert '"object": {' in raw_request + assert '"name": "John Doe"' in raw_request + assert '"age": 30' in raw_request + assert '"email": "john@example.com"' in raw_request diff --git a/api/tests/unit_tests/core/workflow/nodes/test_list_operator.py b/api/tests/unit_tests/core/workflow/nodes/test_list_operator.py new file mode 100644 index 0000000000..53e3c93fcc --- /dev/null +++ b/api/tests/unit_tests/core/workflow/nodes/test_list_operator.py @@ -0,0 +1,111 @@ +from unittest.mock import MagicMock + +import pytest + +from core.file import File +from core.file.models import FileTransferMethod, FileType +from core.variables import ArrayFileSegment +from core.workflow.nodes.list_operator.entities import FilterBy, FilterCondition, Limit, ListOperatorNodeData, OrderBy +from core.workflow.nodes.list_operator.node import ListOperatorNode +from models.workflow import WorkflowNodeExecutionStatus + + +@pytest.fixture +def list_operator_node(): + config = { + "variable": ["test_variable"], + "filter_by": FilterBy( + enabled=True, + conditions=[ + FilterCondition(key="type", comparison_operator="in", value=[FileType.IMAGE, FileType.DOCUMENT]) + ], + ), + "order_by": OrderBy(enabled=False, value="asc"), + "limit": Limit(enabled=False, size=0), + "title": "Test Title", + } + node_data = ListOperatorNodeData(**config) + node = ListOperatorNode( + id="test_node_id", + config={ + "id": "test_node_id", + "data": node_data.model_dump(), + }, + graph_init_params=MagicMock(), + graph=MagicMock(), + graph_runtime_state=MagicMock(), + ) + node.graph_runtime_state = MagicMock() + node.graph_runtime_state.variable_pool = MagicMock() + return node + + +def test_filter_files_by_type(list_operator_node): + # Setup test data + files = [ + File( + filename="image1.jpg", + type=FileType.IMAGE, + tenant_id="tenant1", + transfer_method=FileTransferMethod.LOCAL_FILE, + related_id="related1", + ), + File( + filename="document1.pdf", + type=FileType.DOCUMENT, + tenant_id="tenant1", + transfer_method=FileTransferMethod.LOCAL_FILE, + related_id="related2", + ), + File( + filename="image2.png", + type=FileType.IMAGE, + tenant_id="tenant1", + transfer_method=FileTransferMethod.LOCAL_FILE, + related_id="related3", + ), + File( + filename="audio1.mp3", + type=FileType.AUDIO, + tenant_id="tenant1", + transfer_method=FileTransferMethod.LOCAL_FILE, + related_id="related4", + ), + ] + variable = ArrayFileSegment(value=files) + list_operator_node.graph_runtime_state.variable_pool.get.return_value = variable + + # Run the node + result = list_operator_node._run() + + # Verify the result + expected_files = [ + { + "filename": "image1.jpg", + "type": FileType.IMAGE, + "tenant_id": "tenant1", + "transfer_method": FileTransferMethod.LOCAL_FILE, + "related_id": "related1", + }, + { + "filename": "document1.pdf", + "type": FileType.DOCUMENT, + "tenant_id": "tenant1", + "transfer_method": FileTransferMethod.LOCAL_FILE, + "related_id": "related2", + }, + { + "filename": "image2.png", + "type": FileType.IMAGE, + "tenant_id": "tenant1", + "transfer_method": FileTransferMethod.LOCAL_FILE, + "related_id": "related3", + }, + ] + assert result.status == WorkflowNodeExecutionStatus.SUCCEEDED + for expected_file, result_file in zip(expected_files, result.outputs["result"]): + assert expected_file["filename"] == result_file.filename + assert expected_file["type"] == result_file.type + assert expected_file["tenant_id"] == result_file.tenant_id + assert expected_file["transfer_method"] == result_file.transfer_method + assert expected_file["related_id"] == result_file.related_id diff --git a/api/tests/unit_tests/core/workflow/nodes/test_question_classifier_node.py b/api/tests/unit_tests/core/workflow/nodes/test_question_classifier_node.py new file mode 100644 index 0000000000..f990280c5f --- /dev/null +++ b/api/tests/unit_tests/core/workflow/nodes/test_question_classifier_node.py @@ -0,0 +1,67 @@ +from core.model_runtime.entities import ImagePromptMessageContent +from core.workflow.nodes.question_classifier import QuestionClassifierNodeData + + +def test_init_question_classifier_node_data(): + data = { + "title": "test classifier node", + "query_variable_selector": ["id", "name"], + "model": {"provider": "openai", "name": "gpt-3.5-turbo", "mode": "completion", "completion_params": {}}, + "classes": [{"id": "1", "name": "class 1"}], + "instruction": "This is a test instruction", + "memory": { + "role_prefix": {"user": "Human:", "assistant": "AI:"}, + "window": {"enabled": True, "size": 5}, + "query_prompt_template": "Previous conversation:\n{history}\n\nHuman: {query}\nAI:", + }, + "vision": {"enabled": True, "configs": {"variable_selector": ["image"], "detail": "low"}}, + } + + node_data = QuestionClassifierNodeData(**data) + + assert node_data.query_variable_selector == ["id", "name"] + assert node_data.model.provider == "openai" + assert node_data.classes[0].id == "1" + assert node_data.instruction == "This is a test instruction" + assert node_data.memory is not None + assert node_data.memory.role_prefix is not None + assert node_data.memory.role_prefix.user == "Human:" + assert node_data.memory.role_prefix.assistant == "AI:" + assert node_data.memory.window.enabled == True + assert node_data.memory.window.size == 5 + assert node_data.memory.query_prompt_template == "Previous conversation:\n{history}\n\nHuman: {query}\nAI:" + assert node_data.vision.enabled == True + assert node_data.vision.configs.variable_selector == ["image"] + assert node_data.vision.configs.detail == ImagePromptMessageContent.DETAIL.LOW + + +def test_init_question_classifier_node_data_without_vision_config(): + data = { + "title": "test classifier node", + "query_variable_selector": ["id", "name"], + "model": {"provider": "openai", "name": "gpt-3.5-turbo", "mode": "completion", "completion_params": {}}, + "classes": [{"id": "1", "name": "class 1"}], + "instruction": "This is a test instruction", + "memory": { + "role_prefix": {"user": "Human:", "assistant": "AI:"}, + "window": {"enabled": True, "size": 5}, + "query_prompt_template": "Previous conversation:\n{history}\n\nHuman: {query}\nAI:", + }, + } + + node_data = QuestionClassifierNodeData(**data) + + assert node_data.query_variable_selector == ["id", "name"] + assert node_data.model.provider == "openai" + assert node_data.classes[0].id == "1" + assert node_data.instruction == "This is a test instruction" + assert node_data.memory is not None + assert node_data.memory.role_prefix is not None + assert node_data.memory.role_prefix.user == "Human:" + assert node_data.memory.role_prefix.assistant == "AI:" + assert node_data.memory.window.enabled == True + assert node_data.memory.window.size == 5 + assert node_data.memory.query_prompt_template == "Previous conversation:\n{history}\n\nHuman: {query}\nAI:" + assert node_data.vision.enabled == False + assert node_data.vision.configs.variable_selector == ["sys", "files"] + assert node_data.vision.configs.detail == ImagePromptMessageContent.DETAIL.HIGH diff --git a/api/tests/unit_tests/core/workflow/test_variable_pool.py b/api/tests/unit_tests/core/workflow/test_variable_pool.py new file mode 100644 index 0000000000..9ea6acac17 --- /dev/null +++ b/api/tests/unit_tests/core/workflow/test_variable_pool.py @@ -0,0 +1,45 @@ +import pytest + +from core.file import File, FileTransferMethod, FileType +from core.variables import FileSegment, StringSegment +from core.workflow.entities.variable_pool import VariablePool + + +@pytest.fixture +def pool(): + return VariablePool(system_variables={}, user_inputs={}) + + +@pytest.fixture +def file(): + return File( + tenant_id="test_tenant_id", + type=FileType.DOCUMENT, + transfer_method=FileTransferMethod.LOCAL_FILE, + related_id="test_related_id", + remote_url="test_url", + filename="test_file.txt", + ) + + +def test_get_file_attribute(pool, file): + # Add a FileSegment to the pool + pool.add(("node_1", "file_var"), FileSegment(value=file)) + + # Test getting the 'name' attribute of the file + result = pool.get(("node_1", "file_var", "name")) + + assert result is not None + assert result.value == file.filename + + # Test getting a non-existent attribute + result = pool.get(("node_1", "file_var", "non_existent_attr")) + assert result is None + + +def test_use_long_selector(pool): + pool.add(("node_1", "part_1", "part_2"), StringSegment(value="test_value")) + + result = pool.get(("node_1", "part_1", "part_2")) + assert result is not None + assert result.value == "test_value" diff --git a/api/tests/unit_tests/core/workflow/utils/test_variable_template_parser.py b/api/tests/unit_tests/core/workflow/utils/test_variable_template_parser.py new file mode 100644 index 0000000000..2f90afcf89 --- /dev/null +++ b/api/tests/unit_tests/core/workflow/utils/test_variable_template_parser.py @@ -0,0 +1,28 @@ +from core.variables import SecretVariable +from core.workflow.entities.variable_entities import VariableSelector +from core.workflow.entities.variable_pool import VariablePool +from core.workflow.enums import SystemVariableKey +from core.workflow.utils import variable_template_parser + + +def test_extract_selectors_from_template(): + variable_pool = VariablePool( + system_variables={ + SystemVariableKey("user_id"): "fake-user-id", + }, + user_inputs={}, + environment_variables=[ + SecretVariable(name="secret_key", value="fake-secret-key"), + ], + conversation_variables=[], + ) + variable_pool.add(("node_id", "custom_query"), "fake-user-query") + template = ( + "Hello, {{#sys.user_id#}}! Your query is {{#node_id.custom_query#}}. And your key is {{#env.secret_key#}}." + ) + selectors = variable_template_parser.extract_selectors_from_template(template) + assert selectors == [ + VariableSelector(variable="#sys.user_id#", value_selector=["sys", "user_id"]), + VariableSelector(variable="#node_id.custom_query#", value_selector=["node_id", "custom_query"]), + VariableSelector(variable="#env.secret_key#", value_selector=["env", "secret_key"]), + ] diff --git a/api/tests/unit_tests/oss/__mock/__init__.py b/api/tests/unit_tests/oss/__mock/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/api/tests/unit_tests/oss/__mock/volcengine_tos.py b/api/tests/unit_tests/oss/__mock/volcengine_tos.py new file mode 100644 index 0000000000..241764c521 --- /dev/null +++ b/api/tests/unit_tests/oss/__mock/volcengine_tos.py @@ -0,0 +1,100 @@ +import os +from typing import Union +from unittest.mock import MagicMock + +import pytest +from _pytest.monkeypatch import MonkeyPatch +from tos import TosClientV2 +from tos.clientv2 import DeleteObjectOutput, GetObjectOutput, HeadObjectOutput, PutObjectOutput + + +class AttrDict(dict): + def __getattr__(self, item): + return self.get(item) + + +def get_example_bucket() -> str: + return "dify" + + +def get_example_filename() -> str: + return "test.txt" + + +def get_example_data() -> bytes: + return b"test" + + +def get_example_filepath() -> str: + return "/test" + + +class MockVolcengineTosClass: + def __init__(self, ak="", sk="", endpoint="", region=""): + self.bucket_name = get_example_bucket() + self.key = get_example_filename() + self.content = get_example_data() + self.filepath = get_example_filepath() + self.resp = AttrDict( + { + "x-tos-server-side-encryption": "kms", + "x-tos-server-side-encryption-kms-key-id": "trn:kms:cn-beijing:****:keyrings/ring-test/keys/key-test", + "x-tos-server-side-encryption-customer-algorithm": "AES256", + "x-tos-version-id": "test", + "x-tos-hash-crc64ecma": 123456, + "request_id": "test", + "headers": { + "x-tos-id-2": "test", + "ETag": "123456", + }, + "status": 200, + } + ) + + def put_object(self, bucket: str, key: str, content=None) -> PutObjectOutput: + assert bucket == self.bucket_name + assert key == self.key + assert content == self.content + return PutObjectOutput(self.resp) + + def get_object(self, bucket: str, key: str) -> GetObjectOutput: + assert bucket == self.bucket_name + assert key == self.key + + get_object_output = MagicMock(GetObjectOutput) + get_object_output.read.return_value = self.content + return get_object_output + + def get_object_to_file(self, bucket: str, key: str, file_path: str): + assert bucket == self.bucket_name + assert key == self.key + assert file_path == self.filepath + + def head_object(self, bucket: str, key: str) -> HeadObjectOutput: + assert bucket == self.bucket_name + assert key == self.key + return HeadObjectOutput(self.resp) + + def delete_object(self, bucket: str, key: str): + assert bucket == self.bucket_name + assert key == self.key + return DeleteObjectOutput(self.resp) + + +MOCK = os.getenv("MOCK_SWITCH", "false").lower() == "true" + + +@pytest.fixture +def setup_volcengine_tos_mock(monkeypatch: MonkeyPatch): + if MOCK: + monkeypatch.setattr(TosClientV2, "__init__", MockVolcengineTosClass.__init__) + monkeypatch.setattr(TosClientV2, "put_object", MockVolcengineTosClass.put_object) + monkeypatch.setattr(TosClientV2, "get_object", MockVolcengineTosClass.get_object) + monkeypatch.setattr(TosClientV2, "get_object_to_file", MockVolcengineTosClass.get_object_to_file) + monkeypatch.setattr(TosClientV2, "head_object", MockVolcengineTosClass.head_object) + monkeypatch.setattr(TosClientV2, "delete_object", MockVolcengineTosClass.delete_object) + + yield + + if MOCK: + monkeypatch.undo() diff --git a/api/tests/unit_tests/oss/volcengine_tos/__init__.py b/api/tests/unit_tests/oss/volcengine_tos/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/api/tests/unit_tests/oss/volcengine_tos/test_volcengine_tos.py b/api/tests/unit_tests/oss/volcengine_tos/test_volcengine_tos.py new file mode 100644 index 0000000000..545d18044d --- /dev/null +++ b/api/tests/unit_tests/oss/volcengine_tos/test_volcengine_tos.py @@ -0,0 +1,67 @@ +from collections.abc import Generator + +from flask import Flask +from tos import TosClientV2 +from tos.clientv2 import GetObjectOutput, HeadObjectOutput, PutObjectOutput + +from extensions.storage.volcengine_tos_storage import VolcengineTosStorage +from tests.unit_tests.oss.__mock.volcengine_tos import ( + get_example_bucket, + get_example_data, + get_example_filename, + get_example_filepath, + setup_volcengine_tos_mock, +) + + +class VolcengineTosTest: + _instance = None + + def __new__(cls): + if cls._instance == None: + cls._instance = object.__new__(cls) + return cls._instance + else: + return cls._instance + + def __init__(self): + self.storage = VolcengineTosStorage() + self.storage.bucket_name = get_example_bucket() + self.storage.client = TosClientV2( + ak="dify", + sk="dify", + endpoint="https://xxx.volces.com", + region="cn-beijing", + ) + + +def test_save(setup_volcengine_tos_mock): + volc_tos = VolcengineTosTest() + volc_tos.storage.save(get_example_filename(), get_example_data()) + + +def test_load_once(setup_volcengine_tos_mock): + volc_tos = VolcengineTosTest() + assert volc_tos.storage.load_once(get_example_filename()) == get_example_data() + + +def test_load_stream(setup_volcengine_tos_mock): + volc_tos = VolcengineTosTest() + generator = volc_tos.storage.load_stream(get_example_filename()) + assert isinstance(generator, Generator) + assert next(generator) == get_example_data() + + +def test_download(setup_volcengine_tos_mock): + volc_tos = VolcengineTosTest() + volc_tos.storage.download(get_example_filename(), get_example_filepath()) + + +def test_exists(setup_volcengine_tos_mock): + volc_tos = VolcengineTosTest() + assert volc_tos.storage.exists(get_example_filename()) + + +def test_delete(setup_volcengine_tos_mock): + volc_tos = VolcengineTosTest() + volc_tos.storage.delete(get_example_filename()) diff --git a/web/__mocks__/mime.js b/web/__mocks__/mime.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/web/app/components/app/app-publisher/features-wrapper.tsx b/web/app/components/app/app-publisher/features-wrapper.tsx new file mode 100644 index 0000000000..dadd112135 --- /dev/null +++ b/web/app/components/app/app-publisher/features-wrapper.tsx @@ -0,0 +1,86 @@ +import React, { useCallback, useState } from 'react' +import { useTranslation } from 'react-i18next' +import produce from 'immer' +import type { AppPublisherProps } from '@/app/components/app/app-publisher' +import Confirm from '@/app/components/base/confirm' +import AppPublisher from '@/app/components/app/app-publisher' +import { useFeatures, useFeaturesStore } from '@/app/components/base/features/hooks' +import type { ModelAndParameter } from '@/app/components/app/configuration/debug/types' +import type { FileUpload } from '@/app/components/base/features/types' +import { Resolution } from '@/types/app' +import { FILE_EXTS } from '@/app/components/base/prompt-editor/constants' +import { SupportUploadFileTypes } from '@/app/components/workflow/types' + +type Props = Omit & { + onPublish?: (modelAndParameter?: ModelAndParameter, features?: any) => Promise | any + publishedConfig?: any + resetAppConfig?: () => void +} + +const FeaturesWrappedAppPublisher = (props: Props) => { + const { t } = useTranslation() + const features = useFeatures(s => s.features) + const featuresStore = useFeaturesStore() + const [restoreConfirmOpen, setRestoreConfirmOpen] = useState(false) + const handleConfirm = useCallback(() => { + props.resetAppConfig?.() + const { + features, + setFeatures, + } = featuresStore!.getState() + const newFeatures = produce(features, (draft) => { + draft.moreLikeThis = props.publishedConfig.modelConfig.more_like_this || { enabled: false } + draft.opening = { + enabled: !!props.publishedConfig.modelConfig.opening_statement, + opening_statement: props.publishedConfig.modelConfig.opening_statement || '', + suggested_questions: props.publishedConfig.modelConfig.suggested_questions || [], + } + draft.moderation = props.publishedConfig.modelConfig.sensitive_word_avoidance || { enabled: false } + draft.speech2text = props.publishedConfig.modelConfig.speech_to_text || { enabled: false } + draft.text2speech = props.publishedConfig.modelConfig.text_to_speech || { enabled: false } + draft.suggested = props.publishedConfig.modelConfig.suggested_questions_after_answer || { enabled: false } + draft.citation = props.publishedConfig.modelConfig.retriever_resource || { enabled: false } + draft.annotationReply = props.publishedConfig.modelConfig.annotation_reply || { enabled: false } + draft.file = { + image: { + detail: props.publishedConfig.modelConfig.file_upload?.image?.detail || Resolution.high, + enabled: !!props.publishedConfig.modelConfig.file_upload?.image?.enabled, + number_limits: props.publishedConfig.modelConfig.file_upload?.image?.number_limits || 3, + transfer_methods: props.publishedConfig.modelConfig.file_upload?.image?.transfer_methods || ['local_file', 'remote_url'], + }, + enabled: !!(props.publishedConfig.modelConfig.file_upload?.enabled || props.publishedConfig.modelConfig.file_upload?.image?.enabled), + allowed_file_types: props.publishedConfig.modelConfig.file_upload?.allowed_file_types || [SupportUploadFileTypes.image], + allowed_file_extensions: props.publishedConfig.modelConfig.file_upload?.allowed_file_extensions || FILE_EXTS[SupportUploadFileTypes.image].map(ext => `.${ext}`), + allowed_file_upload_methods: props.publishedConfig.modelConfig.file_upload?.allowed_file_upload_methods || props.publishedConfig.modelConfig.file_upload?.image?.transfer_methods || ['local_file', 'remote_url'], + number_limits: props.publishedConfig.modelConfig.file_upload?.number_limits || props.publishedConfig.modelConfig.file_upload?.image?.number_limits || 3, + } as FileUpload + }) + setFeatures(newFeatures) + setRestoreConfirmOpen(false) + }, [featuresStore, props]) + + const handlePublish = useCallback((modelAndParameter?: ModelAndParameter) => { + return props.onPublish?.(modelAndParameter, features) + }, [features, props]) + + return ( + <> + setRestoreConfirmOpen(true), + }}/> + {restoreConfirmOpen && ( + setRestoreConfirmOpen(false)} + /> + )} + + ) +} + +export default FeaturesWrappedAppPublisher diff --git a/web/app/components/app/configuration/config-var/select-type-item/style.module.css b/web/app/components/app/configuration/config-var/select-type-item/style.module.css deleted file mode 100644 index 8ff716d58b..0000000000 --- a/web/app/components/app/configuration/config-var/select-type-item/style.module.css +++ /dev/null @@ -1,40 +0,0 @@ -.item { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - height: 58px; - width: 98px; - border-radius: 8px; - border: 1px solid #EAECF0; - box-shadow: 0px 1px 2px rgba(16, 24, 40, 0.05); - background-color: #fff; - cursor: pointer; -} - -.item:not(.selected):hover { - border-color: #B2CCFF; - background-color: #F5F8FF; - box-shadow: 0px 4px 8px -2px rgba(16, 24, 40, 0.1), 0px 2px 4px -2px rgba(16, 24, 40, 0.06); -} - -.item.selected { - color: #155EEF; - border-color: #528BFF; - background-color: #F5F8FF; - box-shadow: 0px 1px 3px rgba(16, 24, 40, 0.1), 0px 1px 2px rgba(16, 24, 40, 0.06); -} - -.text { - font-size: 13px; - color: #667085; - font-weight: 500; -} - -.item.selected .text { - color: #155EEF; -} - -.item:not(.selected):hover { - color: #344054; -} \ No newline at end of file diff --git a/web/app/components/app/configuration/config-vision/radio-group/index.tsx b/web/app/components/app/configuration/config-vision/radio-group/index.tsx deleted file mode 100644 index a1cfb06e6a..0000000000 --- a/web/app/components/app/configuration/config-vision/radio-group/index.tsx +++ /dev/null @@ -1,40 +0,0 @@ -'use client' -import type { FC } from 'react' -import React from 'react' -import s from './style.module.css' -import cn from '@/utils/classnames' - -type OPTION = { - label: string - value: any -} - -type Props = { - className?: string - options: OPTION[] - value: any - onChange: (value: any) => void -} - -const RadioGroup: FC = ({ - className = '', - options, - value, - onChange, -}) => { - return ( -
- {options.map(item => ( -
onChange(item.value)} - > -
-
{item.label}
-
- ))} -
- ) -} -export default React.memo(RadioGroup) diff --git a/web/app/components/app/configuration/config-vision/radio-group/style.module.css b/web/app/components/app/configuration/config-vision/radio-group/style.module.css deleted file mode 100644 index 22c29c6a42..0000000000 --- a/web/app/components/app/configuration/config-vision/radio-group/style.module.css +++ /dev/null @@ -1,24 +0,0 @@ -.item { - @apply grow flex items-center h-8 px-2.5 rounded-lg bg-gray-25 border border-gray-100 cursor-pointer space-x-2; -} - -.item:hover { - background-color: #ffffff; - border-color: #B2CCFF; - box-shadow: 0px 12px 16px -4px rgba(16, 24, 40, 0.08), 0px 4px 6px -2px rgba(16, 24, 40, 0.03); -} - -.item.checked { - background-color: #ffffff; - border-color: #528BFF; - box-shadow: 0px 1px 2px 0px rgba(16, 24, 40, 0.06), 0px 1px 3px 0px rgba(16, 24, 40, 0.10); -} - -.radio { - @apply w-4 h-4 border-[2px] border-gray-200 rounded-full; -} - -.item.checked .radio { - border-width: 5px; - border-color: #155eef; -} \ No newline at end of file diff --git a/web/app/components/app/configuration/config-voice/param-config-content.tsx b/web/app/components/app/configuration/config-voice/param-config-content.tsx deleted file mode 100644 index 4e70bdda21..0000000000 --- a/web/app/components/app/configuration/config-voice/param-config-content.tsx +++ /dev/null @@ -1,220 +0,0 @@ -'use client' -import useSWR from 'swr' -import type { FC } from 'react' -import { useContext } from 'use-context-selector' -import React, { Fragment } from 'react' -import { usePathname } from 'next/navigation' -import { useTranslation } from 'react-i18next' -import { Listbox, Transition } from '@headlessui/react' -import { CheckIcon, ChevronDownIcon } from '@heroicons/react/20/solid' -import classNames from '@/utils/classnames' -import RadioGroup from '@/app/components/app/configuration/config-vision/radio-group' -import type { Item } from '@/app/components/base/select' -import ConfigContext from '@/context/debug-configuration' -import { fetchAppVoices } from '@/service/apps' -import Tooltip from '@/app/components/base/tooltip' -import { languages } from '@/i18n/language' -import { TtsAutoPlay } from '@/types/app' -const VoiceParamConfig: FC = () => { - const { t } = useTranslation() - const pathname = usePathname() - const matched = pathname.match(/\/app\/([^/]+)/) - const appId = (matched?.length && matched[1]) ? matched[1] : '' - - const { - textToSpeechConfig, - setTextToSpeechConfig, - } = useContext(ConfigContext) - - let languageItem = languages.find(item => item.value === textToSpeechConfig.language) - const localLanguagePlaceholder = languageItem?.name || t('common.placeholder.select') - if (languages && !languageItem && languages.length > 0) - languageItem = languages[0] - const language = languageItem?.value - const voiceItems = useSWR({ appId, language }, fetchAppVoices).data - let voiceItem = voiceItems?.find(item => item.value === textToSpeechConfig.voice) - if (voiceItems && !voiceItem && voiceItems.length > 0) - voiceItem = voiceItems[0] - - const localVoicePlaceholder = voiceItem?.name || t('common.placeholder.select') - - return ( -
-
-
{t('appDebug.voice.voiceSettings.title')}
-
-
-
-
{t('appDebug.voice.voiceSettings.language')}
- - {t('appDebug.voice.voiceSettings.resolutionTooltip').split('\n').map(item => ( -
{item}
- ))} -
- } - /> -
- { - setTextToSpeechConfig({ - ...textToSpeechConfig, - language: String(value.value), - }) - }} - > -
- - - {languageItem?.name ? t(`common.voice.language.${languageItem?.value.replace('-', '')}`) : localLanguagePlaceholder} - - - - - - - - {languages.map((item: Item) => ( - - `relative cursor-pointer select-none py-2 pl-3 pr-9 rounded-lg hover:bg-gray-100 text-gray-700 ${active ? 'bg-gray-100' : '' - }` - } - value={item} - disabled={false} - > - {({ /* active, */ selected }) => ( - <> - {t(`common.voice.language.${(item.value).toString().replace('-', '')}`)} - {(selected || item.value === textToSpeechConfig.language) && ( - - - )} - - )} - - ))} - - -
-
-
-
-
{t('appDebug.voice.voiceSettings.voice')}
- { - if (!value.value) - return - setTextToSpeechConfig({ - ...textToSpeechConfig, - voice: String(value.value), - }) - }} - > -
- - {voiceItem?.name ?? localVoicePlaceholder} - - - - - - - {voiceItems?.map((item: Item) => ( - - `relative cursor-pointer select-none py-2 pl-3 pr-9 rounded-lg hover:bg-gray-100 text-gray-700 ${active ? 'bg-gray-100' : '' - }` - } - value={item} - disabled={false} - > - {({ /* active, */ selected }) => ( - <> - {item.name} - {(selected || item.value === textToSpeechConfig.voice) && ( - - - )} - - )} - - ))} - - -
-
-
-
-
{t('appDebug.voice.voiceSettings.autoPlay')}
- { - setTextToSpeechConfig({ - ...textToSpeechConfig, - autoPlay: value, - }) - }} - /> -
-
-
-
- ) -} - -export default React.memo(VoiceParamConfig) diff --git a/web/app/components/app/configuration/config-voice/param-config.tsx b/web/app/components/app/configuration/config-voice/param-config.tsx deleted file mode 100644 index f1e2475495..0000000000 --- a/web/app/components/app/configuration/config-voice/param-config.tsx +++ /dev/null @@ -1,41 +0,0 @@ -'use client' -import type { FC } from 'react' -import { memo, useState } from 'react' -import { useTranslation } from 'react-i18next' -import VoiceParamConfig from './param-config-content' -import cn from '@/utils/classnames' -import { Settings01 } from '@/app/components/base/icons/src/vender/line/general' -import { - PortalToFollowElem, - PortalToFollowElemContent, - PortalToFollowElemTrigger, -} from '@/app/components/base/portal-to-follow-elem' - -const ParamsConfig: FC = () => { - const { t } = useTranslation() - const [open, setOpen] = useState(false) - - return ( - - setOpen(v => !v)}> -
- -
{t('appDebug.voice.settings')}
-
-
- -
- -
-
-
- ) -} -export default memo(ParamsConfig) diff --git a/web/app/components/app/configuration/config/code-generator/get-code-generator-res.tsx b/web/app/components/app/configuration/config/code-generator/get-code-generator-res.tsx new file mode 100644 index 0000000000..b63e3e2693 --- /dev/null +++ b/web/app/components/app/configuration/config/code-generator/get-code-generator-res.tsx @@ -0,0 +1,220 @@ +import type { FC } from 'react' +import React from 'react' +import cn from 'classnames' +import useBoolean from 'ahooks/lib/useBoolean' +import { useTranslation } from 'react-i18next' +import ConfigPrompt from '../../config-prompt' +import { languageMap } from '../../../../workflow/nodes/_base/components/editor/code-editor/index' +import { generateRuleCode } from '@/service/debug' +import type { CodeGenRes } from '@/service/debug' +import { type AppType, type Model, ModelModeType } from '@/types/app' +import Modal from '@/app/components/base/modal' +import Button from '@/app/components/base/button' +import { Generator } from '@/app/components/base/icons/src/vender/other' +import Toast from '@/app/components/base/toast' +import Loading from '@/app/components/base/loading' +import Confirm from '@/app/components/base/confirm' +import type { CodeLanguage } from '@/app/components/workflow/nodes/code/types' +import { useModelListAndDefaultModelAndCurrentProviderAndModel } from '@/app/components/header/account-setting/model-provider-page/hooks' +import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations' +import ModelIcon from '@/app/components/header/account-setting/model-provider-page/model-icon' +import ModelName from '@/app/components/header/account-setting/model-provider-page/model-name' +export type IGetCodeGeneratorResProps = { + mode: AppType + isShow: boolean + codeLanguages: CodeLanguage + onClose: () => void + onFinished: (res: CodeGenRes) => void +} + +export const GetCodeGeneratorResModal: FC = ( + { + mode, + isShow, + codeLanguages, + onClose, + onFinished, + }, +) => { + const { + currentProvider, + currentModel, + } = useModelListAndDefaultModelAndCurrentProviderAndModel(ModelTypeEnum.textGeneration) + const { t } = useTranslation() + const [instruction, setInstruction] = React.useState('') + const [isLoading, { setTrue: setLoadingTrue, setFalse: setLoadingFalse }] = useBoolean(false) + const [res, setRes] = React.useState(null) + const isValid = () => { + if (instruction.trim() === '') { + Toast.notify({ + type: 'error', + message: t('common.errorMsg.fieldRequired', { + field: t('appDebug.code.instruction'), + }), + }) + return false + } + return true + } + const model: Model = { + provider: currentProvider?.provider || '', + name: currentModel?.model || '', + mode: ModelModeType.chat, + // This is a fixed parameter + completion_params: { + temperature: 0.7, + max_tokens: 0, + top_p: 0, + echo: false, + stop: [], + presence_penalty: 0, + frequency_penalty: 0, + }, + } + const isInLLMNode = true + const onGenerate = async () => { + if (!isValid()) + return + if (isLoading) + return + setLoadingTrue() + try { + const { error, ...res } = await generateRuleCode({ + instruction, + model_config: model, + no_variable: !!isInLLMNode, + code_language: languageMap[codeLanguages] || 'javascript', + }) + setRes(res) + if (error) { + Toast.notify({ + type: 'error', + message: error, + }) + } + } + finally { + setLoadingFalse() + } + } + const [showConfirmOverwrite, setShowConfirmOverwrite] = React.useState(false) + + const renderLoading = ( +
+ +
{t('appDebug.codegen.loading')}
+
+ ) + + return ( + +
+
+
+
{t('appDebug.codegen.title')}
+
{t('appDebug.codegen.description')}
+
+
+ + +
+
+
+
{t('appDebug.codegen.instruction')}
+ -
- ) - : ( -
- )} - {renderQuestions()} - ) : ( -
{t('appDebug.openingStatement.noDataPlaceHolder')}
- )} - - {isShowConfirmAddVar && ( - - )} - -
- - ) -} -export default React.memo(OpeningStatement) diff --git a/web/app/components/base/features/feature-panel/score-slider/base-slider/index.tsx b/web/app/components/base/features/feature-panel/score-slider/base-slider/index.tsx deleted file mode 100644 index 2e08a99122..0000000000 --- a/web/app/components/base/features/feature-panel/score-slider/base-slider/index.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import ReactSlider from 'react-slider' -import s from './style.module.css' -import cn from '@/utils/classnames' - -type ISliderProps = { - className?: string - value: number - max?: number - min?: number - step?: number - disabled?: boolean - onChange: (value: number) => void -} - -const Slider: React.FC = ({ className, max, min, step, value, disabled, onChange }) => { - return ( -
-
-
- {(state.valueNow / 100).toFixed(2)} -
-
-
- )} - /> -} - -export default Slider diff --git a/web/app/components/base/features/feature-panel/score-slider/base-slider/style.module.css b/web/app/components/base/features/feature-panel/score-slider/base-slider/style.module.css deleted file mode 100644 index 4e93b39563..0000000000 --- a/web/app/components/base/features/feature-panel/score-slider/base-slider/style.module.css +++ /dev/null @@ -1,20 +0,0 @@ -.slider { - position: relative; -} - -.slider.disabled { - opacity: 0.6; -} - -.slider-thumb:focus { - outline: none; -} - -.slider-track { - background-color: #528BFF; - height: 2px; -} - -.slider-track-1 { - background-color: #E5E7EB; -} \ No newline at end of file diff --git a/web/app/components/base/features/feature-panel/speech-to-text/index.tsx b/web/app/components/base/features/feature-panel/speech-to-text/index.tsx deleted file mode 100644 index 2e5e3de439..0000000000 --- a/web/app/components/base/features/feature-panel/speech-to-text/index.tsx +++ /dev/null @@ -1,22 +0,0 @@ -'use client' -import React, { type FC } from 'react' -import { useTranslation } from 'react-i18next' -import { Microphone01 } from '@/app/components/base/icons/src/vender/solid/mediaAndDevices' - -const SpeechToTextConfig: FC = () => { - const { t } = useTranslation() - - return ( -
-
- -
-
-
{t('appDebug.feature.speechToText.title')}
-
-
-
{t('appDebug.feature.speechToText.resDes')}
-
- ) -} -export default React.memo(SpeechToTextConfig) diff --git a/web/app/components/base/features/feature-panel/suggested-questions-after-answer/index.tsx b/web/app/components/base/features/feature-panel/suggested-questions-after-answer/index.tsx deleted file mode 100644 index e6d0b6e7e0..0000000000 --- a/web/app/components/base/features/feature-panel/suggested-questions-after-answer/index.tsx +++ /dev/null @@ -1,25 +0,0 @@ -'use client' -import type { FC } from 'react' -import React from 'react' -import { useTranslation } from 'react-i18next' -import { MessageSmileSquare } from '@/app/components/base/icons/src/vender/solid/communication' -import Tooltip from '@/app/components/base/tooltip' - -const SuggestedQuestionsAfterAnswer: FC = () => { - const { t } = useTranslation() - - return ( -
-
- -
-
-
{t('appDebug.feature.suggestedQuestionsAfterAnswer.title')}
- -
-
-
{t('appDebug.feature.suggestedQuestionsAfterAnswer.resDes')}
-
- ) -} -export default React.memo(SuggestedQuestionsAfterAnswer) diff --git a/web/app/components/base/features/feature-panel/text-to-speech/index.tsx b/web/app/components/base/features/feature-panel/text-to-speech/index.tsx deleted file mode 100644 index 2480a19077..0000000000 --- a/web/app/components/base/features/feature-panel/text-to-speech/index.tsx +++ /dev/null @@ -1,62 +0,0 @@ -'use client' -import useSWR from 'swr' -import React from 'react' -import { useTranslation } from 'react-i18next' -import { usePathname } from 'next/navigation' -import { useFeatures } from '../../hooks' -import type { OnFeaturesChange } from '../../types' -import ParamsConfig from './params-config' -import { Speaker } from '@/app/components/base/icons/src/vender/solid/mediaAndDevices' -import { languages } from '@/i18n/language' -import { fetchAppVoices } from '@/service/apps' -import AudioBtn from '@/app/components/base/audio-btn' - -type TextToSpeechProps = { - onChange?: OnFeaturesChange - disabled?: boolean -} -const TextToSpeech = ({ - onChange, - disabled, -}: TextToSpeechProps) => { - const { t } = useTranslation() - const textToSpeech = useFeatures(s => s.features.text2speech) - - const pathname = usePathname() - const matched = pathname.match(/\/app\/([^/]+)/) - const appId = (matched?.length && matched[1]) ? matched[1] : '' - const language = textToSpeech?.language - const languageInfo = languages.find(i => i.value === textToSpeech?.language) - - const voiceItems = useSWR({ appId, language }, fetchAppVoices).data - const voiceItem = voiceItems?.find(item => item.value === textToSpeech?.voice) - - return ( -
-
- -
-
- {t('appDebug.feature.textToSpeech.title')} -
-
-
-
- {languageInfo && (`${languageInfo?.name} - `)}{voiceItem?.name ?? t('appDebug.voice.defaultDisplay')} - { languageInfo?.example && ( - - )} -
-
- -
-
- ) -} -export default React.memo(TextToSpeech) diff --git a/web/app/components/base/features/feature-panel/text-to-speech/param-config-content.tsx b/web/app/components/base/features/feature-panel/text-to-speech/param-config-content.tsx deleted file mode 100644 index e923d9a333..0000000000 --- a/web/app/components/base/features/feature-panel/text-to-speech/param-config-content.tsx +++ /dev/null @@ -1,241 +0,0 @@ -'use client' -import useSWR from 'swr' -import produce from 'immer' -import React, { Fragment } from 'react' -import { usePathname } from 'next/navigation' -import { useTranslation } from 'react-i18next' -import { Listbox, Transition } from '@headlessui/react' -import { CheckIcon, ChevronDownIcon } from '@heroicons/react/20/solid' -import { - useFeatures, - useFeaturesStore, -} from '../../hooks' -import type { OnFeaturesChange } from '../../types' -import classNames from '@/utils/classnames' -import type { Item } from '@/app/components/base/select' -import { fetchAppVoices } from '@/service/apps' -import Tooltip from '@/app/components/base/tooltip' -import { languages } from '@/i18n/language' -import RadioGroup from '@/app/components/app/configuration/config-vision/radio-group' -import { TtsAutoPlay } from '@/types/app' - -type VoiceParamConfigProps = { - onChange?: OnFeaturesChange -} -const VoiceParamConfig = ({ - onChange, -}: VoiceParamConfigProps) => { - const { t } = useTranslation() - const pathname = usePathname() - const matched = pathname.match(/\/app\/([^/]+)/) - const appId = (matched?.length && matched[1]) ? matched[1] : '' - const text2speech = useFeatures(state => state.features.text2speech) - const featuresStore = useFeaturesStore() - - let languageItem = languages.find(item => item.value === text2speech?.language) - if (languages && !languageItem) - languageItem = languages[0] - const localLanguagePlaceholder = languageItem?.name || t('common.placeholder.select') - - const language = languageItem?.value - const voiceItems = useSWR({ appId, language }, fetchAppVoices).data - let voiceItem = voiceItems?.find(item => item.value === text2speech?.voice) - if (voiceItems && !voiceItem) - voiceItem = voiceItems[0] - const localVoicePlaceholder = voiceItem?.name || t('common.placeholder.select') - - const handleChange = (value: Record) => { - const { - features, - setFeatures, - } = featuresStore!.getState() - - const newFeatures = produce(features, (draft) => { - draft.text2speech = { - ...draft.text2speech, - ...value, - } - }) - - setFeatures(newFeatures) - if (onChange) - onChange(newFeatures) - } - - return ( -
-
-
{t('appDebug.voice.voiceSettings.title')}
-
-
-
-
{t('appDebug.voice.voiceSettings.language')}
- - {t('appDebug.voice.voiceSettings.resolutionTooltip').split('\n').map(item => ( -
{item} -
- ))} -
- } - /> -
- { - handleChange({ - language: String(value.value), - }) - }} - > -
- - - {languageItem?.name ? t(`common.voice.language.${languageItem?.value.replace('-', '')}`) : localLanguagePlaceholder} - - - - - - - - {languages.map((item: Item) => ( - - `relative cursor-pointer select-none py-2 pl-3 pr-9 rounded-lg hover:bg-gray-100 text-gray-700 ${active ? 'bg-gray-100' : '' - }` - } - value={item} - disabled={false} - > - {({ /* active, */ selected }) => ( - <> - {t(`common.voice.language.${(item.value).toString().replace('-', '')}`)} - {(selected || item.value === text2speech?.language) && ( - - - )} - - )} - - ))} - - -
-
-
- -
-
{t('appDebug.voice.voiceSettings.voice')}
- { - handleChange({ - voice: String(value.value), - }) - }} - > -
- - {voiceItem?.name ?? localVoicePlaceholder} - - - - - - - {voiceItems?.map((item: Item) => ( - - `relative cursor-pointer select-none py-2 pl-3 pr-9 rounded-lg hover:bg-gray-100 text-gray-700 ${active ? 'bg-gray-100' : '' - }` - } - value={item} - disabled={false} - > - {({ /* active, */ selected }) => ( - <> - {item.name} - {(selected || item.value === text2speech?.voice) && ( - - - )} - - )} - - ))} - - -
-
-
-
-
{t('appDebug.voice.voiceSettings.autoPlay')}
- { - handleChange({ - autoPlay: value, - }) - }} - /> -
-
-
-
- ) -} - -export default React.memo(VoiceParamConfig) diff --git a/web/app/components/base/features/feature-panel/text-to-speech/params-config.tsx b/web/app/components/base/features/feature-panel/text-to-speech/params-config.tsx deleted file mode 100644 index 095fd6cce8..0000000000 --- a/web/app/components/base/features/feature-panel/text-to-speech/params-config.tsx +++ /dev/null @@ -1,48 +0,0 @@ -'use client' -import { memo, useState } from 'react' -import { useTranslation } from 'react-i18next' -import type { OnFeaturesChange } from '../../types' -import ParamConfigContent from './param-config-content' -import cn from '@/utils/classnames' -import { Settings01 } from '@/app/components/base/icons/src/vender/line/general' -import { - PortalToFollowElem, - PortalToFollowElemContent, - PortalToFollowElemTrigger, -} from '@/app/components/base/portal-to-follow-elem' - -type ParamsConfigProps = { - onChange?: OnFeaturesChange - disabled?: boolean -} -const ParamsConfig = ({ - onChange, - disabled, -}: ParamsConfigProps) => { - const { t } = useTranslation() - const [open, setOpen] = useState(false) - - return ( - - !disabled && setOpen(v => !v)}> -
- -
{t('appDebug.voice.settings')}
-
-
- -
- -
-
-
- ) -} -export default memo(ParamsConfig) diff --git a/web/app/components/app/configuration/toolbox/annotation/annotation-ctrl-btn/index.tsx b/web/app/components/base/features/new-feature-panel/annotation-reply/annotation-ctrl-btn/index.tsx similarity index 100% rename from web/app/components/app/configuration/toolbox/annotation/annotation-ctrl-btn/index.tsx rename to web/app/components/base/features/new-feature-panel/annotation-reply/annotation-ctrl-btn/index.tsx diff --git a/web/app/components/app/configuration/toolbox/annotation/config-param-modal.tsx b/web/app/components/base/features/new-feature-panel/annotation-reply/config-param-modal.tsx similarity index 99% rename from web/app/components/app/configuration/toolbox/annotation/config-param-modal.tsx rename to web/app/components/base/features/new-feature-panel/annotation-reply/config-param-modal.tsx index b660977d08..801f1348ee 100644 --- a/web/app/components/app/configuration/toolbox/annotation/config-param-modal.tsx +++ b/web/app/components/base/features/new-feature-panel/annotation-reply/config-param-modal.tsx @@ -2,7 +2,7 @@ import type { FC } from 'react' import React, { useState } from 'react' import { useTranslation } from 'react-i18next' -import ScoreSlider from '../score-slider' +import ScoreSlider from './score-slider' import { Item } from './config-param' import Modal from '@/app/components/base/modal' import Button from '@/app/components/base/button' diff --git a/web/app/components/base/features/new-feature-panel/annotation-reply/config-param.tsx b/web/app/components/base/features/new-feature-panel/annotation-reply/config-param.tsx new file mode 100644 index 0000000000..8b3a0af240 --- /dev/null +++ b/web/app/components/base/features/new-feature-panel/annotation-reply/config-param.tsx @@ -0,0 +1,24 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import Tooltip from '@/app/components/base/tooltip' + +export const Item: FC<{ title: string; tooltip: string; children: JSX.Element }> = ({ + title, + tooltip, + children, +}) => { + return ( +
+
+
{title}
+ {tooltip}
+ } + /> +
+
{children}
+
+ ) +} diff --git a/web/app/components/base/features/new-feature-panel/annotation-reply/index.tsx b/web/app/components/base/features/new-feature-panel/annotation-reply/index.tsx new file mode 100644 index 0000000000..f44aab5b9c --- /dev/null +++ b/web/app/components/base/features/new-feature-panel/annotation-reply/index.tsx @@ -0,0 +1,152 @@ +import React, { useCallback, useState } from 'react' +import { useTranslation } from 'react-i18next' +import { usePathname, useRouter } from 'next/navigation' +import produce from 'immer' +import { RiEqualizer2Line, RiExternalLinkLine } from '@remixicon/react' +import { MessageFast } from '@/app/components/base/icons/src/vender/features' +import FeatureCard from '@/app/components/base/features/new-feature-panel/feature-card' +import Button from '@/app/components/base/button' +import { useFeatures, useFeaturesStore } from '@/app/components/base/features/hooks' +import type { OnFeaturesChange } from '@/app/components/base/features/types' +import useAnnotationConfig from '@/app/components/base/features/new-feature-panel/annotation-reply/use-annotation-config' +import ConfigParamModal from '@/app/components/base/features/new-feature-panel/annotation-reply/config-param-modal' +import AnnotationFullModal from '@/app/components/billing/annotation-full/modal' +import { ANNOTATION_DEFAULT } from '@/config' + +type Props = { + disabled?: boolean + onChange?: OnFeaturesChange +} + +const AnnotationReply = ({ + disabled, + onChange, +}: Props) => { + const { t } = useTranslation() + const router = useRouter() + const pathname = usePathname() + const matched = pathname.match(/\/app\/([^/]+)/) + const appId = (matched?.length && matched[1]) ? matched[1] : '' + const featuresStore = useFeaturesStore() + const annotationReply = useFeatures(s => s.features.annotationReply) + + const updateAnnotationReply = useCallback((newConfig: any) => { + const { + features, + setFeatures, + } = featuresStore!.getState() + const newFeatures = produce(features, (draft) => { + draft.annotationReply = newConfig + }) + setFeatures(newFeatures) + if (onChange) + onChange(newFeatures) + }, [featuresStore, onChange]) + + const { + handleEnableAnnotation, + handleDisableAnnotation, + isShowAnnotationConfigInit, + setIsShowAnnotationConfigInit, + isShowAnnotationFullModal, + setIsShowAnnotationFullModal, + } = useAnnotationConfig({ + appId, + annotationConfig: annotationReply as any || { + id: '', + enabled: false, + score_threshold: ANNOTATION_DEFAULT.score_threshold, + embedding_model: { + embedding_provider_name: '', + embedding_model_name: '', + }, + }, + setAnnotationConfig: updateAnnotationReply, + }) + + const handleSwitch = useCallback((enabled: boolean) => { + if (enabled) + setIsShowAnnotationConfigInit(true) + else + handleDisableAnnotation(annotationReply?.embedding_model as any) + }, [annotationReply?.embedding_model, handleDisableAnnotation, setIsShowAnnotationConfigInit]) + + const [isHovering, setIsHovering] = useState(false) + + return ( + <> + + +
+ } + title={t('appDebug.feature.annotation.title')} + value={!!annotationReply?.enabled} + onChange={state => handleSwitch(state)} + onMouseEnter={() => setIsHovering(true)} + onMouseLeave={() => setIsHovering(false)} + disabled={disabled} + > + <> + {!annotationReply?.enabled && ( +
{t('appDebug.feature.annotation.description')}
+ )} + {!!annotationReply?.enabled && ( + <> + {!isHovering && ( +
+
+
{t('appDebug.feature.annotation.scoreThreshold.title')}
+
{annotationReply.score_threshold || '-'}
+
+
+
+
{t('common.modelProvider.embeddingModel.key')}
+
{annotationReply.embedding_model?.embedding_model_name}
+
+
+ )} + {isHovering && ( +
+ + +
+ )} + + )} + + + { + setIsShowAnnotationConfigInit(false) + // showChooseFeatureTrue() + }} + onSave={async (embeddingModel, score) => { + await handleEnableAnnotation(embeddingModel, score) + setIsShowAnnotationConfigInit(false) + }} + annotationConfig={annotationReply as any} + /> + {isShowAnnotationFullModal && ( + setIsShowAnnotationFullModal(false)} + /> + )} + + ) +} + +export default AnnotationReply diff --git a/web/app/components/app/configuration/toolbox/score-slider/base-slider/index.tsx b/web/app/components/base/features/new-feature-panel/annotation-reply/score-slider/base-slider/index.tsx similarity index 100% rename from web/app/components/app/configuration/toolbox/score-slider/base-slider/index.tsx rename to web/app/components/base/features/new-feature-panel/annotation-reply/score-slider/base-slider/index.tsx diff --git a/web/app/components/app/configuration/toolbox/score-slider/base-slider/style.module.css b/web/app/components/base/features/new-feature-panel/annotation-reply/score-slider/base-slider/style.module.css similarity index 100% rename from web/app/components/app/configuration/toolbox/score-slider/base-slider/style.module.css rename to web/app/components/base/features/new-feature-panel/annotation-reply/score-slider/base-slider/style.module.css diff --git a/web/app/components/base/features/feature-panel/score-slider/index.tsx b/web/app/components/base/features/new-feature-panel/annotation-reply/score-slider/index.tsx similarity index 90% rename from web/app/components/base/features/feature-panel/score-slider/index.tsx rename to web/app/components/base/features/new-feature-panel/annotation-reply/score-slider/index.tsx index 9826cbadcf..d68db9be73 100644 --- a/web/app/components/base/features/feature-panel/score-slider/index.tsx +++ b/web/app/components/base/features/new-feature-panel/annotation-reply/score-slider/index.tsx @@ -2,7 +2,7 @@ import type { FC } from 'react' import React from 'react' import { useTranslation } from 'react-i18next' -import Slider from '@/app/components/app/configuration/toolbox/score-slider/base-slider' +import Slider from '@/app/components/base/features/new-feature-panel/annotation-reply/score-slider/base-slider' type Props = { className?: string diff --git a/web/app/components/app/configuration/toolbox/annotation/type.ts b/web/app/components/base/features/new-feature-panel/annotation-reply/type.ts similarity index 100% rename from web/app/components/app/configuration/toolbox/annotation/type.ts rename to web/app/components/base/features/new-feature-panel/annotation-reply/type.ts diff --git a/web/app/components/app/configuration/toolbox/annotation/use-annotation-config.ts b/web/app/components/base/features/new-feature-panel/annotation-reply/use-annotation-config.ts similarity index 100% rename from web/app/components/app/configuration/toolbox/annotation/use-annotation-config.ts rename to web/app/components/base/features/new-feature-panel/annotation-reply/use-annotation-config.ts diff --git a/web/app/components/base/features/new-feature-panel/citation.tsx b/web/app/components/base/features/new-feature-panel/citation.tsx new file mode 100644 index 0000000000..a0b702e9f9 --- /dev/null +++ b/web/app/components/base/features/new-feature-panel/citation.tsx @@ -0,0 +1,56 @@ +import React, { useCallback } from 'react' +import { useTranslation } from 'react-i18next' +import produce from 'immer' +import { Citations } from '@/app/components/base/icons/src/vender/features' +import FeatureCard from '@/app/components/base/features/new-feature-panel/feature-card' +import { useFeatures, useFeaturesStore } from '@/app/components/base/features/hooks' +import type { OnFeaturesChange } from '@/app/components/base/features/types' +import { FeatureEnum } from '@/app/components/base/features/types' + +type Props = { + disabled?: boolean + onChange?: OnFeaturesChange +} + +const Citation = ({ + disabled, + onChange, +}: Props) => { + const { t } = useTranslation() + const features = useFeatures(s => s.features) + const featuresStore = useFeaturesStore() + + const handleChange = useCallback((type: FeatureEnum, enabled: boolean) => { + const { + features, + setFeatures, + } = featuresStore!.getState() + + const newFeatures = produce(features, (draft) => { + draft[type] = { + ...draft[type], + enabled, + } + }) + setFeatures(newFeatures) + if (onChange) + onChange(newFeatures) + }, [featuresStore, onChange]) + + return ( + + +
+ } + title={t('appDebug.feature.citation.title')} + value={!!features.citation?.enabled} + description={t('appDebug.feature.citation.description')!} + onChange={state => handleChange(FeatureEnum.citation, state)} + disabled={disabled} + /> + ) +} + +export default Citation diff --git a/web/app/components/base/features/new-feature-panel/conversation-opener/index.tsx b/web/app/components/base/features/new-feature-panel/conversation-opener/index.tsx new file mode 100644 index 0000000000..ab6b3ec6db --- /dev/null +++ b/web/app/components/base/features/new-feature-panel/conversation-opener/index.tsx @@ -0,0 +1,119 @@ +import React, { useCallback, useState } from 'react' +import { useTranslation } from 'react-i18next' +import produce from 'immer' +import { RiEditLine } from '@remixicon/react' +import { LoveMessage } from '@/app/components/base/icons/src/vender/features' +import FeatureCard from '@/app/components/base/features/new-feature-panel/feature-card' +import Button from '@/app/components/base/button' +import { useFeatures, useFeaturesStore } from '@/app/components/base/features/hooks' +import type { OnFeaturesChange } from '@/app/components/base/features/types' +import { FeatureEnum } from '@/app/components/base/features/types' +import { useModalContext } from '@/context/modal-context' +import type { PromptVariable } from '@/models/debug' +import type { InputVar } from '@/app/components/workflow/types' + +type Props = { + disabled?: boolean + onChange?: OnFeaturesChange + promptVariables?: PromptVariable[] + workflowVariables?: InputVar[] + onAutoAddPromptVariable?: (variable: PromptVariable[]) => void +} + +const ConversationOpener = ({ + disabled, + onChange, + promptVariables, + workflowVariables, + onAutoAddPromptVariable, +}: Props) => { + const { t } = useTranslation() + const { setShowOpeningModal } = useModalContext() + const opening = useFeatures(s => s.features.opening) + const featuresStore = useFeaturesStore() + const [isHovering, setIsHovering] = useState(false) + const handleOpenOpeningModal = useCallback(() => { + if (disabled) + return + const { + features, + setFeatures, + } = featuresStore!.getState() + setShowOpeningModal({ + payload: { + ...opening, + promptVariables, + workflowVariables, + onAutoAddPromptVariable, + }, + onSaveCallback: (newOpening) => { + const newFeatures = produce(features, (draft) => { + draft.opening = newOpening + }) + setFeatures(newFeatures) + if (onChange) + onChange() + }, + onCancelCallback: () => { + if (onChange) + onChange() + }, + }) + }, [disabled, featuresStore, onAutoAddPromptVariable, onChange, opening, promptVariables, setShowOpeningModal]) + + const handleChange = useCallback((type: FeatureEnum, enabled: boolean) => { + const { + features, + setFeatures, + } = featuresStore!.getState() + + const newFeatures = produce(features, (draft) => { + draft[type] = { + ...draft[type], + enabled, + } + }) + setFeatures(newFeatures) + if (onChange) + onChange() + }, [featuresStore, onChange]) + + return ( + + +
+ } + title={t('appDebug.feature.conversationOpener.title')} + value={!!opening?.enabled} + onChange={state => handleChange(FeatureEnum.opening, state)} + onMouseEnter={() => setIsHovering(true)} + onMouseLeave={() => setIsHovering(false)} + disabled={disabled} + > + <> + {!opening?.enabled && ( +
{t('appDebug.feature.conversationOpener.description')}
+ )} + {!!opening?.enabled && ( + <> + {!isHovering && ( +
+ {opening.opening_statement || t('appDebug.openingStatement.placeholder')} +
+ )} + {isHovering && ( + + )} + + )} + + + ) +} + +export default ConversationOpener diff --git a/web/app/components/base/features/new-feature-panel/conversation-opener/modal.tsx b/web/app/components/base/features/new-feature-panel/conversation-opener/modal.tsx new file mode 100644 index 0000000000..9f25d0fa11 --- /dev/null +++ b/web/app/components/base/features/new-feature-panel/conversation-opener/modal.tsx @@ -0,0 +1,206 @@ +import React, { useCallback, useEffect, useState } from 'react' +import { useTranslation } from 'react-i18next' +import { useBoolean } from 'ahooks' +import produce from 'immer' +import { ReactSortable } from 'react-sortablejs' +import { RiAddLine, RiAsterisk, RiCloseLine, RiDeleteBinLine, RiDraggable } from '@remixicon/react' +import Modal from '@/app/components/base/modal' +import Button from '@/app/components/base/button' +import ConfirmAddVar from '@/app/components/app/configuration/config-prompt/confirm-add-var' +import type { OpeningStatement } from '@/app/components/base/features/types' +import { getInputKeys } from '@/app/components/base/block-input' +import type { PromptVariable } from '@/models/debug' +import type { InputVar } from '@/app/components/workflow/types' +import { getNewVar } from '@/utils/var' + +type OpeningSettingModalProps = { + data: OpeningStatement + onSave: (newState: OpeningStatement) => void + onCancel: () => void + promptVariables?: PromptVariable[] + workflowVariables?: InputVar[] + onAutoAddPromptVariable?: (variable: PromptVariable[]) => void +} + +const MAX_QUESTION_NUM = 5 + +const OpeningSettingModal = ({ + data, + onSave, + onCancel, + promptVariables = [], + workflowVariables = [], + onAutoAddPromptVariable, +}: OpeningSettingModalProps) => { + const { t } = useTranslation() + const [tempValue, setTempValue] = useState(data?.opening_statement || '') + useEffect(() => { + setTempValue(data.opening_statement || '') + }, [data.opening_statement]) + const [tempSuggestedQuestions, setTempSuggestedQuestions] = useState(data.suggested_questions || []) + const [isShowConfirmAddVar, { setTrue: showConfirmAddVar, setFalse: hideConfirmAddVar }] = useBoolean(false) + const [notIncludeKeys, setNotIncludeKeys] = useState([]) + + const handleSave = useCallback((ignoreVariablesCheck?: boolean) => { + if (!ignoreVariablesCheck) { + const keys = getInputKeys(tempValue) + const promptKeys = promptVariables.map(item => item.key) + const workflowVariableKeys = workflowVariables.map(item => item.variable) + let notIncludeKeys: string[] = [] + + if (promptKeys.length === 0 && workflowVariables.length === 0) { + if (keys.length > 0) + notIncludeKeys = keys + } + else { + if (workflowVariables.length > 0) + notIncludeKeys = keys.filter(key => !workflowVariableKeys.includes(key)) + else notIncludeKeys = keys.filter(key => !promptKeys.includes(key)) + } + + if (notIncludeKeys.length > 0) { + setNotIncludeKeys(notIncludeKeys) + showConfirmAddVar() + return + } + } + const newOpening = produce(data, (draft) => { + if (draft) { + draft.opening_statement = tempValue + draft.suggested_questions = tempSuggestedQuestions + } + }) + onSave(newOpening) + }, [data, onSave, promptVariables, workflowVariables, showConfirmAddVar, tempSuggestedQuestions, tempValue]) + + const cancelAutoAddVar = useCallback(() => { + hideConfirmAddVar() + handleSave(true) + }, [handleSave, hideConfirmAddVar]) + + const autoAddVar = useCallback(() => { + onAutoAddPromptVariable?.([ + ...notIncludeKeys.map(key => getNewVar(key, 'string')), + ]) + hideConfirmAddVar() + handleSave(true) + }, [handleSave, hideConfirmAddVar, notIncludeKeys, onAutoAddPromptVariable]) + + const renderQuestions = () => { + return ( +
+
+
+
{t('appDebug.openingStatement.openingQuestion')}
+
·
+
{tempSuggestedQuestions.length}/{MAX_QUESTION_NUM}
+
+
+
+ { + return { + id: index, + name, + } + })} + setList={list => setTempSuggestedQuestions(list.map(item => item.name))} + handle='.handle' + ghostClass="opacity-50" + animation={150} + > + {tempSuggestedQuestions.map((question, index) => { + return ( +
+ + { + const value = e.target.value + setTempSuggestedQuestions(tempSuggestedQuestions.map((item, i) => { + if (index === i) + return value + + return item + })) + }} + className={'w-full overflow-x-auto pl-1.5 pr-8 text-sm leading-9 text-gray-900 border-0 grow h-9 bg-transparent focus:outline-none cursor-pointer rounded-lg'} + /> + +
{ + setTempSuggestedQuestions(tempSuggestedQuestions.filter((_, i) => index !== i)) + }} + > + +
+
+ ) + })}
+ {tempSuggestedQuestions.length < MAX_QUESTION_NUM && ( +
{ setTempSuggestedQuestions([...tempSuggestedQuestions, '']) }} + className='mt-1 flex items-center h-9 px-3 gap-2 rounded-lg cursor-pointer text-gray-400 bg-gray-100 hover:bg-gray-200'> + +
{t('appDebug.variableConfig.addOption')}
+
+ )} +
+ ) + } + + return ( + { }} + className='!p-6 !mt-14 !max-w-none !w-[640px] !bg-components-panel-bg-blur' + > +
+
{t('appDebug.feature.conversationOpener.title')}
+
+
+
+
+ +
+
+ + ) + }, +) +Textarea.displayName = 'Textarea' + +export default Textarea +export { Textarea, textareaVariants } diff --git a/web/app/components/signin/countdown.tsx b/web/app/components/signin/countdown.tsx new file mode 100644 index 0000000000..6282480d10 --- /dev/null +++ b/web/app/components/signin/countdown.tsx @@ -0,0 +1,41 @@ +'use client' +import { useCountDown } from 'ahooks' +import { useEffect, useState } from 'react' +import { useTranslation } from 'react-i18next' + +export const COUNT_DOWN_TIME_MS = 59000 +export const COUNT_DOWN_KEY = 'leftTime' + +type CountdownProps = { + onResend?: () => void +} + +export default function Countdown({ onResend }: CountdownProps) { + const { t } = useTranslation() + const [leftTime, setLeftTime] = useState(Number(localStorage.getItem(COUNT_DOWN_KEY) || COUNT_DOWN_TIME_MS)) + const [time] = useCountDown({ + leftTime, + onEnd: () => { + setLeftTime(0) + localStorage.removeItem(COUNT_DOWN_KEY) + }, + }) + + const resend = async function () { + setLeftTime(COUNT_DOWN_TIME_MS) + localStorage.setItem(COUNT_DOWN_KEY, `${COUNT_DOWN_TIME_MS}`) + onResend?.() + } + + useEffect(() => { + localStorage.setItem(COUNT_DOWN_KEY, `${time}`) + }, [time]) + + return

+ {t('login.checkCode.didNotReceiveCode')} + {time > 0 && {Math.round(time / 1000)}s} + { + time <= 0 && {t('login.checkCode.resend')} + } +

+} diff --git a/web/app/components/workflow/header/global-variable-button.tsx b/web/app/components/workflow/header/global-variable-button.tsx new file mode 100644 index 0000000000..ff02604b26 --- /dev/null +++ b/web/app/components/workflow/header/global-variable-button.tsx @@ -0,0 +1,20 @@ +import { memo } from 'react' +import Button from '@/app/components/base/button' +import { GlobalVariable } from '@/app/components/base/icons/src/vender/line/others' +import { useStore } from '@/app/components/workflow/store' + +const GlobalVariableButton = ({ disabled }: { disabled: boolean }) => { + const setShowPanel = useStore(s => s.setShowGlobalVariablePanel) + + const handleClick = () => { + setShowPanel(true) + } + + return ( + + ) +} + +export default memo(GlobalVariableButton) diff --git a/web/app/components/workflow/hooks/use-config-vision.ts b/web/app/components/workflow/hooks/use-config-vision.ts new file mode 100644 index 0000000000..a3cddbc47c --- /dev/null +++ b/web/app/components/workflow/hooks/use-config-vision.ts @@ -0,0 +1,88 @@ +import produce from 'immer' +import { useCallback } from 'react' +import { useIsChatMode } from './use-workflow' +import type { ModelConfig, VisionSetting } from '@/app/components/workflow/types' +import { useTextGenerationCurrentProviderAndModelAndModelList } from '@/app/components/header/account-setting/model-provider-page/hooks' +import { + ModelFeatureEnum, +} from '@/app/components/header/account-setting/model-provider-page/declarations' +import { Resolution } from '@/types/app' + +type Payload = { + enabled: boolean + configs?: VisionSetting +} + +type Params = { + payload: Payload + onChange: (payload: Payload) => void +} +const useConfigVision = (model: ModelConfig, { + payload = { + enabled: false, + }, + onChange, +}: Params) => { + const { + currentModel: currModel, + } = useTextGenerationCurrentProviderAndModelAndModelList( + { + provider: model.provider, + model: model.name, + }, + ) + + const isChatMode = useIsChatMode() + + const getIsVisionModel = useCallback(() => { + return !!currModel?.features?.includes(ModelFeatureEnum.vision) + }, [currModel]) + + const isVisionModel = getIsVisionModel() + + const handleVisionResolutionEnabledChange = useCallback((enabled: boolean) => { + const newPayload = produce(payload, (draft) => { + draft.enabled = enabled + if (enabled && isChatMode) { + draft.configs = { + detail: Resolution.high, + variable_selector: ['sys', 'files'], + } + } + }) + onChange(newPayload) + }, [isChatMode, onChange, payload]) + + const handleVisionResolutionChange = useCallback((config: VisionSetting) => { + const newPayload = produce(payload, (draft) => { + draft.configs = config + }) + onChange(newPayload) + }, [onChange, payload]) + + const handleModelChanged = useCallback(() => { + const isVisionModel = getIsVisionModel() + if (!isVisionModel) { + handleVisionResolutionEnabledChange(false) + return + } + if (payload.enabled) { + onChange({ + enabled: true, + configs: { + detail: Resolution.high, + variable_selector: [], + }, + }) + } + }, [getIsVisionModel, handleVisionResolutionEnabledChange, onChange, payload.enabled]) + + return { + isVisionModel, + handleVisionResolutionEnabledChange, + handleVisionResolutionChange, + handleModelChanged, + } +} + +export default useConfigVision diff --git a/web/app/components/workflow/nodes/_base/components/code-generator-button.tsx b/web/app/components/workflow/nodes/_base/components/code-generator-button.tsx new file mode 100644 index 0000000000..7f3a71dc09 --- /dev/null +++ b/web/app/components/workflow/nodes/_base/components/code-generator-button.tsx @@ -0,0 +1,48 @@ +'use client' +import type { FC } from 'react' +import React, { useCallback } from 'react' +import { useBoolean } from 'ahooks' +import cn from 'classnames' +import type { CodeLanguage } from '../../code/types' +import { Generator } from '@/app/components/base/icons/src/vender/other' +import { ActionButton } from '@/app/components/base/action-button' +import { AppType } from '@/types/app' +import type { CodeGenRes } from '@/service/debug' +import { GetCodeGeneratorResModal } from '@/app/components/app/configuration/config/code-generator/get-code-generator-res' + +type Props = { + className?: string + onGenerated?: (prompt: string) => void + codeLanguages: CodeLanguage +} + +const CodeGenerateBtn: FC = ({ + className, + codeLanguages, + onGenerated, +}) => { + const [showAutomatic, { setTrue: showAutomaticTrue, setFalse: showAutomaticFalse }] = useBoolean(false) + const handleAutomaticRes = useCallback((res: CodeGenRes) => { + onGenerated?.(res.code) + showAutomaticFalse() + }, [onGenerated, showAutomaticFalse]) + return ( +
+ + + + {showAutomatic && ( + + )} +
+ ) +} +export default React.memo(CodeGenerateBtn) diff --git a/web/app/components/workflow/nodes/_base/components/config-vision.tsx b/web/app/components/workflow/nodes/_base/components/config-vision.tsx new file mode 100644 index 0000000000..56cd1a5dbb --- /dev/null +++ b/web/app/components/workflow/nodes/_base/components/config-vision.tsx @@ -0,0 +1,91 @@ +'use client' +import type { FC } from 'react' +import React, { useCallback } from 'react' +import { useTranslation } from 'react-i18next' +import produce from 'immer' +import VarReferencePicker from './variable/var-reference-picker' +import ResolutionPicker from '@/app/components/workflow/nodes/llm/components/resolution-picker' +import Field from '@/app/components/workflow/nodes/_base/components/field' +import Switch from '@/app/components/base/switch' +import { type ValueSelector, type Var, VarType, type VisionSetting } from '@/app/components/workflow/types' +import { Resolution } from '@/types/app' +import Tooltip from '@/app/components/base/tooltip' +const i18nPrefix = 'workflow.nodes.llm' + +type Props = { + isVisionModel: boolean + readOnly: boolean + enabled: boolean + onEnabledChange: (enabled: boolean) => void + nodeId: string + config?: VisionSetting + onConfigChange: (config: VisionSetting) => void +} + +const ConfigVision: FC = ({ + isVisionModel, + readOnly, + enabled, + onEnabledChange, + nodeId, + config = { + detail: Resolution.high, + variable_selector: [], + }, + onConfigChange, +}) => { + const { t } = useTranslation() + + const filterVar = useCallback((payload: Var) => { + return [VarType.file, VarType.arrayFile].includes(payload.type) + }, []) + const handleVisionResolutionChange = useCallback((resolution: Resolution) => { + const newConfig = produce(config, (draft) => { + draft.detail = resolution + }) + onConfigChange(newConfig) + }, [config, onConfigChange]) + + const handleVarSelectorChange = useCallback((valueSelector: ValueSelector | string) => { + const newConfig = produce(config, (draft) => { + draft.variable_selector = valueSelector as ValueSelector + }) + onConfigChange(newConfig) + }, [config, onConfigChange]) + + return ( + + + + } + > + {(enabled && isVisionModel) + ? ( +
+ + +
+ ) + : null} + +
+ ) +} +export default React.memo(ConfigVision) diff --git a/web/app/components/workflow/nodes/_base/components/file-type-item.tsx b/web/app/components/workflow/nodes/_base/components/file-type-item.tsx new file mode 100644 index 0000000000..c3d52f265b --- /dev/null +++ b/web/app/components/workflow/nodes/_base/components/file-type-item.tsx @@ -0,0 +1,77 @@ +'use client' +import type { FC } from 'react' +import React, { useCallback } from 'react' +import { useTranslation } from 'react-i18next' +import { SupportUploadFileTypes } from '../../../types' +import cn from '@/utils/classnames' +import { FILE_EXTS } from '@/app/components/base/prompt-editor/constants' +import TagInput from '@/app/components/base/tag-input' +import Checkbox from '@/app/components/base/checkbox' +import { FileTypeIcon } from '@/app/components/base/file-uploader' + +type Props = { + type: SupportUploadFileTypes.image | SupportUploadFileTypes.document | SupportUploadFileTypes.audio | SupportUploadFileTypes.video | SupportUploadFileTypes.custom + selected: boolean + onToggle: (type: SupportUploadFileTypes) => void + onCustomFileTypesChange?: (customFileTypes: string[]) => void + customFileTypes?: string[] +} + +const FileTypeItem: FC = ({ + type, + selected, + onToggle, + customFileTypes = [], + onCustomFileTypesChange = () => { }, +}) => { + const { t } = useTranslation() + + const handleOnSelect = useCallback(() => { + onToggle(type) + }, [onToggle, type]) + + const isCustomSelected = type === SupportUploadFileTypes.custom && selected + + return ( +
+ {isCustomSelected + ? ( +
+
+ +
{t(`appDebug.variableConfig.file.${type}.name`)}
+ +
+
e.stopPropagation()}> + +
+
+ ) + : ( +
+ +
+
{t(`appDebug.variableConfig.file.${type}.name`)}
+
{type !== SupportUploadFileTypes.custom ? FILE_EXTS[type].join(', ') : t('appDebug.variableConfig.file.custom.description')}
+
+ +
+ )} + +
+ ) +} + +export default React.memo(FileTypeItem) diff --git a/web/app/components/workflow/nodes/_base/components/file-upload-setting.tsx b/web/app/components/workflow/nodes/_base/components/file-upload-setting.tsx new file mode 100644 index 0000000000..82a3a906cf --- /dev/null +++ b/web/app/components/workflow/nodes/_base/components/file-upload-setting.tsx @@ -0,0 +1,195 @@ +'use client' +import type { FC } from 'react' +import React, { useCallback } from 'react' +import useSWR from 'swr' +import produce from 'immer' +import { useTranslation } from 'react-i18next' +import type { UploadFileSetting } from '../../../types' +import { SupportUploadFileTypes } from '../../../types' +import OptionCard from './option-card' +import FileTypeItem from './file-type-item' +import InputNumberWithSlider from './input-number-with-slider' +import Field from '@/app/components/app/configuration/config-var/config-modal/field' +import { TransferMethod } from '@/types/app' +import { fetchFileUploadConfig } from '@/service/common' +import { useFileSizeLimit } from '@/app/components/base/file-uploader/hooks' +import { formatFileSize } from '@/utils/format' + +type Props = { + payload: UploadFileSetting + isMultiple: boolean + inFeaturePanel?: boolean + hideSupportFileType?: boolean + onChange: (payload: UploadFileSetting) => void +} + +const FileUploadSetting: FC = ({ + payload, + isMultiple, + inFeaturePanel = false, + hideSupportFileType = false, + onChange, +}) => { + const { t } = useTranslation() + + const { + allowed_file_upload_methods, + max_length, + allowed_file_types, + allowed_file_extensions, + } = payload + const { data: fileUploadConfigResponse } = useSWR({ url: '/files/upload' }, fetchFileUploadConfig) + const { imgSizeLimit, docSizeLimit, audioSizeLimit, videoSizeLimit } = useFileSizeLimit(fileUploadConfigResponse) + + const handleSupportFileTypeChange = useCallback((type: SupportUploadFileTypes) => { + const newPayload = produce(payload, (draft) => { + if (type === SupportUploadFileTypes.custom) { + if (!draft.allowed_file_types.includes(SupportUploadFileTypes.custom)) + draft.allowed_file_types = [SupportUploadFileTypes.custom] + + else + draft.allowed_file_types = draft.allowed_file_types.filter(v => v !== type) + } + else { + draft.allowed_file_types = draft.allowed_file_types.filter(v => v !== SupportUploadFileTypes.custom) + if (draft.allowed_file_types.includes(type)) + draft.allowed_file_types = draft.allowed_file_types.filter(v => v !== type) + else + draft.allowed_file_types.push(type) + } + }) + onChange(newPayload) + }, [onChange, payload]) + + const handleUploadMethodChange = useCallback((method: TransferMethod) => { + return () => { + const newPayload = produce(payload, (draft) => { + if (method === TransferMethod.all) + draft.allowed_file_upload_methods = [TransferMethod.local_file, TransferMethod.remote_url] + else + draft.allowed_file_upload_methods = [method] + }) + onChange(newPayload) + } + }, [onChange, payload]) + + const handleCustomFileTypesChange = useCallback((customFileTypes: string[]) => { + const newPayload = produce(payload, (draft) => { + draft.allowed_file_extensions = customFileTypes.map((v) => { + if (v.startsWith('.')) // Not start with dot + return v.slice(1) + return v + }) + }) + onChange(newPayload) + }, [onChange, payload]) + + const handleMaxUploadNumLimitChange = useCallback((value: number) => { + const newPayload = produce(payload, (draft) => { + draft.max_length = value + }) + onChange(newPayload) + }, [onChange, payload]) + + return ( +
+ {!inFeaturePanel && ( + +
+ { + [SupportUploadFileTypes.document, SupportUploadFileTypes.image, SupportUploadFileTypes.audio, SupportUploadFileTypes.video].map((type: SupportUploadFileTypes) => ( + + )) + } + `.${item}`)} + onCustomFileTypesChange={handleCustomFileTypesChange} + /> +
+
+ )} + +
+ + + +
+
+ {isMultiple && ( + +
+
{t('appDebug.variableConfig.maxNumberTip', { + imgLimit: formatFileSize(imgSizeLimit), + docLimit: formatFileSize(docSizeLimit), + audioLimit: formatFileSize(audioSizeLimit), + videoLimit: formatFileSize(videoSizeLimit), + })}
+ + +
+
+ )} + {inFeaturePanel && !hideSupportFileType && ( + +
+ { + [SupportUploadFileTypes.document, SupportUploadFileTypes.image, SupportUploadFileTypes.audio, SupportUploadFileTypes.video].map((type: SupportUploadFileTypes) => ( + + )) + } + +
+
+ )} + +
+ ) +} +export default React.memo(FileUploadSetting) diff --git a/web/app/components/workflow/nodes/_base/components/input-number-with-slider.tsx b/web/app/components/workflow/nodes/_base/components/input-number-with-slider.tsx new file mode 100644 index 0000000000..0210db2f8e --- /dev/null +++ b/web/app/components/workflow/nodes/_base/components/input-number-with-slider.tsx @@ -0,0 +1,65 @@ +'use client' +import type { FC } from 'react' +import React, { useCallback } from 'react' +import Slider from '@/app/components/base/slider' + +type Props = { + value: number + defaultValue?: number + min?: number + max?: number + readonly?: boolean + onChange: (value: number) => void +} + +const InputNumberWithSlider: FC = ({ + value, + defaultValue = 0, + min, + max, + readonly, + onChange, +}) => { + const handleBlur = useCallback(() => { + if (value === undefined || value === null) { + onChange(defaultValue) + return + } + if (max !== undefined && value > max) { + onChange(max) + return + } + if (min !== undefined && value < min) + onChange(min) + }, [defaultValue, max, min, onChange, value]) + + const handleChange = useCallback((e: React.ChangeEvent) => { + onChange(Number.parseFloat(e.target.value)) + }, [onChange]) + + return ( +
+ + +
+ ) +} +export default React.memo(InputNumberWithSlider) diff --git a/web/app/components/workflow/nodes/code/dependency-picker.tsx b/web/app/components/workflow/nodes/code/dependency-picker.tsx new file mode 100644 index 0000000000..43e8523e17 --- /dev/null +++ b/web/app/components/workflow/nodes/code/dependency-picker.tsx @@ -0,0 +1,85 @@ +import type { FC } from 'react' +import React, { useCallback, useState } from 'react' +import { t } from 'i18next' +import { + RiArrowDownSLine, +} from '@remixicon/react' +import type { CodeDependency } from './types' +import { PortalToFollowElem, PortalToFollowElemContent, PortalToFollowElemTrigger } from '@/app/components/base/portal-to-follow-elem' +import Input from '@/app/components/base/input' +import { Check } from '@/app/components/base/icons/src/vender/line/general' + +type Props = { + value: CodeDependency + available_dependencies: CodeDependency[] + onChange: (dependency: CodeDependency) => void +} + +const DependencyPicker: FC = ({ + available_dependencies, + value, + onChange, +}) => { + const [open, setOpen] = useState(false) + const [searchText, setSearchText] = useState('') + + const handleChange = useCallback((dependency: CodeDependency) => { + return () => { + setOpen(false) + onChange(dependency) + } + }, [onChange]) + + return ( + + setOpen(!open)} className='flex-grow cursor-pointer'> +
+
{value.name}
+ +
+
+ +
+
+ setSearchText(e.target.value)} + onClear={() => setSearchText('')} + autoFocus + /> +
+
+ {available_dependencies.filter((v) => { + if (!searchText) + return true + return v.name.toLowerCase().includes(searchText.toLowerCase()) + }).map(dependency => ( +
+
{dependency.name}
+ {dependency.name === value.name && } +
+ ))} +
+
+
+
+ ) +} + +export default React.memo(DependencyPicker) diff --git a/web/app/components/workflow/nodes/document-extractor/default.ts b/web/app/components/workflow/nodes/document-extractor/default.ts new file mode 100644 index 0000000000..26eddff62b --- /dev/null +++ b/web/app/components/workflow/nodes/document-extractor/default.ts @@ -0,0 +1,36 @@ +import { BlockEnum } from '../../types' +import type { NodeDefault } from '../../types' +import type { DocExtractorNodeType } from './types' +import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/constants' +const i18nPrefix = 'workflow.errorMsg' + +const nodeDefault: NodeDefault = { + defaultValue: { + variable_selector: [], + is_array_file: false, + }, + getAvailablePrevNodes(isChatMode: boolean) { + const nodes = isChatMode + ? ALL_CHAT_AVAILABLE_BLOCKS + : ALL_COMPLETION_AVAILABLE_BLOCKS.filter(type => type !== BlockEnum.End) + return nodes + }, + getAvailableNextNodes(isChatMode: boolean) { + const nodes = isChatMode ? ALL_CHAT_AVAILABLE_BLOCKS : ALL_COMPLETION_AVAILABLE_BLOCKS + return nodes + }, + checkValid(payload: DocExtractorNodeType, t: any) { + let errorMessages = '' + const { variable_selector: variable } = payload + + if (!errorMessages && !variable?.length) + errorMessages = t(`${i18nPrefix}.fieldRequired`, { field: t('workflow.nodes.assigner.assignedVariable') }) + + return { + isValid: !errorMessages, + errorMessage: errorMessages, + } + }, +} + +export default nodeDefault diff --git a/web/app/components/workflow/nodes/document-extractor/node.tsx b/web/app/components/workflow/nodes/document-extractor/node.tsx new file mode 100644 index 0000000000..becf9fda95 --- /dev/null +++ b/web/app/components/workflow/nodes/document-extractor/node.tsx @@ -0,0 +1,42 @@ +import type { FC } from 'react' +import React from 'react' +import { useNodes } from 'reactflow' +import { useTranslation } from 'react-i18next' +import NodeVariableItem from '../variable-assigner/components/node-variable-item' +import type { DocExtractorNodeType } from './types' +import { isConversationVar, isENV, isSystemVar } from '@/app/components/workflow/nodes/_base/components/variable/utils' +import { BlockEnum, type Node, type NodeProps } from '@/app/components/workflow/types' + +const i18nPrefix = 'workflow.nodes.docExtractor' + +const NodeComponent: FC> = ({ + data, +}) => { + const { t } = useTranslation() + + const nodes: Node[] = useNodes() + const { variable_selector: variable } = data + + if (!variable || variable.length === 0) + return null + + const isSystem = isSystemVar(variable) + const isEnv = isENV(variable) + const isChatVar = isConversationVar(variable) + const node = isSystem ? nodes.find(node => node.data.type === BlockEnum.Start) : nodes.find(node => node.id === variable[0]) + const varName = isSystem ? `sys.${variable[variable.length - 1]}` : variable.slice(1).join('.') + return ( +
+
{t(`${i18nPrefix}.inputVar`)}
+ +
+ ) +} + +export default React.memo(NodeComponent) diff --git a/web/app/components/workflow/nodes/document-extractor/panel.tsx b/web/app/components/workflow/nodes/document-extractor/panel.tsx new file mode 100644 index 0000000000..52491875cd --- /dev/null +++ b/web/app/components/workflow/nodes/document-extractor/panel.tsx @@ -0,0 +1,88 @@ +import type { FC } from 'react' +import React from 'react' +import useSWR from 'swr' +import { useTranslation } from 'react-i18next' +import { useContext } from 'use-context-selector' +import VarReferencePicker from '../_base/components/variable/var-reference-picker' +import OutputVars, { VarItem } from '../_base/components/output-vars' +import Split from '../_base/components/split' +import { useNodeHelpLink } from '../_base/hooks/use-node-help-link' +import useConfig from './use-config' +import type { DocExtractorNodeType } from './types' +import { fetchSupportFileTypes } from '@/service/datasets' +import Field from '@/app/components/workflow/nodes/_base/components/field' +import { BlockEnum, type NodePanelProps } from '@/app/components/workflow/types' +import I18n from '@/context/i18n' +import { LanguagesSupported } from '@/i18n/language' + +const i18nPrefix = 'workflow.nodes.docExtractor' + +const Panel: FC> = ({ + id, + data, +}) => { + const { t } = useTranslation() + const { locale } = useContext(I18n) + const link = useNodeHelpLink(BlockEnum.DocExtractor) + const { data: supportFileTypesResponse } = useSWR({ url: '/files/support-type' }, fetchSupportFileTypes) + const supportTypes = supportFileTypesResponse?.allowed_extensions || [] + const supportTypesShowNames = (() => { + const extensionMap: { [key: string]: string } = { + md: 'markdown', + pptx: 'pptx', + htm: 'html', + xlsx: 'xlsx', + docx: 'docx', + } + + return [...supportTypes] + .map(item => extensionMap[item] || item) // map to standardized extension + .map(item => item.toLowerCase()) // convert to lower case + .filter((item, index, self) => self.indexOf(item) === index) // remove duplicates + .join(locale !== LanguagesSupported[1] ? ', ' : '、 ') + })() + const { + readOnly, + inputs, + handleVarChanges, + filterVar, + } = useConfig(id, data) + + return ( +
+
+ + <> + +
+ {t(`${i18nPrefix}.supportFileTypes`, { types: supportTypesShowNames })} + {t(`${i18nPrefix}.learnMore`)} +
+ +
+
+ +
+ + + +
+
+ ) +} + +export default React.memo(Panel) diff --git a/web/app/components/workflow/nodes/document-extractor/types.ts b/web/app/components/workflow/nodes/document-extractor/types.ts new file mode 100644 index 0000000000..8ab7592109 --- /dev/null +++ b/web/app/components/workflow/nodes/document-extractor/types.ts @@ -0,0 +1,6 @@ +import type { CommonNodeType, ValueSelector } from '@/app/components/workflow/types' + +export type DocExtractorNodeType = CommonNodeType & { + variable_selector: ValueSelector + is_array_file: boolean +} diff --git a/web/app/components/workflow/nodes/document-extractor/use-config.ts b/web/app/components/workflow/nodes/document-extractor/use-config.ts new file mode 100644 index 0000000000..1654bee02a --- /dev/null +++ b/web/app/components/workflow/nodes/document-extractor/use-config.ts @@ -0,0 +1,66 @@ +import { useCallback, useMemo } from 'react' +import produce from 'immer' +import { useStoreApi } from 'reactflow' + +import type { ValueSelector, Var } from '../../types' +import { VarType } from '../../types' +import type { DocExtractorNodeType } from './types' +import useNodeCrud from '@/app/components/workflow/nodes/_base/hooks/use-node-crud' +import { + useIsChatMode, + useNodesReadOnly, + useWorkflow, + useWorkflowVariables, +} from '@/app/components/workflow/hooks' + +const useConfig = (id: string, payload: DocExtractorNodeType) => { + const { nodesReadOnly: readOnly } = useNodesReadOnly() + const { inputs, setInputs } = useNodeCrud(id, payload) + + const filterVar = useCallback((varPayload: Var) => { + return varPayload.type === VarType.file || varPayload.type === VarType.arrayFile + }, []) + + const isChatMode = useIsChatMode() + + const store = useStoreApi() + const { getBeforeNodesInSameBranch } = useWorkflow() + const { + getNodes, + } = store.getState() + const currentNode = getNodes().find(n => n.id === id) + const isInIteration = payload.isInIteration + const iterationNode = isInIteration ? getNodes().find(n => n.id === currentNode!.parentId) : null + const availableNodes = useMemo(() => { + return getBeforeNodesInSameBranch(id) + }, [getBeforeNodesInSameBranch, id]) + + const { getCurrentVariableType } = useWorkflowVariables() + const getType = useCallback((variable?: ValueSelector) => { + const varType = getCurrentVariableType({ + parentNode: iterationNode, + valueSelector: variable || [], + availableNodes, + isChatMode, + isConstant: false, + }) + return varType + }, [getCurrentVariableType, availableNodes, isChatMode, iterationNode]) + + const handleVarChanges = useCallback((variable: ValueSelector | string) => { + const newInputs = produce(inputs, (draft) => { + draft.variable_selector = variable as ValueSelector + draft.is_array_file = getType(draft.variable_selector) === VarType.arrayFile + }) + setInputs(newInputs) + }, [getType, inputs, setInputs]) + + return { + readOnly, + inputs, + filterVar, + handleVarChanges, + } +} + +export default useConfig diff --git a/web/app/components/workflow/nodes/if-else/components/condition-files-list-value.tsx b/web/app/components/workflow/nodes/if-else/components/condition-files-list-value.tsx new file mode 100644 index 0000000000..f21a3fac10 --- /dev/null +++ b/web/app/components/workflow/nodes/if-else/components/condition-files-list-value.tsx @@ -0,0 +1,115 @@ +import { + memo, + useCallback, +} from 'react' +import { useTranslation } from 'react-i18next' +import { ComparisonOperator, type Condition } from '../types' +import { + comparisonOperatorNotRequireValue, + isComparisonOperatorNeedTranslate, + isEmptyRelatedOperator, +} from '../utils' +import { FILE_TYPE_OPTIONS, TRANSFER_METHOD } from '../default' +import type { ValueSelector } from '../../../types' +import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development' +import { BubbleX, Env } from '@/app/components/base/icons/src/vender/line/others' +import cn from '@/utils/classnames' +import { isConversationVar, isENV, isSystemVar } from '@/app/components/workflow/nodes/_base/components/variable/utils' +const i18nPrefix = 'workflow.nodes.ifElse' + +type ConditionValueProps = { + condition: Condition +} +const ConditionValue = ({ + condition, +}: ConditionValueProps) => { + const { t } = useTranslation() + const { + variable_selector, + comparison_operator: operator, + sub_variable_condition, + } = condition + + const variableSelector = variable_selector as ValueSelector + + const variableName = (isSystemVar(variableSelector) ? variableSelector.slice(0).join('.') : variableSelector.slice(1).join('.')) + const operatorName = isComparisonOperatorNeedTranslate(operator) ? t(`workflow.nodes.ifElse.comparisonOperator.${operator}`) : operator + const notHasValue = comparisonOperatorNotRequireValue(operator) + const isEnvVar = isENV(variableSelector) + const isChatVar = isConversationVar(variableSelector) + const formatValue = useCallback((c: Condition) => { + const notHasValue = comparisonOperatorNotRequireValue(c.comparison_operator) + if (notHasValue) + return '' + + const value = c.value as string + return value.replace(/{{#([^#]*)#}}/g, (a, b) => { + const arr: string[] = b.split('.') + if (isSystemVar(arr)) + return `{{${b}}}` + + return `{{${arr.slice(1).join('.')}}}` + }) + }, []) + + const isSelect = useCallback((c: Condition) => { + return c.comparison_operator === ComparisonOperator.in || c.comparison_operator === ComparisonOperator.notIn + }, []) + + const selectName = useCallback((c: Condition) => { + const isSelect = c.comparison_operator === ComparisonOperator.in || c.comparison_operator === ComparisonOperator.notIn + if (isSelect) { + const name = [...FILE_TYPE_OPTIONS, ...TRANSFER_METHOD].filter(item => item.value === (Array.isArray(c.value) ? c.value[0] : c.value))[0] + return name + ? t(`workflow.nodes.ifElse.optionName.${name.i18nKey}`).replace(/{{#([^#]*)#}}/g, (a, b) => { + const arr: string[] = b.split('.') + if (isSystemVar(arr)) + return `{{${b}}}` + + return `{{${arr.slice(1).join('.')}}}` + }) + : '' + } + return '' + }, []) + + return ( +
+
+ {!isEnvVar && !isChatVar && } + {isEnvVar && } + {isChatVar && } + +
+ {variableName} +
+
+ {operatorName} +
+
+
+ { + sub_variable_condition?.conditions.map((c: Condition, index) => ( +
+
{c.key}
+
{isComparisonOperatorNeedTranslate(c.comparison_operator) ? t(`workflow.nodes.ifElse.comparisonOperator.${c.comparison_operator}`) : c.comparison_operator}
+ {c.comparison_operator && !isEmptyRelatedOperator(c.comparison_operator) &&
{isSelect(c) ? selectName(c) : formatValue(c)}
} + {index !== sub_variable_condition.conditions.length - 1 && (
{t(`${i18nPrefix}.${sub_variable_condition.logical_operator}`)}
)} +
+ )) + } +
+
+ ) +} + +export default memo(ConditionValue) diff --git a/web/app/components/workflow/nodes/if-else/components/condition-wrap.tsx b/web/app/components/workflow/nodes/if-else/components/condition-wrap.tsx new file mode 100644 index 0000000000..39c03c9b38 --- /dev/null +++ b/web/app/components/workflow/nodes/if-else/components/condition-wrap.tsx @@ -0,0 +1,225 @@ +'use client' +import type { FC } from 'react' +import React, { useCallback, useState } from 'react' +import { useTranslation } from 'react-i18next' +import { ReactSortable } from 'react-sortablejs' +import { + RiAddLine, + RiDeleteBinLine, + RiDraggable, +} from '@remixicon/react' +import type { CaseItem, HandleAddCondition, HandleAddSubVariableCondition, HandleRemoveCondition, HandleToggleConditionLogicalOperator, HandleToggleSubVariableConditionLogicalOperator, HandleUpdateCondition, HandleUpdateSubVariableCondition, handleRemoveSubVariableCondition } from '../types' +import type { Node, NodeOutPutVar, Var } from '../../../types' +import { VarType } from '../../../types' +import { useGetAvailableVars } from '../../variable-assigner/hooks' +import { SUB_VARIABLES } from '../default' +import ConditionList from './condition-list' +import ConditionAdd from './condition-add' +import cn from '@/utils/classnames' +import Button from '@/app/components/base/button' +import { PortalSelect as Select } from '@/app/components/base/select' + +type Props = { + isSubVariable?: boolean + caseId?: string + conditionId?: string + cases: CaseItem[] + readOnly: boolean + handleSortCase?: (sortedCases: (CaseItem & { id: string })[]) => void + handleRemoveCase?: (caseId: string) => void + handleAddCondition?: HandleAddCondition + handleRemoveCondition?: HandleRemoveCondition + handleUpdateCondition?: HandleUpdateCondition + handleToggleConditionLogicalOperator?: HandleToggleConditionLogicalOperator + handleAddSubVariableCondition?: HandleAddSubVariableCondition + handleRemoveSubVariableCondition?: handleRemoveSubVariableCondition + handleUpdateSubVariableCondition?: HandleUpdateSubVariableCondition + handleToggleSubVariableConditionLogicalOperator?: HandleToggleSubVariableConditionLogicalOperator + nodeId: string + nodesOutputVars: NodeOutPutVar[] + availableNodes: Node[] + varsIsVarFileAttribute?: Record + filterVar: (varPayload: Var) => boolean +} + +const ConditionWrap: FC = ({ + isSubVariable, + caseId, + conditionId, + nodeId: id = '', + cases = [], + readOnly, + handleSortCase = () => { }, + handleRemoveCase, + handleUpdateCondition, + handleAddCondition, + handleRemoveCondition, + handleToggleConditionLogicalOperator, + handleAddSubVariableCondition, + handleRemoveSubVariableCondition, + handleUpdateSubVariableCondition, + handleToggleSubVariableConditionLogicalOperator, + nodesOutputVars = [], + availableNodes = [], + varsIsVarFileAttribute = {}, + filterVar = () => true, +}) => { + const { t } = useTranslation() + + const getAvailableVars = useGetAvailableVars() + + const [willDeleteCaseId, setWillDeleteCaseId] = useState('') + const casesLength = cases.length + + const filterNumberVar = useCallback((varPayload: Var) => { + return varPayload.type === VarType.number + }, []) + + const subVarOptions = SUB_VARIABLES.map(item => ({ + name: item, + value: item, + })) + + return ( + <> + ({ ...caseItem, id: caseItem.case_id }))} + setList={handleSortCase} + handle='.handle' + ghostClass='bg-components-panel-bg' + animation={150} + disabled={readOnly || isSubVariable} + > + { + cases.map((item, index) => ( +
+
+ {!isSubVariable && ( + <> + 1 && 'group-hover:block', + )} /> +
+ { + index === 0 ? 'IF' : 'ELIF' + } + { + casesLength > 1 && ( +
CASE {index + 1}
+ ) + } +
+ + )} + + { + !!item.conditions.length && ( +
+ +
+ ) + } + +
+ {isSubVariable + ? ( + handleChange('value')(item.value)} + className='!text-[13px]' + wrapperClassName='grow h-8' + placeholder='Select value' + /> + )} + {!isSelect && ( + handleChange('value')(e.target.value)} + /> + )} + + )} +
+
+ ) +} +export default React.memo(FilterCondition) diff --git a/web/app/components/workflow/nodes/list-operator/components/limit-config.tsx b/web/app/components/workflow/nodes/list-operator/components/limit-config.tsx new file mode 100644 index 0000000000..b8812d3473 --- /dev/null +++ b/web/app/components/workflow/nodes/list-operator/components/limit-config.tsx @@ -0,0 +1,80 @@ +'use client' +import type { FC } from 'react' +import React, { useCallback } from 'react' +import { useTranslation } from 'react-i18next' +import type { Limit } from '../types' +import InputNumberWithSlider from '../../_base/components/input-number-with-slider' +import cn from '@/utils/classnames' +import Field from '@/app/components/workflow/nodes/_base/components/field' +import Switch from '@/app/components/base/switch' + +const i18nPrefix = 'workflow.nodes.listFilter' +const LIMIT_SIZE_MIN = 1 +const LIMIT_SIZE_MAX = 20 +const LIMIT_SIZE_DEFAULT = 10 + +type Props = { + className?: string + readonly: boolean + config: Limit + onChange: (limit: Limit) => void + canSetRoleName?: boolean +} + +const LIMIT_DEFAULT: Limit = { + enabled: false, + size: LIMIT_SIZE_DEFAULT, +} + +const LimitConfig: FC = ({ + className, + readonly, + config = LIMIT_DEFAULT, + onChange, +}) => { + const { t } = useTranslation() + const payload = config + + const handleLimitEnabledChange = useCallback((enabled: boolean) => { + onChange({ + ...config, + enabled, + }) + }, [config, onChange]) + + const handleLimitSizeChange = useCallback((size: number | string) => { + onChange({ + ...config, + size: Number.parseInt(size as string), + }) + }, [onChange, config]) + + return ( +
+ + } + > + {payload?.enabled + ? ( + + ) + : null} + +
+ ) +} +export default React.memo(LimitConfig) diff --git a/web/app/components/workflow/nodes/list-operator/components/sub-variable-picker.tsx b/web/app/components/workflow/nodes/list-operator/components/sub-variable-picker.tsx new file mode 100644 index 0000000000..0a210504cf --- /dev/null +++ b/web/app/components/workflow/nodes/list-operator/components/sub-variable-picker.tsx @@ -0,0 +1,73 @@ +'use client' +import type { FC } from 'react' +import React, { useCallback } from 'react' +import { useTranslation } from 'react-i18next' +import { SUB_VARIABLES } from '../../if-else/default' +import type { Item } from '@/app/components/base/select' +import { SimpleSelect as Select } from '@/app/components/base/select' +import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development' +import cn from '@/utils/classnames' + +type Props = { + value: string + onChange: (value: string) => void + className?: string +} + +const SubVariablePicker: FC = ({ + value, + onChange, + className, +}) => { + const { t } = useTranslation() + const subVarOptions = SUB_VARIABLES.map(item => ({ + value: item, + name: item, + })) + + const renderOption = ({ item }: { item: Record }) => { + return ( +
+
+ + {item.name} +
+ {item.type} +
+ ) + } + + const handleChange = useCallback(({ value }: Item) => { + onChange(value as string) + }, [onChange]) + + return ( +
+ + + setVerifyCode(e.target.value)} max-length={6} className='mt-1' placeholder={t('login.checkCode.verificationCodePlaceholder') as string} /> + + + +
+
+
+
router.back()} className='flex items-center justify-center h-9 text-text-tertiary cursor-pointer'> +
+ +
+ {t('login.back')} +
+
+} diff --git a/web/app/reset-password/layout.tsx b/web/app/reset-password/layout.tsx new file mode 100644 index 0000000000..16d8642ed2 --- /dev/null +++ b/web/app/reset-password/layout.tsx @@ -0,0 +1,39 @@ +import Header from '../signin/_header' +import style from '../signin/page.module.css' + +import cn from '@/utils/classnames' + +export default async function SignInLayout({ children }: any) { + return <> +
+
+
+
+
+ {children} +
+
+
+ © {new Date().getFullYear()} LangGenius, Inc. All rights reserved. +
+
+
+ +} diff --git a/web/app/reset-password/page.tsx b/web/app/reset-password/page.tsx new file mode 100644 index 0000000000..65f1db3fb5 --- /dev/null +++ b/web/app/reset-password/page.tsx @@ -0,0 +1,101 @@ +'use client' +import Link from 'next/link' +import { RiArrowLeftLine, RiLockPasswordLine } from '@remixicon/react' +import { useTranslation } from 'react-i18next' +import { useState } from 'react' +import { useRouter, useSearchParams } from 'next/navigation' +import { useContext } from 'use-context-selector' +import { COUNT_DOWN_KEY, COUNT_DOWN_TIME_MS } from '../components/signin/countdown' +import { emailRegex } from '@/config' +import Button from '@/app/components/base/button' +import Input from '@/app/components/base/input' +import Toast from '@/app/components/base/toast' +import { sendResetPasswordCode } from '@/service/common' +import I18NContext from '@/context/i18n' + +export default function CheckCode() { + const { t } = useTranslation() + const searchParams = useSearchParams() + const router = useRouter() + const [email, setEmail] = useState('') + const [loading, setIsLoading] = useState(false) + const { locale } = useContext(I18NContext) + + const handleGetEMailVerificationCode = async () => { + try { + if (!email) { + Toast.notify({ type: 'error', message: t('login.error.emailEmpty') }) + return + } + + if (!emailRegex.test(email)) { + Toast.notify({ + type: 'error', + message: t('login.error.emailInValid'), + }) + return + } + setIsLoading(true) + const res = await sendResetPasswordCode(email, locale) + if (res.result === 'success') { + localStorage.setItem(COUNT_DOWN_KEY, `${COUNT_DOWN_TIME_MS}`) + const params = new URLSearchParams(searchParams) + params.set('token', encodeURIComponent(res.data)) + params.set('email', encodeURIComponent(email)) + router.push(`/reset-password/check-code?${params.toString()}`) + } + else if (res.code === 'account_not_found') { + Toast.notify({ + type: 'error', + message: t('login.error.registrationNotAllowed'), + }) + } + else { + Toast.notify({ + type: 'error', + message: res.data, + }) + } + } + catch (error) { + console.error(error) + } + finally { + setIsLoading(false) + } + } + + return
+
+ +
+
+

{t('login.resetPassword')}

+

+ {t('login.resetPasswordDesc')} +

+
+ +
{ }}> + +
+ +
+ setEmail(e.target.value)} /> +
+
+ +
+
+
+
+
+
+ +
+ +
+ {t('login.backToLogin')} + +
+} diff --git a/web/app/reset-password/set-password/page.tsx b/web/app/reset-password/set-password/page.tsx new file mode 100644 index 0000000000..7948c59a9a --- /dev/null +++ b/web/app/reset-password/set-password/page.tsx @@ -0,0 +1,193 @@ +'use client' +import { useCallback, useState } from 'react' +import { useTranslation } from 'react-i18next' +import { useRouter, useSearchParams } from 'next/navigation' +import cn from 'classnames' +import { RiCheckboxCircleFill } from '@remixicon/react' +import { useCountDown } from 'ahooks' +import Button from '@/app/components/base/button' +import { changePasswordWithToken } from '@/service/common' +import Toast from '@/app/components/base/toast' +import Input from '@/app/components/base/input' + +const validPassword = /^(?=.*[a-zA-Z])(?=.*\d).{8,}$/ + +const ChangePasswordForm = () => { + const { t } = useTranslation() + const router = useRouter() + const searchParams = useSearchParams() + const token = decodeURIComponent(searchParams.get('token') || '') + + const [password, setPassword] = useState('') + const [confirmPassword, setConfirmPassword] = useState('') + const [showSuccess, setShowSuccess] = useState(false) + const [showPassword, setShowPassword] = useState(false) + const [showConfirmPassword, setShowConfirmPassword] = useState(false) + + const showErrorMessage = useCallback((message: string) => { + Toast.notify({ + type: 'error', + message, + }) + }, []) + + const getSignInUrl = () => { + if (searchParams.has('invite_token')) { + const params = new URLSearchParams() + params.set('token', searchParams.get('invite_token') as string) + return `/activate?${params.toString()}` + } + return '/signin' + } + + const AUTO_REDIRECT_TIME = 5000 + const [leftTime, setLeftTime] = useState(undefined) + const [countdown] = useCountDown({ + leftTime, + onEnd: () => { + router.replace(getSignInUrl()) + }, + }) + + const valid = useCallback(() => { + if (!password.trim()) { + showErrorMessage(t('login.error.passwordEmpty')) + return false + } + if (!validPassword.test(password)) { + showErrorMessage(t('login.error.passwordInvalid')) + return false + } + if (password !== confirmPassword) { + showErrorMessage(t('common.account.notEqual')) + return false + } + return true + }, [password, confirmPassword, showErrorMessage, t]) + + const handleChangePassword = useCallback(async () => { + if (!valid()) + return + try { + await changePasswordWithToken({ + url: '/forgot-password/resets', + body: { + token, + new_password: password, + password_confirm: confirmPassword, + }, + }) + setShowSuccess(true) + setLeftTime(AUTO_REDIRECT_TIME) + } + catch (error) { + console.error(error) + } + }, [password, token, valid, confirmPassword]) + + return ( +
+ {!showSuccess && ( +
+
+

+ {t('login.changePassword')} +

+

+ {t('login.changePasswordTip')} +

+
+ +
+
+ {/* Password */} +
+ +
+ setPassword(e.target.value)} + placeholder={t('login.passwordPlaceholder') || ''} + /> + +
+ +
+
+
{t('login.error.passwordInvalid')}
+
+ {/* Confirm Password */} +
+ +
+ setConfirmPassword(e.target.value)} + placeholder={t('login.confirmPasswordPlaceholder') || ''} + /> +
+ +
+
+
+
+ +
+
+
+
+ )} + {showSuccess && ( +
+
+
+ +
+

+ {t('login.passwordChangedTip')} +

+
+
+ +
+
+ )} +
+ ) +} + +export default ChangePasswordForm diff --git a/web/app/signin/check-code/page.tsx b/web/app/signin/check-code/page.tsx new file mode 100644 index 0000000000..4767308f72 --- /dev/null +++ b/web/app/signin/check-code/page.tsx @@ -0,0 +1,96 @@ +'use client' +import { RiArrowLeftLine, RiMailSendFill } from '@remixicon/react' +import { useTranslation } from 'react-i18next' +import { useState } from 'react' +import { useRouter, useSearchParams } from 'next/navigation' +import { useContext } from 'use-context-selector' +import Countdown from '@/app/components/signin/countdown' +import Button from '@/app/components/base/button' +import Input from '@/app/components/base/input' +import Toast from '@/app/components/base/toast' +import { emailLoginWithCode, sendEMailLoginCode } from '@/service/common' +import I18NContext from '@/context/i18n' + +export default function CheckCode() { + const { t } = useTranslation() + const router = useRouter() + const searchParams = useSearchParams() + const email = decodeURIComponent(searchParams.get('email') as string) + const token = decodeURIComponent(searchParams.get('token') as string) + const invite_token = decodeURIComponent(searchParams.get('invite_token') || '') + const [code, setVerifyCode] = useState('') + const [loading, setIsLoading] = useState(false) + const { locale } = useContext(I18NContext) + + const verify = async () => { + try { + if (!code.trim()) { + Toast.notify({ + type: 'error', + message: t('login.checkCode.emptyCode'), + }) + return + } + if (!/\d{6}/.test(code)) { + Toast.notify({ + type: 'error', + message: t('login.checkCode.invalidCode'), + }) + return + } + setIsLoading(true) + const ret = await emailLoginWithCode({ email, code, token }) + if (ret.result === 'success') { + localStorage.setItem('console_token', ret.data.access_token) + localStorage.setItem('refresh_token', ret.data.refresh_token) + router.replace(invite_token ? `/signin/invite-settings?${searchParams.toString()}` : '/apps') + } + } + catch (error) { console.error(error) } + finally { + setIsLoading(false) + } + } + + const resendCode = async () => { + try { + const ret = await sendEMailLoginCode(email, locale) + if (ret.result === 'success') { + const params = new URLSearchParams(searchParams) + params.set('token', encodeURIComponent(ret.data)) + router.replace(`/signin/check-code?${params.toString()}`) + } + } + catch (error) { console.error(error) } + } + + return
+
+ +
+
+

{t('login.checkCode.checkYourEmail')}

+

+ +
+ {t('login.checkCode.validTime')} +

+
+ +
+ + setVerifyCode(e.target.value)} max-length={6} className='mt-1' placeholder={t('login.checkCode.verificationCodePlaceholder') as string} /> + + + +
+
+
+
router.back()} className='flex items-center justify-center h-9 text-text-tertiary cursor-pointer'> +
+ +
+ {t('login.back')} +
+
+} diff --git a/web/app/signin/components/mail-and-code-auth.tsx b/web/app/signin/components/mail-and-code-auth.tsx new file mode 100644 index 0000000000..7225b094d4 --- /dev/null +++ b/web/app/signin/components/mail-and-code-auth.tsx @@ -0,0 +1,71 @@ +import { useState } from 'react' +import { useTranslation } from 'react-i18next' +import { useRouter, useSearchParams } from 'next/navigation' +import { useContext } from 'use-context-selector' +import Input from '@/app/components/base/input' +import Button from '@/app/components/base/button' +import { emailRegex } from '@/config' +import Toast from '@/app/components/base/toast' +import { sendEMailLoginCode } from '@/service/common' +import { COUNT_DOWN_KEY, COUNT_DOWN_TIME_MS } from '@/app/components/signin/countdown' +import I18NContext from '@/context/i18n' + +type MailAndCodeAuthProps = { + isInvite: boolean +} + +export default function MailAndCodeAuth({ isInvite }: MailAndCodeAuthProps) { + const { t } = useTranslation() + const router = useRouter() + const searchParams = useSearchParams() + const emailFromLink = decodeURIComponent(searchParams.get('email') || '') + const [email, setEmail] = useState(emailFromLink) + const [loading, setIsLoading] = useState(false) + const { locale } = useContext(I18NContext) + + const handleGetEMailVerificationCode = async () => { + try { + if (!email) { + Toast.notify({ type: 'error', message: t('login.error.emailEmpty') }) + return + } + + if (!emailRegex.test(email)) { + Toast.notify({ + type: 'error', + message: t('login.error.emailInValid'), + }) + return + } + setIsLoading(true) + const ret = await sendEMailLoginCode(email, locale) + if (ret.result === 'success') { + localStorage.setItem(COUNT_DOWN_KEY, `${COUNT_DOWN_TIME_MS}`) + const params = new URLSearchParams(searchParams) + params.set('email', encodeURIComponent(email)) + params.set('token', encodeURIComponent(ret.data)) + router.push(`/signin/check-code?${params.toString()}`) + } + } + catch (error) { + console.error(error) + } + finally { + setIsLoading(false) + } + } + + return (
{ }}> + +
+ +
+ setEmail(e.target.value)} /> +
+
+ +
+
+
+ ) +} diff --git a/web/app/signin/components/mail-and-password-auth.tsx b/web/app/signin/components/mail-and-password-auth.tsx new file mode 100644 index 0000000000..210c877bb7 --- /dev/null +++ b/web/app/signin/components/mail-and-password-auth.tsx @@ -0,0 +1,167 @@ +import Link from 'next/link' +import { useState } from 'react' +import { useTranslation } from 'react-i18next' +import { useRouter, useSearchParams } from 'next/navigation' +import { useContext } from 'use-context-selector' +import Button from '@/app/components/base/button' +import Toast from '@/app/components/base/toast' +import { emailRegex } from '@/config' +import { login } from '@/service/common' +import Input from '@/app/components/base/input' +import I18NContext from '@/context/i18n' + +type MailAndPasswordAuthProps = { + isInvite: boolean + allowRegistration: boolean +} + +const passwordRegex = /^(?=.*[a-zA-Z])(?=.*\d).{8,}$/ + +export default function MailAndPasswordAuth({ isInvite, allowRegistration }: MailAndPasswordAuthProps) { + const { t } = useTranslation() + const { locale } = useContext(I18NContext) + const router = useRouter() + const searchParams = useSearchParams() + const [showPassword, setShowPassword] = useState(false) + const emailFromLink = decodeURIComponent(searchParams.get('email') || '') + const [email, setEmail] = useState(emailFromLink) + const [password, setPassword] = useState('') + + const [isLoading, setIsLoading] = useState(false) + const handleEmailPasswordLogin = async () => { + if (!email) { + Toast.notify({ type: 'error', message: t('login.error.emailEmpty') }) + return + } + if (!emailRegex.test(email)) { + Toast.notify({ + type: 'error', + message: t('login.error.emailInValid'), + }) + return + } + if (!password?.trim()) { + Toast.notify({ type: 'error', message: t('login.error.passwordEmpty') }) + return + } + if (!passwordRegex.test(password)) { + Toast.notify({ + type: 'error', + message: t('login.error.passwordInvalid'), + }) + return + } + try { + setIsLoading(true) + const loginData: Record = { + email, + password, + language: locale, + remember_me: true, + } + if (isInvite) + loginData.invite_token = decodeURIComponent(searchParams.get('invite_token') as string) + const res = await login({ + url: '/login', + body: loginData, + }) + if (res.result === 'success') { + if (isInvite) { + router.replace(`/signin/invite-settings?${searchParams.toString()}`) + } + else { + localStorage.setItem('console_token', res.data.access_token) + localStorage.setItem('refresh_token', res.data.refresh_token) + router.replace('/apps') + } + } + else if (res.code === 'account_not_found') { + if (allowRegistration) { + const params = new URLSearchParams() + params.append('email', encodeURIComponent(email)) + params.append('token', encodeURIComponent(res.data)) + router.replace(`/reset-password/check-code?${params.toString()}`) + } + else { + Toast.notify({ + type: 'error', + message: t('login.error.registrationNotAllowed'), + }) + } + } + else { + Toast.notify({ + type: 'error', + message: res.data, + }) + } + } + + finally { + setIsLoading(false) + } + } + + return
{ }}> +
+ +
+ setEmail(e.target.value)} + disabled={isInvite} + id="email" + type="email" + autoComplete="email" + placeholder={t('login.emailPlaceholder') || ''} + tabIndex={1} + /> +
+
+ +
+ +
+ setPassword(e.target.value)} + onKeyDown={(e) => { + if (e.key === 'Enter') + handleEmailPasswordLogin() + }} + type={showPassword ? 'text' : 'password'} + autoComplete="current-password" + placeholder={t('login.passwordPlaceholder') || ''} + tabIndex={2} + /> +
+ +
+
+
+ +
+ +
+
+} diff --git a/web/app/signin/components/social-auth.tsx b/web/app/signin/components/social-auth.tsx new file mode 100644 index 0000000000..39d7ceaa40 --- /dev/null +++ b/web/app/signin/components/social-auth.tsx @@ -0,0 +1,62 @@ +import { useTranslation } from 'react-i18next' +import { useSearchParams } from 'next/navigation' +import style from '../page.module.css' +import Button from '@/app/components/base/button' +import { apiPrefix } from '@/config' +import classNames from '@/utils/classnames' +import { getPurifyHref } from '@/utils' + +type SocialAuthProps = { + disabled?: boolean +} + +export default function SocialAuth(props: SocialAuthProps) { + const { t } = useTranslation() + const searchParams = useSearchParams() + + const getOAuthLink = (href: string) => { + const url = getPurifyHref(`${apiPrefix}${href}`) + if (searchParams.has('invite_token')) + return `${url}?${searchParams.toString()}` + + return url + } + return <> + + + +} diff --git a/web/app/signin/components/sso-auth.tsx b/web/app/signin/components/sso-auth.tsx new file mode 100644 index 0000000000..fb303b93e2 --- /dev/null +++ b/web/app/signin/components/sso-auth.tsx @@ -0,0 +1,73 @@ +'use client' +import { useRouter, useSearchParams } from 'next/navigation' +import type { FC } from 'react' +import { useState } from 'react' +import { useTranslation } from 'react-i18next' +import { Lock01 } from '@/app/components/base/icons/src/vender/solid/security' +import Toast from '@/app/components/base/toast' +import { getUserOAuth2SSOUrl, getUserOIDCSSOUrl, getUserSAMLSSOUrl } from '@/service/sso' +import Button from '@/app/components/base/button' +import { SSOProtocol } from '@/types/feature' + +type SSOAuthProps = { + protocol: SSOProtocol | '' +} + +const SSOAuth: FC = ({ + protocol, +}) => { + const router = useRouter() + const { t } = useTranslation() + const searchParams = useSearchParams() + const invite_token = decodeURIComponent(searchParams.get('invite_token') || '') + + const [isLoading, setIsLoading] = useState(false) + + const handleSSOLogin = () => { + setIsLoading(true) + if (protocol === SSOProtocol.SAML) { + getUserSAMLSSOUrl(invite_token).then((res) => { + router.push(res.url) + }).finally(() => { + setIsLoading(false) + }) + } + else if (protocol === SSOProtocol.OIDC) { + getUserOIDCSSOUrl(invite_token).then((res) => { + document.cookie = `user-oidc-state=${res.state}` + router.push(res.url) + }).finally(() => { + setIsLoading(false) + }) + } + else if (protocol === SSOProtocol.OAuth2) { + getUserOAuth2SSOUrl(invite_token).then((res) => { + document.cookie = `user-oauth2-state=${res.state}` + router.push(res.url) + }).finally(() => { + setIsLoading(false) + }) + } + else { + Toast.notify({ + type: 'error', + message: 'invalid SSO protocol', + }) + setIsLoading(false) + } + } + + return ( + + ) +} + +export default SSOAuth diff --git a/web/app/signin/forms.tsx b/web/app/signin/forms.tsx deleted file mode 100644 index 70a34c26fa..0000000000 --- a/web/app/signin/forms.tsx +++ /dev/null @@ -1,34 +0,0 @@ -'use client' -import React from 'react' -import { useSearchParams } from 'next/navigation' - -import NormalForm from './normalForm' -import OneMoreStep from './oneMoreStep' -import cn from '@/utils/classnames' - -const Forms = () => { - const searchParams = useSearchParams() - const step = searchParams.get('step') - - const getForm = () => { - switch (step) { - case 'next': - return - default: - return - } - } - return
-
- {getForm()} -
-
-} - -export default Forms diff --git a/web/app/signin/invite-settings/page.tsx b/web/app/signin/invite-settings/page.tsx new file mode 100644 index 0000000000..2138399ec3 --- /dev/null +++ b/web/app/signin/invite-settings/page.tsx @@ -0,0 +1,154 @@ +'use client' +import { useTranslation } from 'react-i18next' +import { useCallback, useState } from 'react' +import Link from 'next/link' +import { useContext } from 'use-context-selector' +import { useRouter, useSearchParams } from 'next/navigation' +import useSWR from 'swr' +import { RiAccountCircleLine } from '@remixicon/react' +import Input from '@/app/components/base/input' +import { SimpleSelect } from '@/app/components/base/select' +import Button from '@/app/components/base/button' +import { timezones } from '@/utils/timezone' +import { LanguagesSupported, languages } from '@/i18n/language' +import I18n from '@/context/i18n' +import { activateMember, invitationCheck } from '@/service/common' +import Loading from '@/app/components/base/loading' +import Toast from '@/app/components/base/toast' + +export default function InviteSettingsPage() { + const { t } = useTranslation() + const router = useRouter() + const searchParams = useSearchParams() + const token = decodeURIComponent(searchParams.get('invite_token') as string) + const { locale, setLocaleOnClient } = useContext(I18n) + const [name, setName] = useState('') + const [language, setLanguage] = useState(LanguagesSupported[0]) + const [timezone, setTimezone] = useState(Intl.DateTimeFormat().resolvedOptions().timeZone || 'America/Los_Angeles') + + const checkParams = { + url: '/activate/check', + params: { + token, + }, + } + const { data: checkRes, mutate: recheck } = useSWR(checkParams, invitationCheck, { + revalidateOnFocus: false, + }) + + const handleActivate = useCallback(async () => { + try { + if (!name) { + Toast.notify({ type: 'error', message: t('login.enterYourName') }) + return + } + const res = await activateMember({ + url: '/activate', + body: { + token, + name, + interface_language: language, + timezone, + }, + }) + if (res.result === 'success') { + localStorage.setItem('console_token', res.data.access_token) + localStorage.setItem('refresh_token', res.data.refresh_token) + setLocaleOnClient(language, false) + router.replace('/apps') + } + } + catch { + recheck() + } + }, [language, name, recheck, setLocaleOnClient, timezone, token, router, t]) + + if (!checkRes) + return + if (!checkRes.is_valid) { + return
+
+
🤷‍♂️
+

{t('login.invalid')}

+
+ +
+ } + + return
+
+ +
+
+

{t('login.setYourAccount')}

+
+
+ +
+ +
+ setName(e.target.value)} + placeholder={t('login.namePlaceholder') || ''} + /> +
+
+
+ +
+ item.supported)} + onSelect={(item) => { + setLanguage(item.value as string) + }} + /> +
+
+ {/* timezone */} +
+ +
+ { + setTimezone(item.value as string) + }} + /> +
+
+
+ +
+
+
+ {t('login.license.tip')} +   + {t('login.license.link')} +
+
+} diff --git a/web/app/signin/layout.tsx b/web/app/signin/layout.tsx new file mode 100644 index 0000000000..342876bc53 --- /dev/null +++ b/web/app/signin/layout.tsx @@ -0,0 +1,54 @@ +import Script from 'next/script' +import Header from './_header' +import style from './page.module.css' + +import cn from '@/utils/classnames' +import { IS_CE_EDITION } from '@/config' + +export default async function SignInLayout({ children }: any) { + return <> + {!IS_CE_EDITION && ( + <> + + + + )} + +
+
+
+
+
+ {children} +
+
+
+ © {new Date().getFullYear()} LangGenius, Inc. All rights reserved. +
+
+
+ +} diff --git a/web/app/signin/userSSOForm.tsx b/web/app/signin/userSSOForm.tsx deleted file mode 100644 index f01afa9eaf..0000000000 --- a/web/app/signin/userSSOForm.tsx +++ /dev/null @@ -1,107 +0,0 @@ -'use client' -import { useRouter, useSearchParams } from 'next/navigation' -import type { FC } from 'react' -import { useEffect, useState } from 'react' -import { useTranslation } from 'react-i18next' -import cn from '@/utils/classnames' -import Toast from '@/app/components/base/toast' -import { getUserOAuth2SSOUrl, getUserOIDCSSOUrl, getUserSAMLSSOUrl } from '@/service/sso' -import Button from '@/app/components/base/button' -import useRefreshToken from '@/hooks/use-refresh-token' - -type UserSSOFormProps = { - protocol: string -} - -const UserSSOForm: FC = ({ - protocol, -}) => { - const { getNewAccessToken } = useRefreshToken() - const searchParams = useSearchParams() - const consoleToken = searchParams.get('access_token') - const refreshToken = searchParams.get('refresh_token') - const message = searchParams.get('message') - - const router = useRouter() - const { t } = useTranslation() - - const [isLoading, setIsLoading] = useState(false) - - useEffect(() => { - if (refreshToken && consoleToken) { - localStorage.setItem('console_token', consoleToken) - localStorage.setItem('refresh_token', refreshToken) - getNewAccessToken() - router.replace('/apps') - } - - if (message) { - Toast.notify({ - type: 'error', - message, - }) - } - }, [consoleToken, refreshToken, message, router]) - - const handleSSOLogin = () => { - setIsLoading(true) - if (protocol === 'saml') { - getUserSAMLSSOUrl().then((res) => { - router.push(res.url) - }).finally(() => { - setIsLoading(false) - }) - } - else if (protocol === 'oidc') { - getUserOIDCSSOUrl().then((res) => { - document.cookie = `user-oidc-state=${res.state}` - router.push(res.url) - }).finally(() => { - setIsLoading(false) - }) - } - else if (protocol === 'oauth2') { - getUserOAuth2SSOUrl().then((res) => { - document.cookie = `user-oauth2-state=${res.state}` - router.push(res.url) - }).finally(() => { - setIsLoading(false) - }) - } - else { - Toast.notify({ - type: 'error', - message: 'invalid SSO protocol', - }) - setIsLoading(false) - } - } - - return ( -
-
-
-

{t('login.pageTitle')}

-
-
- -
-
-
- ) -} - -export default UserSSOForm diff --git a/web/tailwind-common-config.ts b/web/tailwind-common-config.ts index 9e800750a3..35fd22e0a4 100644 --- a/web/tailwind-common-config.ts +++ b/web/tailwind-common-config.ts @@ -83,6 +83,11 @@ const config = { fontSize: { '2xs': '0.625rem', }, + backgroundImage: { + 'chatbot-bg': 'var(--color-chatbot-bg)', + 'chat-bubble-bg': 'var(--color-chat-bubble-bg)', + 'workflow-process-bg': 'var(--color-workflow-process-bg)', + }, animation: { 'spin-slow': 'spin 2s linear infinite', }, From 3e011109ad4d08d9cf686b1aeb32eb317842f14a Mon Sep 17 00:00:00 2001 From: Joel Date: Fri, 25 Oct 2024 11:26:41 +0800 Subject: [PATCH 217/346] merge main --- .../app/apps/workflow_logging_callback.py | 220 +++++ api/core/app/segments/__init__.py | 49 ++ api/core/app/segments/exc.py | 2 + api/core/app/segments/factory.py | 76 ++ api/core/app/segments/parser.py | 18 + api/core/app/segments/segment_group.py | 22 + api/core/app/segments/segments.py | 126 +++ api/core/app/segments/types.py | 15 + api/core/app/segments/variables.py | 75 ++ api/core/entities/message_entities.py | 29 + api/core/file/file_obj.py | 145 ++++ api/core/file/message_file_parser.py | 243 ++++++ api/core/file/upload_file_parser.py | 79 ++ .../builtin/feishu_base/_assets/icon.svg | 47 ++ .../feishu_base/tools/add_base_record.py | 56 ++ .../feishu_base/tools/add_base_record.yaml | 66 ++ .../feishu_base/tools/create_base_table.py | 48 ++ .../feishu_base/tools/create_base_table.yaml | 106 +++ .../feishu_base/tools/delete_base_records.py | 56 ++ .../tools/delete_base_records.yaml | 60 ++ .../feishu_base/tools/delete_base_tables.py | 46 ++ .../feishu_base/tools/delete_base_tables.yaml | 48 ++ .../tools/get_tenant_access_token.py | 48 ++ .../tools/get_tenant_access_token.yaml | 39 + .../feishu_base/tools/list_base_records.py | 65 ++ .../feishu_base/tools/list_base_records.yaml | 108 +++ .../feishu_base/tools/list_base_tables.py | 47 ++ .../feishu_base/tools/list_base_tables.yaml | 65 ++ .../feishu_base/tools/read_base_record.py | 49 ++ .../feishu_base/tools/read_base_record.yaml | 60 ++ .../feishu_base/tools/update_base_record.py | 60 ++ .../feishu_base/tools/update_base_record.yaml | 78 ++ .../tools/utils/tool_parameter_converter.py | 71 ++ .../entities/base_node_data_entities.py | 24 + api/core/workflow/nodes/base_node.py | 117 +++ api/core/workflow/nodes/event.py | 20 + .../nodes/http_request/http_executor.py | 343 ++++++++ .../nodes/http_request/http_request_node.py | 165 ++++ api/core/workflow/nodes/llm/llm_node.py | 774 ++++++++++++++++++ .../tools/test_tool_parameter_converter.py | 56 ++ .../select-type-item/style.module.css | 40 + .../config-vision/radio-group/index.tsx | 40 + .../radio-group/style.module.css | 24 + .../config-voice/param-config-content.tsx | 220 +++++ .../config-voice/param-config.tsx | 41 + .../config/feature/add-feature-btn/index.tsx | 40 + .../choose-feature/feature-item/index.tsx | 52 ++ .../feature-item/preview-imgs/citation.png | Bin 0 -> 29852 bytes .../feature-item/preview-imgs/citation.svg | 150 ++++ .../citations-and-attributions-preview@2x.png | Bin 0 -> 20827 bytes .../conversation-opener-preview@2x.png | Bin 0 -> 14409 bytes .../more-like-this-preview@2x.png | Bin 0 -> 19839 bytes .../preview-imgs/more-like-this.png | Bin 0 -> 30202 bytes .../preview-imgs/more-like-this.svg | 188 +++++ .../next-question-suggestion-preview@2x.png | Bin 0 -> 28325 bytes .../preview-imgs/opening-statement.png | Bin 0 -> 19955 bytes .../opening-suggestion-preview@2x.png | Bin 0 -> 24140 bytes .../speech-to-text-preview@2x.png | Bin 0 -> 16929 bytes .../preview-imgs/speech-to-text.png | Bin 0 -> 24529 bytes .../preview-imgs/speech-to-text.svg | 100 +++ .../suggested-questions-after-answer.png | Bin 0 -> 42447 bytes .../suggested-questions-after-answer.svg | 163 ++++ .../text-to-audio-preview-assistant@2x.png | Bin 0 -> 23500 bytes .../text-to-audio-preview-completion@2x.png | Bin 0 -> 18462 bytes .../feature-item/style.module.css | 41 + .../config/feature/choose-feature/index.tsx | 172 ++++ .../config/feature/feature-group/index.tsx | 31 + .../features/chat-group/citation/index.tsx | 25 + .../features/chat-group/index.tsx | 65 ++ .../chat-group/speech-to-text/index.tsx | 25 + .../index.tsx | 34 + .../chat-group/text-to-speech/index.tsx | 55 ++ .../annotation/annotation-ctrl-btn/index.tsx | 135 +++ .../toolbox/annotation/config-param-modal.tsx | 139 ++++ .../configuration/toolbox/annotation/type.ts | 4 + .../annotation/use-annotation-config.ts | 89 ++ .../toolbox/moderation/form-generation.tsx | 79 ++ .../toolbox/moderation/index.tsx | 80 ++ .../toolbox/moderation/moderation-content.tsx | 72 ++ .../moderation/moderation-setting-modal.tsx | 373 +++++++++ .../score-slider/base-slider/index.tsx | 38 + .../score-slider/base-slider/style.module.css | 20 + .../toolbox/score-slider/index.tsx | 46 ++ .../components/base/chat/chat/chat-input.tsx | 258 ++++++ .../feature-choose/feature-group/index.tsx | 31 + .../feature-choose/feature-item/index.tsx | 96 +++ .../feature-item/preview-imgs/citation.svg | 150 ++++ .../citations-and-attributions-preview@2x.png | Bin 0 -> 20827 bytes .../conversation-opener-preview@2x.png | Bin 0 -> 14409 bytes .../more-like-this-preview@2x.png | Bin 0 -> 19839 bytes .../preview-imgs/more-like-this.svg | 188 +++++ .../next-question-suggestion-preview@2x.png | Bin 0 -> 28325 bytes .../preview-imgs/opening-statement.png | Bin 0 -> 19955 bytes .../opening-suggestion-preview@2x.png | Bin 0 -> 24140 bytes .../speech-to-text-preview@2x.png | Bin 0 -> 16929 bytes .../preview-imgs/speech-to-text.svg | 100 +++ .../suggested-questions-after-answer.svg | 163 ++++ .../text-to-audio-preview-assistant@2x.png | Bin 0 -> 23500 bytes .../text-to-audio-preview-completion@2x.png | Bin 0 -> 18462 bytes .../feature-item/style.module.css | 41 + .../features/feature-choose/feature-modal.tsx | 147 ++++ .../base/features/feature-choose/index.tsx | 42 + .../features/feature-panel/citation/index.tsx | 25 + .../feature-panel/file-upload/index.tsx | 63 ++ .../file-upload/param-config-content.tsx | 119 +++ .../file-upload/param-config.tsx | 49 ++ .../file-upload/radio-group/index.tsx | 40 + .../file-upload/radio-group/style.module.css | 24 + .../base/features/feature-panel/index.tsx | 119 +++ .../moderation/form-generation.tsx | 80 ++ .../feature-panel/moderation/index.tsx | 108 +++ .../moderation/moderation-content.tsx | 73 ++ .../moderation/moderation-setting-modal.tsx | 376 +++++++++ .../feature-panel/opening-statement/index.tsx | 327 ++++++++ .../score-slider/base-slider/index.tsx | 38 + .../score-slider/base-slider/style.module.css | 20 + .../feature-panel/score-slider/index.tsx | 46 ++ .../feature-panel/speech-to-text/index.tsx | 22 + .../index.tsx | 25 + .../feature-panel/text-to-speech/index.tsx | 62 ++ .../text-to-speech/param-config-content.tsx | 241 ++++++ .../text-to-speech/params-config.tsx | 48 ++ web/app/signin/forms.tsx | 34 + web/app/signin/userSSOForm.tsx | 107 +++ 124 files changed, 9664 insertions(+) create mode 100644 api/core/app/apps/workflow_logging_callback.py create mode 100644 api/core/app/segments/__init__.py create mode 100644 api/core/app/segments/exc.py create mode 100644 api/core/app/segments/factory.py create mode 100644 api/core/app/segments/parser.py create mode 100644 api/core/app/segments/segment_group.py create mode 100644 api/core/app/segments/segments.py create mode 100644 api/core/app/segments/types.py create mode 100644 api/core/app/segments/variables.py create mode 100644 api/core/entities/message_entities.py create mode 100644 api/core/file/file_obj.py create mode 100644 api/core/file/message_file_parser.py create mode 100644 api/core/file/upload_file_parser.py create mode 100644 api/core/tools/provider/builtin/feishu_base/_assets/icon.svg create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/add_base_record.py create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/add_base_record.yaml create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/create_base_table.py create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/create_base_table.yaml create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/delete_base_records.py create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/delete_base_records.yaml create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/delete_base_tables.py create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/delete_base_tables.yaml create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/get_tenant_access_token.py create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/get_tenant_access_token.yaml create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/list_base_records.py create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/list_base_records.yaml create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/list_base_tables.py create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/list_base_tables.yaml create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/read_base_record.py create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/read_base_record.yaml create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/update_base_record.py create mode 100644 api/core/tools/provider/builtin/feishu_base/tools/update_base_record.yaml create mode 100644 api/core/tools/utils/tool_parameter_converter.py create mode 100644 api/core/workflow/entities/base_node_data_entities.py create mode 100644 api/core/workflow/nodes/base_node.py create mode 100644 api/core/workflow/nodes/event.py create mode 100644 api/core/workflow/nodes/http_request/http_executor.py create mode 100644 api/core/workflow/nodes/http_request/http_request_node.py create mode 100644 api/core/workflow/nodes/llm/llm_node.py create mode 100644 api/tests/unit_tests/core/tools/test_tool_parameter_converter.py create mode 100644 web/app/components/app/configuration/config-var/select-type-item/style.module.css create mode 100644 web/app/components/app/configuration/config-vision/radio-group/index.tsx create mode 100644 web/app/components/app/configuration/config-vision/radio-group/style.module.css create mode 100644 web/app/components/app/configuration/config-voice/param-config-content.tsx create mode 100644 web/app/components/app/configuration/config-voice/param-config.tsx create mode 100644 web/app/components/app/configuration/config/feature/add-feature-btn/index.tsx create mode 100644 web/app/components/app/configuration/config/feature/choose-feature/feature-item/index.tsx create mode 100644 web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/citation.png create mode 100644 web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/citation.svg create mode 100644 web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/citations-and-attributions-preview@2x.png create mode 100644 web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/conversation-opener-preview@2x.png create mode 100644 web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/more-like-this-preview@2x.png create mode 100644 web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/more-like-this.png create mode 100644 web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/more-like-this.svg create mode 100644 web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/next-question-suggestion-preview@2x.png create mode 100644 web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/opening-statement.png create mode 100644 web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/opening-suggestion-preview@2x.png create mode 100644 web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/speech-to-text-preview@2x.png create mode 100644 web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/speech-to-text.png create mode 100644 web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/speech-to-text.svg create mode 100644 web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/suggested-questions-after-answer.png create mode 100644 web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/suggested-questions-after-answer.svg create mode 100644 web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/text-to-audio-preview-assistant@2x.png create mode 100644 web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/text-to-audio-preview-completion@2x.png create mode 100644 web/app/components/app/configuration/config/feature/choose-feature/feature-item/style.module.css create mode 100644 web/app/components/app/configuration/config/feature/choose-feature/index.tsx create mode 100644 web/app/components/app/configuration/config/feature/feature-group/index.tsx create mode 100644 web/app/components/app/configuration/features/chat-group/citation/index.tsx create mode 100644 web/app/components/app/configuration/features/chat-group/index.tsx create mode 100644 web/app/components/app/configuration/features/chat-group/speech-to-text/index.tsx create mode 100644 web/app/components/app/configuration/features/chat-group/suggested-questions-after-answer/index.tsx create mode 100644 web/app/components/app/configuration/features/chat-group/text-to-speech/index.tsx create mode 100644 web/app/components/app/configuration/toolbox/annotation/annotation-ctrl-btn/index.tsx create mode 100644 web/app/components/app/configuration/toolbox/annotation/config-param-modal.tsx create mode 100644 web/app/components/app/configuration/toolbox/annotation/type.ts create mode 100644 web/app/components/app/configuration/toolbox/annotation/use-annotation-config.ts create mode 100644 web/app/components/app/configuration/toolbox/moderation/form-generation.tsx create mode 100644 web/app/components/app/configuration/toolbox/moderation/index.tsx create mode 100644 web/app/components/app/configuration/toolbox/moderation/moderation-content.tsx create mode 100644 web/app/components/app/configuration/toolbox/moderation/moderation-setting-modal.tsx create mode 100644 web/app/components/app/configuration/toolbox/score-slider/base-slider/index.tsx create mode 100644 web/app/components/app/configuration/toolbox/score-slider/base-slider/style.module.css create mode 100644 web/app/components/app/configuration/toolbox/score-slider/index.tsx create mode 100644 web/app/components/base/chat/chat/chat-input.tsx create mode 100644 web/app/components/base/features/feature-choose/feature-group/index.tsx create mode 100644 web/app/components/base/features/feature-choose/feature-item/index.tsx create mode 100644 web/app/components/base/features/feature-choose/feature-item/preview-imgs/citation.svg create mode 100644 web/app/components/base/features/feature-choose/feature-item/preview-imgs/citations-and-attributions-preview@2x.png create mode 100644 web/app/components/base/features/feature-choose/feature-item/preview-imgs/conversation-opener-preview@2x.png create mode 100644 web/app/components/base/features/feature-choose/feature-item/preview-imgs/more-like-this-preview@2x.png create mode 100644 web/app/components/base/features/feature-choose/feature-item/preview-imgs/more-like-this.svg create mode 100644 web/app/components/base/features/feature-choose/feature-item/preview-imgs/next-question-suggestion-preview@2x.png create mode 100644 web/app/components/base/features/feature-choose/feature-item/preview-imgs/opening-statement.png create mode 100644 web/app/components/base/features/feature-choose/feature-item/preview-imgs/opening-suggestion-preview@2x.png create mode 100644 web/app/components/base/features/feature-choose/feature-item/preview-imgs/speech-to-text-preview@2x.png create mode 100644 web/app/components/base/features/feature-choose/feature-item/preview-imgs/speech-to-text.svg create mode 100644 web/app/components/base/features/feature-choose/feature-item/preview-imgs/suggested-questions-after-answer.svg create mode 100644 web/app/components/base/features/feature-choose/feature-item/preview-imgs/text-to-audio-preview-assistant@2x.png create mode 100644 web/app/components/base/features/feature-choose/feature-item/preview-imgs/text-to-audio-preview-completion@2x.png create mode 100644 web/app/components/base/features/feature-choose/feature-item/style.module.css create mode 100644 web/app/components/base/features/feature-choose/feature-modal.tsx create mode 100644 web/app/components/base/features/feature-choose/index.tsx create mode 100644 web/app/components/base/features/feature-panel/citation/index.tsx create mode 100644 web/app/components/base/features/feature-panel/file-upload/index.tsx create mode 100644 web/app/components/base/features/feature-panel/file-upload/param-config-content.tsx create mode 100644 web/app/components/base/features/feature-panel/file-upload/param-config.tsx create mode 100644 web/app/components/base/features/feature-panel/file-upload/radio-group/index.tsx create mode 100644 web/app/components/base/features/feature-panel/file-upload/radio-group/style.module.css create mode 100644 web/app/components/base/features/feature-panel/index.tsx create mode 100644 web/app/components/base/features/feature-panel/moderation/form-generation.tsx create mode 100644 web/app/components/base/features/feature-panel/moderation/index.tsx create mode 100644 web/app/components/base/features/feature-panel/moderation/moderation-content.tsx create mode 100644 web/app/components/base/features/feature-panel/moderation/moderation-setting-modal.tsx create mode 100644 web/app/components/base/features/feature-panel/opening-statement/index.tsx create mode 100644 web/app/components/base/features/feature-panel/score-slider/base-slider/index.tsx create mode 100644 web/app/components/base/features/feature-panel/score-slider/base-slider/style.module.css create mode 100644 web/app/components/base/features/feature-panel/score-slider/index.tsx create mode 100644 web/app/components/base/features/feature-panel/speech-to-text/index.tsx create mode 100644 web/app/components/base/features/feature-panel/suggested-questions-after-answer/index.tsx create mode 100644 web/app/components/base/features/feature-panel/text-to-speech/index.tsx create mode 100644 web/app/components/base/features/feature-panel/text-to-speech/param-config-content.tsx create mode 100644 web/app/components/base/features/feature-panel/text-to-speech/params-config.tsx create mode 100644 web/app/signin/forms.tsx create mode 100644 web/app/signin/userSSOForm.tsx diff --git a/api/core/app/apps/workflow_logging_callback.py b/api/core/app/apps/workflow_logging_callback.py new file mode 100644 index 0000000000..60683b0f21 --- /dev/null +++ b/api/core/app/apps/workflow_logging_callback.py @@ -0,0 +1,220 @@ +from typing import Optional + +from core.model_runtime.utils.encoders import jsonable_encoder +from core.workflow.callbacks.base_workflow_callback import WorkflowCallback +from core.workflow.graph_engine.entities.event import ( + GraphEngineEvent, + GraphRunFailedEvent, + GraphRunStartedEvent, + GraphRunSucceededEvent, + IterationRunFailedEvent, + IterationRunNextEvent, + IterationRunStartedEvent, + IterationRunSucceededEvent, + NodeRunFailedEvent, + NodeRunStartedEvent, + NodeRunStreamChunkEvent, + NodeRunSucceededEvent, + ParallelBranchRunFailedEvent, + ParallelBranchRunStartedEvent, + ParallelBranchRunSucceededEvent, +) + +_TEXT_COLOR_MAPPING = { + "blue": "36;1", + "yellow": "33;1", + "pink": "38;5;200", + "green": "32;1", + "red": "31;1", +} + + +class WorkflowLoggingCallback(WorkflowCallback): + def __init__(self) -> None: + self.current_node_id = None + + def on_event(self, event: GraphEngineEvent) -> None: + if isinstance(event, GraphRunStartedEvent): + self.print_text("\n[GraphRunStartedEvent]", color="pink") + elif isinstance(event, GraphRunSucceededEvent): + self.print_text("\n[GraphRunSucceededEvent]", color="green") + elif isinstance(event, GraphRunFailedEvent): + self.print_text(f"\n[GraphRunFailedEvent] reason: {event.error}", color="red") + elif isinstance(event, NodeRunStartedEvent): + self.on_workflow_node_execute_started(event=event) + elif isinstance(event, NodeRunSucceededEvent): + self.on_workflow_node_execute_succeeded(event=event) + elif isinstance(event, NodeRunFailedEvent): + self.on_workflow_node_execute_failed(event=event) + elif isinstance(event, NodeRunStreamChunkEvent): + self.on_node_text_chunk(event=event) + elif isinstance(event, ParallelBranchRunStartedEvent): + self.on_workflow_parallel_started(event=event) + elif isinstance(event, ParallelBranchRunSucceededEvent | ParallelBranchRunFailedEvent): + self.on_workflow_parallel_completed(event=event) + elif isinstance(event, IterationRunStartedEvent): + self.on_workflow_iteration_started(event=event) + elif isinstance(event, IterationRunNextEvent): + self.on_workflow_iteration_next(event=event) + elif isinstance(event, IterationRunSucceededEvent | IterationRunFailedEvent): + self.on_workflow_iteration_completed(event=event) + else: + self.print_text(f"\n[{event.__class__.__name__}]", color="blue") + + def on_workflow_node_execute_started(self, event: NodeRunStartedEvent) -> None: + """ + Workflow node execute started + """ + self.print_text("\n[NodeRunStartedEvent]", color="yellow") + self.print_text(f"Node ID: {event.node_id}", color="yellow") + self.print_text(f"Node Title: {event.node_data.title}", color="yellow") + self.print_text(f"Type: {event.node_type.value}", color="yellow") + + def on_workflow_node_execute_succeeded(self, event: NodeRunSucceededEvent) -> None: + """ + Workflow node execute succeeded + """ + route_node_state = event.route_node_state + + self.print_text("\n[NodeRunSucceededEvent]", color="green") + self.print_text(f"Node ID: {event.node_id}", color="green") + self.print_text(f"Node Title: {event.node_data.title}", color="green") + self.print_text(f"Type: {event.node_type.value}", color="green") + + if route_node_state.node_run_result: + node_run_result = route_node_state.node_run_result + self.print_text( + f"Inputs: {jsonable_encoder(node_run_result.inputs) if node_run_result.inputs else ''}", + color="green", + ) + self.print_text( + f"Process Data: " + f"{jsonable_encoder(node_run_result.process_data) if node_run_result.process_data else ''}", + color="green", + ) + self.print_text( + f"Outputs: {jsonable_encoder(node_run_result.outputs) if node_run_result.outputs else ''}", + color="green", + ) + self.print_text( + f"Metadata: {jsonable_encoder(node_run_result.metadata) if node_run_result.metadata else ''}", + color="green", + ) + + def on_workflow_node_execute_failed(self, event: NodeRunFailedEvent) -> None: + """ + Workflow node execute failed + """ + route_node_state = event.route_node_state + + self.print_text("\n[NodeRunFailedEvent]", color="red") + self.print_text(f"Node ID: {event.node_id}", color="red") + self.print_text(f"Node Title: {event.node_data.title}", color="red") + self.print_text(f"Type: {event.node_type.value}", color="red") + + if route_node_state.node_run_result: + node_run_result = route_node_state.node_run_result + self.print_text(f"Error: {node_run_result.error}", color="red") + self.print_text( + f"Inputs: {jsonable_encoder(node_run_result.inputs) if node_run_result.inputs else ''}", + color="red", + ) + self.print_text( + f"Process Data: " + f"{jsonable_encoder(node_run_result.process_data) if node_run_result.process_data else ''}", + color="red", + ) + self.print_text( + f"Outputs: {jsonable_encoder(node_run_result.outputs) if node_run_result.outputs else ''}", + color="red", + ) + + def on_node_text_chunk(self, event: NodeRunStreamChunkEvent) -> None: + """ + Publish text chunk + """ + route_node_state = event.route_node_state + if not self.current_node_id or self.current_node_id != route_node_state.node_id: + self.current_node_id = route_node_state.node_id + self.print_text("\n[NodeRunStreamChunkEvent]") + self.print_text(f"Node ID: {route_node_state.node_id}") + + node_run_result = route_node_state.node_run_result + if node_run_result: + self.print_text( + f"Metadata: {jsonable_encoder(node_run_result.metadata) if node_run_result.metadata else ''}" + ) + + self.print_text(event.chunk_content, color="pink", end="") + + def on_workflow_parallel_started(self, event: ParallelBranchRunStartedEvent) -> None: + """ + Publish parallel started + """ + self.print_text("\n[ParallelBranchRunStartedEvent]", color="blue") + self.print_text(f"Parallel ID: {event.parallel_id}", color="blue") + self.print_text(f"Branch ID: {event.parallel_start_node_id}", color="blue") + if event.in_iteration_id: + self.print_text(f"Iteration ID: {event.in_iteration_id}", color="blue") + + def on_workflow_parallel_completed( + self, event: ParallelBranchRunSucceededEvent | ParallelBranchRunFailedEvent + ) -> None: + """ + Publish parallel completed + """ + if isinstance(event, ParallelBranchRunSucceededEvent): + color = "blue" + elif isinstance(event, ParallelBranchRunFailedEvent): + color = "red" + + self.print_text( + "\n[ParallelBranchRunSucceededEvent]" + if isinstance(event, ParallelBranchRunSucceededEvent) + else "\n[ParallelBranchRunFailedEvent]", + color=color, + ) + self.print_text(f"Parallel ID: {event.parallel_id}", color=color) + self.print_text(f"Branch ID: {event.parallel_start_node_id}", color=color) + if event.in_iteration_id: + self.print_text(f"Iteration ID: {event.in_iteration_id}", color=color) + + if isinstance(event, ParallelBranchRunFailedEvent): + self.print_text(f"Error: {event.error}", color=color) + + def on_workflow_iteration_started(self, event: IterationRunStartedEvent) -> None: + """ + Publish iteration started + """ + self.print_text("\n[IterationRunStartedEvent]", color="blue") + self.print_text(f"Iteration Node ID: {event.iteration_id}", color="blue") + + def on_workflow_iteration_next(self, event: IterationRunNextEvent) -> None: + """ + Publish iteration next + """ + self.print_text("\n[IterationRunNextEvent]", color="blue") + self.print_text(f"Iteration Node ID: {event.iteration_id}", color="blue") + self.print_text(f"Iteration Index: {event.index}", color="blue") + + def on_workflow_iteration_completed(self, event: IterationRunSucceededEvent | IterationRunFailedEvent) -> None: + """ + Publish iteration completed + """ + self.print_text( + "\n[IterationRunSucceededEvent]" + if isinstance(event, IterationRunSucceededEvent) + else "\n[IterationRunFailedEvent]", + color="blue", + ) + self.print_text(f"Node ID: {event.iteration_id}", color="blue") + + def print_text(self, text: str, color: Optional[str] = None, end: str = "\n") -> None: + """Print text with highlighting and no end characters.""" + text_to_print = self._get_colored_text(text, color) if color else text + print(f"{text_to_print}", end=end) + + def _get_colored_text(self, text: str, color: str) -> str: + """Get colored text.""" + color_str = _TEXT_COLOR_MAPPING[color] + return f"\u001b[{color_str}m\033[1;3m{text}\u001b[0m" diff --git a/api/core/app/segments/__init__.py b/api/core/app/segments/__init__.py new file mode 100644 index 0000000000..652ef243b4 --- /dev/null +++ b/api/core/app/segments/__init__.py @@ -0,0 +1,49 @@ +from .segment_group import SegmentGroup +from .segments import ( + ArrayAnySegment, + ArraySegment, + FloatSegment, + IntegerSegment, + NoneSegment, + ObjectSegment, + Segment, + StringSegment, +) +from .types import SegmentType +from .variables import ( + ArrayAnyVariable, + ArrayNumberVariable, + ArrayObjectVariable, + ArrayStringVariable, + FloatVariable, + IntegerVariable, + NoneVariable, + ObjectVariable, + SecretVariable, + StringVariable, + Variable, +) + +__all__ = [ + "IntegerVariable", + "FloatVariable", + "ObjectVariable", + "SecretVariable", + "StringVariable", + "ArrayAnyVariable", + "Variable", + "SegmentType", + "SegmentGroup", + "Segment", + "NoneSegment", + "NoneVariable", + "IntegerSegment", + "FloatSegment", + "ObjectSegment", + "ArrayAnySegment", + "StringSegment", + "ArrayStringVariable", + "ArrayNumberVariable", + "ArrayObjectVariable", + "ArraySegment", +] diff --git a/api/core/app/segments/exc.py b/api/core/app/segments/exc.py new file mode 100644 index 0000000000..5cf67c3bac --- /dev/null +++ b/api/core/app/segments/exc.py @@ -0,0 +1,2 @@ +class VariableError(ValueError): + pass diff --git a/api/core/app/segments/factory.py b/api/core/app/segments/factory.py new file mode 100644 index 0000000000..40a69ed4eb --- /dev/null +++ b/api/core/app/segments/factory.py @@ -0,0 +1,76 @@ +from collections.abc import Mapping +from typing import Any + +from configs import dify_config + +from .exc import VariableError +from .segments import ( + ArrayAnySegment, + FloatSegment, + IntegerSegment, + NoneSegment, + ObjectSegment, + Segment, + StringSegment, +) +from .types import SegmentType +from .variables import ( + ArrayNumberVariable, + ArrayObjectVariable, + ArrayStringVariable, + FloatVariable, + IntegerVariable, + ObjectVariable, + SecretVariable, + StringVariable, + Variable, +) + + +def build_variable_from_mapping(mapping: Mapping[str, Any], /) -> Variable: + if (value_type := mapping.get("value_type")) is None: + raise VariableError("missing value type") + if not mapping.get("name"): + raise VariableError("missing name") + if (value := mapping.get("value")) is None: + raise VariableError("missing value") + match value_type: + case SegmentType.STRING: + result = StringVariable.model_validate(mapping) + case SegmentType.SECRET: + result = SecretVariable.model_validate(mapping) + case SegmentType.NUMBER if isinstance(value, int): + result = IntegerVariable.model_validate(mapping) + case SegmentType.NUMBER if isinstance(value, float): + result = FloatVariable.model_validate(mapping) + case SegmentType.NUMBER if not isinstance(value, float | int): + raise VariableError(f"invalid number value {value}") + case SegmentType.OBJECT if isinstance(value, dict): + result = ObjectVariable.model_validate(mapping) + case SegmentType.ARRAY_STRING if isinstance(value, list): + result = ArrayStringVariable.model_validate(mapping) + case SegmentType.ARRAY_NUMBER if isinstance(value, list): + result = ArrayNumberVariable.model_validate(mapping) + case SegmentType.ARRAY_OBJECT if isinstance(value, list): + result = ArrayObjectVariable.model_validate(mapping) + case _: + raise VariableError(f"not supported value type {value_type}") + if result.size > dify_config.MAX_VARIABLE_SIZE: + raise VariableError(f"variable size {result.size} exceeds limit {dify_config.MAX_VARIABLE_SIZE}") + return result + + +def build_segment(value: Any, /) -> Segment: + if value is None: + return NoneSegment() + if isinstance(value, str): + return StringSegment(value=value) + if isinstance(value, int): + return IntegerSegment(value=value) + if isinstance(value, float): + return FloatSegment(value=value) + if isinstance(value, dict): + return ObjectSegment(value=value) + if isinstance(value, list): + return ArrayAnySegment(value=value) + raise ValueError(f"not supported value {value}") diff --git a/api/core/app/segments/parser.py b/api/core/app/segments/parser.py new file mode 100644 index 0000000000..3c4d7046f4 --- /dev/null +++ b/api/core/app/segments/parser.py @@ -0,0 +1,18 @@ +import re + +from core.workflow.entities.variable_pool import VariablePool + +from . import SegmentGroup, factory + +VARIABLE_PATTERN = re.compile(r"\{\{#([a-zA-Z0-9_]{1,50}(?:\.[a-zA-Z_][a-zA-Z0-9_]{0,29}){1,10})#\}\}") + + +def convert_template(*, template: str, variable_pool: VariablePool): + parts = re.split(VARIABLE_PATTERN, template) + segments = [] + for part in filter(lambda x: x, parts): + if "." in part and (value := variable_pool.get(part.split("."))): + segments.append(value) + else: + segments.append(factory.build_segment(part)) + return SegmentGroup(value=segments) diff --git a/api/core/app/segments/segment_group.py b/api/core/app/segments/segment_group.py new file mode 100644 index 0000000000..b363255b2c --- /dev/null +++ b/api/core/app/segments/segment_group.py @@ -0,0 +1,22 @@ +from .segments import Segment +from .types import SegmentType + + +class SegmentGroup(Segment): + value_type: SegmentType = SegmentType.GROUP + value: list[Segment] + + @property + def text(self): + return "".join([segment.text for segment in self.value]) + + @property + def log(self): + return "".join([segment.log for segment in self.value]) + + @property + def markdown(self): + return "".join([segment.markdown for segment in self.value]) + + def to_object(self): + return [segment.to_object() for segment in self.value] diff --git a/api/core/app/segments/segments.py b/api/core/app/segments/segments.py new file mode 100644 index 0000000000..b26b3c8291 --- /dev/null +++ b/api/core/app/segments/segments.py @@ -0,0 +1,126 @@ +import json +import sys +from collections.abc import Mapping, Sequence +from typing import Any + +from pydantic import BaseModel, ConfigDict, field_validator + +from .types import SegmentType + + +class Segment(BaseModel): + model_config = ConfigDict(frozen=True) + + value_type: SegmentType + value: Any + + @field_validator("value_type") + @classmethod + def validate_value_type(cls, value): + """ + This validator checks if the provided value is equal to the default value of the 'value_type' field. + If the value is different, a ValueError is raised. + """ + if value != cls.model_fields["value_type"].default: + raise ValueError("Cannot modify 'value_type'") + return value + + @property + def text(self) -> str: + return str(self.value) + + @property + def log(self) -> str: + return str(self.value) + + @property + def markdown(self) -> str: + return str(self.value) + + @property + def size(self) -> int: + return sys.getsizeof(self.value) + + def to_object(self) -> Any: + return self.value + + +class NoneSegment(Segment): + value_type: SegmentType = SegmentType.NONE + value: None = None + + @property + def text(self) -> str: + return "null" + + @property + def log(self) -> str: + return "null" + + @property + def markdown(self) -> str: + return "null" + + +class StringSegment(Segment): + value_type: SegmentType = SegmentType.STRING + value: str + + +class FloatSegment(Segment): + value_type: SegmentType = SegmentType.NUMBER + value: float + + +class IntegerSegment(Segment): + value_type: SegmentType = SegmentType.NUMBER + value: int + + +class ObjectSegment(Segment): + value_type: SegmentType = SegmentType.OBJECT + value: Mapping[str, Any] + + @property + def text(self) -> str: + return json.dumps(self.model_dump()["value"], ensure_ascii=False) + + @property + def log(self) -> str: + return json.dumps(self.model_dump()["value"], ensure_ascii=False, indent=2) + + @property + def markdown(self) -> str: + return json.dumps(self.model_dump()["value"], ensure_ascii=False, indent=2) + + +class ArraySegment(Segment): + @property + def markdown(self) -> str: + items = [] + for item in self.value: + if hasattr(item, "to_markdown"): + items.append(item.to_markdown()) + else: + items.append(str(item)) + return "\n".join(items) + + +class ArrayAnySegment(ArraySegment): + value_type: SegmentType = SegmentType.ARRAY_ANY + value: Sequence[Any] + + +class ArrayStringSegment(ArraySegment): + value_type: SegmentType = SegmentType.ARRAY_STRING + value: Sequence[str] + + +class ArrayNumberSegment(ArraySegment): + value_type: SegmentType = SegmentType.ARRAY_NUMBER + value: Sequence[float | int] + + +class ArrayObjectSegment(ArraySegment): + value_type: SegmentType = SegmentType.ARRAY_OBJECT + value: Sequence[Mapping[str, Any]] diff --git a/api/core/app/segments/types.py b/api/core/app/segments/types.py new file mode 100644 index 0000000000..9cf0856df5 --- /dev/null +++ b/api/core/app/segments/types.py @@ -0,0 +1,15 @@ +from enum import Enum + + +class SegmentType(str, Enum): + NONE = "none" + NUMBER = "number" + STRING = "string" + SECRET = "secret" + ARRAY_ANY = "array[any]" + ARRAY_STRING = "array[string]" + ARRAY_NUMBER = "array[number]" + ARRAY_OBJECT = "array[object]" + OBJECT = "object" + + GROUP = "group" diff --git a/api/core/app/segments/variables.py b/api/core/app/segments/variables.py new file mode 100644 index 0000000000..f0e403ab8d --- /dev/null +++ b/api/core/app/segments/variables.py @@ -0,0 +1,75 @@ +from pydantic import Field + +from core.helper import encrypter + +from .segments import ( + ArrayAnySegment, + ArrayNumberSegment, + ArrayObjectSegment, + ArrayStringSegment, + FloatSegment, + IntegerSegment, + NoneSegment, + ObjectSegment, + Segment, + StringSegment, +) +from .types import SegmentType + + +class Variable(Segment): + """ + A variable is a segment that has a name. + """ + + id: str = Field( + default="", + description="Unique identity for variable. It's only used by environment variables now.", + ) + name: str + description: str = Field(default="", description="Description of the variable.") + + +class StringVariable(StringSegment, Variable): + pass + + +class FloatVariable(FloatSegment, Variable): + pass + + +class IntegerVariable(IntegerSegment, Variable): + pass + + +class ObjectVariable(ObjectSegment, Variable): + pass + + +class ArrayAnyVariable(ArrayAnySegment, Variable): + pass + + +class ArrayStringVariable(ArrayStringSegment, Variable): + pass + + +class ArrayNumberVariable(ArrayNumberSegment, Variable): + pass + + +class ArrayObjectVariable(ArrayObjectSegment, Variable): + pass + + +class SecretVariable(StringVariable): + value_type: SegmentType = SegmentType.SECRET + + @property + def log(self) -> str: + return encrypter.obfuscated_token(self.value) + + +class NoneVariable(NoneSegment, Variable): + value_type: SegmentType = SegmentType.NONE + value: None = None diff --git a/api/core/entities/message_entities.py b/api/core/entities/message_entities.py new file mode 100644 index 0000000000..10bc9f6ed7 --- /dev/null +++ b/api/core/entities/message_entities.py @@ -0,0 +1,29 @@ +import enum +from typing import Any + +from pydantic import BaseModel + + +class PromptMessageFileType(enum.Enum): + IMAGE = "image" + + @staticmethod + def value_of(value): + for member in PromptMessageFileType: + if member.value == value: + return member + raise ValueError(f"No matching enum found for value '{value}'") + + +class PromptMessageFile(BaseModel): + type: PromptMessageFileType + data: Any = None + + +class ImagePromptMessageFile(PromptMessageFile): + class DETAIL(enum.Enum): + LOW = "low" + HIGH = "high" + + type: PromptMessageFileType = PromptMessageFileType.IMAGE + detail: DETAIL = DETAIL.LOW diff --git a/api/core/file/file_obj.py b/api/core/file/file_obj.py new file mode 100644 index 0000000000..5c4e694025 --- /dev/null +++ b/api/core/file/file_obj.py @@ -0,0 +1,145 @@ +import enum +from typing import Any, Optional + +from pydantic import BaseModel + +from core.file.tool_file_parser import ToolFileParser +from core.file.upload_file_parser import UploadFileParser +from core.model_runtime.entities.message_entities import ImagePromptMessageContent +from extensions.ext_database import db + + +class FileExtraConfig(BaseModel): + """ + File Upload Entity. + """ + + image_config: Optional[dict[str, Any]] = None + + +class FileType(enum.Enum): + IMAGE = "image" + + @staticmethod + def value_of(value): + for member in FileType: + if member.value == value: + return member + raise ValueError(f"No matching enum found for value '{value}'") + + +class FileTransferMethod(enum.Enum): + REMOTE_URL = "remote_url" + LOCAL_FILE = "local_file" + TOOL_FILE = "tool_file" + + @staticmethod + def value_of(value): + for member in FileTransferMethod: + if member.value == value: + return member + raise ValueError(f"No matching enum found for value '{value}'") + + +class FileBelongsTo(enum.Enum): + USER = "user" + ASSISTANT = "assistant" + + @staticmethod + def value_of(value): + for member in FileBelongsTo: + if member.value == value: + return member + raise ValueError(f"No matching enum found for value '{value}'") + + +class FileVar(BaseModel): + id: Optional[str] = None # message file id + tenant_id: str + type: FileType + transfer_method: FileTransferMethod + url: Optional[str] = None # remote url + related_id: Optional[str] = None + extra_config: Optional[FileExtraConfig] = None + filename: Optional[str] = None + extension: Optional[str] = None + mime_type: Optional[str] = None + + def to_dict(self) -> dict: + return { + "__variant": self.__class__.__name__, + "tenant_id": self.tenant_id, + "type": self.type.value, + "transfer_method": self.transfer_method.value, + "url": self.preview_url, + "remote_url": self.url, + "related_id": self.related_id, + "filename": self.filename, + "extension": self.extension, + "mime_type": self.mime_type, + } + + def to_markdown(self) -> str: + """ + Convert file to markdown + :return: + """ + preview_url = self.preview_url + if self.type == FileType.IMAGE: + text = f'![{self.filename or ""}]({preview_url})' + else: + text = f"[{self.filename or preview_url}]({preview_url})" + + return text + + @property + def data(self) -> Optional[str]: + """ + Get image data, file signed url or base64 data + depending on config MULTIMODAL_SEND_IMAGE_FORMAT + :return: + """ + return self._get_data() + + @property + def preview_url(self) -> Optional[str]: + """ + Get signed preview url + :return: + """ + return self._get_data(force_url=True) + + @property + def prompt_message_content(self) -> ImagePromptMessageContent: + if self.type == FileType.IMAGE: + image_config = self.extra_config.image_config + + return ImagePromptMessageContent( + data=self.data, + detail=ImagePromptMessageContent.DETAIL.HIGH + if image_config.get("detail") == "high" + else ImagePromptMessageContent.DETAIL.LOW, + ) + + def _get_data(self, force_url: bool = False) -> Optional[str]: + from models.model import UploadFile + + if self.type == FileType.IMAGE: + if self.transfer_method == FileTransferMethod.REMOTE_URL: + return self.url + elif self.transfer_method == FileTransferMethod.LOCAL_FILE: + upload_file = ( + db.session.query(UploadFile) + .filter(UploadFile.id == self.related_id, UploadFile.tenant_id == self.tenant_id) + .first() + ) + + return UploadFileParser.get_image_data(upload_file=upload_file, force_url=force_url) + elif self.transfer_method == FileTransferMethod.TOOL_FILE: + extension = self.extension + # add sign url + return ToolFileParser.get_tool_file_manager().sign_file( + tool_file_id=self.related_id, extension=extension + ) + + return None diff --git a/api/core/file/message_file_parser.py b/api/core/file/message_file_parser.py new file mode 100644 index 0000000000..641686bd7c --- /dev/null +++ b/api/core/file/message_file_parser.py @@ -0,0 +1,243 @@ +import re +from collections.abc import Mapping, Sequence +from typing import Any, Union +from urllib.parse import parse_qs, urlparse + +import requests + +from core.file.file_obj import FileBelongsTo, FileExtraConfig, FileTransferMethod, FileType, FileVar +from extensions.ext_database import db +from models.account import Account +from models.model import EndUser, MessageFile, UploadFile +from services.file_service import IMAGE_EXTENSIONS + + +class MessageFileParser: + def __init__(self, tenant_id: str, app_id: str) -> None: + self.tenant_id = tenant_id + self.app_id = app_id + + def validate_and_transform_files_arg( + self, files: Sequence[Mapping[str, Any]], file_extra_config: FileExtraConfig, user: Union[Account, EndUser] + ) -> list[FileVar]: + """ + validate and transform files arg + + :param files: + :param file_extra_config: + :param user: + :return: + """ + for file in files: + if not isinstance(file, dict): + raise ValueError("Invalid file format, must be dict") + if not file.get("type"): + raise ValueError("Missing file type") + FileType.value_of(file.get("type")) + if not file.get("transfer_method"): + raise ValueError("Missing file transfer method") + FileTransferMethod.value_of(file.get("transfer_method")) + if file.get("transfer_method") == FileTransferMethod.REMOTE_URL.value: + if not file.get("url"): + raise ValueError("Missing file url") + if not file.get("url").startswith("http"): + raise ValueError("Invalid file url") + if file.get("transfer_method") == FileTransferMethod.LOCAL_FILE.value and not file.get("upload_file_id"): + raise ValueError("Missing file upload_file_id") + if file.get("transform_method") == FileTransferMethod.TOOL_FILE.value and not file.get("tool_file_id"): + raise ValueError("Missing file tool_file_id") + + # transform files to file objs + type_file_objs = self._to_file_objs(files, file_extra_config) + + # validate files + new_files = [] + for file_type, file_objs in type_file_objs.items(): + if file_type == FileType.IMAGE: + # parse and validate files + image_config = file_extra_config.image_config + + # check if image file feature is enabled + if not image_config: + continue + + # Validate number of files + if len(files) > image_config["number_limits"]: + raise ValueError(f"Number of image files exceeds the maximum limit {image_config['number_limits']}") + + for file_obj in file_objs: + # Validate transfer method + if file_obj.transfer_method.value not in image_config["transfer_methods"]: + raise ValueError(f"Invalid transfer method: {file_obj.transfer_method.value}") + + # Validate file type + if file_obj.type != FileType.IMAGE: + raise ValueError(f"Invalid file type: {file_obj.type}") + + if file_obj.transfer_method == FileTransferMethod.REMOTE_URL: + # check remote url valid and is image + result, error = self._check_image_remote_url(file_obj.url) + if result is False: + raise ValueError(error) + elif file_obj.transfer_method == FileTransferMethod.LOCAL_FILE: + # get upload file from upload_file_id + upload_file = ( + db.session.query(UploadFile) + .filter( + UploadFile.id == file_obj.related_id, + UploadFile.tenant_id == self.tenant_id, + UploadFile.created_by == user.id, + UploadFile.created_by_role == ("account" if isinstance(user, Account) else "end_user"), + UploadFile.extension.in_(IMAGE_EXTENSIONS), + ) + .first() + ) + + # check upload file is belong to tenant and user + if not upload_file: + raise ValueError("Invalid upload file") + + new_files.append(file_obj) + + # return all file objs + return new_files + + def transform_message_files(self, files: list[MessageFile], file_extra_config: FileExtraConfig): + """ + transform message files + + :param files: + :param file_extra_config: + :return: + """ + # transform files to file objs + type_file_objs = self._to_file_objs(files, file_extra_config) + + # return all file objs + return [file_obj for file_objs in type_file_objs.values() for file_obj in file_objs] + + def _to_file_objs( + self, files: list[Union[dict, MessageFile]], file_extra_config: FileExtraConfig + ) -> dict[FileType, list[FileVar]]: + """ + transform files to file objs + + :param files: + :param file_extra_config: + :return: + """ + type_file_objs: dict[FileType, list[FileVar]] = { + # Currently only support image + FileType.IMAGE: [] + } + + if not files: + return type_file_objs + + # group by file type and convert file args or message files to FileObj + for file in files: + if isinstance(file, MessageFile): + if file.belongs_to == FileBelongsTo.ASSISTANT.value: + continue + + file_obj = self._to_file_obj(file, file_extra_config) + if file_obj.type not in type_file_objs: + continue + + type_file_objs[file_obj.type].append(file_obj) + + return type_file_objs + + def _to_file_obj(self, file: Union[dict, MessageFile], file_extra_config: FileExtraConfig): + """ + transform file to file obj + + :param file: + :return: + """ + if isinstance(file, dict): + transfer_method = FileTransferMethod.value_of(file.get("transfer_method")) + if transfer_method != FileTransferMethod.TOOL_FILE: + return FileVar( + tenant_id=self.tenant_id, + type=FileType.value_of(file.get("type")), + transfer_method=transfer_method, + url=file.get("url") if transfer_method == FileTransferMethod.REMOTE_URL else None, + related_id=file.get("upload_file_id") if transfer_method == FileTransferMethod.LOCAL_FILE else None, + extra_config=file_extra_config, + ) + return FileVar( + tenant_id=self.tenant_id, + type=FileType.value_of(file.get("type")), + transfer_method=transfer_method, + url=None, + related_id=file.get("tool_file_id"), + extra_config=file_extra_config, + ) + else: + return FileVar( + id=file.id, + tenant_id=self.tenant_id, + type=FileType.value_of(file.type), + transfer_method=FileTransferMethod.value_of(file.transfer_method), + url=file.url, + related_id=file.upload_file_id or None, + extra_config=file_extra_config, + ) + + def _check_image_remote_url(self, url): + try: + headers = { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)" + " Chrome/91.0.4472.124 Safari/537.36" + } + + def is_s3_presigned_url(url): + try: + parsed_url = urlparse(url) + if "amazonaws.com" not in parsed_url.netloc: + return False + query_params = parse_qs(parsed_url.query) + + def check_presign_v2(query_params): + required_params = ["Signature", "Expires"] + for param in required_params: + if param not in query_params: + return False + if not query_params["Expires"][0].isdigit(): + return False + signature = query_params["Signature"][0] + if not re.match(r"^[A-Za-z0-9+/]+={0,2}$", signature): + return False + + return True + + def check_presign_v4(query_params): + required_params = ["X-Amz-Signature", "X-Amz-Expires"] + for param in required_params: + if param not in query_params: + return False + if not query_params["X-Amz-Expires"][0].isdigit(): + return False + signature = query_params["X-Amz-Signature"][0] + if not re.match(r"^[A-Za-z0-9+/]+={0,2}$", signature): + return False + + return True + + return check_presign_v4(query_params) or check_presign_v2(query_params) + except Exception: + return False + + if is_s3_presigned_url(url): + response = requests.get(url, headers=headers, allow_redirects=True) + if response.status_code in {200, 304}: + return True, "" + + response = requests.head(url, headers=headers, allow_redirects=True) + if response.status_code in {200, 304}: + return True, "" + else: + return False, "URL does not exist." + except requests.RequestException as e: + return False, f"Error checking URL: {e}" diff --git a/api/core/file/upload_file_parser.py b/api/core/file/upload_file_parser.py new file mode 100644 index 0000000000..a8c1fd4d02 --- /dev/null +++ b/api/core/file/upload_file_parser.py @@ -0,0 +1,79 @@ +import base64 +import hashlib +import hmac +import logging +import os +import time +from typing import Optional + +from configs import dify_config +from extensions.ext_storage import storage + +IMAGE_EXTENSIONS = ["jpg", "jpeg", "png", "webp", "gif", "svg"] +IMAGE_EXTENSIONS.extend([ext.upper() for ext in IMAGE_EXTENSIONS]) + + +class UploadFileParser: + @classmethod + def get_image_data(cls, upload_file, force_url: bool = False) -> Optional[str]: + if not upload_file: + return None + + if upload_file.extension not in IMAGE_EXTENSIONS: + return None + + if dify_config.MULTIMODAL_SEND_IMAGE_FORMAT == "url" or force_url: + return cls.get_signed_temp_image_url(upload_file.id) + else: + # get image file base64 + try: + data = storage.load(upload_file.key) + except FileNotFoundError: + logging.error(f"File not found: {upload_file.key}") + return None + + encoded_string = base64.b64encode(data).decode("utf-8") + return f"data:{upload_file.mime_type};base64,{encoded_string}" + + @classmethod + def get_signed_temp_image_url(cls, upload_file_id) -> str: + """ + get signed url from upload file + + :param upload_file: UploadFile object + :return: + """ + base_url = dify_config.FILES_URL + image_preview_url = f"{base_url}/files/{upload_file_id}/image-preview" + + timestamp = str(int(time.time())) + nonce = os.urandom(16).hex() + data_to_sign = f"image-preview|{upload_file_id}|{timestamp}|{nonce}" + secret_key = dify_config.SECRET_KEY.encode() + sign = hmac.new(secret_key, data_to_sign.encode(), hashlib.sha256).digest() + encoded_sign = base64.urlsafe_b64encode(sign).decode() + + return f"{image_preview_url}?timestamp={timestamp}&nonce={nonce}&sign={encoded_sign}" + + @classmethod + def verify_image_file_signature(cls, upload_file_id: str, timestamp: str, nonce: str, sign: str) -> bool: + """ + verify signature + + :param upload_file_id: file id + :param timestamp: timestamp + :param nonce: nonce + :param sign: signature + :return: + """ + data_to_sign = f"image-preview|{upload_file_id}|{timestamp}|{nonce}" + secret_key = dify_config.SECRET_KEY.encode() + recalculated_sign = hmac.new(secret_key, data_to_sign.encode(), hashlib.sha256).digest() + recalculated_encoded_sign = base64.urlsafe_b64encode(recalculated_sign).decode() + + # verify signature + if sign != recalculated_encoded_sign: + return False + + current_time = int(time.time()) + return current_time - int(timestamp) <= dify_config.FILES_ACCESS_TIMEOUT diff --git a/api/core/tools/provider/builtin/feishu_base/_assets/icon.svg b/api/core/tools/provider/builtin/feishu_base/_assets/icon.svg new file mode 100644 index 0000000000..2663a0f59e --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/_assets/icon.svg @@ -0,0 +1,47 @@ + + + + diff --git a/api/core/tools/provider/builtin/feishu_base/tools/add_base_record.py b/api/core/tools/provider/builtin/feishu_base/tools/add_base_record.py new file mode 100644 index 0000000000..4a605fbffe --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/add_base_record.py @@ -0,0 +1,56 @@ +import json +from typing import Any, Union + +import httpx + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.tool.builtin_tool import BuiltinTool + + +class AddBaseRecordTool(BuiltinTool): + def _invoke( + self, user_id: str, tool_parameters: dict[str, Any] + ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: + url = "https://open.feishu.cn/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/records" + + access_token = tool_parameters.get("Authorization", "") + if not access_token: + return self.create_text_message("Invalid parameter access_token") + + app_token = tool_parameters.get("app_token", "") + if not app_token: + return self.create_text_message("Invalid parameter app_token") + + table_id = tool_parameters.get("table_id", "") + if not table_id: + return self.create_text_message("Invalid parameter table_id") + + fields = tool_parameters.get("fields", "") + if not fields: + return self.create_text_message("Invalid parameter fields") + + headers = { + "Content-Type": "application/json", + "Authorization": f"Bearer {access_token}", + } + + params = {} + payload = {"fields": json.loads(fields)} + + try: + res = httpx.post( + url.format(app_token=app_token, table_id=table_id), + headers=headers, + params=params, + json=payload, + timeout=30, + ) + res_json = res.json() + if res.is_success: + return self.create_text_message(text=json.dumps(res_json)) + else: + return self.create_text_message( + f"Failed to add base record, status code: {res.status_code}, response: {res.text}" + ) + except Exception as e: + return self.create_text_message("Failed to add base record. {}".format(e)) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/add_base_record.yaml b/api/core/tools/provider/builtin/feishu_base/tools/add_base_record.yaml new file mode 100644 index 0000000000..3ce0154efd --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/add_base_record.yaml @@ -0,0 +1,66 @@ +identity: + name: add_base_record + author: Doug Lea + label: + en_US: Add Base Record + zh_Hans: 在多维表格数据表中新增一条记录 +description: + human: + en_US: Add Base Record + zh_Hans: | + 在多维表格数据表中新增一条记录,详细请参考:https://open.larkoffice.com/document/server-docs/docs/bitable-v1/app-table-record/create + llm: Add a new record in the multidimensional table data table. +parameters: + - name: Authorization + type: string + required: true + label: + en_US: token + zh_Hans: 凭证 + human_description: + en_US: API access token parameter, tenant_access_token or user_access_token + zh_Hans: API 的访问凭证参数,tenant_access_token 或 user_access_token + llm_description: API access token parameter, tenant_access_token or user_access_token + form: llm + + - name: app_token + type: string + required: true + label: + en_US: app_token + zh_Hans: 多维表格 + human_description: + en_US: bitable app token + zh_Hans: 多维表格的唯一标识符 app_token + llm_description: bitable app token + form: llm + + - name: table_id + type: string + required: true + label: + en_US: table_id + zh_Hans: 多维表格的数据表 + human_description: + en_US: bitable table id + zh_Hans: 多维表格数据表的唯一标识符 table_id + llm_description: bitable table id + form: llm + + - name: fields + type: string + required: true + label: + en_US: fields + zh_Hans: 数据表的列字段内容 + human_description: + en_US: The fields of the Base data table are the columns of the data table. + zh_Hans: | + 要增加一行多维表格记录,字段结构拼接如下:{"多行文本":"多行文本内容","单选":"选项1","多选":["选项1","选项2"],"复选框":true,"人员":[{"id":"ou_2910013f1e6456f16a0ce75ede950a0a"}],"群组":[{"id":"oc_cd07f55f14d6f4a4f1b51504e7e97f48"}],"电话号码":"13026162666"} + 当前接口支持的字段类型为:多行文本、单选、条码、多选、日期、人员、附件、复选框、超链接、数字、单向关联、双向关联、电话号码、地理位置。 + 不同类型字段的数据结构请参考数据结构概述:https://open.larkoffice.com/document/server-docs/docs/bitable-v1/bitable-structure + llm_description: | + 要增加一行多维表格记录,字段结构拼接如下:{"多行文本":"多行文本内容","单选":"选项1","多选":["选项1","选项2"],"复选框":true,"人员":[{"id":"ou_2910013f1e6456f16a0ce75ede950a0a"}],"群组":[{"id":"oc_cd07f55f14d6f4a4f1b51504e7e97f48"}],"电话号码":"13026162666"} + 当前接口支持的字段类型为:多行文本、单选、条码、多选、日期、人员、附件、复选框、超链接、数字、单向关联、双向关联、电话号码、地理位置。 + 不同类型字段的数据结构请参考数据结构概述:https://open.larkoffice.com/document/server-docs/docs/bitable-v1/bitable-structure + form: llm diff --git a/api/core/tools/provider/builtin/feishu_base/tools/create_base_table.py b/api/core/tools/provider/builtin/feishu_base/tools/create_base_table.py new file mode 100644 index 0000000000..b05d700113 --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/create_base_table.py @@ -0,0 +1,48 @@ +import json +from typing import Any, Union + +import httpx + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.tool.builtin_tool import BuiltinTool + + +class CreateBaseTableTool(BuiltinTool): + def _invoke( + self, user_id: str, tool_parameters: dict[str, Any] + ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: + url = "https://open.feishu.cn/open-apis/bitable/v1/apps/{app_token}/tables" + + access_token = tool_parameters.get("Authorization", "") + if not access_token: + return self.create_text_message("Invalid parameter access_token") + + app_token = tool_parameters.get("app_token", "") + if not app_token: + return self.create_text_message("Invalid parameter app_token") + + name = tool_parameters.get("name", "") + + fields = tool_parameters.get("fields", "") + if not fields: + return self.create_text_message("Invalid parameter fields") + + headers = { + "Content-Type": "application/json", + "Authorization": f"Bearer {access_token}", + } + + params = {} + payload = {"table": {"name": name, "fields": json.loads(fields)}} + + try: + res = httpx.post(url.format(app_token=app_token), headers=headers, params=params, json=payload, timeout=30) + res_json = res.json() + if res.is_success: + return self.create_text_message(text=json.dumps(res_json)) + else: + return self.create_text_message( + f"Failed to create base table, status code: {res.status_code}, response: {res.text}" + ) + except Exception as e: + return self.create_text_message("Failed to create base table. {}".format(e)) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/create_base_table.yaml b/api/core/tools/provider/builtin/feishu_base/tools/create_base_table.yaml new file mode 100644 index 0000000000..48c46bec14 --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/create_base_table.yaml @@ -0,0 +1,106 @@ +identity: + name: create_base_table + author: Doug Lea + label: + en_US: Create Base Table + zh_Hans: 多维表格新增一个数据表 +description: + human: + en_US: Create base table + zh_Hans: | + 多维表格新增一个数据表,详细请参考:https://open.larkoffice.com/document/server-docs/docs/bitable-v1/app-table/create + llm: A tool for add a new data table to the multidimensional table. +parameters: + - name: Authorization + type: string + required: true + label: + en_US: token + zh_Hans: 凭证 + human_description: + en_US: API access token parameter, tenant_access_token or user_access_token + zh_Hans: API 的访问凭证参数,tenant_access_token 或 user_access_token + llm_description: API access token parameter, tenant_access_token or user_access_token + form: llm + + - name: app_token + type: string + required: true + label: + en_US: app_token + zh_Hans: 多维表格 + human_description: + en_US: bitable app token + zh_Hans: 多维表格的唯一标识符 app_token + llm_description: bitable app token + form: llm + + - name: name + type: string + required: false + label: + en_US: name + zh_Hans: name + human_description: + en_US: Multidimensional table data table name + zh_Hans: 多维表格数据表名称 + llm_description: Multidimensional table data table name + form: llm + + - name: fields + type: string + required: true + label: + en_US: fields + zh_Hans: fields + human_description: + en_US: Initial fields of the data table + zh_Hans: | + 数据表的初始字段,格式为:[{"field_name":"多行文本","type":1},{"field_name":"数字","type":2},{"field_name":"单选","type":3},{"field_name":"多选","type":4},{"field_name":"日期","type":5}]。 + field_name:字段名; + type: 字段类型;可选值有 + 1:多行文本 + 2:数字 + 3:单选 + 4:多选 + 5:日期 + 7:复选框 + 11:人员 + 13:电话号码 + 15:超链接 + 17:附件 + 18:单向关联 + 20:公式 + 21:双向关联 + 22:地理位置 + 23:群组 + 1001:创建时间 + 1002:最后更新时间 + 1003:创建人 + 1004:修改人 + 1005:自动编号 + llm_description: | + 数据表的初始字段,格式为:[{"field_name":"多行文本","type":1},{"field_name":"数字","type":2},{"field_name":"单选","type":3},{"field_name":"多选","type":4},{"field_name":"日期","type":5}]。 + field_name:字段名; + type: 字段类型;可选值有 + 1:多行文本 + 2:数字 + 3:单选 + 4:多选 + 5:日期 + 7:复选框 + 11:人员 + 13:电话号码 + 15:超链接 + 17:附件 + 18:单向关联 + 20:公式 + 21:双向关联 + 22:地理位置 + 23:群组 + 1001:创建时间 + 1002:最后更新时间 + 1003:创建人 + 1004:修改人 + 1005:自动编号 + form: llm diff --git a/api/core/tools/provider/builtin/feishu_base/tools/delete_base_records.py b/api/core/tools/provider/builtin/feishu_base/tools/delete_base_records.py new file mode 100644 index 0000000000..862eb2171b --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/delete_base_records.py @@ -0,0 +1,56 @@ +import json +from typing import Any, Union + +import httpx + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.tool.builtin_tool import BuiltinTool + + +class DeleteBaseRecordsTool(BuiltinTool): + def _invoke( + self, user_id: str, tool_parameters: dict[str, Any] + ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: + url = "https://open.feishu.cn/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/records/batch_delete" + + access_token = tool_parameters.get("Authorization", "") + if not access_token: + return self.create_text_message("Invalid parameter access_token") + + app_token = tool_parameters.get("app_token", "") + if not app_token: + return self.create_text_message("Invalid parameter app_token") + + table_id = tool_parameters.get("table_id", "") + if not table_id: + return self.create_text_message("Invalid parameter table_id") + + record_ids = tool_parameters.get("record_ids", "") + if not record_ids: + return self.create_text_message("Invalid parameter record_ids") + + headers = { + "Content-Type": "application/json", + "Authorization": f"Bearer {access_token}", + } + + params = {} + payload = {"records": json.loads(record_ids)} + + try: + res = httpx.post( + url.format(app_token=app_token, table_id=table_id), + headers=headers, + params=params, + json=payload, + timeout=30, + ) + res_json = res.json() + if res.is_success: + return self.create_text_message(text=json.dumps(res_json)) + else: + return self.create_text_message( + f"Failed to delete base records, status code: {res.status_code}, response: {res.text}" + ) + except Exception as e: + return self.create_text_message("Failed to delete base records. {}".format(e)) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/delete_base_records.yaml b/api/core/tools/provider/builtin/feishu_base/tools/delete_base_records.yaml new file mode 100644 index 0000000000..595b287029 --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/delete_base_records.yaml @@ -0,0 +1,60 @@ +identity: + name: delete_base_records + author: Doug Lea + label: + en_US: Delete Base Records + zh_Hans: 在多维表格数据表中删除多条记录 +description: + human: + en_US: Delete base records + zh_Hans: | + 该接口用于删除多维表格数据表中的多条记录,单次调用中最多删除 500 条记录。 + llm: A tool for delete multiple records in a multidimensional table data table, up to 500 records can be deleted in a single call. +parameters: + - name: Authorization + type: string + required: true + label: + en_US: token + zh_Hans: 凭证 + human_description: + en_US: API access token parameter, tenant_access_token or user_access_token + zh_Hans: API 的访问凭证参数,tenant_access_token 或 user_access_token + llm_description: API access token parameter, tenant_access_token or user_access_token + form: llm + + - name: app_token + type: string + required: true + label: + en_US: app_token + zh_Hans: 多维表格 + human_description: + en_US: bitable app token + zh_Hans: 多维表格的唯一标识符 app_token + llm_description: bitable app token + form: llm + + - name: table_id + type: string + required: true + label: + en_US: table_id + zh_Hans: 多维表格的数据表 + human_description: + en_US: bitable table id + zh_Hans: 多维表格数据表的唯一标识符 table_id + llm_description: bitable table id + form: llm + + - name: record_ids + type: string + required: true + label: + en_US: record_ids + zh_Hans: record_ids + human_description: + en_US: A list of multiple record IDs to be deleted, for example ["recwNXzPQv","recpCsf4ME"] + zh_Hans: 待删除的多条记录id列表,示例为 ["recwNXzPQv","recpCsf4ME"] + llm_description: A list of multiple record IDs to be deleted, for example ["recwNXzPQv","recpCsf4ME"] + form: llm diff --git a/api/core/tools/provider/builtin/feishu_base/tools/delete_base_tables.py b/api/core/tools/provider/builtin/feishu_base/tools/delete_base_tables.py new file mode 100644 index 0000000000..f512186303 --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/delete_base_tables.py @@ -0,0 +1,46 @@ +import json +from typing import Any, Union + +import httpx + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.tool.builtin_tool import BuiltinTool + + +class DeleteBaseTablesTool(BuiltinTool): + def _invoke( + self, user_id: str, tool_parameters: dict[str, Any] + ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: + url = "https://open.feishu.cn/open-apis/bitable/v1/apps/{app_token}/tables/batch_delete" + + access_token = tool_parameters.get("Authorization", "") + if not access_token: + return self.create_text_message("Invalid parameter access_token") + + app_token = tool_parameters.get("app_token", "") + if not app_token: + return self.create_text_message("Invalid parameter app_token") + + table_ids = tool_parameters.get("table_ids", "") + if not table_ids: + return self.create_text_message("Invalid parameter table_ids") + + headers = { + "Content-Type": "application/json", + "Authorization": f"Bearer {access_token}", + } + + params = {} + payload = {"table_ids": json.loads(table_ids)} + + try: + res = httpx.post(url.format(app_token=app_token), headers=headers, params=params, json=payload, timeout=30) + res_json = res.json() + if res.is_success: + return self.create_text_message(text=json.dumps(res_json)) + else: + return self.create_text_message( + f"Failed to delete base tables, status code: {res.status_code}, response: {res.text}" + ) + except Exception as e: + return self.create_text_message("Failed to delete base tables. {}".format(e)) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/delete_base_tables.yaml b/api/core/tools/provider/builtin/feishu_base/tools/delete_base_tables.yaml new file mode 100644 index 0000000000..5d72814363 --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/delete_base_tables.yaml @@ -0,0 +1,48 @@ +identity: + name: delete_base_tables + author: Doug Lea + label: + en_US: Delete Base Tables + zh_Hans: 删除多维表格中的数据表 +description: + human: + en_US: Delete base tables + zh_Hans: | + 删除多维表格中的数据表 + llm: A tool for deleting a data table in a multidimensional table +parameters: + - name: Authorization + type: string + required: true + label: + en_US: token + zh_Hans: 凭证 + human_description: + en_US: API access token parameter, tenant_access_token or user_access_token + zh_Hans: API 的访问凭证参数,tenant_access_token 或 user_access_token + llm_description: API access token parameter, tenant_access_token or user_access_token + form: llm + + - name: app_token + type: string + required: true + label: + en_US: app_token + zh_Hans: 多维表格 + human_description: + en_US: bitable app token + zh_Hans: 多维表格的唯一标识符 app_token + llm_description: bitable app token + form: llm + + - name: table_ids + type: string + required: true + label: + en_US: table_ids + zh_Hans: table_ids + human_description: + en_US: The ID list of the data tables to be deleted. Currently, a maximum of 50 data tables can be deleted at a time. The example is ["tbl1TkhyTWDkSoZ3","tblsRc9GRRXKqhvW"] + zh_Hans: 待删除数据表的id列表,当前一次操作最多支持50个数据表,示例为 ["tbl1TkhyTWDkSoZ3","tblsRc9GRRXKqhvW"] + llm_description: The ID list of the data tables to be deleted. Currently, a maximum of 50 data tables can be deleted at a time. The example is ["tbl1TkhyTWDkSoZ3","tblsRc9GRRXKqhvW"] + form: llm diff --git a/api/core/tools/provider/builtin/feishu_base/tools/get_tenant_access_token.py b/api/core/tools/provider/builtin/feishu_base/tools/get_tenant_access_token.py new file mode 100644 index 0000000000..2ea61d0068 --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/get_tenant_access_token.py @@ -0,0 +1,48 @@ +import json +from typing import Any, Union + +import httpx + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.tool.builtin_tool import BuiltinTool + + +class GetTenantAccessTokenTool(BuiltinTool): + def _invoke( + self, user_id: str, tool_parameters: dict[str, Any] + ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: + url = "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal" + + app_id = tool_parameters.get("app_id", "") + if not app_id: + return self.create_text_message("Invalid parameter app_id") + + app_secret = tool_parameters.get("app_secret", "") + if not app_secret: + return self.create_text_message("Invalid parameter app_secret") + + headers = { + "Content-Type": "application/json", + } + params = {} + payload = {"app_id": app_id, "app_secret": app_secret} + + """ + { + "code": 0, + "msg": "ok", + "tenant_access_token": "t-caecc734c2e3328a62489fe0648c4b98779515d3", + "expire": 7200 + } + """ + try: + res = httpx.post(url, headers=headers, params=params, json=payload, timeout=30) + res_json = res.json() + if res.is_success: + return self.create_text_message(text=json.dumps(res_json)) + else: + return self.create_text_message( + f"Failed to get tenant access token, status code: {res.status_code}, response: {res.text}" + ) + except Exception as e: + return self.create_text_message("Failed to get tenant access token. {}".format(e)) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/get_tenant_access_token.yaml b/api/core/tools/provider/builtin/feishu_base/tools/get_tenant_access_token.yaml new file mode 100644 index 0000000000..88acc27e06 --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/get_tenant_access_token.yaml @@ -0,0 +1,39 @@ +identity: + name: get_tenant_access_token + author: Doug Lea + label: + en_US: Get Tenant Access Token + zh_Hans: 获取飞书自建应用的 tenant_access_token +description: + human: + en_US: Get tenant access token + zh_Hans: | + 获取飞书自建应用的 tenant_access_token,响应体示例: + {"code":0,"msg":"ok","tenant_access_token":"t-caecc734c2e3328a62489fe0648c4b98779515d3","expire":7200} + tenant_access_token: 租户访问凭证; + expire: tenant_access_token 的过期时间,单位为秒; + llm: A tool for obtaining a tenant access token. The input parameters must include app_id and app_secret. +parameters: + - name: app_id + type: string + required: true + label: + en_US: app_id + zh_Hans: 应用唯一标识 + human_description: + en_US: app_id is the unique identifier of the Lark Open Platform application + zh_Hans: app_id 是飞书开放平台应用的唯一标识 + llm_description: app_id is the unique identifier of the Lark Open Platform application + form: llm + + - name: app_secret + type: secret-input + required: true + label: + en_US: app_secret + zh_Hans: 应用秘钥 + human_description: + en_US: app_secret is the secret key of the application + zh_Hans: app_secret 是应用的秘钥 + llm_description: app_secret is the secret key of the application + form: llm diff --git a/api/core/tools/provider/builtin/feishu_base/tools/list_base_records.py b/api/core/tools/provider/builtin/feishu_base/tools/list_base_records.py new file mode 100644 index 0000000000..e579d02f69 --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/list_base_records.py @@ -0,0 +1,65 @@ +import json +from typing import Any, Union + +import httpx + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.tool.builtin_tool import BuiltinTool + + +class ListBaseRecordsTool(BuiltinTool): + def _invoke( + self, user_id: str, tool_parameters: dict[str, Any] + ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: + url = "https://open.feishu.cn/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/records/search" + + access_token = tool_parameters.get("Authorization", "") + if not access_token: + return self.create_text_message("Invalid parameter access_token") + + app_token = tool_parameters.get("app_token", "") + if not app_token: + return self.create_text_message("Invalid parameter app_token") + + table_id = tool_parameters.get("table_id", "") + if not table_id: + return self.create_text_message("Invalid parameter table_id") + + page_token = tool_parameters.get("page_token", "") + page_size = tool_parameters.get("page_size", "") + sort_condition = tool_parameters.get("sort_condition", "") + filter_condition = tool_parameters.get("filter_condition", "") + + headers = { + "Content-Type": "application/json", + "Authorization": f"Bearer {access_token}", + } + + params = { + "page_token": page_token, + "page_size": page_size, + } + + payload = {"automatic_fields": True} + if sort_condition: + payload["sort"] = json.loads(sort_condition) + if filter_condition: + payload["filter"] = json.loads(filter_condition) + + try: + res = httpx.post( + url.format(app_token=app_token, table_id=table_id), + headers=headers, + params=params, + json=payload, + timeout=30, + ) + res_json = res.json() + if res.is_success: + return self.create_text_message(text=json.dumps(res_json)) + else: + return self.create_text_message( + f"Failed to list base records, status code: {res.status_code}, response: {res.text}" + ) + except Exception as e: + return self.create_text_message("Failed to list base records. {}".format(e)) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/list_base_records.yaml b/api/core/tools/provider/builtin/feishu_base/tools/list_base_records.yaml new file mode 100644 index 0000000000..8647c880a6 --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/list_base_records.yaml @@ -0,0 +1,108 @@ +identity: + name: list_base_records + author: Doug Lea + label: + en_US: List Base Records + zh_Hans: 查询多维表格数据表中的现有记录 +description: + human: + en_US: List base records + zh_Hans: | + 查询多维表格数据表中的现有记录,单次最多查询 500 行记录,支持分页获取。 + llm: Query existing records in a multidimensional table data table. A maximum of 500 rows of records can be queried at a time, and paging retrieval is supported. +parameters: + - name: Authorization + type: string + required: true + label: + en_US: token + zh_Hans: 凭证 + human_description: + en_US: API access token parameter, tenant_access_token or user_access_token + zh_Hans: API 的访问凭证参数,tenant_access_token 或 user_access_token + llm_description: API access token parameter, tenant_access_token or user_access_token + form: llm + + - name: app_token + type: string + required: true + label: + en_US: app_token + zh_Hans: 多维表格 + human_description: + en_US: bitable app token + zh_Hans: 多维表格的唯一标识符 app_token + llm_description: bitable app token + form: llm + + - name: table_id + type: string + required: true + label: + en_US: table_id + zh_Hans: 多维表格的数据表 + human_description: + en_US: bitable table id + zh_Hans: 多维表格数据表的唯一标识符 table_id + llm_description: bitable table id + form: llm + + - name: page_token + type: string + required: false + label: + en_US: page_token + zh_Hans: 分页标记 + human_description: + en_US: Pagination mark. If it is not filled in the first request, it means to traverse from the beginning. + zh_Hans: 分页标记,第一次请求不填,表示从头开始遍历。 + llm_description: 分页标记,第一次请求不填,表示从头开始遍历;分页查询结果还有更多项时会同时返回新的 page_token,下次遍历可采用该 page_token 获取查询结果。 + form: llm + + - name: page_size + type: number + required: false + default: 20 + label: + en_US: page_size + zh_Hans: 分页大小 + human_description: + en_US: paging size + zh_Hans: 分页大小,默认值为 20,最大值为 100。 + llm_description: The default value of paging size is 20 and the maximum value is 100. + form: llm + + - name: sort_condition + type: string + required: false + label: + en_US: sort_condition + zh_Hans: 排序条件 + human_description: + en_US: sort condition + zh_Hans: | + 排序条件,格式为:[{"field_name":"多行文本","desc":true}]。 + field_name: 字段名称; + desc: 是否倒序排序; + llm_description: | + Sorting conditions, the format is: [{"field_name":"multi-line text","desc":true}]. + form: llm + + - name: filter_condition + type: string + required: false + label: + en_US: filter_condition + zh_Hans: 筛选条件 + human_description: + en_US: filter condition + zh_Hans: | + 筛选条件,格式为:{"conjunction":"and","conditions":[{"field_name":"字段1","operator":"is","value":["文本内容"]}]}。 + conjunction:条件逻辑连接词; + conditions:筛选条件集合; + field_name:筛选条件的左值,值为字段的名称; + operator:条件运算符; + value:目标值; + llm_description: | + The format of the filter condition is: {"conjunction":"and","conditions":[{"field_name":"Field 1","operator":"is","value":["text content"]}]}. + form: llm diff --git a/api/core/tools/provider/builtin/feishu_base/tools/list_base_tables.py b/api/core/tools/provider/builtin/feishu_base/tools/list_base_tables.py new file mode 100644 index 0000000000..4ec9a476bc --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/list_base_tables.py @@ -0,0 +1,47 @@ +import json +from typing import Any, Union + +import httpx + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.tool.builtin_tool import BuiltinTool + + +class ListBaseTablesTool(BuiltinTool): + def _invoke( + self, user_id: str, tool_parameters: dict[str, Any] + ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: + url = "https://open.feishu.cn/open-apis/bitable/v1/apps/{app_token}/tables" + + access_token = tool_parameters.get("Authorization", "") + if not access_token: + return self.create_text_message("Invalid parameter access_token") + + app_token = tool_parameters.get("app_token", "") + if not app_token: + return self.create_text_message("Invalid parameter app_token") + + page_token = tool_parameters.get("page_token", "") + page_size = tool_parameters.get("page_size", "") + + headers = { + "Content-Type": "application/json", + "Authorization": f"Bearer {access_token}", + } + + params = { + "page_token": page_token, + "page_size": page_size, + } + + try: + res = httpx.get(url.format(app_token=app_token), headers=headers, params=params, timeout=30) + res_json = res.json() + if res.is_success: + return self.create_text_message(text=json.dumps(res_json)) + else: + return self.create_text_message( + f"Failed to list base tables, status code: {res.status_code}, response: {res.text}" + ) + except Exception as e: + return self.create_text_message("Failed to list base tables. {}".format(e)) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/list_base_tables.yaml b/api/core/tools/provider/builtin/feishu_base/tools/list_base_tables.yaml new file mode 100644 index 0000000000..9887124a28 --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/list_base_tables.yaml @@ -0,0 +1,65 @@ +identity: + name: list_base_tables + author: Doug Lea + label: + en_US: List Base Tables + zh_Hans: 根据 app_token 获取多维表格下的所有数据表 +description: + human: + en_US: List base tables + zh_Hans: | + 根据 app_token 获取多维表格下的所有数据表 + llm: A tool for getting all data tables under a multidimensional table based on app_token. +parameters: + - name: Authorization + type: string + required: true + label: + en_US: token + zh_Hans: 凭证 + human_description: + en_US: API access token parameter, tenant_access_token or user_access_token + zh_Hans: API 的访问凭证参数,tenant_access_token 或 user_access_token + llm_description: API access token parameter, tenant_access_token or user_access_token + form: llm + + - name: app_token + type: string + required: true + label: + en_US: app_token + zh_Hans: 多维表格 + human_description: + en_US: bitable app token + zh_Hans: 多维表格的唯一标识符 app_token + llm_description: bitable app token + form: llm + + - name: page_token + type: string + required: false + label: + en_US: page_token + zh_Hans: 分页标记 + human_description: + en_US: Pagination mark. If it is not filled in the first request, it means to traverse from the beginning. + zh_Hans: 分页标记,第一次请求不填,表示从头开始遍历。 + llm_description: | + Pagination token. If it is not filled in the first request, it means to start traversal from the beginning. + If there are more items in the pagination query result, a new page_token will be returned at the same time. + The page_token can be used to obtain the query result in the next traversal. + 分页标记,第一次请求不填,表示从头开始遍历;分页查询结果还有更多项时会同时返回新的 page_token,下次遍历可采用该 page_token 获取查询结果。 + form: llm + + - name: page_size + type: number + required: false + default: 20 + label: + en_US: page_size + zh_Hans: 分页大小 + human_description: + en_US: paging size + zh_Hans: 分页大小,默认值为 20,最大值为 100。 + llm_description: The default value of paging size is 20 and the maximum value is 100. + form: llm diff --git a/api/core/tools/provider/builtin/feishu_base/tools/read_base_record.py b/api/core/tools/provider/builtin/feishu_base/tools/read_base_record.py new file mode 100644 index 0000000000..fb818f8380 --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/read_base_record.py @@ -0,0 +1,49 @@ +import json +from typing import Any, Union + +import httpx + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.tool.builtin_tool import BuiltinTool + + +class ReadBaseRecordTool(BuiltinTool): + def _invoke( + self, user_id: str, tool_parameters: dict[str, Any] + ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: + url = "https://open.feishu.cn/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/records/{record_id}" + + access_token = tool_parameters.get("Authorization", "") + if not access_token: + return self.create_text_message("Invalid parameter access_token") + + app_token = tool_parameters.get("app_token", "") + if not app_token: + return self.create_text_message("Invalid parameter app_token") + + table_id = tool_parameters.get("table_id", "") + if not table_id: + return self.create_text_message("Invalid parameter table_id") + + record_id = tool_parameters.get("record_id", "") + if not record_id: + return self.create_text_message("Invalid parameter record_id") + + headers = { + "Content-Type": "application/json", + "Authorization": f"Bearer {access_token}", + } + + try: + res = httpx.get( + url.format(app_token=app_token, table_id=table_id, record_id=record_id), headers=headers, timeout=30 + ) + res_json = res.json() + if res.is_success: + return self.create_text_message(text=json.dumps(res_json)) + else: + return self.create_text_message( + f"Failed to read base record, status code: {res.status_code}, response: {res.text}" + ) + except Exception as e: + return self.create_text_message("Failed to read base record. {}".format(e)) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/read_base_record.yaml b/api/core/tools/provider/builtin/feishu_base/tools/read_base_record.yaml new file mode 100644 index 0000000000..400e9a1021 --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/read_base_record.yaml @@ -0,0 +1,60 @@ +identity: + name: read_base_record + author: Doug Lea + label: + en_US: Read Base Record + zh_Hans: 根据 record_id 的值检索多维表格数据表的记录 +description: + human: + en_US: Read base record + zh_Hans: | + 根据 record_id 的值检索多维表格数据表的记录 + llm: Retrieve records from a multidimensional table based on the value of record_id +parameters: + - name: Authorization + type: string + required: true + label: + en_US: token + zh_Hans: 凭证 + human_description: + en_US: API access token parameter, tenant_access_token or user_access_token + zh_Hans: API 的访问凭证参数,tenant_access_token 或 user_access_token + llm_description: API access token parameter, tenant_access_token or user_access_token + form: llm + + - name: app_token + type: string + required: true + label: + en_US: app_token + zh_Hans: 多维表格 + human_description: + en_US: bitable app token + zh_Hans: 多维表格的唯一标识符 app_token + llm_description: bitable app token + form: llm + + - name: table_id + type: string + required: true + label: + en_US: table_id + zh_Hans: 多维表格的数据表 + human_description: + en_US: bitable table id + zh_Hans: 多维表格数据表的唯一标识符 table_id + llm_description: bitable table id + form: llm + + - name: record_id + type: string + required: true + label: + en_US: record_id + zh_Hans: 单条记录的 id + human_description: + en_US: The id of a single record + zh_Hans: 单条记录的 id + llm_description: The id of a single record + form: llm diff --git a/api/core/tools/provider/builtin/feishu_base/tools/update_base_record.py b/api/core/tools/provider/builtin/feishu_base/tools/update_base_record.py new file mode 100644 index 0000000000..6d7e33f3ff --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/update_base_record.py @@ -0,0 +1,60 @@ +import json +from typing import Any, Union + +import httpx + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.tool.builtin_tool import BuiltinTool + + +class UpdateBaseRecordTool(BuiltinTool): + def _invoke( + self, user_id: str, tool_parameters: dict[str, Any] + ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: + url = "https://open.feishu.cn/open-apis/bitable/v1/apps/{app_token}/tables/{table_id}/records/{record_id}" + + access_token = tool_parameters.get("Authorization", "") + if not access_token: + return self.create_text_message("Invalid parameter access_token") + + app_token = tool_parameters.get("app_token", "") + if not app_token: + return self.create_text_message("Invalid parameter app_token") + + table_id = tool_parameters.get("table_id", "") + if not table_id: + return self.create_text_message("Invalid parameter table_id") + + record_id = tool_parameters.get("record_id", "") + if not record_id: + return self.create_text_message("Invalid parameter record_id") + + fields = tool_parameters.get("fields", "") + if not fields: + return self.create_text_message("Invalid parameter fields") + + headers = { + "Content-Type": "application/json", + "Authorization": f"Bearer {access_token}", + } + + params = {} + payload = {"fields": json.loads(fields)} + + try: + res = httpx.put( + url.format(app_token=app_token, table_id=table_id, record_id=record_id), + headers=headers, + params=params, + json=payload, + timeout=30, + ) + res_json = res.json() + if res.is_success: + return self.create_text_message(text=json.dumps(res_json)) + else: + return self.create_text_message( + f"Failed to update base record, status code: {res.status_code}, response: {res.text}" + ) + except Exception as e: + return self.create_text_message("Failed to update base record. {}".format(e)) diff --git a/api/core/tools/provider/builtin/feishu_base/tools/update_base_record.yaml b/api/core/tools/provider/builtin/feishu_base/tools/update_base_record.yaml new file mode 100644 index 0000000000..788798c4b3 --- /dev/null +++ b/api/core/tools/provider/builtin/feishu_base/tools/update_base_record.yaml @@ -0,0 +1,78 @@ +identity: + name: update_base_record + author: Doug Lea + label: + en_US: Update Base Record + zh_Hans: 更新多维表格数据表中的一条记录 +description: + human: + en_US: Update base record + zh_Hans: | + 更新多维表格数据表中的一条记录,详细请参考:https://open.larkoffice.com/document/server-docs/docs/bitable-v1/app-table-record/update + llm: Update a record in a multidimensional table data table +parameters: + - name: Authorization + type: string + required: true + label: + en_US: token + zh_Hans: 凭证 + human_description: + en_US: API access token parameter, tenant_access_token or user_access_token + zh_Hans: API 的访问凭证参数,tenant_access_token 或 user_access_token + llm_description: API access token parameter, tenant_access_token or user_access_token + form: llm + + - name: app_token + type: string + required: true + label: + en_US: app_token + zh_Hans: 多维表格 + human_description: + en_US: bitable app token + zh_Hans: 多维表格的唯一标识符 app_token + llm_description: bitable app token + form: llm + + - name: table_id + type: string + required: true + label: + en_US: table_id + zh_Hans: 多维表格的数据表 + human_description: + en_US: bitable table id + zh_Hans: 多维表格数据表的唯一标识符 table_id + llm_description: bitable table id + form: llm + + - name: record_id + type: string + required: true + label: + en_US: record_id + zh_Hans: 单条记录的 id + human_description: + en_US: The id of a single record + zh_Hans: 单条记录的 id + llm_description: The id of a single record + form: llm + + - name: fields + type: string + required: true + label: + en_US: fields + zh_Hans: 数据表的列字段内容 + human_description: + en_US: The fields of a multidimensional table data table, that is, the columns of the data table. + zh_Hans: | + 要更新一行多维表格记录,字段结构拼接如下:{"多行文本":"多行文本内容","单选":"选项1","多选":["选项1","选项2"],"复选框":true,"人员":[{"id":"ou_2910013f1e6456f16a0ce75ede950a0a"}],"群组":[{"id":"oc_cd07f55f14d6f4a4f1b51504e7e97f48"}],"电话号码":"13026162666"} + 当前接口支持的字段类型为:多行文本、单选、条码、多选、日期、人员、附件、复选框、超链接、数字、单向关联、双向关联、电话号码、地理位置。 + 不同类型字段的数据结构请参考数据结构概述:https://open.larkoffice.com/document/server-docs/docs/bitable-v1/bitable-structure + llm_description: | + 要更新一行多维表格记录,字段结构拼接如下:{"多行文本":"多行文本内容","单选":"选项1","多选":["选项1","选项2"],"复选框":true,"人员":[{"id":"ou_2910013f1e6456f16a0ce75ede950a0a"}],"群组":[{"id":"oc_cd07f55f14d6f4a4f1b51504e7e97f48"}],"电话号码":"13026162666"} + 当前接口支持的字段类型为:多行文本、单选、条码、多选、日期、人员、附件、复选框、超链接、数字、单向关联、双向关联、电话号码、地理位置。 + 不同类型字段的数据结构请参考数据结构概述:https://open.larkoffice.com/document/server-docs/docs/bitable-v1/bitable-structure + form: llm diff --git a/api/core/tools/utils/tool_parameter_converter.py b/api/core/tools/utils/tool_parameter_converter.py new file mode 100644 index 0000000000..6f7610651c --- /dev/null +++ b/api/core/tools/utils/tool_parameter_converter.py @@ -0,0 +1,71 @@ +from typing import Any + +from core.tools.entities.tool_entities import ToolParameter + + +class ToolParameterConverter: + @staticmethod + def get_parameter_type(parameter_type: str | ToolParameter.ToolParameterType) -> str: + match parameter_type: + case ( + ToolParameter.ToolParameterType.STRING + | ToolParameter.ToolParameterType.SECRET_INPUT + | ToolParameter.ToolParameterType.SELECT + ): + return "string" + + case ToolParameter.ToolParameterType.BOOLEAN: + return "boolean" + + case ToolParameter.ToolParameterType.NUMBER: + return "number" + + case _: + raise ValueError(f"Unsupported parameter type {parameter_type}") + + @staticmethod + def cast_parameter_by_type(value: Any, parameter_type: str) -> Any: + # convert tool parameter config to correct type + try: + match parameter_type: + case ( + ToolParameter.ToolParameterType.STRING + | ToolParameter.ToolParameterType.SECRET_INPUT + | ToolParameter.ToolParameterType.SELECT + ): + if value is None: + return "" + else: + return value if isinstance(value, str) else str(value) + + case ToolParameter.ToolParameterType.BOOLEAN: + if value is None: + return False + elif isinstance(value, str): + # Allowed YAML boolean value strings: https://yaml.org/type/bool.html + # and also '0' for False and '1' for True + match value.lower(): + case "true" | "yes" | "y" | "1": + return True + case "false" | "no" | "n" | "0": + return False + case _: + return bool(value) + else: + return value if isinstance(value, bool) else bool(value) + + case ToolParameter.ToolParameterType.NUMBER: + if isinstance(value, int) | isinstance(value, float): + return value + elif isinstance(value, str) and value != "": + if "." in value: + return float(value) + else: + return int(value) + case ToolParameter.ToolParameterType.FILE: + return value + case _: + return str(value) + + except Exception: + raise ValueError(f"The tool parameter value {value} is not in correct type of {parameter_type}.") diff --git a/api/core/workflow/entities/base_node_data_entities.py b/api/core/workflow/entities/base_node_data_entities.py new file mode 100644 index 0000000000..2a864dd7a8 --- /dev/null +++ b/api/core/workflow/entities/base_node_data_entities.py @@ -0,0 +1,24 @@ +from abc import ABC +from typing import Optional + +from pydantic import BaseModel + + +class BaseNodeData(ABC, BaseModel): + title: str + desc: Optional[str] = None + + +class BaseIterationNodeData(BaseNodeData): + start_node_id: Optional[str] = None + + +class BaseIterationState(BaseModel): + iteration_node_id: str + index: int + inputs: dict + + class MetaData(BaseModel): + pass + + metadata: MetaData diff --git a/api/core/workflow/nodes/base_node.py b/api/core/workflow/nodes/base_node.py new file mode 100644 index 0000000000..7bfe45a13c --- /dev/null +++ b/api/core/workflow/nodes/base_node.py @@ -0,0 +1,117 @@ +from abc import ABC, abstractmethod +from collections.abc import Generator, Mapping, Sequence +from typing import Any, Optional + +from core.workflow.entities.base_node_data_entities import BaseNodeData +from core.workflow.entities.node_entities import NodeRunResult, NodeType +from core.workflow.graph_engine.entities.event import InNodeEvent +from core.workflow.graph_engine.entities.graph import Graph +from core.workflow.graph_engine.entities.graph_init_params import GraphInitParams +from core.workflow.graph_engine.entities.graph_runtime_state import GraphRuntimeState +from core.workflow.nodes.event import RunCompletedEvent, RunEvent + + +class BaseNode(ABC): + _node_data_cls: type[BaseNodeData] + _node_type: NodeType + + def __init__( + self, + id: str, + config: Mapping[str, Any], + graph_init_params: GraphInitParams, + graph: Graph, + graph_runtime_state: GraphRuntimeState, + previous_node_id: Optional[str] = None, + thread_pool_id: Optional[str] = None, + ) -> None: + self.id = id + self.tenant_id = graph_init_params.tenant_id + self.app_id = graph_init_params.app_id + self.workflow_type = graph_init_params.workflow_type + self.workflow_id = graph_init_params.workflow_id + self.graph_config = graph_init_params.graph_config + self.user_id = graph_init_params.user_id + self.user_from = graph_init_params.user_from + self.invoke_from = graph_init_params.invoke_from + self.workflow_call_depth = graph_init_params.call_depth + self.graph = graph + self.graph_runtime_state = graph_runtime_state + self.previous_node_id = previous_node_id + self.thread_pool_id = thread_pool_id + + node_id = config.get("id") + if not node_id: + raise ValueError("Node ID is required.") + + self.node_id = node_id + self.node_data = self._node_data_cls(**config.get("data", {})) + + @abstractmethod + def _run(self) -> NodeRunResult | Generator[RunEvent | InNodeEvent, None, None]: + """ + Run node + :return: + """ + raise NotImplementedError + + def run(self) -> Generator[RunEvent | InNodeEvent, None, None]: + """ + Run node entry + :return: + """ + result = self._run() + + if isinstance(result, NodeRunResult): + yield RunCompletedEvent(run_result=result) + else: + yield from result + + @classmethod + def extract_variable_selector_to_variable_mapping( + cls, graph_config: Mapping[str, Any], config: dict + ) -> Mapping[str, Sequence[str]]: + """ + Extract variable selector to variable mapping + :param graph_config: graph config + :param config: node config + :return: + """ + node_id = config.get("id") + if not node_id: + raise ValueError("Node ID is required when extracting variable selector to variable mapping.") + + node_data = cls._node_data_cls(**config.get("data", {})) + return cls._extract_variable_selector_to_variable_mapping( + graph_config=graph_config, node_id=node_id, node_data=node_data + ) + + @classmethod + def _extract_variable_selector_to_variable_mapping( + cls, graph_config: Mapping[str, Any], node_id: str, node_data: BaseNodeData + ) -> Mapping[str, Sequence[str]]: + """ + Extract variable selector to variable mapping + :param graph_config: graph config + :param node_id: node id + :param node_data: node data + :return: + """ + return {} + + @classmethod + def get_default_config(cls, filters: Optional[dict] = None) -> dict: + """ + Get default config of node. + :param filters: filter by node config parameters. + :return: + """ + return {} + + @property + def node_type(self) -> NodeType: + """ + Get node type + :return: + """ + return self._node_type diff --git a/api/core/workflow/nodes/event.py b/api/core/workflow/nodes/event.py new file mode 100644 index 0000000000..276c13a6d4 --- /dev/null +++ b/api/core/workflow/nodes/event.py @@ -0,0 +1,20 @@ +from pydantic import BaseModel, Field + +from core.workflow.entities.node_entities import NodeRunResult + + +class RunCompletedEvent(BaseModel): + run_result: NodeRunResult = Field(..., description="run result") + + +class RunStreamChunkEvent(BaseModel): + chunk_content: str = Field(..., description="chunk content") + from_variable_selector: list[str] = Field(..., description="from variable selector") + + +class RunRetrieverResourceEvent(BaseModel): + retriever_resources: list[dict] = Field(..., description="retriever resources") + context: str = Field(..., description="context") + + +RunEvent = RunCompletedEvent | RunStreamChunkEvent | RunRetrieverResourceEvent diff --git a/api/core/workflow/nodes/http_request/http_executor.py b/api/core/workflow/nodes/http_request/http_executor.py new file mode 100644 index 0000000000..f8ab4e3132 --- /dev/null +++ b/api/core/workflow/nodes/http_request/http_executor.py @@ -0,0 +1,343 @@ +import json +from copy import deepcopy +from random import randint +from typing import Any, Optional, Union +from urllib.parse import urlencode + +import httpx + +from configs import dify_config +from core.helper import ssrf_proxy +from core.workflow.entities.variable_entities import VariableSelector +from core.workflow.entities.variable_pool import VariablePool +from core.workflow.nodes.http_request.entities import ( + HttpRequestNodeAuthorization, + HttpRequestNodeBody, + HttpRequestNodeData, + HttpRequestNodeTimeout, +) +from core.workflow.utils.variable_template_parser import VariableTemplateParser + + +class HttpExecutorResponse: + headers: dict[str, str] + response: httpx.Response + + def __init__(self, response: httpx.Response): + self.response = response + self.headers = dict(response.headers) if isinstance(self.response, httpx.Response) else {} + + @property + def is_file(self) -> bool: + """ + check if response is file + """ + content_type = self.get_content_type() + file_content_types = ["image", "audio", "video"] + + return any(v in content_type for v in file_content_types) + + def get_content_type(self) -> str: + return self.headers.get("content-type", "") + + def extract_file(self) -> tuple[str, bytes]: + """ + extract file from response if content type is file related + """ + if self.is_file: + return self.get_content_type(), self.body + + return "", b"" + + @property + def content(self) -> str: + if isinstance(self.response, httpx.Response): + return self.response.text + else: + raise ValueError(f"Invalid response type {type(self.response)}") + + @property + def body(self) -> bytes: + if isinstance(self.response, httpx.Response): + return self.response.content + else: + raise ValueError(f"Invalid response type {type(self.response)}") + + @property + def status_code(self) -> int: + if isinstance(self.response, httpx.Response): + return self.response.status_code + else: + raise ValueError(f"Invalid response type {type(self.response)}") + + @property + def size(self) -> int: + return len(self.body) + + @property + def readable_size(self) -> str: + if self.size < 1024: + return f"{self.size} bytes" + elif self.size < 1024 * 1024: + return f"{(self.size / 1024):.2f} KB" + else: + return f"{(self.size / 1024 / 1024):.2f} MB" + + +class HttpExecutor: + server_url: str + method: str + authorization: HttpRequestNodeAuthorization + params: dict[str, Any] + headers: dict[str, Any] + body: Union[None, str] + files: Union[None, dict[str, Any]] + boundary: str + variable_selectors: list[VariableSelector] + timeout: HttpRequestNodeTimeout + + def __init__( + self, + node_data: HttpRequestNodeData, + timeout: HttpRequestNodeTimeout, + variable_pool: Optional[VariablePool] = None, + ): + self.server_url = node_data.url + self.method = node_data.method + self.authorization = node_data.authorization + self.timeout = timeout + self.params = {} + self.headers = {} + self.body = None + self.files = None + + # init template + self.variable_selectors = [] + self._init_template(node_data, variable_pool) + + @staticmethod + def _is_json_body(body: HttpRequestNodeBody): + """ + check if body is json + """ + if body and body.type == "json" and body.data: + try: + json.loads(body.data) + return True + except: + return False + + return False + + @staticmethod + def _to_dict(convert_text: str): + """ + Convert the string like `aa:bb\n cc:dd` to dict `{aa:bb, cc:dd}` + """ + kv_paris = convert_text.split("\n") + result = {} + for kv in kv_paris: + if not kv.strip(): + continue + + kv = kv.split(":", maxsplit=1) + if len(kv) == 1: + k, v = kv[0], "" + else: + k, v = kv + result[k.strip()] = v + return result + + def _init_template(self, node_data: HttpRequestNodeData, variable_pool: Optional[VariablePool] = None): + # extract all template in url + self.server_url, server_url_variable_selectors = self._format_template(node_data.url, variable_pool) + + # extract all template in params + params, params_variable_selectors = self._format_template(node_data.params, variable_pool) + self.params = self._to_dict(params) + + # extract all template in headers + headers, headers_variable_selectors = self._format_template(node_data.headers, variable_pool) + self.headers = self._to_dict(headers) + + # extract all template in body + body_data_variable_selectors = [] + if node_data.body: + # check if it's a valid JSON + is_valid_json = self._is_json_body(node_data.body) + + body_data = node_data.body.data or "" + if body_data: + body_data, body_data_variable_selectors = self._format_template(body_data, variable_pool, is_valid_json) + + content_type_is_set = any(key.lower() == "content-type" for key in self.headers) + if node_data.body.type == "json" and not content_type_is_set: + self.headers["Content-Type"] = "application/json" + elif node_data.body.type == "x-www-form-urlencoded" and not content_type_is_set: + self.headers["Content-Type"] = "application/x-www-form-urlencoded" + + if node_data.body.type in {"form-data", "x-www-form-urlencoded"}: + body = self._to_dict(body_data) + + if node_data.body.type == "form-data": + self.files = {k: ("", v) for k, v in body.items()} + random_str = lambda n: "".join([chr(randint(97, 122)) for _ in range(n)]) + self.boundary = f"----WebKitFormBoundary{random_str(16)}" + + self.headers["Content-Type"] = f"multipart/form-data; boundary={self.boundary}" + else: + self.body = urlencode(body) + elif node_data.body.type in {"json", "raw-text"}: + self.body = body_data + elif node_data.body.type == "none": + self.body = "" + + self.variable_selectors = ( + server_url_variable_selectors + + params_variable_selectors + + headers_variable_selectors + + body_data_variable_selectors + ) + + def _assembling_headers(self) -> dict[str, Any]: + authorization = deepcopy(self.authorization) + headers = deepcopy(self.headers) or {} + if self.authorization.type == "api-key": + if self.authorization.config is None: + raise ValueError("self.authorization config is required") + if authorization.config is None: + raise ValueError("authorization config is required") + + if self.authorization.config.api_key is None: + raise ValueError("api_key is required") + + if not authorization.config.header: + authorization.config.header = "Authorization" + + if self.authorization.config.type == "bearer": + headers[authorization.config.header] = f"Bearer {authorization.config.api_key}" + elif self.authorization.config.type == "basic": + headers[authorization.config.header] = f"Basic {authorization.config.api_key}" + elif self.authorization.config.type == "custom": + headers[authorization.config.header] = authorization.config.api_key + + return headers + + def _validate_and_parse_response(self, response: httpx.Response) -> HttpExecutorResponse: + """ + validate the response + """ + if isinstance(response, httpx.Response): + executor_response = HttpExecutorResponse(response) + else: + raise ValueError(f"Invalid response type {type(response)}") + + threshold_size = ( + dify_config.HTTP_REQUEST_NODE_MAX_BINARY_SIZE + if executor_response.is_file + else dify_config.HTTP_REQUEST_NODE_MAX_TEXT_SIZE + ) + if executor_response.size > threshold_size: + raise ValueError( + f'{"File" if executor_response.is_file else "Text"} size is too large,' + f' max size is {threshold_size / 1024 / 1024:.2f} MB,' + f' but current size is {executor_response.readable_size}.' + ) + + return executor_response + + def _do_http_request(self, headers: dict[str, Any]) -> httpx.Response: + """ + do http request depending on api bundle + """ + kwargs = { + "url": self.server_url, + "headers": headers, + "params": self.params, + "timeout": (self.timeout.connect, self.timeout.read, self.timeout.write), + "follow_redirects": True, + } + + if self.method in {"get", "head", "post", "put", "delete", "patch"}: + response = getattr(ssrf_proxy, self.method)(data=self.body, files=self.files, **kwargs) + else: + raise ValueError(f"Invalid http method {self.method}") + return response + + def invoke(self) -> HttpExecutorResponse: + """ + invoke http request + """ + # assemble headers + headers = self._assembling_headers() + + # do http request + response = self._do_http_request(headers) + + # validate response + return self._validate_and_parse_response(response) + + def to_raw_request(self) -> str: + """ + convert to raw request + """ + server_url = self.server_url + if self.params: + server_url += f"?{urlencode(self.params)}" + + raw_request = f"{self.method.upper()} {server_url} HTTP/1.1\n" + + headers = self._assembling_headers() + for k, v in headers.items(): + # get authorization header + if self.authorization.type == "api-key": + authorization_header = "Authorization" + if self.authorization.config and self.authorization.config.header: + authorization_header = self.authorization.config.header + + if k.lower() == authorization_header.lower(): + raw_request += f'{k}: {"*" * len(v)}\n' + continue + + raw_request += f"{k}: {v}\n" + + raw_request += "\n" + + # if files, use multipart/form-data with boundary + if self.files: + boundary = self.boundary + raw_request += f"--{boundary}" + for k, v in self.files.items(): + raw_request += f'\nContent-Disposition: form-data; name="{k}"\n\n' + raw_request += f"{v[1]}\n" + raw_request += f"--{boundary}" + raw_request += "--" + else: + raw_request += self.body or "" + + return raw_request + + def _format_template( + self, template: str, variable_pool: Optional[VariablePool], escape_quotes: bool = False + ) -> tuple[str, list[VariableSelector]]: + """ + format template + """ + variable_template_parser = VariableTemplateParser(template=template) + variable_selectors = variable_template_parser.extract_variable_selectors() + + if variable_pool: + variable_value_mapping = {} + for variable_selector in variable_selectors: + variable = variable_pool.get_any(variable_selector.value_selector) + if variable is None: + raise ValueError(f"Variable {variable_selector.variable} not found") + if escape_quotes and isinstance(variable, str): + value = variable.replace('"', '\\"').replace("\n", "\\n") + else: + value = variable + variable_value_mapping[variable_selector.variable] = value + + return variable_template_parser.format(variable_value_mapping), variable_selectors + else: + return template, variable_selectors diff --git a/api/core/workflow/nodes/http_request/http_request_node.py b/api/core/workflow/nodes/http_request/http_request_node.py new file mode 100644 index 0000000000..cd40819126 --- /dev/null +++ b/api/core/workflow/nodes/http_request/http_request_node.py @@ -0,0 +1,165 @@ +import logging +from collections.abc import Mapping, Sequence +from mimetypes import guess_extension +from os import path +from typing import Any, cast + +from configs import dify_config +from core.app.segments import parser +from core.file.file_obj import FileTransferMethod, FileType, FileVar +from core.tools.tool_file_manager import ToolFileManager +from core.workflow.entities.node_entities import NodeRunResult, NodeType +from core.workflow.nodes.base_node import BaseNode +from core.workflow.nodes.http_request.entities import ( + HttpRequestNodeData, + HttpRequestNodeTimeout, +) +from core.workflow.nodes.http_request.http_executor import HttpExecutor, HttpExecutorResponse +from models.workflow import WorkflowNodeExecutionStatus + +HTTP_REQUEST_DEFAULT_TIMEOUT = HttpRequestNodeTimeout( + connect=dify_config.HTTP_REQUEST_MAX_CONNECT_TIMEOUT, + read=dify_config.HTTP_REQUEST_MAX_READ_TIMEOUT, + write=dify_config.HTTP_REQUEST_MAX_WRITE_TIMEOUT, +) + + +class HttpRequestNode(BaseNode): + _node_data_cls = HttpRequestNodeData + _node_type = NodeType.HTTP_REQUEST + + @classmethod + def get_default_config(cls, filters: dict | None = None) -> dict: + return { + "type": "http-request", + "config": { + "method": "get", + "authorization": { + "type": "no-auth", + }, + "body": {"type": "none"}, + "timeout": { + **HTTP_REQUEST_DEFAULT_TIMEOUT.model_dump(), + "max_connect_timeout": dify_config.HTTP_REQUEST_MAX_CONNECT_TIMEOUT, + "max_read_timeout": dify_config.HTTP_REQUEST_MAX_READ_TIMEOUT, + "max_write_timeout": dify_config.HTTP_REQUEST_MAX_WRITE_TIMEOUT, + }, + }, + } + + def _run(self) -> NodeRunResult: + node_data: HttpRequestNodeData = cast(HttpRequestNodeData, self.node_data) + # TODO: Switch to use segment directly + if node_data.authorization.config and node_data.authorization.config.api_key: + node_data.authorization.config.api_key = parser.convert_template( + template=node_data.authorization.config.api_key, variable_pool=self.graph_runtime_state.variable_pool + ).text + + # init http executor + http_executor = None + try: + http_executor = HttpExecutor( + node_data=node_data, + timeout=self._get_request_timeout(node_data), + variable_pool=self.graph_runtime_state.variable_pool, + ) + + # invoke http executor + response = http_executor.invoke() + except Exception as e: + process_data = {} + if http_executor: + process_data = { + "request": http_executor.to_raw_request(), + } + return NodeRunResult( + status=WorkflowNodeExecutionStatus.FAILED, + error=str(e), + process_data=process_data, + ) + + files = self.extract_files(http_executor.server_url, response) + + return NodeRunResult( + status=WorkflowNodeExecutionStatus.SUCCEEDED, + outputs={ + "status_code": response.status_code, + "body": response.content if not files else "", + "headers": response.headers, + "files": files, + }, + process_data={ + "request": http_executor.to_raw_request(), + }, + ) + + @staticmethod + def _get_request_timeout(node_data: HttpRequestNodeData) -> HttpRequestNodeTimeout: + timeout = node_data.timeout + if timeout is None: + return HTTP_REQUEST_DEFAULT_TIMEOUT + + timeout.connect = timeout.connect or HTTP_REQUEST_DEFAULT_TIMEOUT.connect + timeout.read = timeout.read or HTTP_REQUEST_DEFAULT_TIMEOUT.read + timeout.write = timeout.write or HTTP_REQUEST_DEFAULT_TIMEOUT.write + return timeout + + @classmethod + def _extract_variable_selector_to_variable_mapping( + cls, graph_config: Mapping[str, Any], node_id: str, node_data: HttpRequestNodeData + ) -> Mapping[str, Sequence[str]]: + """ + Extract variable selector to variable mapping + :param graph_config: graph config + :param node_id: node id + :param node_data: node data + :return: + """ + try: + http_executor = HttpExecutor(node_data=node_data, timeout=HTTP_REQUEST_DEFAULT_TIMEOUT) + + variable_selectors = http_executor.variable_selectors + + variable_mapping = {} + for variable_selector in variable_selectors: + variable_mapping[node_id + "." + variable_selector.variable] = variable_selector.value_selector + + return variable_mapping + except Exception as e: + logging.exception(f"Failed to extract variable selector to variable mapping: {e}") + return {} + + def extract_files(self, url: str, response: HttpExecutorResponse) -> list[FileVar]: + """ + Extract files from response + """ + files = [] + mimetype, file_binary = response.extract_file() + + if mimetype: + # extract filename from url + filename = path.basename(url) + # extract extension if possible + extension = guess_extension(mimetype) or ".bin" + + tool_file = ToolFileManager.create_file_by_raw( + user_id=self.user_id, + tenant_id=self.tenant_id, + conversation_id=None, + file_binary=file_binary, + mimetype=mimetype, + ) + + files.append( + FileVar( + tenant_id=self.tenant_id, + type=FileType.IMAGE, + transfer_method=FileTransferMethod.TOOL_FILE, + related_id=tool_file.id, + filename=filename, + extension=extension, + mime_type=mimetype, + ) + ) + + return files diff --git a/api/core/workflow/nodes/llm/llm_node.py b/api/core/workflow/nodes/llm/llm_node.py new file mode 100644 index 0000000000..3d336b0b0b --- /dev/null +++ b/api/core/workflow/nodes/llm/llm_node.py @@ -0,0 +1,774 @@ +import json +from collections.abc import Generator, Mapping, Sequence +from copy import deepcopy +from typing import TYPE_CHECKING, Any, Optional, cast + +from pydantic import BaseModel + +from core.app.entities.app_invoke_entities import ModelConfigWithCredentialsEntity +from core.entities.model_entities import ModelStatus +from core.entities.provider_entities import QuotaUnit +from core.errors.error import ModelCurrentlyNotSupportError, ProviderTokenNotInitError, QuotaExceededError +from core.memory.token_buffer_memory import TokenBufferMemory +from core.model_manager import ModelInstance, ModelManager +from core.model_runtime.entities.llm_entities import LLMResult, LLMUsage +from core.model_runtime.entities.message_entities import ( + ImagePromptMessageContent, + PromptMessage, + PromptMessageContentType, +) +from core.model_runtime.entities.model_entities import ModelType +from core.model_runtime.model_providers.__base.large_language_model import LargeLanguageModel +from core.model_runtime.utils.encoders import jsonable_encoder +from core.prompt.advanced_prompt_transform import AdvancedPromptTransform +from core.prompt.entities.advanced_prompt_entities import CompletionModelPromptTemplate, MemoryConfig +from core.prompt.utils.prompt_message_util import PromptMessageUtil +from core.workflow.entities.node_entities import NodeRunMetadataKey, NodeRunResult, NodeType +from core.workflow.entities.variable_pool import VariablePool +from core.workflow.enums import SystemVariableKey +from core.workflow.graph_engine.entities.event import InNodeEvent +from core.workflow.nodes.base_node import BaseNode +from core.workflow.nodes.event import RunCompletedEvent, RunEvent, RunRetrieverResourceEvent, RunStreamChunkEvent +from core.workflow.nodes.llm.entities import ( + LLMNodeChatModelMessage, + LLMNodeCompletionModelPromptTemplate, + LLMNodeData, + ModelConfig, +) +from core.workflow.utils.variable_template_parser import VariableTemplateParser +from extensions.ext_database import db +from models.model import Conversation +from models.provider import Provider, ProviderType +from models.workflow import WorkflowNodeExecutionStatus + +if TYPE_CHECKING: + from core.file.file_obj import FileVar + + +class ModelInvokeCompleted(BaseModel): + """ + Model invoke completed + """ + + text: str + usage: LLMUsage + finish_reason: Optional[str] = None + + +class LLMNode(BaseNode): + _node_data_cls = LLMNodeData + _node_type = NodeType.LLM + + def _run(self) -> Generator[RunEvent | InNodeEvent, None, None]: + """ + Run node + :return: + """ + node_data = cast(LLMNodeData, deepcopy(self.node_data)) + variable_pool = self.graph_runtime_state.variable_pool + + node_inputs = None + process_data = None + + try: + # init messages template + node_data.prompt_template = self._transform_chat_messages(node_data.prompt_template) + + # fetch variables and fetch values from variable pool + inputs = self._fetch_inputs(node_data, variable_pool) + + # fetch jinja2 inputs + jinja_inputs = self._fetch_jinja_inputs(node_data, variable_pool) + + # merge inputs + inputs.update(jinja_inputs) + + node_inputs = {} + + # fetch files + files = self._fetch_files(node_data, variable_pool) + + if files: + node_inputs["#files#"] = [file.to_dict() for file in files] + + # fetch context value + generator = self._fetch_context(node_data, variable_pool) + context = None + for event in generator: + if isinstance(event, RunRetrieverResourceEvent): + context = event.context + yield event + + if context: + node_inputs["#context#"] = context # type: ignore + + # fetch model config + model_instance, model_config = self._fetch_model_config(node_data.model) + + # fetch memory + memory = self._fetch_memory(node_data.memory, variable_pool, model_instance) + + # fetch prompt messages + prompt_messages, stop = self._fetch_prompt_messages( + node_data=node_data, + query=variable_pool.get_any(["sys", SystemVariableKey.QUERY.value]) if node_data.memory else None, + query_prompt_template=node_data.memory.query_prompt_template if node_data.memory else None, + inputs=inputs, + files=files, + context=context, + memory=memory, + model_config=model_config, + ) + + process_data = { + "model_mode": model_config.mode, + "prompts": PromptMessageUtil.prompt_messages_to_prompt_for_saving( + model_mode=model_config.mode, prompt_messages=prompt_messages + ), + "model_provider": model_config.provider, + "model_name": model_config.model, + } + + # handle invoke result + generator = self._invoke_llm( + node_data_model=node_data.model, + model_instance=model_instance, + prompt_messages=prompt_messages, + stop=stop, + ) + + result_text = "" + usage = LLMUsage.empty_usage() + finish_reason = None + for event in generator: + if isinstance(event, RunStreamChunkEvent): + yield event + elif isinstance(event, ModelInvokeCompleted): + result_text = event.text + usage = event.usage + finish_reason = event.finish_reason + break + except Exception as e: + yield RunCompletedEvent( + run_result=NodeRunResult( + status=WorkflowNodeExecutionStatus.FAILED, + error=str(e), + inputs=node_inputs, + process_data=process_data, + ) + ) + return + + outputs = {"text": result_text, "usage": jsonable_encoder(usage), "finish_reason": finish_reason} + + yield RunCompletedEvent( + run_result=NodeRunResult( + status=WorkflowNodeExecutionStatus.SUCCEEDED, + inputs=node_inputs, + process_data=process_data, + outputs=outputs, + metadata={ + NodeRunMetadataKey.TOTAL_TOKENS: usage.total_tokens, + NodeRunMetadataKey.TOTAL_PRICE: usage.total_price, + NodeRunMetadataKey.CURRENCY: usage.currency, + }, + llm_usage=usage, + ) + ) + + def _invoke_llm( + self, + node_data_model: ModelConfig, + model_instance: ModelInstance, + prompt_messages: list[PromptMessage], + stop: Optional[list[str]] = None, + ) -> Generator[RunEvent | ModelInvokeCompleted, None, None]: + """ + Invoke large language model + :param node_data_model: node data model + :param model_instance: model instance + :param prompt_messages: prompt messages + :param stop: stop + :return: + """ + db.session.close() + + invoke_result = model_instance.invoke_llm( + prompt_messages=prompt_messages, + model_parameters=node_data_model.completion_params, + stop=stop, + stream=True, + user=self.user_id, + ) + + # handle invoke result + generator = self._handle_invoke_result(invoke_result=invoke_result) + + usage = LLMUsage.empty_usage() + for event in generator: + yield event + if isinstance(event, ModelInvokeCompleted): + usage = event.usage + + # deduct quota + self.deduct_llm_quota(tenant_id=self.tenant_id, model_instance=model_instance, usage=usage) + + def _handle_invoke_result( + self, invoke_result: LLMResult | Generator + ) -> Generator[RunEvent | ModelInvokeCompleted, None, None]: + """ + Handle invoke result + :param invoke_result: invoke result + :return: + """ + if isinstance(invoke_result, LLMResult): + return + + model = None + prompt_messages: list[PromptMessage] = [] + full_text = "" + usage = None + finish_reason = None + for result in invoke_result: + text = result.delta.message.content + full_text += text + + yield RunStreamChunkEvent(chunk_content=text, from_variable_selector=[self.node_id, "text"]) + + if not model: + model = result.model + + if not prompt_messages: + prompt_messages = result.prompt_messages + + if not usage and result.delta.usage: + usage = result.delta.usage + + if not finish_reason and result.delta.finish_reason: + finish_reason = result.delta.finish_reason + + if not usage: + usage = LLMUsage.empty_usage() + + yield ModelInvokeCompleted(text=full_text, usage=usage, finish_reason=finish_reason) + + def _transform_chat_messages( + self, messages: list[LLMNodeChatModelMessage] | LLMNodeCompletionModelPromptTemplate + ) -> list[LLMNodeChatModelMessage] | LLMNodeCompletionModelPromptTemplate: + """ + Transform chat messages + + :param messages: chat messages + :return: + """ + + if isinstance(messages, LLMNodeCompletionModelPromptTemplate): + if messages.edition_type == "jinja2" and messages.jinja2_text: + messages.text = messages.jinja2_text + + return messages + + for message in messages: + if message.edition_type == "jinja2" and message.jinja2_text: + message.text = message.jinja2_text + + return messages + + def _fetch_jinja_inputs(self, node_data: LLMNodeData, variable_pool: VariablePool) -> dict[str, str]: + """ + Fetch jinja inputs + :param node_data: node data + :param variable_pool: variable pool + :return: + """ + variables = {} + + if not node_data.prompt_config: + return variables + + for variable_selector in node_data.prompt_config.jinja2_variables or []: + variable = variable_selector.variable + value = variable_pool.get_any(variable_selector.value_selector) + + def parse_dict(d: dict) -> str: + """ + Parse dict into string + """ + # check if it's a context structure + if "metadata" in d and "_source" in d["metadata"] and "content" in d: + return d["content"] + + # else, parse the dict + try: + return json.dumps(d, ensure_ascii=False) + except Exception: + return str(d) + + if isinstance(value, str): + value = value + elif isinstance(value, list): + result = "" + for item in value: + if isinstance(item, dict): + result += parse_dict(item) + elif isinstance(item, str): + result += item + elif isinstance(item, int | float): + result += str(item) + else: + result += str(item) + result += "\n" + value = result.strip() + elif isinstance(value, dict): + value = parse_dict(value) + elif isinstance(value, int | float): + value = str(value) + else: + value = str(value) + + variables[variable] = value + + return variables + + def _fetch_inputs(self, node_data: LLMNodeData, variable_pool: VariablePool) -> dict[str, str]: + """ + Fetch inputs + :param node_data: node data + :param variable_pool: variable pool + :return: + """ + inputs = {} + prompt_template = node_data.prompt_template + + variable_selectors = [] + if isinstance(prompt_template, list): + for prompt in prompt_template: + variable_template_parser = VariableTemplateParser(template=prompt.text) + variable_selectors.extend(variable_template_parser.extract_variable_selectors()) + elif isinstance(prompt_template, CompletionModelPromptTemplate): + variable_template_parser = VariableTemplateParser(template=prompt_template.text) + variable_selectors = variable_template_parser.extract_variable_selectors() + + for variable_selector in variable_selectors: + variable_value = variable_pool.get_any(variable_selector.value_selector) + if variable_value is None: + raise ValueError(f"Variable {variable_selector.variable} not found") + + inputs[variable_selector.variable] = variable_value + + memory = node_data.memory + if memory and memory.query_prompt_template: + query_variable_selectors = VariableTemplateParser( + template=memory.query_prompt_template + ).extract_variable_selectors() + for variable_selector in query_variable_selectors: + variable_value = variable_pool.get_any(variable_selector.value_selector) + if variable_value is None: + raise ValueError(f"Variable {variable_selector.variable} not found") + + inputs[variable_selector.variable] = variable_value + + return inputs + + def _fetch_files(self, node_data: LLMNodeData, variable_pool: VariablePool) -> list["FileVar"]: + """ + Fetch files + :param node_data: node data + :param variable_pool: variable pool + :return: + """ + if not node_data.vision.enabled: + return [] + + files = variable_pool.get_any(["sys", SystemVariableKey.FILES.value]) + if not files: + return [] + + return files + + def _fetch_context(self, node_data: LLMNodeData, variable_pool: VariablePool) -> Generator[RunEvent, None, None]: + """ + Fetch context + :param node_data: node data + :param variable_pool: variable pool + :return: + """ + if not node_data.context.enabled: + return + + if not node_data.context.variable_selector: + return + + context_value = variable_pool.get_any(node_data.context.variable_selector) + if context_value: + if isinstance(context_value, str): + yield RunRetrieverResourceEvent(retriever_resources=[], context=context_value) + elif isinstance(context_value, list): + context_str = "" + original_retriever_resource = [] + for item in context_value: + if isinstance(item, str): + context_str += item + "\n" + else: + if "content" not in item: + raise ValueError(f"Invalid context structure: {item}") + + context_str += item["content"] + "\n" + + retriever_resource = self._convert_to_original_retriever_resource(item) + if retriever_resource: + original_retriever_resource.append(retriever_resource) + + yield RunRetrieverResourceEvent( + retriever_resources=original_retriever_resource, context=context_str.strip() + ) + + def _convert_to_original_retriever_resource(self, context_dict: dict) -> Optional[dict]: + """ + Convert to original retriever resource, temp. + :param context_dict: context dict + :return: + """ + if ( + "metadata" in context_dict + and "_source" in context_dict["metadata"] + and context_dict["metadata"]["_source"] == "knowledge" + ): + metadata = context_dict.get("metadata", {}) + + source = { + "position": metadata.get("position"), + "dataset_id": metadata.get("dataset_id"), + "dataset_name": metadata.get("dataset_name"), + "document_id": metadata.get("document_id"), + "document_name": metadata.get("document_name"), + "data_source_type": metadata.get("document_data_source_type"), + "segment_id": metadata.get("segment_id"), + "retriever_from": metadata.get("retriever_from"), + "score": metadata.get("score"), + "hit_count": metadata.get("segment_hit_count"), + "word_count": metadata.get("segment_word_count"), + "segment_position": metadata.get("segment_position"), + "index_node_hash": metadata.get("segment_index_node_hash"), + "content": context_dict.get("content"), + } + + return source + + return None + + def _fetch_model_config( + self, node_data_model: ModelConfig + ) -> tuple[ModelInstance, ModelConfigWithCredentialsEntity]: + """ + Fetch model config + :param node_data_model: node data model + :return: + """ + model_name = node_data_model.name + provider_name = node_data_model.provider + + model_manager = ModelManager() + model_instance = model_manager.get_model_instance( + tenant_id=self.tenant_id, model_type=ModelType.LLM, provider=provider_name, model=model_name + ) + + provider_model_bundle = model_instance.provider_model_bundle + model_type_instance = model_instance.model_type_instance + model_type_instance = cast(LargeLanguageModel, model_type_instance) + + model_credentials = model_instance.credentials + + # check model + provider_model = provider_model_bundle.configuration.get_provider_model( + model=model_name, model_type=ModelType.LLM + ) + + if provider_model is None: + raise ValueError(f"Model {model_name} not exist.") + + if provider_model.status == ModelStatus.NO_CONFIGURE: + raise ProviderTokenNotInitError(f"Model {model_name} credentials is not initialized.") + elif provider_model.status == ModelStatus.NO_PERMISSION: + raise ModelCurrentlyNotSupportError(f"Dify Hosted OpenAI {model_name} currently not support.") + elif provider_model.status == ModelStatus.QUOTA_EXCEEDED: + raise QuotaExceededError(f"Model provider {provider_name} quota exceeded.") + + # model config + completion_params = node_data_model.completion_params + stop = [] + if "stop" in completion_params: + stop = completion_params["stop"] + del completion_params["stop"] + + # get model mode + model_mode = node_data_model.mode + if not model_mode: + raise ValueError("LLM mode is required.") + + model_schema = model_type_instance.get_model_schema(model_name, model_credentials) + + if not model_schema: + raise ValueError(f"Model {model_name} not exist.") + + return model_instance, ModelConfigWithCredentialsEntity( + provider=provider_name, + model=model_name, + model_schema=model_schema, + mode=model_mode, + provider_model_bundle=provider_model_bundle, + credentials=model_credentials, + parameters=completion_params, + stop=stop, + ) + + def _fetch_memory( + self, node_data_memory: Optional[MemoryConfig], variable_pool: VariablePool, model_instance: ModelInstance + ) -> Optional[TokenBufferMemory]: + """ + Fetch memory + :param node_data_memory: node data memory + :param variable_pool: variable pool + :return: + """ + if not node_data_memory: + return None + + # get conversation id + conversation_id = variable_pool.get_any(["sys", SystemVariableKey.CONVERSATION_ID.value]) + if conversation_id is None: + return None + + # get conversation + conversation = ( + db.session.query(Conversation) + .filter(Conversation.app_id == self.app_id, Conversation.id == conversation_id) + .first() + ) + + if not conversation: + return None + + memory = TokenBufferMemory(conversation=conversation, model_instance=model_instance) + + return memory + + def _fetch_prompt_messages( + self, + node_data: LLMNodeData, + query: Optional[str], + query_prompt_template: Optional[str], + inputs: dict[str, str], + files: list["FileVar"], + context: Optional[str], + memory: Optional[TokenBufferMemory], + model_config: ModelConfigWithCredentialsEntity, + ) -> tuple[list[PromptMessage], Optional[list[str]]]: + """ + Fetch prompt messages + :param node_data: node data + :param query: query + :param query_prompt_template: query prompt template + :param inputs: inputs + :param files: files + :param context: context + :param memory: memory + :param model_config: model config + :return: + """ + prompt_transform = AdvancedPromptTransform(with_variable_tmpl=True) + prompt_messages = prompt_transform.get_prompt( + prompt_template=node_data.prompt_template, + inputs=inputs, + query=query or "", + files=files, + context=context, + memory_config=node_data.memory, + memory=memory, + model_config=model_config, + query_prompt_template=query_prompt_template, + ) + stop = model_config.stop + + vision_enabled = node_data.vision.enabled + vision_detail = node_data.vision.configs.detail if node_data.vision.configs else None + filtered_prompt_messages = [] + for prompt_message in prompt_messages: + if prompt_message.is_empty(): + continue + + if not isinstance(prompt_message.content, str): + prompt_message_content = [] + for content_item in prompt_message.content: + if ( + vision_enabled + and content_item.type == PromptMessageContentType.IMAGE + and isinstance(content_item, ImagePromptMessageContent) + ): + # Override vision config if LLM node has vision config + if vision_detail: + content_item.detail = ImagePromptMessageContent.DETAIL(vision_detail) + prompt_message_content.append(content_item) + elif content_item.type == PromptMessageContentType.TEXT: + prompt_message_content.append(content_item) + + if len(prompt_message_content) > 1: + prompt_message.content = prompt_message_content + elif ( + len(prompt_message_content) == 1 and prompt_message_content[0].type == PromptMessageContentType.TEXT + ): + prompt_message.content = prompt_message_content[0].data + + filtered_prompt_messages.append(prompt_message) + + if not filtered_prompt_messages: + raise ValueError( + "No prompt found in the LLM configuration. " + "Please ensure a prompt is properly configured before proceeding." + ) + + return filtered_prompt_messages, stop + + @classmethod + def deduct_llm_quota(cls, tenant_id: str, model_instance: ModelInstance, usage: LLMUsage) -> None: + """ + Deduct LLM quota + :param tenant_id: tenant id + :param model_instance: model instance + :param usage: usage + :return: + """ + provider_model_bundle = model_instance.provider_model_bundle + provider_configuration = provider_model_bundle.configuration + + if provider_configuration.using_provider_type != ProviderType.SYSTEM: + return + + system_configuration = provider_configuration.system_configuration + + quota_unit = None + for quota_configuration in system_configuration.quota_configurations: + if quota_configuration.quota_type == system_configuration.current_quota_type: + quota_unit = quota_configuration.quota_unit + + if quota_configuration.quota_limit == -1: + return + + break + + used_quota = None + if quota_unit: + if quota_unit == QuotaUnit.TOKENS: + used_quota = usage.total_tokens + elif quota_unit == QuotaUnit.CREDITS: + used_quota = 1 + + if "gpt-4" in model_instance.model: + used_quota = 20 + else: + used_quota = 1 + + if used_quota is not None: + db.session.query(Provider).filter( + Provider.tenant_id == tenant_id, + Provider.provider_name == model_instance.provider, + Provider.provider_type == ProviderType.SYSTEM.value, + Provider.quota_type == system_configuration.current_quota_type.value, + Provider.quota_limit > Provider.quota_used, + ).update({"quota_used": Provider.quota_used + used_quota}) + db.session.commit() + + @classmethod + def _extract_variable_selector_to_variable_mapping( + cls, graph_config: Mapping[str, Any], node_id: str, node_data: LLMNodeData + ) -> Mapping[str, Sequence[str]]: + """ + Extract variable selector to variable mapping + :param graph_config: graph config + :param node_id: node id + :param node_data: node data + :return: + """ + prompt_template = node_data.prompt_template + + variable_selectors = [] + if isinstance(prompt_template, list): + for prompt in prompt_template: + if prompt.edition_type != "jinja2": + variable_template_parser = VariableTemplateParser(template=prompt.text) + variable_selectors.extend(variable_template_parser.extract_variable_selectors()) + else: + if prompt_template.edition_type != "jinja2": + variable_template_parser = VariableTemplateParser(template=prompt_template.text) + variable_selectors = variable_template_parser.extract_variable_selectors() + + variable_mapping = {} + for variable_selector in variable_selectors: + variable_mapping[variable_selector.variable] = variable_selector.value_selector + + memory = node_data.memory + if memory and memory.query_prompt_template: + query_variable_selectors = VariableTemplateParser( + template=memory.query_prompt_template + ).extract_variable_selectors() + for variable_selector in query_variable_selectors: + variable_mapping[variable_selector.variable] = variable_selector.value_selector + + if node_data.context.enabled: + variable_mapping["#context#"] = node_data.context.variable_selector + + if node_data.vision.enabled: + variable_mapping["#files#"] = ["sys", SystemVariableKey.FILES.value] + + if node_data.memory: + variable_mapping["#sys.query#"] = ["sys", SystemVariableKey.QUERY.value] + + if node_data.prompt_config: + enable_jinja = False + + if isinstance(prompt_template, list): + for prompt in prompt_template: + if prompt.edition_type == "jinja2": + enable_jinja = True + break + else: + if prompt_template.edition_type == "jinja2": + enable_jinja = True + + if enable_jinja: + for variable_selector in node_data.prompt_config.jinja2_variables or []: + variable_mapping[variable_selector.variable] = variable_selector.value_selector + + variable_mapping = {node_id + "." + key: value for key, value in variable_mapping.items()} + + return variable_mapping + + @classmethod + def get_default_config(cls, filters: Optional[dict] = None) -> dict: + """ + Get default config of node. + :param filters: filter by node config parameters. + :return: + """ + return { + "type": "llm", + "config": { + "prompt_templates": { + "chat_model": { + "prompts": [ + {"role": "system", "text": "You are a helpful AI assistant.", "edition_type": "basic"} + ] + }, + "completion_model": { + "conversation_histories_role": {"user_prefix": "Human", "assistant_prefix": "Assistant"}, + "prompt": { + "text": "Here is the chat histories between human and assistant, inside " + " XML tags.\n\n\n{{" + "#histories#}}\n\n\n\nHuman: {{#sys.query#}}\n\nAssistant:", + "edition_type": "basic", + }, + "stop": ["Human:"], + }, + } + }, + } diff --git a/api/tests/unit_tests/core/tools/test_tool_parameter_converter.py b/api/tests/unit_tests/core/tools/test_tool_parameter_converter.py new file mode 100644 index 0000000000..279a6cdbc3 --- /dev/null +++ b/api/tests/unit_tests/core/tools/test_tool_parameter_converter.py @@ -0,0 +1,56 @@ +import pytest + +from core.tools.entities.tool_entities import ToolParameter +from core.tools.utils.tool_parameter_converter import ToolParameterConverter + + +def test_get_parameter_type(): + assert ToolParameterConverter.get_parameter_type(ToolParameter.ToolParameterType.STRING) == "string" + assert ToolParameterConverter.get_parameter_type(ToolParameter.ToolParameterType.SELECT) == "string" + assert ToolParameterConverter.get_parameter_type(ToolParameter.ToolParameterType.BOOLEAN) == "boolean" + assert ToolParameterConverter.get_parameter_type(ToolParameter.ToolParameterType.NUMBER) == "number" + with pytest.raises(ValueError): + ToolParameterConverter.get_parameter_type("unsupported_type") + + +def test_cast_parameter_by_type(): + # string + assert ToolParameterConverter.cast_parameter_by_type("test", ToolParameter.ToolParameterType.STRING) == "test" + assert ToolParameterConverter.cast_parameter_by_type(1, ToolParameter.ToolParameterType.STRING) == "1" + assert ToolParameterConverter.cast_parameter_by_type(1.0, ToolParameter.ToolParameterType.STRING) == "1.0" + assert ToolParameterConverter.cast_parameter_by_type(None, ToolParameter.ToolParameterType.STRING) == "" + + # secret input + assert ToolParameterConverter.cast_parameter_by_type("test", ToolParameter.ToolParameterType.SECRET_INPUT) == "test" + assert ToolParameterConverter.cast_parameter_by_type(1, ToolParameter.ToolParameterType.SECRET_INPUT) == "1" + assert ToolParameterConverter.cast_parameter_by_type(1.0, ToolParameter.ToolParameterType.SECRET_INPUT) == "1.0" + assert ToolParameterConverter.cast_parameter_by_type(None, ToolParameter.ToolParameterType.SECRET_INPUT) == "" + + # select + assert ToolParameterConverter.cast_parameter_by_type("test", ToolParameter.ToolParameterType.SELECT) == "test" + assert ToolParameterConverter.cast_parameter_by_type(1, ToolParameter.ToolParameterType.SELECT) == "1" + assert ToolParameterConverter.cast_parameter_by_type(1.0, ToolParameter.ToolParameterType.SELECT) == "1.0" + assert ToolParameterConverter.cast_parameter_by_type(None, ToolParameter.ToolParameterType.SELECT) == "" + + # boolean + true_values = [True, "True", "true", "1", "YES", "Yes", "yes", "y", "something"] + for value in true_values: + assert ToolParameterConverter.cast_parameter_by_type(value, ToolParameter.ToolParameterType.BOOLEAN) is True + + false_values = [False, "False", "false", "0", "NO", "No", "no", "n", None, ""] + for value in false_values: + assert ToolParameterConverter.cast_parameter_by_type(value, ToolParameter.ToolParameterType.BOOLEAN) is False + + # number + assert ToolParameterConverter.cast_parameter_by_type("1", ToolParameter.ToolParameterType.NUMBER) == 1 + assert ToolParameterConverter.cast_parameter_by_type("1.0", ToolParameter.ToolParameterType.NUMBER) == 1.0 + assert ToolParameterConverter.cast_parameter_by_type("-1.0", ToolParameter.ToolParameterType.NUMBER) == -1.0 + assert ToolParameterConverter.cast_parameter_by_type(1, ToolParameter.ToolParameterType.NUMBER) == 1 + assert ToolParameterConverter.cast_parameter_by_type(1.0, ToolParameter.ToolParameterType.NUMBER) == 1.0 + assert ToolParameterConverter.cast_parameter_by_type(-1.0, ToolParameter.ToolParameterType.NUMBER) == -1.0 + assert ToolParameterConverter.cast_parameter_by_type(None, ToolParameter.ToolParameterType.NUMBER) is None + + # unknown + assert ToolParameterConverter.cast_parameter_by_type("1", "unknown_type") == "1" + assert ToolParameterConverter.cast_parameter_by_type(1, "unknown_type") == "1" + assert ToolParameterConverter.cast_parameter_by_type(None, ToolParameter.ToolParameterType.NUMBER) is None diff --git a/web/app/components/app/configuration/config-var/select-type-item/style.module.css b/web/app/components/app/configuration/config-var/select-type-item/style.module.css new file mode 100644 index 0000000000..8ff716d58b --- /dev/null +++ b/web/app/components/app/configuration/config-var/select-type-item/style.module.css @@ -0,0 +1,40 @@ +.item { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + height: 58px; + width: 98px; + border-radius: 8px; + border: 1px solid #EAECF0; + box-shadow: 0px 1px 2px rgba(16, 24, 40, 0.05); + background-color: #fff; + cursor: pointer; +} + +.item:not(.selected):hover { + border-color: #B2CCFF; + background-color: #F5F8FF; + box-shadow: 0px 4px 8px -2px rgba(16, 24, 40, 0.1), 0px 2px 4px -2px rgba(16, 24, 40, 0.06); +} + +.item.selected { + color: #155EEF; + border-color: #528BFF; + background-color: #F5F8FF; + box-shadow: 0px 1px 3px rgba(16, 24, 40, 0.1), 0px 1px 2px rgba(16, 24, 40, 0.06); +} + +.text { + font-size: 13px; + color: #667085; + font-weight: 500; +} + +.item.selected .text { + color: #155EEF; +} + +.item:not(.selected):hover { + color: #344054; +} \ No newline at end of file diff --git a/web/app/components/app/configuration/config-vision/radio-group/index.tsx b/web/app/components/app/configuration/config-vision/radio-group/index.tsx new file mode 100644 index 0000000000..a1cfb06e6a --- /dev/null +++ b/web/app/components/app/configuration/config-vision/radio-group/index.tsx @@ -0,0 +1,40 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import s from './style.module.css' +import cn from '@/utils/classnames' + +type OPTION = { + label: string + value: any +} + +type Props = { + className?: string + options: OPTION[] + value: any + onChange: (value: any) => void +} + +const RadioGroup: FC = ({ + className = '', + options, + value, + onChange, +}) => { + return ( +
+ {options.map(item => ( +
onChange(item.value)} + > +
+
{item.label}
+
+ ))} +
+ ) +} +export default React.memo(RadioGroup) diff --git a/web/app/components/app/configuration/config-vision/radio-group/style.module.css b/web/app/components/app/configuration/config-vision/radio-group/style.module.css new file mode 100644 index 0000000000..22c29c6a42 --- /dev/null +++ b/web/app/components/app/configuration/config-vision/radio-group/style.module.css @@ -0,0 +1,24 @@ +.item { + @apply grow flex items-center h-8 px-2.5 rounded-lg bg-gray-25 border border-gray-100 cursor-pointer space-x-2; +} + +.item:hover { + background-color: #ffffff; + border-color: #B2CCFF; + box-shadow: 0px 12px 16px -4px rgba(16, 24, 40, 0.08), 0px 4px 6px -2px rgba(16, 24, 40, 0.03); +} + +.item.checked { + background-color: #ffffff; + border-color: #528BFF; + box-shadow: 0px 1px 2px 0px rgba(16, 24, 40, 0.06), 0px 1px 3px 0px rgba(16, 24, 40, 0.10); +} + +.radio { + @apply w-4 h-4 border-[2px] border-gray-200 rounded-full; +} + +.item.checked .radio { + border-width: 5px; + border-color: #155eef; +} \ No newline at end of file diff --git a/web/app/components/app/configuration/config-voice/param-config-content.tsx b/web/app/components/app/configuration/config-voice/param-config-content.tsx new file mode 100644 index 0000000000..4e70bdda21 --- /dev/null +++ b/web/app/components/app/configuration/config-voice/param-config-content.tsx @@ -0,0 +1,220 @@ +'use client' +import useSWR from 'swr' +import type { FC } from 'react' +import { useContext } from 'use-context-selector' +import React, { Fragment } from 'react' +import { usePathname } from 'next/navigation' +import { useTranslation } from 'react-i18next' +import { Listbox, Transition } from '@headlessui/react' +import { CheckIcon, ChevronDownIcon } from '@heroicons/react/20/solid' +import classNames from '@/utils/classnames' +import RadioGroup from '@/app/components/app/configuration/config-vision/radio-group' +import type { Item } from '@/app/components/base/select' +import ConfigContext from '@/context/debug-configuration' +import { fetchAppVoices } from '@/service/apps' +import Tooltip from '@/app/components/base/tooltip' +import { languages } from '@/i18n/language' +import { TtsAutoPlay } from '@/types/app' +const VoiceParamConfig: FC = () => { + const { t } = useTranslation() + const pathname = usePathname() + const matched = pathname.match(/\/app\/([^/]+)/) + const appId = (matched?.length && matched[1]) ? matched[1] : '' + + const { + textToSpeechConfig, + setTextToSpeechConfig, + } = useContext(ConfigContext) + + let languageItem = languages.find(item => item.value === textToSpeechConfig.language) + const localLanguagePlaceholder = languageItem?.name || t('common.placeholder.select') + if (languages && !languageItem && languages.length > 0) + languageItem = languages[0] + const language = languageItem?.value + const voiceItems = useSWR({ appId, language }, fetchAppVoices).data + let voiceItem = voiceItems?.find(item => item.value === textToSpeechConfig.voice) + if (voiceItems && !voiceItem && voiceItems.length > 0) + voiceItem = voiceItems[0] + + const localVoicePlaceholder = voiceItem?.name || t('common.placeholder.select') + + return ( +
+
+
{t('appDebug.voice.voiceSettings.title')}
+
+
+
+
{t('appDebug.voice.voiceSettings.language')}
+ + {t('appDebug.voice.voiceSettings.resolutionTooltip').split('\n').map(item => ( +
{item}
+ ))} +
+ } + /> +
+ { + setTextToSpeechConfig({ + ...textToSpeechConfig, + language: String(value.value), + }) + }} + > +
+ + + {languageItem?.name ? t(`common.voice.language.${languageItem?.value.replace('-', '')}`) : localLanguagePlaceholder} + + + + + + + + {languages.map((item: Item) => ( + + `relative cursor-pointer select-none py-2 pl-3 pr-9 rounded-lg hover:bg-gray-100 text-gray-700 ${active ? 'bg-gray-100' : '' + }` + } + value={item} + disabled={false} + > + {({ /* active, */ selected }) => ( + <> + {t(`common.voice.language.${(item.value).toString().replace('-', '')}`)} + {(selected || item.value === textToSpeechConfig.language) && ( + + + )} + + )} + + ))} + + +
+
+
+
+
{t('appDebug.voice.voiceSettings.voice')}
+ { + if (!value.value) + return + setTextToSpeechConfig({ + ...textToSpeechConfig, + voice: String(value.value), + }) + }} + > +
+ + {voiceItem?.name ?? localVoicePlaceholder} + + + + + + + {voiceItems?.map((item: Item) => ( + + `relative cursor-pointer select-none py-2 pl-3 pr-9 rounded-lg hover:bg-gray-100 text-gray-700 ${active ? 'bg-gray-100' : '' + }` + } + value={item} + disabled={false} + > + {({ /* active, */ selected }) => ( + <> + {item.name} + {(selected || item.value === textToSpeechConfig.voice) && ( + + + )} + + )} + + ))} + + +
+
+
+
+
{t('appDebug.voice.voiceSettings.autoPlay')}
+ { + setTextToSpeechConfig({ + ...textToSpeechConfig, + autoPlay: value, + }) + }} + /> +
+
+
+
+ ) +} + +export default React.memo(VoiceParamConfig) diff --git a/web/app/components/app/configuration/config-voice/param-config.tsx b/web/app/components/app/configuration/config-voice/param-config.tsx new file mode 100644 index 0000000000..f1e2475495 --- /dev/null +++ b/web/app/components/app/configuration/config-voice/param-config.tsx @@ -0,0 +1,41 @@ +'use client' +import type { FC } from 'react' +import { memo, useState } from 'react' +import { useTranslation } from 'react-i18next' +import VoiceParamConfig from './param-config-content' +import cn from '@/utils/classnames' +import { Settings01 } from '@/app/components/base/icons/src/vender/line/general' +import { + PortalToFollowElem, + PortalToFollowElemContent, + PortalToFollowElemTrigger, +} from '@/app/components/base/portal-to-follow-elem' + +const ParamsConfig: FC = () => { + const { t } = useTranslation() + const [open, setOpen] = useState(false) + + return ( + + setOpen(v => !v)}> +
+ +
{t('appDebug.voice.settings')}
+
+
+ +
+ +
+
+
+ ) +} +export default memo(ParamsConfig) diff --git a/web/app/components/app/configuration/config/feature/add-feature-btn/index.tsx b/web/app/components/app/configuration/config/feature/add-feature-btn/index.tsx new file mode 100644 index 0000000000..eb3edc7593 --- /dev/null +++ b/web/app/components/app/configuration/config/feature/add-feature-btn/index.tsx @@ -0,0 +1,40 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import { useTranslation } from 'react-i18next' +import { PlusIcon } from '@heroicons/react/24/solid' + +export type IAddFeatureBtnProps = { + toBottomHeight: number + onClick: () => void +} + +const ITEM_HEIGHT = 48 + +const AddFeatureBtn: FC = ({ + toBottomHeight, + onClick, +}) => { + const { t } = useTranslation() + return ( +
+
+ +
{t('appDebug.operation.addFeature')}
+
+
+ ) +} +export default React.memo(AddFeatureBtn) diff --git a/web/app/components/app/configuration/config/feature/choose-feature/feature-item/index.tsx b/web/app/components/app/configuration/config/feature/choose-feature/feature-item/index.tsx new file mode 100644 index 0000000000..18623c11c3 --- /dev/null +++ b/web/app/components/app/configuration/config/feature/choose-feature/feature-item/index.tsx @@ -0,0 +1,52 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import s from './style.module.css' +import cn from '@/utils/classnames' +import Switch from '@/app/components/base/switch' + +export type IFeatureItemProps = { + icon: React.ReactNode + previewImgClassName?: string + title: string + description: string + value: boolean + onChange: (value: boolean) => void +} + +const FeatureItem: FC = ({ + icon, + previewImgClassName, + title, + description, + value, + onChange, +}) => { + return ( +
+
+ {/* icon */} +
+ {icon} +
+
+
{title}
+
{description}
+
+
+ + + { + previewImgClassName && ( +
+
) + } +
+ ) +} +export default React.memo(FeatureItem) diff --git a/web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/citation.png b/web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/citation.png new file mode 100644 index 0000000000000000000000000000000000000000..cc0847c942693ac2a2026395c3e6fc86c2dc0626 GIT binary patch literal 29852 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μW73O{l_UeVFQ1ZJfvH!n^l%*g(RX!_ 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 literal 0 HcmV?d00001 diff --git a/web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/citation.svg b/web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/citation.svg new file mode 100644 index 0000000000..82fb182a7a --- /dev/null +++ b/web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/citation.svg @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/citations-and-attributions-preview@2x.png b/web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/citations-and-attributions-preview@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..ef066204ca42478c976a0136385221a9464fb9b6 GIT binary patch literal 20827 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 S6Vpuq0000bQ7k~|VfI^{kel1jKD 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 VA{u6Wnt$HVkd;!BEE6{j{4XB~qQ?LL literal 0 HcmV?d00001 diff --git a/web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/more-like-this-preview@2x.png b/web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/more-like-this-preview@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..62671c5889edba480d8454d5e767db9482772b33 GIT binary patch literal 19839 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 KZ(uZR!~ProepMC# literal 0 HcmV?d00001 diff --git a/web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/more-like-this.svg b/web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/more-like-this.svg new file mode 100644 index 0000000000..6ccc84e70f --- /dev/null +++ b/web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/more-like-this.svg @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/next-question-suggestion-preview@2x.png b/web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/next-question-suggestion-preview@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..758708ff15d33549a0dbcb128debe2393cdb1e30 GIT binary patch literal 28325 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 HCj9>a)KP2< literal 0 HcmV?d00001 diff --git a/web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/speech-to-text-preview@2x.png b/web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/speech-to-text-preview@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..68df3983dc7df3a163fdec8041b7e9ebfc2c3b56 GIT binary patch literal 16929 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 z%0D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 literal 0 HcmV?d00001 diff --git a/web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/speech-to-text.png b/web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/speech-to-text.png new file mode 100644 index 0000000000000000000000000000000000000000..c951d0c418b04f345c269307a278c156ca1a5c70 GIT binary patch literal 24529 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 literal 0 HcmV?d00001 diff --git a/web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/speech-to-text.svg b/web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/speech-to-text.svg new file mode 100644 index 0000000000..029b92fee4 --- /dev/null +++ b/web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/speech-to-text.svg @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/suggested-questions-after-answer.png b/web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/suggested-questions-after-answer.png new file mode 100644 index 0000000000000000000000000000000000000000..bee4be0acf7a4f96252a39d845d0a8fc7e84ac03 GIT binary patch literal 42447 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%0DIHHARnZ~e<=P(Ej+YJgif};= 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%0DV?P)8sE z>BEjQXun|uokRcmO9Z4%NPE|-KW`^wo2oRgyQ+lWPa?ek!_GJF|M0)V_7_%W3E8&e z``_*}CHP$H<&OBg72djPeJ@75xXZ&|G%3FQ4wHcd@q(Z^U%~=^S_%3!r?f6`%=%i& zP(@!m$G zlP!I7kVPhV6mfmoAQ(yvOqkoqUe^4*5cO~4ziXTTuknIRM3l*|aKjX^t(HZ$s$%hN z>qxLVcLLT$9j()3c~IHI@{c;!pkoKskiT2mZ%}!qg|t-(?qI{}&fk$s$o4_s(jHfG@s&9!P1yaP2q{n0 zF_?XcY(3W^(e)dYSF_`cTGz_8)#~*Z^xMGuKYaUP-v4?ZJ_}3`4d={P;2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/text-to-audio-preview-assistant@2x.png b/web/app/components/app/configuration/config/feature/choose-feature/feature-item/preview-imgs/text-to-audio-preview-assistant@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..91396e72c75b34a9707de3d258d41f3d321f2508 GIT binary patch literal 23500 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

SDUaRr+>9aIL|AS=u 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 literal 0 HcmV?d00001 diff --git a/web/app/components/app/configuration/config/feature/choose-feature/feature-item/style.module.css b/web/app/components/app/configuration/config/feature/choose-feature/feature-item/style.module.css new file mode 100644 index 0000000000..32dc6be3ba --- /dev/null +++ b/web/app/components/app/configuration/config/feature/choose-feature/feature-item/style.module.css @@ -0,0 +1,41 @@ +.preview { + display: none; + position: absolute; + top: 0; + left: 100%; + transform: translate(32px, -54px); + width: 280px; + height: 360px; + background: center center no-repeat; + background-size: contain; + border-radius: 8px; +} + +.wrap:hover .preview { + display: block; +} + +.openingStatementPreview { + background-image: url(./preview-imgs/opening-statement.png); +} + +.suggestedQuestionsAfterAnswerPreview { + background-image: url(./preview-imgs/suggested-questions-after-answer.png); +} + +.moreLikeThisPreview { + background-image: url(./preview-imgs/more-like-this.png); +} + +.speechToTextPreview { + background-image: url(./preview-imgs/speech-to-text.png); +} + +.textToSpeechPreview { + @apply shadow-lg rounded-lg; + background-image: url(./preview-imgs/text-to-audio-preview-assistant@2x.png); +} + +.citationPreview { + background-image: url(./preview-imgs/citation.png); +} diff --git a/web/app/components/app/configuration/config/feature/choose-feature/index.tsx b/web/app/components/app/configuration/config/feature/choose-feature/index.tsx new file mode 100644 index 0000000000..8364f9529d --- /dev/null +++ b/web/app/components/app/configuration/config/feature/choose-feature/index.tsx @@ -0,0 +1,172 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import { useTranslation } from 'react-i18next' +import FeatureGroup from '../feature-group' +import MoreLikeThisIcon from '../../../base/icons/more-like-this-icon' +import FeatureItem from './feature-item' +import Modal from '@/app/components/base/modal' +import SuggestedQuestionsAfterAnswerIcon from '@/app/components/app/configuration/base/icons/suggested-questions-after-answer-icon' +import { Microphone01, Speaker } from '@/app/components/base/icons/src/vender/solid/mediaAndDevices' +import { Citations } from '@/app/components/base/icons/src/vender/solid/editor' +import { FileSearch02 } from '@/app/components/base/icons/src/vender/solid/files' +import { MessageFast } from '@/app/components/base/icons/src/vender/solid/communication' +type IConfig = { + openingStatement: boolean + moreLikeThis: boolean + suggestedQuestionsAfterAnswer: boolean + speechToText: boolean + textToSpeech: boolean + citation: boolean + moderation: boolean + annotation: boolean +} + +export type IChooseFeatureProps = { + isShow: boolean + onClose: () => void + config: IConfig + isChatApp: boolean + onChange: (key: string, value: boolean) => void + showTextToSpeechItem?: boolean + showSpeechToTextItem?: boolean +} + +const OpeningStatementIcon = ( + + + +) + +const ChooseFeature: FC = ({ + isShow, + onClose, + isChatApp, + config, + onChange, + showTextToSpeechItem, + showSpeechToTextItem, +}) => { + const { t } = useTranslation() + return ( + +

+ {/* Chat Feature */} + {isChatApp && ( + + <> + onChange('openingStatement', value)} + /> + } + previewImgClassName='suggestedQuestionsAfterAnswerPreview' + title={t('appDebug.feature.suggestedQuestionsAfterAnswer.title')} + description={t('appDebug.feature.suggestedQuestionsAfterAnswer.description')} + value={config.suggestedQuestionsAfterAnswer} + onChange={value => onChange('suggestedQuestionsAfterAnswer', value)} + /> + { + showTextToSpeechItem && ( + } + previewImgClassName='textToSpeechPreview' + title={t('appDebug.feature.textToSpeech.title')} + description={t('appDebug.feature.textToSpeech.description')} + value={config.textToSpeech} + onChange={value => onChange('textToSpeech', value)} + /> + ) + } + { + showSpeechToTextItem && ( + } + previewImgClassName='speechToTextPreview' + title={t('appDebug.feature.speechToText.title')} + description={t('appDebug.feature.speechToText.description')} + value={config.speechToText} + onChange={value => onChange('speechToText', value)} + /> + ) + } + } + previewImgClassName='citationPreview' + title={t('appDebug.feature.citation.title')} + description={t('appDebug.feature.citation.description')} + value={config.citation} + onChange={value => onChange('citation', value)} + /> + + + )} + + {/* Text Generation Feature */} + {!isChatApp && ( + + <> + } + previewImgClassName='moreLikeThisPreview' + title={t('appDebug.feature.moreLikeThis.title')} + description={t('appDebug.feature.moreLikeThis.description')} + value={config.moreLikeThis} + onChange={value => onChange('moreLikeThis', value)} + /> + { + showTextToSpeechItem && ( + } + previewImgClassName='textToSpeechPreview' + title={t('appDebug.feature.textToSpeech.title')} + description={t('appDebug.feature.textToSpeech.description')} + value={config.textToSpeech} + onChange={value => onChange('textToSpeech', value)} + /> + ) + } + + + )} + + <> + } + previewImgClassName='' + title={t('appDebug.feature.moderation.title')} + description={t('appDebug.feature.moderation.description')} + value={config.moderation} + onChange={value => onChange('moderation', value)} + /> + {isChatApp && ( + } + title={t('appDebug.feature.annotation.title')} + description={t('appDebug.feature.annotation.description')} + value={config.annotation} + onChange={value => onChange('annotation', value)} + /> + )} + + +
+ + ) +} +export default React.memo(ChooseFeature) diff --git a/web/app/components/app/configuration/config/feature/feature-group/index.tsx b/web/app/components/app/configuration/config/feature/feature-group/index.tsx new file mode 100644 index 0000000000..a4b27f18d4 --- /dev/null +++ b/web/app/components/app/configuration/config/feature/feature-group/index.tsx @@ -0,0 +1,31 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import GroupName from '@/app/components/app/configuration/base/group-name' + +export type IFeatureGroupProps = { + title: string + description?: string + children: React.ReactNode +} + +const FeatureGroup: FC = ({ + title, + description, + children, +}) => { + return ( +
+
+ + {description && ( +
{description}
+ )} +
+
+ {children} +
+
+ ) +} +export default React.memo(FeatureGroup) diff --git a/web/app/components/app/configuration/features/chat-group/citation/index.tsx b/web/app/components/app/configuration/features/chat-group/citation/index.tsx new file mode 100644 index 0000000000..4003b68cd3 --- /dev/null +++ b/web/app/components/app/configuration/features/chat-group/citation/index.tsx @@ -0,0 +1,25 @@ +'use client' +import React, { type FC } from 'react' +import { useTranslation } from 'react-i18next' +import Panel from '@/app/components/app/configuration/base/feature-panel' +import { Citations } from '@/app/components/base/icons/src/vender/solid/editor' + +const Citation: FC = () => { + const { t } = useTranslation() + + return ( + +
{t('appDebug.feature.citation.title')}
+
+ } + headerIcon={} + headerRight={ +
{t('appDebug.feature.citation.resDes')}
+ } + noBodySpacing + /> + ) +} +export default React.memo(Citation) diff --git a/web/app/components/app/configuration/features/chat-group/index.tsx b/web/app/components/app/configuration/features/chat-group/index.tsx new file mode 100644 index 0000000000..fd3cfa3a68 --- /dev/null +++ b/web/app/components/app/configuration/features/chat-group/index.tsx @@ -0,0 +1,65 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import { useTranslation } from 'react-i18next' +import GroupName from '../../base/group-name' +import type { IOpeningStatementProps } from './opening-statement' +import OpeningStatement from './opening-statement' +import SuggestedQuestionsAfterAnswer from './suggested-questions-after-answer' +import SpeechToText from './speech-to-text' +import TextToSpeech from './text-to-speech' +import Citation from './citation' +/* +* Include +* 1. Conversation Opener +* 2. Opening Suggestion +* 3. Next question suggestion +*/ +type ChatGroupProps = { + isShowOpeningStatement: boolean + openingStatementConfig: IOpeningStatementProps + isShowSuggestedQuestionsAfterAnswer: boolean + isShowSpeechText: boolean + isShowTextToSpeech: boolean + isShowCitation: boolean +} +const ChatGroup: FC = ({ + isShowOpeningStatement, + openingStatementConfig, + isShowSuggestedQuestionsAfterAnswer, + isShowSpeechText, + isShowTextToSpeech, + isShowCitation, +}) => { + const { t } = useTranslation() + + return ( +
+ +
+ {isShowOpeningStatement && ( + + )} + {isShowSuggestedQuestionsAfterAnswer && ( + + )} + { + isShowTextToSpeech && ( + + ) + } + { + isShowSpeechText && ( + + ) + } + { + isShowCitation && ( + + ) + } +
+
+ ) +} +export default React.memo(ChatGroup) diff --git a/web/app/components/app/configuration/features/chat-group/speech-to-text/index.tsx b/web/app/components/app/configuration/features/chat-group/speech-to-text/index.tsx new file mode 100644 index 0000000000..e452b38971 --- /dev/null +++ b/web/app/components/app/configuration/features/chat-group/speech-to-text/index.tsx @@ -0,0 +1,25 @@ +'use client' +import React, { type FC } from 'react' +import { useTranslation } from 'react-i18next' +import Panel from '@/app/components/app/configuration/base/feature-panel' +import { Microphone01 } from '@/app/components/base/icons/src/vender/solid/mediaAndDevices' + +const SpeechToTextConfig: FC = () => { + const { t } = useTranslation() + + return ( + +
{t('appDebug.feature.speechToText.title')}
+
+ } + headerIcon={} + headerRight={ +
{t('appDebug.feature.speechToText.resDes')}
+ } + noBodySpacing + /> + ) +} +export default React.memo(SpeechToTextConfig) diff --git a/web/app/components/app/configuration/features/chat-group/suggested-questions-after-answer/index.tsx b/web/app/components/app/configuration/features/chat-group/suggested-questions-after-answer/index.tsx new file mode 100644 index 0000000000..199558f4aa --- /dev/null +++ b/web/app/components/app/configuration/features/chat-group/suggested-questions-after-answer/index.tsx @@ -0,0 +1,34 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import { useTranslation } from 'react-i18next' +import Panel from '@/app/components/app/configuration/base/feature-panel' +import SuggestedQuestionsAfterAnswerIcon from '@/app/components/app/configuration/base/icons/suggested-questions-after-answer-icon' +import Tooltip from '@/app/components/base/tooltip' + +const SuggestedQuestionsAfterAnswer: FC = () => { + const { t } = useTranslation() + + return ( + +
{t('appDebug.feature.suggestedQuestionsAfterAnswer.title')}
+ + {t('appDebug.feature.suggestedQuestionsAfterAnswer.description')} +
+ } + /> +
+ } + headerIcon={} + headerRight={ +
{t('appDebug.feature.suggestedQuestionsAfterAnswer.resDes')}
+ } + noBodySpacing + /> + ) +} +export default React.memo(SuggestedQuestionsAfterAnswer) diff --git a/web/app/components/app/configuration/features/chat-group/text-to-speech/index.tsx b/web/app/components/app/configuration/features/chat-group/text-to-speech/index.tsx new file mode 100644 index 0000000000..72d617c3c3 --- /dev/null +++ b/web/app/components/app/configuration/features/chat-group/text-to-speech/index.tsx @@ -0,0 +1,55 @@ +'use client' +import useSWR from 'swr' +import React, { type FC } from 'react' +import { useTranslation } from 'react-i18next' +import { useContext } from 'use-context-selector' +import { usePathname } from 'next/navigation' +import Panel from '@/app/components/app/configuration/base/feature-panel' +import { Speaker } from '@/app/components/base/icons/src/vender/solid/mediaAndDevices' +import ConfigContext from '@/context/debug-configuration' +import { languages } from '@/i18n/language' +import { fetchAppVoices } from '@/service/apps' +import AudioBtn from '@/app/components/base/audio-btn' + +const TextToSpeech: FC = () => { + const { t } = useTranslation() + const { + textToSpeechConfig, + } = useContext(ConfigContext) + + const pathname = usePathname() + const matched = pathname.match(/\/app\/([^/]+)/) + const appId = (matched?.length && matched[1]) ? matched[1] : '' + const language = textToSpeechConfig.language + const languageInfo = languages.find(i => i.value === textToSpeechConfig.language) + + const voiceItems = useSWR({ appId, language }, fetchAppVoices).data + const voiceItem = voiceItems?.find(item => item.value === textToSpeechConfig.voice) + + return ( + +
{t('appDebug.feature.textToSpeech.title')}
+
+ } + headerIcon={} + headerRight={ +
+ {languageInfo && (`${languageInfo?.name} - `)}{voiceItem?.name ?? t('appDebug.voice.defaultDisplay')} + { languageInfo?.example && ( + + )} +
+ } + noBodySpacing + isShowTextToSpeech + /> + ) +} +export default React.memo(TextToSpeech) diff --git a/web/app/components/app/configuration/toolbox/annotation/annotation-ctrl-btn/index.tsx b/web/app/components/app/configuration/toolbox/annotation/annotation-ctrl-btn/index.tsx new file mode 100644 index 0000000000..809b907d62 --- /dev/null +++ b/web/app/components/app/configuration/toolbox/annotation/annotation-ctrl-btn/index.tsx @@ -0,0 +1,135 @@ +'use client' +import type { FC } from 'react' +import React, { useRef, useState } from 'react' +import { useHover } from 'ahooks' +import { useTranslation } from 'react-i18next' +import cn from '@/utils/classnames' +import { MessageCheckRemove, MessageFastPlus } from '@/app/components/base/icons/src/vender/line/communication' +import { MessageFast } from '@/app/components/base/icons/src/vender/solid/communication' +import { Edit04 } from '@/app/components/base/icons/src/vender/line/general' +import RemoveAnnotationConfirmModal from '@/app/components/app/annotation/remove-annotation-confirm-modal' +import Tooltip from '@/app/components/base/tooltip' +import { addAnnotation, delAnnotation } from '@/service/annotation' +import Toast from '@/app/components/base/toast' +import { useProviderContext } from '@/context/provider-context' +import { useModalContext } from '@/context/modal-context' + +type Props = { + appId: string + messageId?: string + annotationId?: string + className?: string + cached: boolean + query: string + answer: string + onAdded: (annotationId: string, authorName: string) => void + onEdit: () => void + onRemoved: () => void +} + +const CacheCtrlBtn: FC = ({ + className, + cached, + query, + answer, + appId, + messageId, + annotationId, + onAdded, + onEdit, + onRemoved, +}) => { + const { t } = useTranslation() + const { plan, enableBilling } = useProviderContext() + const isAnnotationFull = (enableBilling && plan.usage.annotatedResponse >= plan.total.annotatedResponse) + const { setShowAnnotationFullModal } = useModalContext() + const [showModal, setShowModal] = useState(false) + const cachedBtnRef = useRef(null) + const isCachedBtnHovering = useHover(cachedBtnRef) + const handleAdd = async () => { + if (isAnnotationFull) { + setShowAnnotationFullModal() + return + } + const res: any = await addAnnotation(appId, { + message_id: messageId, + question: query, + answer, + }) + Toast.notify({ + message: t('common.api.actionSuccess') as string, + type: 'success', + }) + onAdded(res.id, res.account?.name) + } + + const handleRemove = async () => { + await delAnnotation(appId, annotationId!) + Toast.notify({ + message: t('common.api.actionSuccess') as string, + type: 'success', + }) + onRemoved() + setShowModal(false) + } + return ( +
+
+ {cached + ? ( +
+
setShowModal(true)} + > + {!isCachedBtnHovering + ? ( + <> + +
{t('appDebug.feature.annotation.cached')}
+ + ) + : <> + +
{t('appDebug.feature.annotation.remove')}
+ } +
+
+ ) + : answer + ? ( + +
+ +
+
+ ) + : null + } + +
+ +
+
+ +
+ setShowModal(false)} + onRemove={handleRemove} + /> +
+ ) +} +export default React.memo(CacheCtrlBtn) diff --git a/web/app/components/app/configuration/toolbox/annotation/config-param-modal.tsx b/web/app/components/app/configuration/toolbox/annotation/config-param-modal.tsx new file mode 100644 index 0000000000..b660977d08 --- /dev/null +++ b/web/app/components/app/configuration/toolbox/annotation/config-param-modal.tsx @@ -0,0 +1,139 @@ +'use client' +import type { FC } from 'react' +import React, { useState } from 'react' +import { useTranslation } from 'react-i18next' +import ScoreSlider from '../score-slider' +import { Item } from './config-param' +import Modal from '@/app/components/base/modal' +import Button from '@/app/components/base/button' +import Toast from '@/app/components/base/toast' +import type { AnnotationReplyConfig } from '@/models/debug' +import { ANNOTATION_DEFAULT } from '@/config' +import ModelSelector from '@/app/components/header/account-setting/model-provider-page/model-selector' +import { useModelListAndDefaultModelAndCurrentProviderAndModel } from '@/app/components/header/account-setting/model-provider-page/hooks' +import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations' + +type Props = { + appId: string + isShow: boolean + onHide: () => void + onSave: (embeddingModel: { + embedding_provider_name: string + embedding_model_name: string + }, score: number) => void + isInit?: boolean + annotationConfig: AnnotationReplyConfig +} + +const ConfigParamModal: FC = ({ + isShow, + onHide: doHide, + onSave, + isInit, + annotationConfig: oldAnnotationConfig, +}) => { + const { t } = useTranslation() + const { + modelList: embeddingsModelList, + defaultModel: embeddingsDefaultModel, + currentModel: isEmbeddingsDefaultModelValid, + } = useModelListAndDefaultModelAndCurrentProviderAndModel(ModelTypeEnum.textEmbedding) + const [annotationConfig, setAnnotationConfig] = useState(oldAnnotationConfig) + + const [isLoading, setLoading] = useState(false) + const [embeddingModel, setEmbeddingModel] = useState(oldAnnotationConfig.embedding_model + ? { + providerName: oldAnnotationConfig.embedding_model.embedding_provider_name, + modelName: oldAnnotationConfig.embedding_model.embedding_model_name, + } + : (embeddingsDefaultModel + ? { + providerName: embeddingsDefaultModel.provider.provider, + modelName: embeddingsDefaultModel.model, + } + : undefined)) + const onHide = () => { + if (!isLoading) + doHide() + } + + const handleSave = async () => { + if (!embeddingModel || !embeddingModel.modelName || (embeddingModel.modelName === embeddingsDefaultModel?.model && !isEmbeddingsDefaultModelValid)) { + Toast.notify({ + message: t('common.modelProvider.embeddingModel.required'), + type: 'error', + }) + return + } + setLoading(true) + await onSave({ + embedding_provider_name: embeddingModel.providerName, + embedding_model_name: embeddingModel.modelName, + }, annotationConfig.score_threshold) + setLoading(false) + } + + return ( + +
+ {t(`appAnnotation.initSetup.${isInit ? 'title' : 'configTitle'}`)} +
+ +
+ + { + setAnnotationConfig({ + ...annotationConfig, + score_threshold: val / 100, + }) + }} + /> + + + +
+ { + setEmbeddingModel({ + providerName: val.provider, + modelName: val.model, + }) + }} + /> +
+
+
+ +
+ + +
+
+ ) +} +export default React.memo(ConfigParamModal) diff --git a/web/app/components/app/configuration/toolbox/annotation/type.ts b/web/app/components/app/configuration/toolbox/annotation/type.ts new file mode 100644 index 0000000000..910453478c --- /dev/null +++ b/web/app/components/app/configuration/toolbox/annotation/type.ts @@ -0,0 +1,4 @@ +export enum PageType { + log = 'log', + annotation = 'annotation', +} diff --git a/web/app/components/app/configuration/toolbox/annotation/use-annotation-config.ts b/web/app/components/app/configuration/toolbox/annotation/use-annotation-config.ts new file mode 100644 index 0000000000..540302cb27 --- /dev/null +++ b/web/app/components/app/configuration/toolbox/annotation/use-annotation-config.ts @@ -0,0 +1,89 @@ +import React, { useState } from 'react' +import produce from 'immer' +import type { AnnotationReplyConfig } from '@/models/debug' +import { queryAnnotationJobStatus, updateAnnotationStatus } from '@/service/annotation' +import type { EmbeddingModelConfig } from '@/app/components/app/annotation/type' +import { AnnotationEnableStatus, JobStatus } from '@/app/components/app/annotation/type' +import { sleep } from '@/utils' +import { ANNOTATION_DEFAULT } from '@/config' +import { useProviderContext } from '@/context/provider-context' + +type Params = { + appId: string + annotationConfig: AnnotationReplyConfig + setAnnotationConfig: (annotationConfig: AnnotationReplyConfig) => void +} +const useAnnotationConfig = ({ + appId, + annotationConfig, + setAnnotationConfig, +}: Params) => { + const { plan, enableBilling } = useProviderContext() + const isAnnotationFull = (enableBilling && plan.usage.annotatedResponse >= plan.total.annotatedResponse) + const [isShowAnnotationFullModal, setIsShowAnnotationFullModal] = useState(false) + const [isShowAnnotationConfigInit, doSetIsShowAnnotationConfigInit] = React.useState(false) + const setIsShowAnnotationConfigInit = (isShow: boolean) => { + if (isShow) { + if (isAnnotationFull) { + setIsShowAnnotationFullModal(true) + return + } + } + doSetIsShowAnnotationConfigInit(isShow) + } + const ensureJobCompleted = async (jobId: string, status: AnnotationEnableStatus) => { + let isCompleted = false + while (!isCompleted) { + const res: any = await queryAnnotationJobStatus(appId, status, jobId) + isCompleted = res.job_status === JobStatus.completed + if (isCompleted) + break + + await sleep(2000) + } + } + + const handleEnableAnnotation = async (embeddingModel: EmbeddingModelConfig, score?: number) => { + if (isAnnotationFull) + return + + const { job_id: jobId }: any = await updateAnnotationStatus(appId, AnnotationEnableStatus.enable, embeddingModel, score) + await ensureJobCompleted(jobId, AnnotationEnableStatus.enable) + setAnnotationConfig(produce(annotationConfig, (draft: AnnotationReplyConfig) => { + draft.enabled = true + draft.embedding_model = embeddingModel + if (!draft.score_threshold) + draft.score_threshold = ANNOTATION_DEFAULT.score_threshold + })) + } + + const setScore = (score: number, embeddingModel?: EmbeddingModelConfig) => { + setAnnotationConfig(produce(annotationConfig, (draft: AnnotationReplyConfig) => { + draft.score_threshold = score + if (embeddingModel) + draft.embedding_model = embeddingModel + })) + } + + const handleDisableAnnotation = async (embeddingModel: EmbeddingModelConfig) => { + if (!annotationConfig.enabled) + return + + await updateAnnotationStatus(appId, AnnotationEnableStatus.disable, embeddingModel) + setAnnotationConfig(produce(annotationConfig, (draft: AnnotationReplyConfig) => { + draft.enabled = false + })) + } + + return { + handleEnableAnnotation, + handleDisableAnnotation, + isShowAnnotationConfigInit, + setIsShowAnnotationConfigInit, + isShowAnnotationFullModal, + setIsShowAnnotationFullModal, + setScore, + } +} + +export default useAnnotationConfig diff --git a/web/app/components/app/configuration/toolbox/moderation/form-generation.tsx b/web/app/components/app/configuration/toolbox/moderation/form-generation.tsx new file mode 100644 index 0000000000..daf964447b --- /dev/null +++ b/web/app/components/app/configuration/toolbox/moderation/form-generation.tsx @@ -0,0 +1,79 @@ +import type { FC } from 'react' +import { useContext } from 'use-context-selector' +import type { CodeBasedExtensionForm } from '@/models/common' +import I18n from '@/context/i18n' +import { PortalSelect } from '@/app/components/base/select' +import type { ModerationConfig } from '@/models/debug' + +type FormGenerationProps = { + forms: CodeBasedExtensionForm[] + value: ModerationConfig['config'] + onChange: (v: Record) => void +} +const FormGeneration: FC = ({ + forms, + value, + onChange, +}) => { + const { locale } = useContext(I18n) + + const handleFormChange = (type: string, v: string) => { + onChange({ ...value, [type]: v }) + } + + return ( + <> + { + forms.map((form, index) => ( +
+
+ {locale === 'zh-Hans' ? form.label['zh-Hans'] : form.label['en-US']} +
+ { + form.type === 'text-input' && ( + handleFormChange(form.variable, e.target.value)} + /> + ) + } + { + form.type === 'paragraph' && ( +
+ +
+ ) + : ( +
+ )} + {renderQuestions()} + ) : ( +
{t('appDebug.openingStatement.noDataPlaceHolder')}
+ )} + + {isShowConfirmAddVar && ( + + )} + +
+ + ) +} +export default React.memo(OpeningStatement) diff --git a/web/app/components/base/features/feature-panel/score-slider/base-slider/index.tsx b/web/app/components/base/features/feature-panel/score-slider/base-slider/index.tsx new file mode 100644 index 0000000000..2e08a99122 --- /dev/null +++ b/web/app/components/base/features/feature-panel/score-slider/base-slider/index.tsx @@ -0,0 +1,38 @@ +import ReactSlider from 'react-slider' +import s from './style.module.css' +import cn from '@/utils/classnames' + +type ISliderProps = { + className?: string + value: number + max?: number + min?: number + step?: number + disabled?: boolean + onChange: (value: number) => void +} + +const Slider: React.FC = ({ className, max, min, step, value, disabled, onChange }) => { + return ( +
+
+
+ {(state.valueNow / 100).toFixed(2)} +
+
+
+ )} + /> +} + +export default Slider diff --git a/web/app/components/base/features/feature-panel/score-slider/base-slider/style.module.css b/web/app/components/base/features/feature-panel/score-slider/base-slider/style.module.css new file mode 100644 index 0000000000..4e93b39563 --- /dev/null +++ b/web/app/components/base/features/feature-panel/score-slider/base-slider/style.module.css @@ -0,0 +1,20 @@ +.slider { + position: relative; +} + +.slider.disabled { + opacity: 0.6; +} + +.slider-thumb:focus { + outline: none; +} + +.slider-track { + background-color: #528BFF; + height: 2px; +} + +.slider-track-1 { + background-color: #E5E7EB; +} \ No newline at end of file diff --git a/web/app/components/base/features/feature-panel/score-slider/index.tsx b/web/app/components/base/features/feature-panel/score-slider/index.tsx new file mode 100644 index 0000000000..9826cbadcf --- /dev/null +++ b/web/app/components/base/features/feature-panel/score-slider/index.tsx @@ -0,0 +1,46 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import { useTranslation } from 'react-i18next' +import Slider from '@/app/components/app/configuration/toolbox/score-slider/base-slider' + +type Props = { + className?: string + value: number + onChange: (value: number) => void +} + +const ScoreSlider: FC = ({ + className, + value, + onChange, +}) => { + const { t } = useTranslation() + + return ( +
+
+ +
+
+
+
0.8
+
·
+
{t('appDebug.feature.annotation.scoreThreshold.easyMatch')}
+
+
+
1.0
+
·
+
{t('appDebug.feature.annotation.scoreThreshold.accurateMatch')}
+
+
+
+ ) +} +export default React.memo(ScoreSlider) diff --git a/web/app/components/base/features/feature-panel/speech-to-text/index.tsx b/web/app/components/base/features/feature-panel/speech-to-text/index.tsx new file mode 100644 index 0000000000..2e5e3de439 --- /dev/null +++ b/web/app/components/base/features/feature-panel/speech-to-text/index.tsx @@ -0,0 +1,22 @@ +'use client' +import React, { type FC } from 'react' +import { useTranslation } from 'react-i18next' +import { Microphone01 } from '@/app/components/base/icons/src/vender/solid/mediaAndDevices' + +const SpeechToTextConfig: FC = () => { + const { t } = useTranslation() + + return ( +
+
+ +
+
+
{t('appDebug.feature.speechToText.title')}
+
+
+
{t('appDebug.feature.speechToText.resDes')}
+
+ ) +} +export default React.memo(SpeechToTextConfig) diff --git a/web/app/components/base/features/feature-panel/suggested-questions-after-answer/index.tsx b/web/app/components/base/features/feature-panel/suggested-questions-after-answer/index.tsx new file mode 100644 index 0000000000..e6d0b6e7e0 --- /dev/null +++ b/web/app/components/base/features/feature-panel/suggested-questions-after-answer/index.tsx @@ -0,0 +1,25 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import { useTranslation } from 'react-i18next' +import { MessageSmileSquare } from '@/app/components/base/icons/src/vender/solid/communication' +import Tooltip from '@/app/components/base/tooltip' + +const SuggestedQuestionsAfterAnswer: FC = () => { + const { t } = useTranslation() + + return ( +
+
+ +
+
+
{t('appDebug.feature.suggestedQuestionsAfterAnswer.title')}
+ +
+
+
{t('appDebug.feature.suggestedQuestionsAfterAnswer.resDes')}
+
+ ) +} +export default React.memo(SuggestedQuestionsAfterAnswer) diff --git a/web/app/components/base/features/feature-panel/text-to-speech/index.tsx b/web/app/components/base/features/feature-panel/text-to-speech/index.tsx new file mode 100644 index 0000000000..2480a19077 --- /dev/null +++ b/web/app/components/base/features/feature-panel/text-to-speech/index.tsx @@ -0,0 +1,62 @@ +'use client' +import useSWR from 'swr' +import React from 'react' +import { useTranslation } from 'react-i18next' +import { usePathname } from 'next/navigation' +import { useFeatures } from '../../hooks' +import type { OnFeaturesChange } from '../../types' +import ParamsConfig from './params-config' +import { Speaker } from '@/app/components/base/icons/src/vender/solid/mediaAndDevices' +import { languages } from '@/i18n/language' +import { fetchAppVoices } from '@/service/apps' +import AudioBtn from '@/app/components/base/audio-btn' + +type TextToSpeechProps = { + onChange?: OnFeaturesChange + disabled?: boolean +} +const TextToSpeech = ({ + onChange, + disabled, +}: TextToSpeechProps) => { + const { t } = useTranslation() + const textToSpeech = useFeatures(s => s.features.text2speech) + + const pathname = usePathname() + const matched = pathname.match(/\/app\/([^/]+)/) + const appId = (matched?.length && matched[1]) ? matched[1] : '' + const language = textToSpeech?.language + const languageInfo = languages.find(i => i.value === textToSpeech?.language) + + const voiceItems = useSWR({ appId, language }, fetchAppVoices).data + const voiceItem = voiceItems?.find(item => item.value === textToSpeech?.voice) + + return ( +
+
+ +
+
+ {t('appDebug.feature.textToSpeech.title')} +
+
+
+
+ {languageInfo && (`${languageInfo?.name} - `)}{voiceItem?.name ?? t('appDebug.voice.defaultDisplay')} + { languageInfo?.example && ( + + )} +
+
+ +
+
+ ) +} +export default React.memo(TextToSpeech) diff --git a/web/app/components/base/features/feature-panel/text-to-speech/param-config-content.tsx b/web/app/components/base/features/feature-panel/text-to-speech/param-config-content.tsx new file mode 100644 index 0000000000..e923d9a333 --- /dev/null +++ b/web/app/components/base/features/feature-panel/text-to-speech/param-config-content.tsx @@ -0,0 +1,241 @@ +'use client' +import useSWR from 'swr' +import produce from 'immer' +import React, { Fragment } from 'react' +import { usePathname } from 'next/navigation' +import { useTranslation } from 'react-i18next' +import { Listbox, Transition } from '@headlessui/react' +import { CheckIcon, ChevronDownIcon } from '@heroicons/react/20/solid' +import { + useFeatures, + useFeaturesStore, +} from '../../hooks' +import type { OnFeaturesChange } from '../../types' +import classNames from '@/utils/classnames' +import type { Item } from '@/app/components/base/select' +import { fetchAppVoices } from '@/service/apps' +import Tooltip from '@/app/components/base/tooltip' +import { languages } from '@/i18n/language' +import RadioGroup from '@/app/components/app/configuration/config-vision/radio-group' +import { TtsAutoPlay } from '@/types/app' + +type VoiceParamConfigProps = { + onChange?: OnFeaturesChange +} +const VoiceParamConfig = ({ + onChange, +}: VoiceParamConfigProps) => { + const { t } = useTranslation() + const pathname = usePathname() + const matched = pathname.match(/\/app\/([^/]+)/) + const appId = (matched?.length && matched[1]) ? matched[1] : '' + const text2speech = useFeatures(state => state.features.text2speech) + const featuresStore = useFeaturesStore() + + let languageItem = languages.find(item => item.value === text2speech?.language) + if (languages && !languageItem) + languageItem = languages[0] + const localLanguagePlaceholder = languageItem?.name || t('common.placeholder.select') + + const language = languageItem?.value + const voiceItems = useSWR({ appId, language }, fetchAppVoices).data + let voiceItem = voiceItems?.find(item => item.value === text2speech?.voice) + if (voiceItems && !voiceItem) + voiceItem = voiceItems[0] + const localVoicePlaceholder = voiceItem?.name || t('common.placeholder.select') + + const handleChange = (value: Record) => { + const { + features, + setFeatures, + } = featuresStore!.getState() + + const newFeatures = produce(features, (draft) => { + draft.text2speech = { + ...draft.text2speech, + ...value, + } + }) + + setFeatures(newFeatures) + if (onChange) + onChange(newFeatures) + } + + return ( +
+
+
{t('appDebug.voice.voiceSettings.title')}
+
+
+
+
{t('appDebug.voice.voiceSettings.language')}
+ + {t('appDebug.voice.voiceSettings.resolutionTooltip').split('\n').map(item => ( +
{item} +
+ ))} +
+ } + /> +
+ { + handleChange({ + language: String(value.value), + }) + }} + > +
+ + + {languageItem?.name ? t(`common.voice.language.${languageItem?.value.replace('-', '')}`) : localLanguagePlaceholder} + + + + + + + + {languages.map((item: Item) => ( + + `relative cursor-pointer select-none py-2 pl-3 pr-9 rounded-lg hover:bg-gray-100 text-gray-700 ${active ? 'bg-gray-100' : '' + }` + } + value={item} + disabled={false} + > + {({ /* active, */ selected }) => ( + <> + {t(`common.voice.language.${(item.value).toString().replace('-', '')}`)} + {(selected || item.value === text2speech?.language) && ( + + + )} + + )} + + ))} + + +
+
+
+ +
+
{t('appDebug.voice.voiceSettings.voice')}
+ { + handleChange({ + voice: String(value.value), + }) + }} + > +
+ + {voiceItem?.name ?? localVoicePlaceholder} + + + + + + + {voiceItems?.map((item: Item) => ( + + `relative cursor-pointer select-none py-2 pl-3 pr-9 rounded-lg hover:bg-gray-100 text-gray-700 ${active ? 'bg-gray-100' : '' + }` + } + value={item} + disabled={false} + > + {({ /* active, */ selected }) => ( + <> + {item.name} + {(selected || item.value === text2speech?.voice) && ( + + + )} + + )} + + ))} + + +
+
+
+
+
{t('appDebug.voice.voiceSettings.autoPlay')}
+ { + handleChange({ + autoPlay: value, + }) + }} + /> +
+
+
+
+ ) +} + +export default React.memo(VoiceParamConfig) diff --git a/web/app/components/base/features/feature-panel/text-to-speech/params-config.tsx b/web/app/components/base/features/feature-panel/text-to-speech/params-config.tsx new file mode 100644 index 0000000000..095fd6cce8 --- /dev/null +++ b/web/app/components/base/features/feature-panel/text-to-speech/params-config.tsx @@ -0,0 +1,48 @@ +'use client' +import { memo, useState } from 'react' +import { useTranslation } from 'react-i18next' +import type { OnFeaturesChange } from '../../types' +import ParamConfigContent from './param-config-content' +import cn from '@/utils/classnames' +import { Settings01 } from '@/app/components/base/icons/src/vender/line/general' +import { + PortalToFollowElem, + PortalToFollowElemContent, + PortalToFollowElemTrigger, +} from '@/app/components/base/portal-to-follow-elem' + +type ParamsConfigProps = { + onChange?: OnFeaturesChange + disabled?: boolean +} +const ParamsConfig = ({ + onChange, + disabled, +}: ParamsConfigProps) => { + const { t } = useTranslation() + const [open, setOpen] = useState(false) + + return ( + + !disabled && setOpen(v => !v)}> +
+ +
{t('appDebug.voice.settings')}
+
+
+ +
+ +
+
+
+ ) +} +export default memo(ParamsConfig) diff --git a/web/app/signin/forms.tsx b/web/app/signin/forms.tsx new file mode 100644 index 0000000000..70a34c26fa --- /dev/null +++ b/web/app/signin/forms.tsx @@ -0,0 +1,34 @@ +'use client' +import React from 'react' +import { useSearchParams } from 'next/navigation' + +import NormalForm from './normalForm' +import OneMoreStep from './oneMoreStep' +import cn from '@/utils/classnames' + +const Forms = () => { + const searchParams = useSearchParams() + const step = searchParams.get('step') + + const getForm = () => { + switch (step) { + case 'next': + return + default: + return + } + } + return
+
+ {getForm()} +
+
+} + +export default Forms diff --git a/web/app/signin/userSSOForm.tsx b/web/app/signin/userSSOForm.tsx new file mode 100644 index 0000000000..f01afa9eaf --- /dev/null +++ b/web/app/signin/userSSOForm.tsx @@ -0,0 +1,107 @@ +'use client' +import { useRouter, useSearchParams } from 'next/navigation' +import type { FC } from 'react' +import { useEffect, useState } from 'react' +import { useTranslation } from 'react-i18next' +import cn from '@/utils/classnames' +import Toast from '@/app/components/base/toast' +import { getUserOAuth2SSOUrl, getUserOIDCSSOUrl, getUserSAMLSSOUrl } from '@/service/sso' +import Button from '@/app/components/base/button' +import useRefreshToken from '@/hooks/use-refresh-token' + +type UserSSOFormProps = { + protocol: string +} + +const UserSSOForm: FC = ({ + protocol, +}) => { + const { getNewAccessToken } = useRefreshToken() + const searchParams = useSearchParams() + const consoleToken = searchParams.get('access_token') + const refreshToken = searchParams.get('refresh_token') + const message = searchParams.get('message') + + const router = useRouter() + const { t } = useTranslation() + + const [isLoading, setIsLoading] = useState(false) + + useEffect(() => { + if (refreshToken && consoleToken) { + localStorage.setItem('console_token', consoleToken) + localStorage.setItem('refresh_token', refreshToken) + getNewAccessToken() + router.replace('/apps') + } + + if (message) { + Toast.notify({ + type: 'error', + message, + }) + } + }, [consoleToken, refreshToken, message, router]) + + const handleSSOLogin = () => { + setIsLoading(true) + if (protocol === 'saml') { + getUserSAMLSSOUrl().then((res) => { + router.push(res.url) + }).finally(() => { + setIsLoading(false) + }) + } + else if (protocol === 'oidc') { + getUserOIDCSSOUrl().then((res) => { + document.cookie = `user-oidc-state=${res.state}` + router.push(res.url) + }).finally(() => { + setIsLoading(false) + }) + } + else if (protocol === 'oauth2') { + getUserOAuth2SSOUrl().then((res) => { + document.cookie = `user-oauth2-state=${res.state}` + router.push(res.url) + }).finally(() => { + setIsLoading(false) + }) + } + else { + Toast.notify({ + type: 'error', + message: 'invalid SSO protocol', + }) + setIsLoading(false) + } + } + + return ( +
+
+
+

{t('login.pageTitle')}

+
+
+ +
+
+
+ ) +} + +export default UserSSOForm From d9a0584052342f4ca53b060de8936ecfef9d12f3 Mon Sep 17 00:00:00 2001 From: AkaraChen Date: Fri, 25 Oct 2024 12:51:11 +0800 Subject: [PATCH 218/346] build: update eslint & fix some case --- web/eslint.config.mjs | 61 ++++-------------- web/package.json | 6 +- web/pnpm-lock.yaml | 143 +++--------------------------------------- 3 files changed, 25 insertions(+), 185 deletions(-) diff --git a/web/eslint.config.mjs b/web/eslint.config.mjs index 2ff4d704fd..6416e3e9a1 100644 --- a/web/eslint.config.mjs +++ b/web/eslint.config.mjs @@ -7,6 +7,8 @@ import { fileURLToPath } from 'node:url' import js from '@eslint/js' import { FlatCompat } from '@eslint/eslintrc' import globals from 'globals' +import storybook from 'eslint-plugin-storybook' +import { fixupConfigRules } from '@eslint/compat' const __filename = fileURLToPath(import.meta.url) const __dirname = path.dirname(__filename) @@ -16,34 +18,6 @@ const compat = new FlatCompat({ allConfig: js.configs.all, }) -// storybook plugin not support v9, so add its recommended rules here -const storybook = [ - { - plugins: ['storybook'], - files: ['*.stories.@(ts|tsx|js|jsx|mjs|cjs)', '*.story.@(ts|tsx|js|jsx|mjs|cjs)'], - rules: { - 'react-hooks/rules-of-hooks': 'off', - 'import/no-anonymous-default-export': 'off', - 'storybook/await-interactions': 'error', - 'storybook/context-in-play-function': 'error', - 'storybook/default-exports': 'error', - 'storybook/hierarchy-separator': 'warn', - 'storybook/no-redundant-story-name': 'warn', - 'storybook/prefer-pascal-case': 'warn', - 'storybook/story-exports': 'error', - 'storybook/use-storybook-expect': 'error', - 'storybook/use-storybook-testing-library': 'error', - }, - }, - { - plugins: ['storybook'], - files: ['*.stories.@(ts|tsx|js|jsx|mjs|cjs)', '*.story.@(ts|tsx|js|jsx|mjs|cjs)'], - rules: { - 'storybook/no-uninstalled-addons': 'error', - }, - }, -] - export default combine( stylistic({ lessOpinionated: true, @@ -55,7 +29,7 @@ export default combine( // original config 'style/indent': ['error', 2], 'style/quotes': ['error', 'single'], - 'curly': ['error', 'multi-line'], + 'curly': ['error', 'multi-or-nest', 'consistent'], 'style/comma-spacing': ['error', { before: false, after: true }], 'style/quote-props': ['warn', 'consistent-as-needed'], @@ -79,27 +53,26 @@ export default combine( 'style/member-delimiter-style': 'off', }, }), + javascript({ + overrides: { + // handled by unused-imports/no-unused-vars + 'no-unused-vars': 'off', + }, + }), typescript({ overrides: { // useful, but big change 'ts/no-empty-object-type': 'off', }, }), - javascript({ - overrides: { - // handled by unused-imports/no-unused-vars - 'no-unused-vars': 'off', - - // useless - 'no-use-before-define': 'warn', - }, - }), unicorn(), node(), + // use nextjs config will break @eslint/config-inspector + // use `ESLINT_CONFIG_INSPECTOR=true pnpx @eslint/config-inspector` to check the config ...process.env.ESLINT_CONFIG_INSPECTOR ? [] // TODO: remove this when upgrade to nextjs 15 - : [compat.extends('next')], + : fixupConfigRules(compat.extends('next')), { ignores: [ '**/node_modules/*', @@ -115,11 +88,6 @@ export default combine( { // orignal config rules: { - // from old version of antfu/eslint-config - // typescript will handle this, see https://typescript-eslint.io/troubleshooting/faqs/eslint/#i-get-errors-from-the-no-undef-rule-about-global-variables-not-being-defined-even-though-there-are-no-typescript-errors - 'no-undef': 'off', - - 'ts/consistent-type-definitions': ['error', 'type'], // orignal ts/no-var-requires 'ts/no-require-imports': 'off', 'no-console': 'off', @@ -132,10 +100,7 @@ export default combine( // copy from eslint-config-antfu 0.36.0 'camelcase': 'off', - 'curly': ['error', 'multi-or-nest', 'consistent'], 'default-case-last': 'error', - 'dot-notation': ['error', { allowKeywords: true }], - 'new-cap': ['error', { newIsCap: true, capIsNew: false, properties: true }], // antfu use eslint-plugin-perfectionist to replace this // will cause big change, so keep the original sort-imports @@ -165,7 +130,7 @@ export default combine( }, }, }, - storybook, + storybook.configs['flat/recommended'], // need futher research { rules: { diff --git a/web/package.json b/web/package.json index 970b3f12b1..acfe4f4af7 100644 --- a/web/package.json +++ b/web/package.json @@ -150,11 +150,11 @@ "code-inspector-plugin": "^0.13.0", "cross-env": "^7.0.3", "eslint": "^9.13.0", - "eslint-config-next": "^15.0.0-canary.202", + "eslint-config-next": "^15.0.0", "eslint-plugin-react-hooks": "^5.0.0", - "eslint-plugin-react-refresh": "^0.4.12", - "eslint-plugin-storybook": "^0.9.0", "husky": "^8.0.3", + "eslint-plugin-react-refresh": "^0.4.13", + "eslint-plugin-storybook": "^0.10.1", "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", "lint-staged": "^13.2.2", diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index cfc0b8887b..ee85a4179b 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -387,17 +387,17 @@ importers: specifier: ^9.13.0 version: 9.13.0(jiti@1.21.6) eslint-config-next: - specifier: ^15.0.0-canary.202 + specifier: ^15.0.0 version: 15.0.0(eslint-plugin-import-x@4.3.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) eslint-plugin-react-hooks: specifier: ^5.0.0 version: 5.0.0(eslint@9.13.0(jiti@1.21.6)) eslint-plugin-react-refresh: - specifier: ^0.4.12 + specifier: ^0.4.13 version: 0.4.13(eslint@9.13.0(jiti@1.21.6)) eslint-plugin-storybook: - specifier: ^0.9.0 - version: 0.9.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + specifier: ^0.10.1 + version: 0.10.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) husky: specifier: ^8.0.3 version: 8.0.3 @@ -2195,9 +2195,6 @@ packages: peerDependencies: storybook: ^8.3.6 - '@storybook/csf@0.0.1': - resolution: {integrity: sha512-USTLkZze5gkel8MYCujSRBVIrUQ3YPBrLOx7GNk/0wttvVtlzWXAq9eLbQ4p/NicGxP+3T7KPEMVV//g+yubpw==} - '@storybook/csf@0.1.11': resolution: {integrity: sha512-dHYFQH3mA+EtnCkHXzicbLgsvzYjcDJ1JWsogbItZogkPHgSJM/Wr71uMkcvw8v9mmCyP4NpXJuu6bPoVsOnzg==} @@ -2712,10 +2709,6 @@ packages: typescript: optional: true - '@typescript-eslint/scope-manager@5.62.0': - resolution: {integrity: sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - '@typescript-eslint/scope-manager@8.11.0': resolution: {integrity: sha512-Uholz7tWhXmA4r6epo+vaeV7yjdKy5QFCERMjs1kMVsLRKIrSdM6o21W2He9ftp5PP6aWOVpD5zvrvuHZC0bMQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2729,23 +2722,10 @@ packages: typescript: optional: true - '@typescript-eslint/types@5.62.0': - resolution: {integrity: sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - '@typescript-eslint/types@8.11.0': resolution: {integrity: sha512-tn6sNMHf6EBAYMvmPUaKaVeYvhUsrE6x+bXQTxjQRp360h1giATU0WvgeEys1spbvb5R+VpNOZ+XJmjD8wOUHw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@5.62.0': - resolution: {integrity: sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - '@typescript-eslint/typescript-estree@8.11.0': resolution: {integrity: sha512-yHC3s1z1RCHoCz5t06gf7jH24rr3vns08XXhfEqzYpd6Hll3z/3g23JRi0jM8A47UFKNc3u/y5KIMx8Ynbjohg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2755,22 +2735,12 @@ packages: typescript: optional: true - '@typescript-eslint/utils@5.62.0': - resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - '@typescript-eslint/utils@8.11.0': resolution: {integrity: sha512-CYiX6WZcbXNJV7UNB4PLDIBtSdRmRI/nb0FMyqHPTQD1rMjA0foPLaPUV39C/MxkTd/QKSeX+Gb34PPsDVC35g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 - '@typescript-eslint/visitor-keys@5.62.0': - resolution: {integrity: sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - '@typescript-eslint/visitor-keys@8.11.0': resolution: {integrity: sha512-EaewX6lxSjRJnc+99+dqzTeoDZUfyrA52d2/HRrkI830kgovWsmIiTfmr0NZorzqic7ga+1bS60lRBUgR3n/Bw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -3039,10 +3009,6 @@ packages: resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==} engines: {node: '>= 0.4'} - array-union@2.1.0: - resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} - engines: {node: '>=8'} - array.prototype.findlast@1.2.5: resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} engines: {node: '>= 0.4'} @@ -3964,10 +3930,6 @@ packages: diffie-hellman@5.0.3: resolution: {integrity: sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==} - dir-glob@3.0.1: - resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} - engines: {node: '>=8'} - dlv@1.1.3: resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} @@ -4388,8 +4350,8 @@ packages: peerDependencies: eslint: '>=8.44.0' - eslint-plugin-storybook@0.9.0: - resolution: {integrity: sha512-qOT/2vQBo0VqrG/BhZv8IdSsKQiyzJw+2Wqq+WFCiblI/PfxLSrGkF/buiXF+HumwfsCyBdaC94UhqhmYFmAvA==} + eslint-plugin-storybook@0.10.1: + resolution: {integrity: sha512-YpxkdqyiKpMIrRquuvBaCinsqmZJ86JvXRX/gtRa4Qctpk0ipFt2cWqEjkB1HHWWG0DVRXlUBKHjRogC2Ig1fg==} engines: {node: '>= 18'} peerDependencies: eslint: '>=6' @@ -4780,10 +4742,6 @@ packages: resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} engines: {node: '>= 0.4'} - globby@11.1.0: - resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} - engines: {node: '>=10'} - gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} @@ -7037,10 +6995,6 @@ packages: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} - requireindex@1.2.0: - resolution: {integrity: sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==} - engines: {node: '>=0.10.5'} - requires-port@1.0.0: resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} @@ -7674,21 +7628,12 @@ packages: resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} engines: {node: '>=6'} - tslib@1.14.1: - resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} - tslib@2.3.0: resolution: {integrity: sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==} tslib@2.8.0: resolution: {integrity: sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==} - tsutils@3.21.0: - resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} - engines: {node: '>= 6'} - peerDependencies: - typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' - tty-browserify@0.0.1: resolution: {integrity: sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==} @@ -10390,10 +10335,6 @@ snapshots: transitivePeerDependencies: - webpack-sources - '@storybook/csf@0.0.1': - dependencies: - lodash: 4.17.21 - '@storybook/csf@0.1.11': dependencies: type-fest: 2.19.0 @@ -11069,11 +11010,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@5.62.0': - dependencies: - '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/visitor-keys': 5.62.0 - '@typescript-eslint/scope-manager@8.11.0': dependencies: '@typescript-eslint/types': 8.11.0 @@ -11091,24 +11027,8 @@ snapshots: - eslint - supports-color - '@typescript-eslint/types@5.62.0': {} - '@typescript-eslint/types@8.11.0': {} - '@typescript-eslint/typescript-estree@5.62.0(typescript@4.9.5)': - dependencies: - '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/visitor-keys': 5.62.0 - debug: 4.3.7 - globby: 11.1.0 - is-glob: 4.0.3 - semver: 7.6.3 - tsutils: 3.21.0(typescript@4.9.5) - optionalDependencies: - typescript: 4.9.5 - transitivePeerDependencies: - - supports-color - '@typescript-eslint/typescript-estree@8.11.0(typescript@4.9.5)': dependencies: '@typescript-eslint/types': 8.11.0 @@ -11124,21 +11044,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@5.62.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5)': - dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.13.0(jiti@1.21.6)) - '@types/json-schema': 7.0.15 - '@types/semver': 7.5.8 - '@typescript-eslint/scope-manager': 5.62.0 - '@typescript-eslint/types': 5.62.0 - '@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5) - eslint: 9.13.0(jiti@1.21.6) - eslint-scope: 5.1.1 - semver: 7.6.3 - transitivePeerDependencies: - - supports-color - - typescript - '@typescript-eslint/utils@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5)': dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@9.13.0(jiti@1.21.6)) @@ -11150,11 +11055,6 @@ snapshots: - supports-color - typescript - '@typescript-eslint/visitor-keys@5.62.0': - dependencies: - '@typescript-eslint/types': 5.62.0 - eslint-visitor-keys: 3.4.3 - '@typescript-eslint/visitor-keys@8.11.0': dependencies: '@typescript-eslint/types': 8.11.0 @@ -11471,8 +11371,6 @@ snapshots: get-intrinsic: 1.2.4 is-string: 1.0.7 - array-union@2.1.0: {} - array.prototype.findlast@1.2.5: dependencies: call-bind: 1.0.7 @@ -12481,10 +12379,6 @@ snapshots: miller-rabin: 4.0.1 randombytes: 2.1.0 - dir-glob@3.0.1: - dependencies: - path-type: 4.0.0 - dlv@1.1.3: {} doctrine@2.1.0: @@ -13130,12 +13024,11 @@ snapshots: regexp-ast-analysis: 0.7.1 scslre: 0.3.0 - eslint-plugin-storybook@0.9.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5): + eslint-plugin-storybook@0.10.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5): dependencies: - '@storybook/csf': 0.0.1 - '@typescript-eslint/utils': 5.62.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) + '@storybook/csf': 0.1.11 + '@typescript-eslint/utils': 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) eslint: 9.13.0(jiti@1.21.6) - requireindex: 1.2.0 ts-dedent: 2.2.0 transitivePeerDependencies: - supports-color @@ -13658,15 +13551,6 @@ snapshots: define-properties: 1.2.1 gopd: 1.0.1 - globby@11.1.0: - dependencies: - array-union: 2.1.0 - dir-glob: 3.0.1 - fast-glob: 3.3.2 - ignore: 5.3.2 - merge2: 1.4.1 - slash: 3.0.0 - gopd@1.0.1: dependencies: get-intrinsic: 1.2.4 @@ -16784,8 +16668,6 @@ snapshots: require-from-string@2.0.2: {} - requireindex@1.2.0: {} - requires-port@1.0.0: {} resize-observer-polyfill@1.5.1: {} @@ -17462,17 +17344,10 @@ snapshots: minimist: 1.2.8 strip-bom: 3.0.0 - tslib@1.14.1: {} - tslib@2.3.0: {} tslib@2.8.0: {} - tsutils@3.21.0(typescript@4.9.5): - dependencies: - tslib: 1.14.1 - typescript: 4.9.5 - tty-browserify@0.0.1: {} tween-functions@1.2.0: {} From d5043c6628784c911e89532126b3eb0cc5d1d16e Mon Sep 17 00:00:00 2001 From: AkaraChen Date: Fri, 25 Oct 2024 12:55:35 +0800 Subject: [PATCH 219/346] build: update husky & lint-staged --- web/.husky/pre-commit | 5 +- web/package.json | 6 +- web/pnpm-lock.yaml | 243 +++++++++++++++++++++++------------------- 3 files changed, 136 insertions(+), 118 deletions(-) diff --git a/web/.husky/pre-commit b/web/.husky/pre-commit index 1c80c8c20b..cca8abe27a 100755 --- a/web/.husky/pre-commit +++ b/web/.husky/pre-commit @@ -1,6 +1,3 @@ -#!/usr/bin/env bash -. "$(dirname -- "$0")/_/husky.sh" - # get the list of modified files files=$(git diff --cached --name-only) @@ -50,7 +47,7 @@ fi if $web_modified; then echo "Running ESLint on web module" cd ./web || exit 1 - npx lint-staged + lint-staged echo "Running unit tests check" modified_files=$(git diff --cached --name-only -- utils | grep -v '\.spec\.ts$' || true) diff --git a/web/package.json b/web/package.json index acfe4f4af7..0a277c7481 100644 --- a/web/package.json +++ b/web/package.json @@ -12,7 +12,7 @@ "lint": "next lint", "fix": "next lint --fix", "eslint-fix": "eslint --fix", - "prepare": "cd ../ && node -e \"if (process.env.NODE_ENV !== 'production'){process.exit(1)} \" || husky install ./web/.husky", + "prepare": "cd ../ && node -e \"if (process.env.NODE_ENV !== 'production'){process.exit(1)} \" || husky ./web/.husky", "gen-icons": "node ./app/components/base/icons/script.mjs", "uglify-embed": "node ./bin/uglify-embed", "check-i18n": "node ./i18n/check-i18n.js", @@ -152,12 +152,12 @@ "eslint": "^9.13.0", "eslint-config-next": "^15.0.0", "eslint-plugin-react-hooks": "^5.0.0", - "husky": "^8.0.3", + "husky": "^9.1.6", "eslint-plugin-react-refresh": "^0.4.13", "eslint-plugin-storybook": "^0.10.1", "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", - "lint-staged": "^13.2.2", + "lint-staged": "^15.2.10", "magicast": "^0.3.4", "postcss": "^8.4.31", "sass": "^1.61.0", diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index ee85a4179b..dab3b4edb2 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -399,8 +399,8 @@ importers: specifier: ^0.10.1 version: 0.10.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) husky: - specifier: ^8.0.3 - version: 8.0.3 + specifier: ^9.1.6 + version: 9.1.6 jest: specifier: ^29.7.0 version: 29.7.0(@types/node@18.15.0)(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5)) @@ -408,8 +408,8 @@ importers: specifier: ^29.7.0 version: 29.7.0 lint-staged: - specifier: ^13.2.2 - version: 13.3.0 + specifier: ^15.2.10 + version: 15.2.10 magicast: specifier: ^0.3.4 version: 0.3.5 @@ -2930,9 +2930,9 @@ packages: resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} engines: {node: '>=8'} - ansi-escapes@5.0.0: - resolution: {integrity: sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==} - engines: {node: '>=12'} + ansi-escapes@7.0.0: + resolution: {integrity: sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==} + engines: {node: '>=18'} ansi-html-community@0.0.8: resolution: {integrity: sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==} @@ -3385,13 +3385,13 @@ packages: resolution: {integrity: sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==} engines: {node: '>=4'} - cli-cursor@4.0.0: - resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + cli-cursor@5.0.0: + resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==} + engines: {node: '>=18'} - cli-truncate@3.1.0: - resolution: {integrity: sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + cli-truncate@4.0.0: + resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==} + engines: {node: '>=18'} client-only@0.0.1: resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} @@ -3457,9 +3457,9 @@ packages: comma-separated-tokens@2.0.3: resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} - commander@11.0.0: - resolution: {integrity: sha512-9HMlXtt/BNoYr8ooyjjNRdIilOTkVJXB+GhxMTtOKwk0R4j4lS4NpjuqmRxroBfnfTSHQIHQB7wryHhXarNjmQ==} - engines: {node: '>=16'} + commander@12.1.0: + resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} + engines: {node: '>=18'} commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} @@ -3808,15 +3808,6 @@ packages: supports-color: optional: true - debug@4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - debug@4.3.7: resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} engines: {node: '>=6.0'} @@ -4045,6 +4036,10 @@ packages: resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} engines: {node: '>=6'} + environment@1.1.0: + resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} + engines: {node: '>=18'} + error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} @@ -4501,9 +4496,9 @@ packages: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} - execa@7.2.0: - resolution: {integrity: sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==} - engines: {node: ^14.18.0 || ^16.14.0 || >=18.0.0} + execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} exit@0.1.2: resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} @@ -4677,6 +4672,10 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} + get-east-asian-width@1.3.0: + resolution: {integrity: sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==} + engines: {node: '>=18'} + get-intrinsic@1.2.4: resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} engines: {node: '>= 0.4'} @@ -4693,6 +4692,10 @@ packages: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} + get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + get-symbol-description@1.0.2: resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} engines: {node: '>= 0.4'} @@ -4941,13 +4944,13 @@ packages: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} - human-signals@4.3.1: - resolution: {integrity: sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==} - engines: {node: '>=14.18.0'} + human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} - husky@8.0.3: - resolution: {integrity: sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==} - engines: {node: '>=14'} + husky@9.1.6: + resolution: {integrity: sha512-sqbjZKK7kf44hfdE94EoX8MZNk0n7HeW37O4YrVGCF4wzgQjp+akPAkfUK5LZ6KuR/6sqeAVuXHji+RzQgOn5A==} + engines: {node: '>=18'} hasBin: true i18next-resources-to-backend@1.2.1: @@ -5134,6 +5137,10 @@ packages: resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} engines: {node: '>=12'} + is-fullwidth-code-point@5.0.0: + resolution: {integrity: sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==} + engines: {node: '>=18'} + is-generator-fn@2.1.0: resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} engines: {node: '>=6'} @@ -5568,19 +5575,14 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - lint-staged@13.3.0: - resolution: {integrity: sha512-mPRtrYnipYYv1FEE134ufbWpeggNTo+O/UPzngoaKzbzHAthvR55am+8GfHTnqNRQVRRrYQLGW9ZyUoD7DsBHQ==} - engines: {node: ^16.14.0 || >=18.0.0} + lint-staged@15.2.10: + resolution: {integrity: sha512-5dY5t743e1byO19P9I4b3x8HJwalIznL5E1FWYnU6OWw33KxNBSLAc6Cy7F2PsFEO8FKnLwjwm5hx7aMF0jzZg==} + engines: {node: '>=18.12.0'} hasBin: true - listr2@6.6.1: - resolution: {integrity: sha512-+rAXGHh0fkEWdXBmX+L6mmfmXmXvDGEKzkjxO+8mP3+nI/r/CWznVBvsibXdxda9Zz0OW2e2ikphN3OwCT/jSg==} - engines: {node: '>=16.0.0'} - peerDependencies: - enquirer: '>= 2.3.0 < 3' - peerDependenciesMeta: - enquirer: - optional: true + listr2@8.2.5: + resolution: {integrity: sha512-iyAZCeyD+c1gPyE9qpFu8af0Y+MRtmKOncdGoA2S5EY8iFq99dmmvkNnHiWo+pj0s7yH7l3KPIgee77tKpXPWQ==} + engines: {node: '>=18.0.0'} loader-runner@4.3.0: resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==} @@ -5631,9 +5633,9 @@ packages: lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - log-update@5.0.1: - resolution: {integrity: sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + log-update@6.1.0: + resolution: {integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==} + engines: {node: '>=18'} longest-streak@3.1.0: resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} @@ -6020,10 +6022,6 @@ packages: micromark@4.0.0: resolution: {integrity: sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==} - micromatch@4.0.5: - resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} - engines: {node: '>=8.6'} - micromatch@4.0.8: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} @@ -6053,6 +6051,10 @@ packages: resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} engines: {node: '>=12'} + mimic-function@5.0.1: + resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} + engines: {node: '>=18'} + mimic-response@1.0.1: resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} engines: {node: '>=4'} @@ -6106,9 +6108,6 @@ packages: ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} - ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -6269,6 +6268,10 @@ packages: resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} engines: {node: '>=12'} + onetime@7.0.0: + resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} + engines: {node: '>=18'} + open@8.4.2: resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} engines: {node: '>=12'} @@ -7038,9 +7041,9 @@ packages: responselike@2.0.1: resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==} - restore-cursor@4.0.0: - resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + restore-cursor@5.1.0: + resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} + engines: {node: '>=18'} reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} @@ -7226,6 +7229,10 @@ packages: resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} engines: {node: '>=12'} + slice-ansi@7.1.0: + resolution: {integrity: sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==} + engines: {node: '>=18'} + sortablejs@1.15.3: resolution: {integrity: sha512-zdK3/kwwAK1cJgy1rwl1YtNTbRmc8qW/+vgXf75A7NHag5of4pyI6uK86ktmQETyWRH7IGaE73uZOOBcGxgqZg==} @@ -7664,10 +7671,6 @@ packages: resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} engines: {node: '>=8'} - type-fest@1.4.0: - resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} - engines: {node: '>=10'} - type-fest@2.19.0: resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} engines: {node: '>=12.20'} @@ -7997,6 +8000,10 @@ packages: resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} engines: {node: '>=12'} + wrap-ansi@9.0.0: + resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==} + engines: {node: '>=18'} + wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} @@ -8042,9 +8049,10 @@ packages: resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} engines: {node: '>= 6'} - yaml@2.3.1: - resolution: {integrity: sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==} + yaml@2.5.1: + resolution: {integrity: sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==} engines: {node: '>= 14'} + hasBin: true yaml@2.6.0: resolution: {integrity: sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ==} @@ -11306,9 +11314,9 @@ snapshots: dependencies: type-fest: 0.21.3 - ansi-escapes@5.0.0: + ansi-escapes@7.0.0: dependencies: - type-fest: 1.4.0 + environment: 1.1.0 ansi-html-community@0.0.8: {} @@ -11828,11 +11836,11 @@ snapshots: dependencies: escape-string-regexp: 1.0.5 - cli-cursor@4.0.0: + cli-cursor@5.0.0: dependencies: - restore-cursor: 4.0.0 + restore-cursor: 5.1.0 - cli-truncate@3.1.0: + cli-truncate@4.0.0: dependencies: slice-ansi: 5.0.0 string-width: 4.2.3 @@ -11906,7 +11914,7 @@ snapshots: comma-separated-tokens@2.0.3: {} - commander@11.0.0: {} + commander@12.1.0: {} commander@2.20.3: {} @@ -12294,10 +12302,6 @@ snapshots: dependencies: ms: 2.1.3 - debug@4.3.4: - dependencies: - ms: 2.1.2 - debug@4.3.7: dependencies: ms: 2.1.3 @@ -12491,6 +12495,8 @@ snapshots: env-paths@2.2.1: {} + environment@1.1.0: {} + error-ex@1.3.2: dependencies: is-arrayish: 0.2.1 @@ -13243,16 +13249,16 @@ snapshots: signal-exit: 3.0.7 strip-final-newline: 2.0.0 - execa@7.2.0: + execa@8.0.1: dependencies: cross-spawn: 7.0.3 - get-stream: 6.0.1 - human-signals: 4.3.1 + get-stream: 8.0.1 + human-signals: 5.0.0 is-stream: 3.0.0 merge-stream: 2.0.0 npm-run-path: 5.3.0 onetime: 6.0.0 - signal-exit: 3.0.7 + signal-exit: 4.1.0 strip-final-newline: 3.0.0 exit@0.1.2: {} @@ -13480,6 +13486,8 @@ snapshots: get-caller-file@2.0.5: {} + get-east-asian-width@1.3.0: {} + get-intrinsic@1.2.4: dependencies: es-errors: 1.3.0 @@ -13496,6 +13504,8 @@ snapshots: get-stream@6.0.1: {} + get-stream@8.0.1: {} + get-symbol-description@1.0.2: dependencies: call-bind: 1.0.7 @@ -13853,9 +13863,9 @@ snapshots: human-signals@2.1.0: {} - human-signals@4.3.1: {} + human-signals@5.0.0: {} - husky@8.0.3: {} + husky@9.1.6: {} i18next-resources-to-backend@1.2.1: dependencies: @@ -14015,6 +14025,10 @@ snapshots: is-fullwidth-code-point@4.0.0: {} + is-fullwidth-code-point@5.0.0: + dependencies: + get-east-asian-width: 1.3.0 + is-generator-fn@2.1.0: {} is-generator-function@1.0.10: @@ -14642,30 +14656,29 @@ snapshots: lines-and-columns@1.2.4: {} - lint-staged@13.3.0: + lint-staged@15.2.10: dependencies: chalk: 5.3.0 - commander: 11.0.0 - debug: 4.3.4 - execa: 7.2.0 - lilconfig: 2.1.0 - listr2: 6.6.1 - micromatch: 4.0.5 + commander: 12.1.0 + debug: 4.3.7 + execa: 8.0.1 + lilconfig: 3.1.2 + listr2: 8.2.5 + micromatch: 4.0.8 pidtree: 0.6.0 string-argv: 0.3.2 - yaml: 2.3.1 + yaml: 2.5.1 transitivePeerDependencies: - - enquirer - supports-color - listr2@6.6.1: + listr2@8.2.5: dependencies: - cli-truncate: 3.1.0 + cli-truncate: 4.0.0 colorette: 2.0.20 eventemitter3: 5.0.1 - log-update: 5.0.1 + log-update: 6.1.0 rfdc: 1.4.1 - wrap-ansi: 8.1.0 + wrap-ansi: 9.0.0 loader-runner@4.3.0: {} @@ -14710,13 +14723,13 @@ snapshots: lodash@4.17.21: {} - log-update@5.0.1: + log-update@6.1.0: dependencies: - ansi-escapes: 5.0.0 - cli-cursor: 4.0.0 - slice-ansi: 5.0.0 + ansi-escapes: 7.0.0 + cli-cursor: 5.0.0 + slice-ansi: 7.1.0 strip-ansi: 7.1.0 - wrap-ansi: 8.1.0 + wrap-ansi: 9.0.0 longest-streak@3.1.0: {} @@ -15571,11 +15584,6 @@ snapshots: transitivePeerDependencies: - supports-color - micromatch@4.0.5: - dependencies: - braces: 3.0.3 - picomatch: 2.3.1 - micromatch@4.0.8: dependencies: braces: 3.0.3 @@ -15598,6 +15606,8 @@ snapshots: mimic-fn@4.0.0: {} + mimic-function@5.0.1: {} + mimic-response@1.0.1: {} mimic-response@3.1.0: {} @@ -15641,8 +15651,6 @@ snapshots: ms@2.0.0: {} - ms@2.1.2: {} - ms@2.1.3: {} mz@2.7.0: @@ -15825,6 +15833,10 @@ snapshots: dependencies: mimic-fn: 4.0.0 + onetime@7.0.0: + dependencies: + mimic-function: 5.0.1 + open@8.4.2: dependencies: define-lazy-prop: 2.0.0 @@ -16710,10 +16722,10 @@ snapshots: dependencies: lowercase-keys: 2.0.0 - restore-cursor@4.0.0: + restore-cursor@5.1.0: dependencies: - onetime: 5.1.2 - signal-exit: 3.0.7 + onetime: 7.0.0 + signal-exit: 4.1.0 reusify@1.0.4: {} @@ -16928,6 +16940,11 @@ snapshots: ansi-styles: 6.2.1 is-fullwidth-code-point: 4.0.0 + slice-ansi@7.1.0: + dependencies: + ansi-styles: 6.2.1 + is-fullwidth-code-point: 5.0.0 + sortablejs@1.15.3: {} source-map-js@1.2.1: {} @@ -17366,8 +17383,6 @@ snapshots: type-fest@0.8.1: {} - type-fest@1.4.0: {} - type-fest@2.19.0: {} type-is@1.6.18: @@ -17786,6 +17801,12 @@ snapshots: string-width: 4.2.3 strip-ansi: 7.1.0 + wrap-ansi@9.0.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 4.2.3 + strip-ansi: 7.1.0 + wrappy@1.0.2: {} write-file-atomic@4.0.2: @@ -17813,7 +17834,7 @@ snapshots: yaml@1.10.2: {} - yaml@2.3.1: {} + yaml@2.5.1: {} yaml@2.6.0: {} From bd82c7edac9ff4dd23d0b326fe74de3857f33535 Mon Sep 17 00:00:00 2001 From: AkaraChen Date: Fri, 25 Oct 2024 10:32:19 +0800 Subject: [PATCH 220/346] build: update storybook --- web/package.json | 22 +++++++------- web/pnpm-lock.yaml | 71 +++++++++++++++++++++++++++++++++------------- 2 files changed, 63 insertions(+), 30 deletions(-) diff --git a/web/package.json b/web/package.json index 0a277c7481..895fa2111d 100644 --- a/web/package.json +++ b/web/package.json @@ -110,21 +110,21 @@ }, "devDependencies": { "@antfu/eslint-config": "^3.8.0", - "@chromatic-com/storybook": "^1.9.0", + "@chromatic-com/storybook": "^3.1.0", "@eslint-react/eslint-plugin": "^1.15.0", "@eslint/eslintrc": "^3.1.0", "@eslint/js": "^9.13.0", "@faker-js/faker": "^7.6.0", "@rgrove/parse-xml": "^4.1.0", - "@storybook/addon-essentials": "^8.3.5", - "@storybook/addon-interactions": "^8.3.5", - "@storybook/addon-links": "^8.3.5", - "@storybook/addon-onboarding": "^8.3.5", - "@storybook/addon-themes": "^8.3.5", - "@storybook/blocks": "^8.3.5", - "@storybook/nextjs": "^8.3.5", - "@storybook/react": "^8.3.5", - "@storybook/test": "^8.3.5", + "@storybook/addon-essentials": "^8.3.6", + "@storybook/addon-interactions": "^8.3.6", + "@storybook/addon-links": "^8.3.6", + "@storybook/addon-onboarding": "^8.3.6", + "@storybook/addon-themes": "^8.3.6", + "@storybook/blocks": "^8.3.6", + "@storybook/nextjs": "^8.3.6", + "@storybook/react": "^8.3.6", + "@storybook/test": "^8.3.6", "@testing-library/dom": "^10.3.2", "@testing-library/jest-dom": "^6.4.6", "@testing-library/react": "^16.0.0", @@ -161,7 +161,7 @@ "magicast": "^0.3.4", "postcss": "^8.4.31", "sass": "^1.61.0", - "storybook": "^8.3.5", + "storybook": "^8.3.6", "tailwindcss": "^3.4.4", "ts-node": "^10.9.2", "typescript": "4.9.5", diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index dab3b4edb2..91d714b5c1 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -267,8 +267,8 @@ importers: specifier: ^3.8.0 version: 3.8.0(@eslint-react/eslint-plugin@1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(@typescript-eslint/utils@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(@vue/compiler-sfc@3.5.12)(eslint-plugin-react-hooks@5.0.0(eslint@9.13.0(jiti@1.21.6)))(eslint-plugin-react-refresh@0.4.13(eslint@9.13.0(jiti@1.21.6)))(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) '@chromatic-com/storybook': - specifier: ^1.9.0 - version: 1.9.0(react@18.2.0) + specifier: ^3.1.0 + version: 3.1.0(react@18.2.0)(storybook@8.3.6) '@eslint-react/eslint-plugin': specifier: ^1.15.0 version: 1.15.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) @@ -285,31 +285,31 @@ importers: specifier: ^4.1.0 version: 4.1.0 '@storybook/addon-essentials': - specifier: ^8.3.5 + specifier: ^8.3.6 version: 8.3.6(storybook@8.3.6)(webpack-sources@3.2.3) '@storybook/addon-interactions': - specifier: ^8.3.5 + specifier: ^8.3.6 version: 8.3.6(storybook@8.3.6) '@storybook/addon-links': - specifier: ^8.3.5 + specifier: ^8.3.6 version: 8.3.6(react@18.2.0)(storybook@8.3.6) '@storybook/addon-onboarding': - specifier: ^8.3.5 + specifier: ^8.3.6 version: 8.3.6(react@18.2.0)(storybook@8.3.6) '@storybook/addon-themes': - specifier: ^8.3.5 + specifier: ^8.3.6 version: 8.3.6(storybook@8.3.6) '@storybook/blocks': - specifier: ^8.3.5 + specifier: ^8.3.6 version: 8.3.6(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(storybook@8.3.6) '@storybook/nextjs': - specifier: ^8.3.5 + specifier: ^8.3.6 version: 8.3.6(esbuild@0.23.1)(next@14.2.15(@babel/core@7.25.8)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.80.3))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.80.3)(storybook@8.3.6)(type-fest@2.19.0)(typescript@4.9.5)(uglify-js@3.19.3)(webpack-hot-middleware@2.26.1)(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3)) '@storybook/react': - specifier: ^8.3.5 + specifier: ^8.3.6 version: 8.3.6(@storybook/test@8.3.6(storybook@8.3.6))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(storybook@8.3.6)(typescript@4.9.5) '@storybook/test': - specifier: ^8.3.5 + specifier: ^8.3.6 version: 8.3.6(storybook@8.3.6) '@testing-library/dom': specifier: ^10.3.2 @@ -420,7 +420,7 @@ importers: specifier: ^1.61.0 version: 1.80.3 storybook: - specifier: ^8.3.5 + specifier: ^8.3.6 version: 8.3.6 tailwindcss: specifier: ^3.4.4 @@ -1138,9 +1138,11 @@ packages: '@braintree/sanitize-url@6.0.4': resolution: {integrity: sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A==} - '@chromatic-com/storybook@1.9.0': - resolution: {integrity: sha512-vYQ+TcfktEE3GHnLZXHCzXF/sN9dw+KivH8a5cmPyd9YtQs7fZtHrEgsIjWpYycXiweKMo1Lm1RZsjxk8DH3rA==} + '@chromatic-com/storybook@3.1.0': + resolution: {integrity: sha512-AM8jDwoBNNwJKgmoWkHIOhu4ObsxvDtOzZC9tPCVEW6P+pFwg5xjSZAQglIE2c8/SsEPSduNdxBt31ES3iDwoA==} engines: {node: '>=16.0.0', yarn: '>=1.22.18'} + peerDependencies: + storybook: ^8.3.0 '@clack/core@0.3.4': resolution: {integrity: sha512-H4hxZDXgHtWTwV3RAVenqcC4VbJZNegbBjlPvzOzCouXtS2y3sDvlO3IsbrPNWuLWPPlYVYPghQdSF64683Ldw==} @@ -2177,6 +2179,11 @@ packages: typescript: optional: true + '@storybook/channels@8.3.6': + resolution: {integrity: sha512-6ahY0n1A19diR5cI63lhDEpMaDsq7LFtMOgWab2NwCsdXoEAl6anvDptyPWW60umN3HrDzSKFdpRx4imOEjlWw==} + peerDependencies: + storybook: ^8.3.6 + '@storybook/components@8.3.6': resolution: {integrity: sha512-TXuoGZY7X3iixF45lXkYOFk8k2q9OHcqHyHyem1gATLLQXgyOvDgzm+VB7uKBNzssRQPEE+La70nfG8bq/viRw==} peerDependencies: @@ -2279,6 +2286,11 @@ packages: typescript: optional: true + '@storybook/telemetry@8.3.6': + resolution: {integrity: sha512-fhpbZok7mPeujjFxAKo2vuqhfjhv5BO/mHH7Z8QtgsYqeR7px56arDRgV6CngBZWgFvrQ2wBS0HPV4nB6YWvJQ==} + peerDependencies: + storybook: ^8.3.6 + '@storybook/test@8.3.6': resolution: {integrity: sha512-WIc8LzK9jaEw+e3OiweEM2j3cppPzsWod59swuf6gDBf176EQLIyjtVc+Kh3qO4NNkcL+lwmqaLPjOxlBLaDbg==} peerDependencies: @@ -2289,6 +2301,11 @@ packages: peerDependencies: storybook: ^8.3.6 + '@storybook/types@8.3.6': + resolution: {integrity: sha512-EY+bjIxxmKkFrL7CyDQb3EXbmy0+Y9OieaPrNNM7QXTfGgp81lXhfqMX3HLMMjplk+rcxVJLyzXSBx0nIn91fQ==} + peerDependencies: + storybook: ^8.3.6 + '@stylistic/eslint-plugin@2.9.0': resolution: {integrity: sha512-OrDyFAYjBT61122MIY1a3SfEgy3YCMgt2vL4eoPmvTwDBwyQhAXurxNQznlRD/jESNfYWfID8Ej+31LljvF7Xg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -3335,8 +3352,8 @@ packages: resolution: {integrity: sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==} engines: {node: '>= 14.16.0'} - chromatic@11.14.0: - resolution: {integrity: sha512-qt7xXpdrwssBtXWv30aW46HAK10bF4Ep7SMjtMQhD61Fg4IS9aImT0WFeig7utpXYHOx0eSysjwhz0cgYz9SDg==} + chromatic@11.15.0: + resolution: {integrity: sha512-5WBm+akQnxsdJv7A//XBafYxk88RJYmRjOh61lVitbPCIN2J9jcsQR+hYApnInmQsWRZvO8GKkMy7SdTlnm1dg==} hasBin: true peerDependencies: '@chromatic-com/cypress': ^0.*.* || ^1.0.0 @@ -9003,12 +9020,16 @@ snapshots: '@braintree/sanitize-url@6.0.4': {} - '@chromatic-com/storybook@1.9.0(react@18.2.0)': + '@chromatic-com/storybook@3.1.0(react@18.2.0)(storybook@8.3.6)': dependencies: - chromatic: 11.14.0 + '@storybook/channels': 8.3.6(storybook@8.3.6) + '@storybook/telemetry': 8.3.6(storybook@8.3.6) + '@storybook/types': 8.3.6(storybook@8.3.6) + chromatic: 11.15.0 filesize: 10.1.6 jsonfile: 6.1.0 react-confetti: 6.1.0(react@18.2.0) + storybook: 8.3.6 strip-ansi: 7.1.0 transitivePeerDependencies: - '@chromatic-com/cypress' @@ -10306,6 +10327,10 @@ snapshots: - uglify-js - webpack-cli + '@storybook/channels@8.3.6(storybook@8.3.6)': + dependencies: + storybook: 8.3.6 + '@storybook/components@8.3.6(storybook@8.3.6)': dependencies: storybook: 8.3.6 @@ -10514,6 +10539,10 @@ snapshots: '@storybook/test': 8.3.6(storybook@8.3.6) typescript: 4.9.5 + '@storybook/telemetry@8.3.6(storybook@8.3.6)': + dependencies: + storybook: 8.3.6 + '@storybook/test@8.3.6(storybook@8.3.6)': dependencies: '@storybook/csf': 0.1.11 @@ -10531,6 +10560,10 @@ snapshots: dependencies: storybook: 8.3.6 + '@storybook/types@8.3.6(storybook@8.3.6)': + dependencies: + storybook: 8.3.6 + '@stylistic/eslint-plugin@2.9.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5)': dependencies: '@typescript-eslint/utils': 8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5) @@ -11803,7 +11836,7 @@ snapshots: dependencies: readdirp: 4.0.2 - chromatic@11.14.0: {} + chromatic@11.15.0: {} chrome-trace-event@1.0.4: {} From cd27ae43193ae1e55e9a46a9e3413fd7ea8d7c8b Mon Sep 17 00:00:00 2001 From: AkaraChen Date: Fri, 25 Oct 2024 12:57:57 +0800 Subject: [PATCH 221/346] build: update testing-library --- web/package.json | 6 +++--- web/pnpm-lock.yaml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/web/package.json b/web/package.json index 895fa2111d..2f5065a642 100644 --- a/web/package.json +++ b/web/package.json @@ -125,9 +125,9 @@ "@storybook/nextjs": "^8.3.6", "@storybook/react": "^8.3.6", "@storybook/test": "^8.3.6", - "@testing-library/dom": "^10.3.2", - "@testing-library/jest-dom": "^6.4.6", - "@testing-library/react": "^16.0.0", + "@testing-library/dom": "^10.4.0", + "@testing-library/jest-dom": "^6.6.2", + "@testing-library/react": "^16.0.1", "@types/crypto-js": "^4.1.1", "@types/dagre": "^0.7.52", "@types/jest": "^29.5.12", diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index 91d714b5c1..9af099a780 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -312,13 +312,13 @@ importers: specifier: ^8.3.6 version: 8.3.6(storybook@8.3.6) '@testing-library/dom': - specifier: ^10.3.2 + specifier: ^10.4.0 version: 10.4.0 '@testing-library/jest-dom': - specifier: ^6.4.6 + specifier: ^6.6.2 version: 6.6.2 '@testing-library/react': - specifier: ^16.0.0 + specifier: ^16.0.1 version: 16.0.1(@testing-library/dom@10.4.0)(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@types/crypto-js': specifier: ^4.1.1 From 18106a4fc6c099b45360af0ae33ff01f021e77e7 Mon Sep 17 00:00:00 2001 From: Jyong <76649700+JohnJyong@users.noreply.github.com> Date: Fri, 25 Oct 2024 13:57:03 +0800 Subject: [PATCH 222/346] add tidb on qdrant type (#9831) Co-authored-by: Zhaofeng Miao <522856232@qq.com> --- api/configs/feature/__init__.py | 5 + api/configs/middleware/__init__.py | 7 + .../middleware/vdb/tidb_on_qdrant_config.py | 65 +++ api/controllers/console/datasets/datasets.py | 1 + .../datasource/vdb/tidb_on_qdrant/__init__.py | 0 .../vdb/tidb_on_qdrant/tidb_entities.py | 17 + .../tidb_on_qdrant/tidb_on_qdrant_vector.py | 526 ++++++++++++++++++ .../vdb/tidb_on_qdrant/tidb_service.py | 250 +++++++++ api/core/rag/datasource/vdb/vector_factory.py | 17 +- api/core/rag/datasource/vdb/vector_type.py | 1 + api/extensions/ext_celery.py | 11 + ...0956-0251a1c768cc_add_tidb_auth_binding.py | 51 ++ ..._10_22_0959-43fa78bc3b7d_add_white_list.py | 42 ++ api/models/dataset.py | 32 ++ api/schedule/create_tidb_serverless_task.py | 56 ++ .../update_tidb_serverless_status_task.py | 51 ++ api/services/auth/jina.py | 44 ++ .../jina-reader/base/checkbox-with-label.tsx | 40 ++ .../jina-reader/base/error-message.tsx | 30 + .../create/website/jina-reader/base/field.tsx | 54 ++ .../create/website/jina-reader/base/input.tsx | 58 ++ .../website/jina-reader/base/options-wrap.tsx | 55 ++ .../website/jina-reader/base/url-input.tsx | 48 ++ .../jina-reader/crawled-result-item.tsx | 40 ++ .../website/jina-reader/crawled-result.tsx | 87 +++ .../create/website/jina-reader/crawling.tsx | 37 ++ .../website/jina-reader/mock-crawl-result.ts | 24 + 27 files changed, 1648 insertions(+), 1 deletion(-) create mode 100644 api/configs/middleware/vdb/tidb_on_qdrant_config.py create mode 100644 api/core/rag/datasource/vdb/tidb_on_qdrant/__init__.py create mode 100644 api/core/rag/datasource/vdb/tidb_on_qdrant/tidb_entities.py create mode 100644 api/core/rag/datasource/vdb/tidb_on_qdrant/tidb_on_qdrant_vector.py create mode 100644 api/core/rag/datasource/vdb/tidb_on_qdrant/tidb_service.py create mode 100644 api/migrations/versions/2024_08_15_0956-0251a1c768cc_add_tidb_auth_binding.py create mode 100644 api/migrations/versions/2024_10_22_0959-43fa78bc3b7d_add_white_list.py create mode 100644 api/schedule/create_tidb_serverless_task.py create mode 100644 api/schedule/update_tidb_serverless_status_task.py create mode 100644 api/services/auth/jina.py create mode 100644 web/app/components/datasets/create/website/jina-reader/base/checkbox-with-label.tsx create mode 100644 web/app/components/datasets/create/website/jina-reader/base/error-message.tsx create mode 100644 web/app/components/datasets/create/website/jina-reader/base/field.tsx create mode 100644 web/app/components/datasets/create/website/jina-reader/base/input.tsx create mode 100644 web/app/components/datasets/create/website/jina-reader/base/options-wrap.tsx create mode 100644 web/app/components/datasets/create/website/jina-reader/base/url-input.tsx create mode 100644 web/app/components/datasets/create/website/jina-reader/crawled-result-item.tsx create mode 100644 web/app/components/datasets/create/website/jina-reader/crawled-result.tsx create mode 100644 web/app/components/datasets/create/website/jina-reader/crawling.tsx create mode 100644 web/app/components/datasets/create/website/jina-reader/mock-crawl-result.ts diff --git a/api/configs/feature/__init__.py b/api/configs/feature/__init__.py index 4d6c9aedc1..0fa926038d 100644 --- a/api/configs/feature/__init__.py +++ b/api/configs/feature/__init__.py @@ -571,6 +571,11 @@ class DataSetConfig(BaseSettings): default=False, ) + TIDB_SERVERLESS_NUMBER: PositiveInt = Field( + description="number of tidb serverless cluster", + default=500, + ) + class WorkspaceConfig(BaseSettings): """ diff --git a/api/configs/middleware/__init__.py b/api/configs/middleware/__init__.py index 705e30b7ff..3d68e29d0e 100644 --- a/api/configs/middleware/__init__.py +++ b/api/configs/middleware/__init__.py @@ -27,6 +27,7 @@ from configs.middleware.vdb.pgvectors_config import PGVectoRSConfig from configs.middleware.vdb.qdrant_config import QdrantConfig from configs.middleware.vdb.relyt_config import RelytConfig from configs.middleware.vdb.tencent_vector_config import TencentVectorDBConfig +from configs.middleware.vdb.tidb_on_qdrant_config import TidbOnQdrantConfig from configs.middleware.vdb.tidb_vector_config import TiDBVectorConfig from configs.middleware.vdb.upstash_config import UpstashConfig from configs.middleware.vdb.vikingdb_config import VikingDBConfig @@ -54,6 +55,11 @@ class VectorStoreConfig(BaseSettings): default=None, ) + VECTOR_STORE_WHITELIST_ENABLE: Optional[bool] = Field( + description="Enable whitelist for vector store.", + default=False, + ) + class KeywordStoreConfig(BaseSettings): KEYWORD_STORE: str = Field( @@ -248,5 +254,6 @@ class MiddlewareConfig( InternalTestConfig, VikingDBConfig, UpstashConfig, + TidbOnQdrantConfig, ): pass diff --git a/api/configs/middleware/vdb/tidb_on_qdrant_config.py b/api/configs/middleware/vdb/tidb_on_qdrant_config.py new file mode 100644 index 0000000000..98268798ef --- /dev/null +++ b/api/configs/middleware/vdb/tidb_on_qdrant_config.py @@ -0,0 +1,65 @@ +from typing import Optional + +from pydantic import Field, NonNegativeInt, PositiveInt +from pydantic_settings import BaseSettings + + +class TidbOnQdrantConfig(BaseSettings): + """ + Tidb on Qdrant configs + """ + + TIDB_ON_QDRANT_URL: Optional[str] = Field( + description="Tidb on Qdrant url", + default=None, + ) + + TIDB_ON_QDRANT_API_KEY: Optional[str] = Field( + description="Tidb on Qdrant api key", + default=None, + ) + + TIDB_ON_QDRANT_CLIENT_TIMEOUT: NonNegativeInt = Field( + description="Tidb on Qdrant client timeout in seconds", + default=20, + ) + + TIDB_ON_QDRANT_GRPC_ENABLED: bool = Field( + description="whether enable grpc support for Tidb on Qdrant connection", + default=False, + ) + + TIDB_ON_QDRANT_GRPC_PORT: PositiveInt = Field( + description="Tidb on Qdrant grpc port", + default=6334, + ) + + TIDB_PUBLIC_KEY: Optional[str] = Field( + description="Tidb account public key", + default=None, + ) + + TIDB_PRIVATE_KEY: Optional[str] = Field( + description="Tidb account private key", + default=None, + ) + + TIDB_API_URL: Optional[str] = Field( + description="Tidb API url", + default=None, + ) + + TIDB_IAM_API_URL: Optional[str] = Field( + description="Tidb IAM API url", + default=None, + ) + + TIDB_REGION: Optional[str] = Field( + description="Tidb serverless region", + default="regions/aws-us-east-1", + ) + + TIDB_PROJECT_ID: Optional[str] = Field( + description="Tidb project id", + default=None, + ) diff --git a/api/controllers/console/datasets/datasets.py b/api/controllers/console/datasets/datasets.py index b500c6c3fa..c8022efb8b 100644 --- a/api/controllers/console/datasets/datasets.py +++ b/api/controllers/console/datasets/datasets.py @@ -639,6 +639,7 @@ class DatasetRetrievalSettingApi(Resource): | VectorType.ORACLE | VectorType.ELASTICSEARCH | VectorType.PGVECTOR + | VectorType.TIDB_ON_QDRANT ): return { "retrieval_method": [ diff --git a/api/core/rag/datasource/vdb/tidb_on_qdrant/__init__.py b/api/core/rag/datasource/vdb/tidb_on_qdrant/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/api/core/rag/datasource/vdb/tidb_on_qdrant/tidb_entities.py b/api/core/rag/datasource/vdb/tidb_on_qdrant/tidb_entities.py new file mode 100644 index 0000000000..1e62b3c589 --- /dev/null +++ b/api/core/rag/datasource/vdb/tidb_on_qdrant/tidb_entities.py @@ -0,0 +1,17 @@ +from typing import Optional + +from pydantic import BaseModel + + +class ClusterEntity(BaseModel): + """ + Model Config Entity. + """ + + name: str + cluster_id: str + displayName: str + region: str + spendingLimit: Optional[int] = 1000 + version: str + createdBy: str diff --git a/api/core/rag/datasource/vdb/tidb_on_qdrant/tidb_on_qdrant_vector.py b/api/core/rag/datasource/vdb/tidb_on_qdrant/tidb_on_qdrant_vector.py new file mode 100644 index 0000000000..a38f84636e --- /dev/null +++ b/api/core/rag/datasource/vdb/tidb_on_qdrant/tidb_on_qdrant_vector.py @@ -0,0 +1,526 @@ +import json +import os +import uuid +from collections.abc import Generator, Iterable, Sequence +from itertools import islice +from typing import TYPE_CHECKING, Any, Optional, Union, cast + +import qdrant_client +import requests +from flask import current_app +from pydantic import BaseModel +from qdrant_client.http import models as rest +from qdrant_client.http.models import ( + FilterSelector, + HnswConfigDiff, + PayloadSchemaType, + TextIndexParams, + TextIndexType, + TokenizerType, +) +from qdrant_client.local.qdrant_local import QdrantLocal +from requests.auth import HTTPDigestAuth + +from configs import dify_config +from core.rag.datasource.vdb.field import Field +from core.rag.datasource.vdb.tidb_on_qdrant.tidb_service import TidbService +from core.rag.datasource.vdb.vector_base import BaseVector +from core.rag.datasource.vdb.vector_factory import AbstractVectorFactory +from core.rag.datasource.vdb.vector_type import VectorType +from core.rag.embedding.embedding_base import Embeddings +from core.rag.models.document import Document +from extensions.ext_database import db +from extensions.ext_redis import redis_client +from models.dataset import Dataset, TidbAuthBinding + +if TYPE_CHECKING: + from qdrant_client import grpc # noqa + from qdrant_client.conversions import common_types + from qdrant_client.http import models as rest + + DictFilter = dict[str, Union[str, int, bool, dict, list]] + MetadataFilter = Union[DictFilter, common_types.Filter] + + +class TidbOnQdrantConfig(BaseModel): + endpoint: str + api_key: Optional[str] = None + timeout: float = 20 + root_path: Optional[str] = None + grpc_port: int = 6334 + prefer_grpc: bool = False + + def to_qdrant_params(self): + if self.endpoint and self.endpoint.startswith("path:"): + path = self.endpoint.replace("path:", "") + if not os.path.isabs(path): + path = os.path.join(self.root_path, path) + + return {"path": path} + else: + return { + "url": self.endpoint, + "api_key": self.api_key, + "timeout": self.timeout, + "verify": False, + "grpc_port": self.grpc_port, + "prefer_grpc": self.prefer_grpc, + } + + +class TidbConfig(BaseModel): + api_url: str + public_key: str + private_key: str + + +class TidbOnQdrantVector(BaseVector): + def __init__(self, collection_name: str, group_id: str, config: TidbOnQdrantConfig, distance_func: str = "Cosine"): + super().__init__(collection_name) + self._client_config = config + self._client = qdrant_client.QdrantClient(**self._client_config.to_qdrant_params()) + self._distance_func = distance_func.upper() + self._group_id = group_id + + def get_type(self) -> str: + return VectorType.TIDB_ON_QDRANT + + def to_index_struct(self) -> dict: + return {"type": self.get_type(), "vector_store": {"class_prefix": self._collection_name}} + + def create(self, texts: list[Document], embeddings: list[list[float]], **kwargs): + if texts: + # get embedding vector size + vector_size = len(embeddings[0]) + # get collection name + collection_name = self._collection_name + # create collection + self.create_collection(collection_name, vector_size) + + self.add_texts(texts, embeddings, **kwargs) + + def create_collection(self, collection_name: str, vector_size: int): + lock_name = "vector_indexing_lock_{}".format(collection_name) + with redis_client.lock(lock_name, timeout=20): + collection_exist_cache_key = "vector_indexing_{}".format(self._collection_name) + if redis_client.get(collection_exist_cache_key): + return + collection_name = collection_name or uuid.uuid4().hex + all_collection_name = [] + collections_response = self._client.get_collections() + collection_list = collections_response.collections + for collection in collection_list: + all_collection_name.append(collection.name) + if collection_name not in all_collection_name: + from qdrant_client.http import models as rest + + vectors_config = rest.VectorParams( + size=vector_size, + distance=rest.Distance[self._distance_func], + ) + hnsw_config = HnswConfigDiff( + m=0, + payload_m=16, + ef_construct=100, + full_scan_threshold=10000, + max_indexing_threads=0, + on_disk=False, + ) + self._client.recreate_collection( + collection_name=collection_name, + vectors_config=vectors_config, + hnsw_config=hnsw_config, + timeout=int(self._client_config.timeout), + ) + + # create group_id payload index + self._client.create_payload_index( + collection_name, Field.GROUP_KEY.value, field_schema=PayloadSchemaType.KEYWORD + ) + # create doc_id payload index + self._client.create_payload_index( + collection_name, Field.DOC_ID.value, field_schema=PayloadSchemaType.KEYWORD + ) + # create full text index + text_index_params = TextIndexParams( + type=TextIndexType.TEXT, + tokenizer=TokenizerType.MULTILINGUAL, + min_token_len=2, + max_token_len=20, + lowercase=True, + ) + self._client.create_payload_index( + collection_name, Field.CONTENT_KEY.value, field_schema=text_index_params + ) + redis_client.set(collection_exist_cache_key, 1, ex=3600) + + def add_texts(self, documents: list[Document], embeddings: list[list[float]], **kwargs): + uuids = self._get_uuids(documents) + texts = [d.page_content for d in documents] + metadatas = [d.metadata for d in documents] + + added_ids = [] + for batch_ids, points in self._generate_rest_batches(texts, embeddings, metadatas, uuids, 64, self._group_id): + self._client.upsert(collection_name=self._collection_name, points=points) + added_ids.extend(batch_ids) + + return added_ids + + def _generate_rest_batches( + self, + texts: Iterable[str], + embeddings: list[list[float]], + metadatas: Optional[list[dict]] = None, + ids: Optional[Sequence[str]] = None, + batch_size: int = 64, + group_id: Optional[str] = None, + ) -> Generator[tuple[list[str], list[rest.PointStruct]], None, None]: + from qdrant_client.http import models as rest + + texts_iterator = iter(texts) + embeddings_iterator = iter(embeddings) + metadatas_iterator = iter(metadatas or []) + ids_iterator = iter(ids or [uuid.uuid4().hex for _ in iter(texts)]) + while batch_texts := list(islice(texts_iterator, batch_size)): + # Take the corresponding metadata and id for each text in a batch + batch_metadatas = list(islice(metadatas_iterator, batch_size)) or None + batch_ids = list(islice(ids_iterator, batch_size)) + + # Generate the embeddings for all the texts in a batch + batch_embeddings = list(islice(embeddings_iterator, batch_size)) + + points = [ + rest.PointStruct( + id=point_id, + vector=vector, + payload=payload, + ) + for point_id, vector, payload in zip( + batch_ids, + batch_embeddings, + self._build_payloads( + batch_texts, + batch_metadatas, + Field.CONTENT_KEY.value, + Field.METADATA_KEY.value, + group_id, + Field.GROUP_KEY.value, + ), + ) + ] + + yield batch_ids, points + + @classmethod + def _build_payloads( + cls, + texts: Iterable[str], + metadatas: Optional[list[dict]], + content_payload_key: str, + metadata_payload_key: str, + group_id: str, + group_payload_key: str, + ) -> list[dict]: + payloads = [] + for i, text in enumerate(texts): + if text is None: + raise ValueError( + "At least one of the texts is None. Please remove it before " + "calling .from_texts or .add_texts on Qdrant instance." + ) + metadata = metadatas[i] if metadatas is not None else None + payloads.append({content_payload_key: text, metadata_payload_key: metadata, group_payload_key: group_id}) + + return payloads + + def delete_by_metadata_field(self, key: str, value: str): + from qdrant_client.http import models + from qdrant_client.http.exceptions import UnexpectedResponse + + try: + filter = models.Filter( + must=[ + models.FieldCondition( + key=f"metadata.{key}", + match=models.MatchValue(value=value), + ), + ], + ) + + self._reload_if_needed() + + self._client.delete( + collection_name=self._collection_name, + points_selector=FilterSelector(filter=filter), + ) + except UnexpectedResponse as e: + # Collection does not exist, so return + if e.status_code == 404: + return + # Some other error occurred, so re-raise the exception + else: + raise e + + def delete(self): + from qdrant_client.http.exceptions import UnexpectedResponse + + try: + self._client.delete_collection(collection_name=self._collection_name) + except UnexpectedResponse as e: + # Collection does not exist, so return + if e.status_code == 404: + return + # Some other error occurred, so re-raise the exception + else: + raise e + + def delete_by_ids(self, ids: list[str]) -> None: + from qdrant_client.http import models + from qdrant_client.http.exceptions import UnexpectedResponse + + for node_id in ids: + try: + filter = models.Filter( + must=[ + models.FieldCondition( + key="metadata.doc_id", + match=models.MatchValue(value=node_id), + ), + ], + ) + self._client.delete( + collection_name=self._collection_name, + points_selector=FilterSelector(filter=filter), + ) + except UnexpectedResponse as e: + # Collection does not exist, so return + if e.status_code == 404: + return + # Some other error occurred, so re-raise the exception + else: + raise e + + def text_exists(self, id: str) -> bool: + all_collection_name = [] + collections_response = self._client.get_collections() + collection_list = collections_response.collections + for collection in collection_list: + all_collection_name.append(collection.name) + if self._collection_name not in all_collection_name: + return False + response = self._client.retrieve(collection_name=self._collection_name, ids=[id]) + + return len(response) > 0 + + def search_by_vector(self, query_vector: list[float], **kwargs: Any) -> list[Document]: + from qdrant_client.http import models + + filter = models.Filter( + must=[ + models.FieldCondition( + key="group_id", + match=models.MatchValue(value=self._group_id), + ), + ], + ) + results = self._client.search( + collection_name=self._collection_name, + query_vector=query_vector, + query_filter=filter, + limit=kwargs.get("top_k", 4), + with_payload=True, + with_vectors=True, + score_threshold=kwargs.get("score_threshold", 0.0), + ) + docs = [] + for result in results: + metadata = result.payload.get(Field.METADATA_KEY.value) or {} + # duplicate check score threshold + score_threshold = kwargs.get("score_threshold") or 0.0 + if result.score > score_threshold: + metadata["score"] = result.score + doc = Document( + page_content=result.payload.get(Field.CONTENT_KEY.value), + metadata=metadata, + ) + docs.append(doc) + # Sort the documents by score in descending order + docs = sorted(docs, key=lambda x: x.metadata["score"], reverse=True) + return docs + + def search_by_full_text(self, query: str, **kwargs: Any) -> list[Document]: + """Return docs most similar by bm25. + Returns: + List of documents most similar to the query text and distance for each. + """ + from qdrant_client.http import models + + scroll_filter = models.Filter( + must=[ + models.FieldCondition( + key="page_content", + match=models.MatchText(text=query), + ) + ] + ) + response = self._client.scroll( + collection_name=self._collection_name, + scroll_filter=scroll_filter, + limit=kwargs.get("top_k", 2), + with_payload=True, + with_vectors=True, + ) + results = response[0] + documents = [] + for result in results: + if result: + document = self._document_from_scored_point(result, Field.CONTENT_KEY.value, Field.METADATA_KEY.value) + document.metadata["vector"] = result.vector + documents.append(document) + + return documents + + def _reload_if_needed(self): + if isinstance(self._client, QdrantLocal): + self._client = cast(QdrantLocal, self._client) + self._client._load() + + @classmethod + def _document_from_scored_point( + cls, + scored_point: Any, + content_payload_key: str, + metadata_payload_key: str, + ) -> Document: + return Document( + page_content=scored_point.payload.get(content_payload_key), + metadata=scored_point.payload.get(metadata_payload_key) or {}, + ) + + +class TidbOnQdrantVectorFactory(AbstractVectorFactory): + def init_vector(self, dataset: Dataset, attributes: list, embeddings: Embeddings) -> TidbOnQdrantVector: + tidb_auth_binding = ( + db.session.query(TidbAuthBinding).filter(TidbAuthBinding.tenant_id == dataset.tenant_id).one_or_none() + ) + if not tidb_auth_binding: + idle_tidb_auth_binding = ( + db.session.query(TidbAuthBinding) + .filter(TidbAuthBinding.active == False, TidbAuthBinding.status == "ACTIVE") + .limit(1) + .one_or_none() + ) + if idle_tidb_auth_binding: + idle_tidb_auth_binding.active = True + idle_tidb_auth_binding.tenant_id = dataset.tenant_id + db.session.commit() + TIDB_ON_QDRANT_API_KEY = f"{idle_tidb_auth_binding.account}:{idle_tidb_auth_binding.password}" + else: + with redis_client.lock("create_tidb_serverless_cluster_lock", timeout=900): + tidb_auth_binding = ( + db.session.query(TidbAuthBinding) + .filter(TidbAuthBinding.tenant_id == dataset.tenant_id) + .one_or_none() + ) + if tidb_auth_binding: + TIDB_ON_QDRANT_API_KEY = f"{tidb_auth_binding.account}:{tidb_auth_binding.password}" + + else: + new_cluster = TidbService.create_tidb_serverless_cluster( + dify_config.TIDB_PROJECT_ID, + dify_config.TIDB_API_URL, + dify_config.TIDB_IAM_API_URL, + dify_config.TIDB_PUBLIC_KEY, + dify_config.TIDB_PRIVATE_KEY, + dify_config.TIDB_REGION, + ) + new_tidb_auth_binding = TidbAuthBinding( + cluster_id=new_cluster["cluster_id"], + cluster_name=new_cluster["cluster_name"], + account=new_cluster["account"], + password=new_cluster["password"], + tenant_id=dataset.tenant_id, + active=True, + status="ACTIVE", + ) + db.session.add(new_tidb_auth_binding) + db.session.commit() + TIDB_ON_QDRANT_API_KEY = f"{new_tidb_auth_binding.account}:{new_tidb_auth_binding.password}" + + else: + TIDB_ON_QDRANT_API_KEY = f"{tidb_auth_binding.account}:{tidb_auth_binding.password}" + + if dataset.index_struct_dict: + class_prefix: str = dataset.index_struct_dict["vector_store"]["class_prefix"] + collection_name = class_prefix + else: + dataset_id = dataset.id + collection_name = Dataset.gen_collection_name_by_id(dataset_id) + dataset.index_struct = json.dumps(self.gen_index_struct_dict(VectorType.TIDB_ON_QDRANT, collection_name)) + + config = current_app.config + + return TidbOnQdrantVector( + collection_name=collection_name, + group_id=dataset.id, + config=TidbOnQdrantConfig( + endpoint=dify_config.TIDB_ON_QDRANT_URL, + api_key=TIDB_ON_QDRANT_API_KEY, + root_path=config.root_path, + timeout=dify_config.TIDB_ON_QDRANT_CLIENT_TIMEOUT, + grpc_port=dify_config.TIDB_ON_QDRANT_GRPC_PORT, + prefer_grpc=dify_config.TIDB_ON_QDRANT_GRPC_ENABLED, + ), + ) + + def create_tidb_serverless_cluster(self, tidb_config: TidbConfig, display_name: str, region: str): + """ + Creates a new TiDB Serverless cluster. + :param tidb_config: The configuration for the TiDB Cloud API. + :param display_name: The user-friendly display name of the cluster (required). + :param region: The region where the cluster will be created (required). + + :return: The response from the API. + """ + region_object = { + "name": region, + } + + labels = { + "tidb.cloud/project": "1372813089454548012", + } + cluster_data = {"displayName": display_name, "region": region_object, "labels": labels} + + response = requests.post( + f"{tidb_config.api_url}/clusters", + json=cluster_data, + auth=HTTPDigestAuth(tidb_config.public_key, tidb_config.private_key), + ) + + if response.status_code == 200: + return response.json() + else: + response.raise_for_status() + + def change_tidb_serverless_root_password(self, tidb_config: TidbConfig, cluster_id: str, new_password: str): + """ + Changes the root password of a specific TiDB Serverless cluster. + + :param tidb_config: The configuration for the TiDB Cloud API. + :param cluster_id: The ID of the cluster for which the password is to be changed (required). + :param new_password: The new password for the root user (required). + :return: The response from the API. + """ + + body = {"password": new_password} + + response = requests.put( + f"{tidb_config.api_url}/clusters/{cluster_id}/password", + json=body, + auth=HTTPDigestAuth(tidb_config.public_key, tidb_config.private_key), + ) + + if response.status_code == 200: + return response.json() + else: + response.raise_for_status() diff --git a/api/core/rag/datasource/vdb/tidb_on_qdrant/tidb_service.py b/api/core/rag/datasource/vdb/tidb_on_qdrant/tidb_service.py new file mode 100644 index 0000000000..f10d6339ee --- /dev/null +++ b/api/core/rag/datasource/vdb/tidb_on_qdrant/tidb_service.py @@ -0,0 +1,250 @@ +import time +import uuid + +import requests +from requests.auth import HTTPDigestAuth + +from extensions.ext_database import db +from extensions.ext_redis import redis_client +from models.dataset import TidbAuthBinding + + +class TidbService: + @staticmethod + def create_tidb_serverless_cluster( + project_id: str, api_url: str, iam_url: str, public_key: str, private_key: str, region: str + ): + """ + Creates a new TiDB Serverless cluster. + :param project_id: The project ID of the TiDB Cloud project (required). + :param api_url: The URL of the TiDB Cloud API (required). + :param iam_url: The URL of the TiDB Cloud IAM API (required). + :param public_key: The public key for the API (required). + :param private_key: The private key for the API (required). + :param display_name: The user-friendly display name of the cluster (required). + :param region: The region where the cluster will be created (required). + + :return: The response from the API. + """ + + region_object = { + "name": region, + } + + labels = { + "tidb.cloud/project": project_id, + } + + spending_limit = { + "monthly": 100, + } + password = str(uuid.uuid4()).replace("-", "")[:16] + display_name = str(uuid.uuid4()).replace("-", "")[:16] + cluster_data = { + "displayName": display_name, + "region": region_object, + "labels": labels, + "spendingLimit": spending_limit, + "rootPassword": password, + } + + response = requests.post(f"{api_url}/clusters", json=cluster_data, auth=HTTPDigestAuth(public_key, private_key)) + + if response.status_code == 200: + response_data = response.json() + cluster_id = response_data["clusterId"] + retry_count = 0 + max_retries = 30 + while retry_count < max_retries: + cluster_response = TidbService.get_tidb_serverless_cluster(api_url, public_key, private_key, cluster_id) + if cluster_response["state"] == "ACTIVE": + user_prefix = cluster_response["userPrefix"] + return { + "cluster_id": cluster_id, + "cluster_name": display_name, + "account": f"{user_prefix}.root", + "password": password, + } + time.sleep(30) # wait 30 seconds before retrying + retry_count += 1 + else: + response.raise_for_status() + + @staticmethod + def delete_tidb_serverless_cluster(api_url: str, public_key: str, private_key: str, cluster_id: str): + """ + Deletes a specific TiDB Serverless cluster. + + :param api_url: The URL of the TiDB Cloud API (required). + :param public_key: The public key for the API (required). + :param private_key: The private key for the API (required). + :param cluster_id: The ID of the cluster to be deleted (required). + :return: The response from the API. + """ + + response = requests.delete(f"{api_url}/clusters/{cluster_id}", auth=HTTPDigestAuth(public_key, private_key)) + + if response.status_code == 200: + return response.json() + else: + response.raise_for_status() + + @staticmethod + def get_tidb_serverless_cluster(api_url: str, public_key: str, private_key: str, cluster_id: str): + """ + Deletes a specific TiDB Serverless cluster. + + :param api_url: The URL of the TiDB Cloud API (required). + :param public_key: The public key for the API (required). + :param private_key: The private key for the API (required). + :param cluster_id: The ID of the cluster to be deleted (required). + :return: The response from the API. + """ + + response = requests.get(f"{api_url}/clusters/{cluster_id}", auth=HTTPDigestAuth(public_key, private_key)) + + if response.status_code == 200: + return response.json() + else: + response.raise_for_status() + + @staticmethod + def change_tidb_serverless_root_password( + api_url: str, public_key: str, private_key: str, cluster_id: str, account: str, new_password: str + ): + """ + Changes the root password of a specific TiDB Serverless cluster. + + :param api_url: The URL of the TiDB Cloud API (required). + :param public_key: The public key for the API (required). + :param private_key: The private key for the API (required). + :param cluster_id: The ID of the cluster for which the password is to be changed (required).+ + :param account: The account for which the password is to be changed (required). + :param new_password: The new password for the root user (required). + :return: The response from the API. + """ + + body = {"password": new_password, "builtinRole": "role_admin", "customRoles": []} + + response = requests.patch( + f"{api_url}/clusters/{cluster_id}/sqlUsers/{account}", + json=body, + auth=HTTPDigestAuth(public_key, private_key), + ) + + if response.status_code == 200: + return response.json() + else: + response.raise_for_status() + + @staticmethod + def batch_update_tidb_serverless_cluster_status( + tidb_serverless_list: list[TidbAuthBinding], + project_id: str, + api_url: str, + iam_url: str, + public_key: str, + private_key: str, + ) -> list[dict]: + """ + Update the status of a new TiDB Serverless cluster. + :param project_id: The project ID of the TiDB Cloud project (required). + :param api_url: The URL of the TiDB Cloud API (required). + :param iam_url: The URL of the TiDB Cloud IAM API (required). + :param public_key: The public key for the API (required). + :param private_key: The private key for the API (required). + :param display_name: The user-friendly display name of the cluster (required). + :param region: The region where the cluster will be created (required). + + :return: The response from the API. + """ + clusters = [] + tidb_serverless_list_map = {item.cluster_id: item for item in tidb_serverless_list} + cluster_ids = [item.cluster_id for item in tidb_serverless_list] + params = {"clusterIds": cluster_ids, "view": "FULL"} + response = requests.get( + f"{api_url}/clusters:batchGet", params=params, auth=HTTPDigestAuth(public_key, private_key) + ) + + if response.status_code == 200: + response_data = response.json() + cluster_infos = [] + for item in response_data["clusters"]: + state = item["state"] + userPrefix = item["userPrefix"] + if state == "ACTIVE" and len(userPrefix) > 0: + cluster_info = tidb_serverless_list_map[item["clusterId"]] + cluster_info.status = "ACTIVE" + cluster_info.account = f"{userPrefix}.root" + db.session.add(cluster_info) + db.session.commit() + else: + response.raise_for_status() + + @staticmethod + def batch_create_tidb_serverless_cluster( + batch_size: int, project_id: str, api_url: str, iam_url: str, public_key: str, private_key: str, region: str + ) -> list[dict]: + """ + Creates a new TiDB Serverless cluster. + :param project_id: The project ID of the TiDB Cloud project (required). + :param api_url: The URL of the TiDB Cloud API (required). + :param iam_url: The URL of the TiDB Cloud IAM API (required). + :param public_key: The public key for the API (required). + :param private_key: The private key for the API (required). + :param display_name: The user-friendly display name of the cluster (required). + :param region: The region where the cluster will be created (required). + + :return: The response from the API. + """ + clusters = [] + for _ in range(batch_size): + region_object = { + "name": region, + } + + labels = { + "tidb.cloud/project": project_id, + } + + spending_limit = { + "monthly": 10, + } + password = str(uuid.uuid4()).replace("-", "")[:16] + display_name = str(uuid.uuid4()).replace("-", "") + cluster_data = { + "cluster": { + "displayName": display_name, + "region": region_object, + "labels": labels, + "spendingLimit": spending_limit, + "rootPassword": password, + } + } + cache_key = f"tidb_serverless_cluster_password:{display_name}" + redis_client.setex(cache_key, 3600, password) + clusters.append(cluster_data) + + request_body = {"requests": clusters} + response = requests.post( + f"{api_url}/clusters:batchCreate", json=request_body, auth=HTTPDigestAuth(public_key, private_key) + ) + + if response.status_code == 200: + response_data = response.json() + cluster_infos = [] + for item in response_data["clusters"]: + cache_key = f"tidb_serverless_cluster_password:{item['displayName']}" + password = redis_client.get(cache_key) + if not password: + continue + cluster_info = { + "cluster_id": item["clusterId"], + "cluster_name": item["displayName"], + "account": "root", + "password": password.decode("utf-8"), + } + cluster_infos.append(cluster_info) + return cluster_infos + else: + response.raise_for_status() diff --git a/api/core/rag/datasource/vdb/vector_factory.py b/api/core/rag/datasource/vdb/vector_factory.py index 9ea3cf4b6b..59a5aadacd 100644 --- a/api/core/rag/datasource/vdb/vector_factory.py +++ b/api/core/rag/datasource/vdb/vector_factory.py @@ -9,8 +9,9 @@ from core.rag.datasource.vdb.vector_type import VectorType from core.rag.embedding.cached_embedding import CacheEmbedding from core.rag.embedding.embedding_base import Embeddings from core.rag.models.document import Document +from extensions.ext_database import db from extensions.ext_redis import redis_client -from models.dataset import Dataset +from models.dataset import Dataset, Whitelist class AbstractVectorFactory(ABC): @@ -35,8 +36,18 @@ class Vector: def _init_vector(self) -> BaseVector: vector_type = dify_config.VECTOR_STORE + if self._dataset.index_struct_dict: vector_type = self._dataset.index_struct_dict["type"] + else: + if dify_config.VECTOR_STORE_WHITELIST_ENABLE: + whitelist = ( + db.session.query(Whitelist) + .filter(Whitelist.tenant_id == self._dataset.tenant_id, Whitelist.category == "vector_db") + .one_or_none() + ) + if whitelist: + vector_type = VectorType.TIDB_ON_QDRANT if not vector_type: raise ValueError("Vector store must be specified.") @@ -115,6 +126,10 @@ class Vector: from core.rag.datasource.vdb.upstash.upstash_vector import UpstashVectorFactory return UpstashVectorFactory + case VectorType.TIDB_ON_QDRANT: + from core.rag.datasource.vdb.tidb_on_qdrant.tidb_on_qdrant_vector import TidbOnQdrantVectorFactory + + return TidbOnQdrantVectorFactory case _: raise ValueError(f"Vector store {vector_type} is not supported.") diff --git a/api/core/rag/datasource/vdb/vector_type.py b/api/core/rag/datasource/vdb/vector_type.py index 30aa814553..3b6df94f78 100644 --- a/api/core/rag/datasource/vdb/vector_type.py +++ b/api/core/rag/datasource/vdb/vector_type.py @@ -19,3 +19,4 @@ class VectorType(str, Enum): BAIDU = "baidu" VIKINGDB = "vikingdb" UPSTASH = "upstash" + TIDB_ON_QDRANT = "tidb_on_qdrant" diff --git a/api/extensions/ext_celery.py b/api/extensions/ext_celery.py index b9b019373d..504899c276 100644 --- a/api/extensions/ext_celery.py +++ b/api/extensions/ext_celery.py @@ -1,6 +1,7 @@ from datetime import timedelta from celery import Celery, Task +from celery.schedules import crontab from flask import Flask from configs import dify_config @@ -55,6 +56,8 @@ def init_app(app: Flask) -> Celery: imports = [ "schedule.clean_embedding_cache_task", "schedule.clean_unused_datasets_task", + "schedule.create_tidb_serverless_task", + "schedule.update_tidb_serverless_status_task", ] day = dify_config.CELERY_BEAT_SCHEDULER_TIME beat_schedule = { @@ -66,6 +69,14 @@ def init_app(app: Flask) -> Celery: "task": "schedule.clean_unused_datasets_task.clean_unused_datasets_task", "schedule": timedelta(days=day), }, + "create_tidb_serverless_task": { + "task": "schedule.create_tidb_serverless_task.create_tidb_serverless_task", + "schedule": crontab(minute="0", hour="*"), + }, + "update_tidb_serverless_status_task": { + "task": "schedule.update_tidb_serverless_status_task.update_tidb_serverless_status_task", + "schedule": crontab(minute="30", hour="*"), + }, } celery_app.conf.update(beat_schedule=beat_schedule, imports=imports) diff --git a/api/migrations/versions/2024_08_15_0956-0251a1c768cc_add_tidb_auth_binding.py b/api/migrations/versions/2024_08_15_0956-0251a1c768cc_add_tidb_auth_binding.py new file mode 100644 index 0000000000..ca2e410442 --- /dev/null +++ b/api/migrations/versions/2024_08_15_0956-0251a1c768cc_add_tidb_auth_binding.py @@ -0,0 +1,51 @@ +"""add-tidb-auth-binding + +Revision ID: 0251a1c768cc +Revises: 63a83fcf12ba +Create Date: 2024-08-15 09:56:59.012490 + +""" +import sqlalchemy as sa +from alembic import op + +import models as models + +# revision identifiers, used by Alembic. +revision = '0251a1c768cc' +down_revision = 'bbadea11becb' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('tidb_auth_bindings', + sa.Column('id', models.types.StringUUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False), + sa.Column('tenant_id', models.types.StringUUID(), nullable=True), + sa.Column('cluster_id', sa.String(length=255), nullable=False), + sa.Column('cluster_name', sa.String(length=255), nullable=False), + sa.Column('active', sa.Boolean(), server_default=sa.text('false'), nullable=False), + sa.Column('status', sa.String(length=255), server_default=sa.text("'CREATING'::character varying"), nullable=False), + sa.Column('account', sa.String(length=255), nullable=False), + sa.Column('password', sa.String(length=255), nullable=False), + sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False), + sa.PrimaryKeyConstraint('id', name='tidb_auth_bindings_pkey') + ) + with op.batch_alter_table('tidb_auth_bindings', schema=None) as batch_op: + batch_op.create_index('tidb_auth_bindings_active_idx', ['active'], unique=False) + batch_op.create_index('tidb_auth_bindings_status_idx', ['status'], unique=False) + batch_op.create_index('tidb_auth_bindings_created_at_idx', ['created_at'], unique=False) + batch_op.create_index('tidb_auth_bindings_tenant_idx', ['tenant_id'], unique=False) + + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('tidb_auth_bindings', schema=None) as batch_op: + batch_op.drop_index('tidb_auth_bindings_tenant_idx') + batch_op.drop_index('tidb_auth_bindings_created_at_idx') + batch_op.drop_index('tidb_auth_bindings_active_idx') + batch_op.drop_index('tidb_auth_bindings_status_idx') + op.drop_table('tidb_auth_bindings') + # ### end Alembic commands ### diff --git a/api/migrations/versions/2024_10_22_0959-43fa78bc3b7d_add_white_list.py b/api/migrations/versions/2024_10_22_0959-43fa78bc3b7d_add_white_list.py new file mode 100644 index 0000000000..9daf148bc4 --- /dev/null +++ b/api/migrations/versions/2024_10_22_0959-43fa78bc3b7d_add_white_list.py @@ -0,0 +1,42 @@ +"""add_white_list + +Revision ID: 43fa78bc3b7d +Revises: 0251a1c768cc +Create Date: 2024-10-22 09:59:23.713716 + +""" +from alembic import op +import models as models +import sqlalchemy as sa +from sqlalchemy.dialects import postgresql + +# revision identifiers, used by Alembic. +revision = '43fa78bc3b7d' +down_revision = '0251a1c768cc' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('whitelists', + sa.Column('id', models.types.StringUUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False), + sa.Column('tenant_id', models.types.StringUUID(), nullable=True), + sa.Column('category', sa.String(length=255), nullable=False), + sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False), + sa.PrimaryKeyConstraint('id', name='whitelists_pkey') + ) + with op.batch_alter_table('whitelists', schema=None) as batch_op: + batch_op.create_index('whitelists_tenant_idx', ['tenant_id'], unique=False) + + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + + with op.batch_alter_table('whitelists', schema=None) as batch_op: + batch_op.drop_index('whitelists_tenant_idx') + + op.drop_table('whitelists') + # ### end Alembic commands ### diff --git a/api/models/dataset.py b/api/models/dataset.py index 4e2ccab7e8..459bfa47c0 100644 --- a/api/models/dataset.py +++ b/api/models/dataset.py @@ -704,6 +704,38 @@ class DatasetCollectionBinding(db.Model): created_at = db.Column(db.DateTime, nullable=False, server_default=db.text("CURRENT_TIMESTAMP(0)")) +class TidbAuthBinding(db.Model): + __tablename__ = "tidb_auth_bindings" + __table_args__ = ( + db.PrimaryKeyConstraint("id", name="tidb_auth_bindings_pkey"), + db.Index("tidb_auth_bindings_tenant_idx", "tenant_id"), + db.Index("tidb_auth_bindings_active_idx", "active"), + db.Index("tidb_auth_bindings_created_at_idx", "created_at"), + db.Index("tidb_auth_bindings_status_idx", "status"), + ) + id = db.Column(StringUUID, primary_key=True, server_default=db.text("uuid_generate_v4()")) + tenant_id = db.Column(StringUUID, nullable=True) + cluster_id = db.Column(db.String(255), nullable=False) + cluster_name = db.Column(db.String(255), nullable=False) + active = db.Column(db.Boolean, nullable=False, server_default=db.text("false")) + status = db.Column(db.String(255), nullable=False, server_default=db.text("CREATING")) + account = db.Column(db.String(255), nullable=False) + password = db.Column(db.String(255), nullable=False) + created_at = db.Column(db.DateTime, nullable=False, server_default=db.text("CURRENT_TIMESTAMP(0)")) + + +class Whitelist(db.Model): + __tablename__ = "whitelists" + __table_args__ = ( + db.PrimaryKeyConstraint("id", name="whitelists_pkey"), + db.Index("whitelists_tenant_idx", "tenant_id"), + ) + id = db.Column(StringUUID, primary_key=True, server_default=db.text("uuid_generate_v4()")) + tenant_id = db.Column(StringUUID, nullable=True) + category = db.Column(db.String(255), nullable=False) + created_at = db.Column(db.DateTime, nullable=False, server_default=db.text("CURRENT_TIMESTAMP(0)")) + + class DatasetPermission(db.Model): __tablename__ = "dataset_permissions" __table_args__ = ( diff --git a/api/schedule/create_tidb_serverless_task.py b/api/schedule/create_tidb_serverless_task.py new file mode 100644 index 0000000000..42d6c04beb --- /dev/null +++ b/api/schedule/create_tidb_serverless_task.py @@ -0,0 +1,56 @@ +import time + +import click + +import app +from configs import dify_config +from core.rag.datasource.vdb.tidb_on_qdrant.tidb_service import TidbService +from extensions.ext_database import db +from models.dataset import TidbAuthBinding + + +@app.celery.task(queue="dataset") +def create_tidb_serverless_task(): + click.echo(click.style("Start create tidb serverless task.", fg="green")) + tidb_serverless_number = dify_config.TIDB_SERVERLESS_NUMBER + start_at = time.perf_counter() + while True: + try: + # check the number of idle tidb serverless + idle_tidb_serverless_number = TidbAuthBinding.query.filter(TidbAuthBinding.active == False).count() + if idle_tidb_serverless_number >= tidb_serverless_number: + break + # create tidb serverless + iterations_per_thread = 20 + create_clusters(iterations_per_thread) + + except Exception as e: + click.echo(click.style(f"Error: {e}", fg="red")) + break + + end_at = time.perf_counter() + click.echo(click.style("Create tidb serverless task success latency: {}".format(end_at - start_at), fg="green")) + + +def create_clusters(batch_size): + try: + new_clusters = TidbService.batch_create_tidb_serverless_cluster( + batch_size, + dify_config.TIDB_PROJECT_ID, + dify_config.TIDB_API_URL, + dify_config.TIDB_IAM_API_URL, + dify_config.TIDB_PUBLIC_KEY, + dify_config.TIDB_PRIVATE_KEY, + dify_config.TIDB_REGION, + ) + for new_cluster in new_clusters: + tidb_auth_binding = TidbAuthBinding( + cluster_id=new_cluster["cluster_id"], + cluster_name=new_cluster["cluster_name"], + account=new_cluster["account"], + password=new_cluster["password"], + ) + db.session.add(tidb_auth_binding) + db.session.commit() + except Exception as e: + click.echo(click.style(f"Error: {e}", fg="red")) diff --git a/api/schedule/update_tidb_serverless_status_task.py b/api/schedule/update_tidb_serverless_status_task.py new file mode 100644 index 0000000000..07eca3173b --- /dev/null +++ b/api/schedule/update_tidb_serverless_status_task.py @@ -0,0 +1,51 @@ +import time + +import click + +import app +from configs import dify_config +from core.rag.datasource.vdb.tidb_on_qdrant.tidb_service import TidbService +from models.dataset import TidbAuthBinding + + +@app.celery.task(queue="dataset") +def update_tidb_serverless_status_task(): + click.echo(click.style("Update tidb serverless status task.", fg="green")) + start_at = time.perf_counter() + while True: + try: + # check the number of idle tidb serverless + tidb_serverless_list = TidbAuthBinding.query.filter( + TidbAuthBinding.active == False, TidbAuthBinding.status == "CREATING" + ).all() + if len(tidb_serverless_list) == 0: + break + # update tidb serverless status + iterations_per_thread = 20 + update_clusters(tidb_serverless_list) + + except Exception as e: + click.echo(click.style(f"Error: {e}", fg="red")) + break + + end_at = time.perf_counter() + click.echo( + click.style("Update tidb serverless status task success latency: {}".format(end_at - start_at), fg="green") + ) + + +def update_clusters(tidb_serverless_list: list[TidbAuthBinding]): + try: + # batch 20 + for i in range(0, len(tidb_serverless_list), 20): + items = tidb_serverless_list[i : i + 20] + TidbService.batch_update_tidb_serverless_cluster_status( + items, + dify_config.TIDB_PROJECT_ID, + dify_config.TIDB_API_URL, + dify_config.TIDB_IAM_API_URL, + dify_config.TIDB_PUBLIC_KEY, + dify_config.TIDB_PRIVATE_KEY, + ) + except Exception as e: + click.echo(click.style(f"Error: {e}", fg="red")) diff --git a/api/services/auth/jina.py b/api/services/auth/jina.py new file mode 100644 index 0000000000..de898a1f94 --- /dev/null +++ b/api/services/auth/jina.py @@ -0,0 +1,44 @@ +import json + +import requests + +from services.auth.api_key_auth_base import ApiKeyAuthBase + + +class JinaAuth(ApiKeyAuthBase): + def __init__(self, credentials: dict): + super().__init__(credentials) + auth_type = credentials.get("auth_type") + if auth_type != "bearer": + raise ValueError("Invalid auth type, Jina Reader auth type must be Bearer") + self.api_key = credentials.get("config").get("api_key", None) + + if not self.api_key: + raise ValueError("No API key provided") + + def validate_credentials(self): + headers = self._prepare_headers() + options = { + "url": "https://example.com", + } + response = self._post_request("https://r.jina.ai", options, headers) + if response.status_code == 200: + return True + else: + self._handle_error(response) + + def _prepare_headers(self): + return {"Content-Type": "application/json", "Authorization": f"Bearer {self.api_key}"} + + def _post_request(self, url, data, headers): + return requests.post(url, headers=headers, json=data) + + def _handle_error(self, response): + if response.status_code in {402, 409, 500}: + error_message = response.json().get("error", "Unknown error occurred") + raise Exception(f"Failed to authorize. Status code: {response.status_code}. Error: {error_message}") + else: + if response.text: + error_message = json.loads(response.text).get("error", "Unknown error occurred") + raise Exception(f"Failed to authorize. Status code: {response.status_code}. Error: {error_message}") + raise Exception(f"Unexpected error occurred while trying to authorize. Status code: {response.status_code}") diff --git a/web/app/components/datasets/create/website/jina-reader/base/checkbox-with-label.tsx b/web/app/components/datasets/create/website/jina-reader/base/checkbox-with-label.tsx new file mode 100644 index 0000000000..25d40fe076 --- /dev/null +++ b/web/app/components/datasets/create/website/jina-reader/base/checkbox-with-label.tsx @@ -0,0 +1,40 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import cn from '@/utils/classnames' +import Checkbox from '@/app/components/base/checkbox' +import Tooltip from '@/app/components/base/tooltip' + +type Props = { + className?: string + isChecked: boolean + onChange: (isChecked: boolean) => void + label: string + labelClassName?: string + tooltip?: string +} + +const CheckboxWithLabel: FC = ({ + className = '', + isChecked, + onChange, + label, + labelClassName, + tooltip, +}) => { + return ( +
+ } + triggerClassName='ml-0.5 w-4 h-4' + /> + )} + + ) +} +export default React.memo(CheckboxWithLabel) diff --git a/web/app/components/datasets/create/website/jina-reader/base/error-message.tsx b/web/app/components/datasets/create/website/jina-reader/base/error-message.tsx new file mode 100644 index 0000000000..aa337ec4bf --- /dev/null +++ b/web/app/components/datasets/create/website/jina-reader/base/error-message.tsx @@ -0,0 +1,30 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import cn from '@/utils/classnames' +import { AlertTriangle } from '@/app/components/base/icons/src/vender/solid/alertsAndFeedback' + +type Props = { + className?: string + title: string + errorMsg?: string +} + +const ErrorMessage: FC = ({ + className, + title, + errorMsg, +}) => { + return ( +
+
+ +
{title}
+
+ {errorMsg && ( +
{errorMsg}
+ )} +
+ ) +} +export default React.memo(ErrorMessage) diff --git a/web/app/components/datasets/create/website/jina-reader/base/field.tsx b/web/app/components/datasets/create/website/jina-reader/base/field.tsx new file mode 100644 index 0000000000..5b5ca90c5d --- /dev/null +++ b/web/app/components/datasets/create/website/jina-reader/base/field.tsx @@ -0,0 +1,54 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import Input from './input' +import cn from '@/utils/classnames' +import Tooltip from '@/app/components/base/tooltip' + +type Props = { + className?: string + label: string + labelClassName?: string + value: string | number + onChange: (value: string | number) => void + isRequired?: boolean + placeholder?: string + isNumber?: boolean + tooltip?: string +} + +const Field: FC = ({ + className, + label, + labelClassName, + value, + onChange, + isRequired = false, + placeholder = '', + isNumber = false, + tooltip, +}) => { + return ( +
+
+
{label}
+ {isRequired && *} + {tooltip && ( + {tooltip}
+ } + triggerClassName='ml-0.5 w-4 h-4' + /> + )} +
+ +
+ ) +} +export default React.memo(Field) diff --git a/web/app/components/datasets/create/website/jina-reader/base/input.tsx b/web/app/components/datasets/create/website/jina-reader/base/input.tsx new file mode 100644 index 0000000000..7d2d2b609f --- /dev/null +++ b/web/app/components/datasets/create/website/jina-reader/base/input.tsx @@ -0,0 +1,58 @@ +'use client' +import type { FC } from 'react' +import React, { useCallback } from 'react' + +type Props = { + value: string | number + onChange: (value: string | number) => void + placeholder?: string + isNumber?: boolean +} + +const MIN_VALUE = 0 + +const Input: FC = ({ + value, + onChange, + placeholder = '', + isNumber = false, +}) => { + const handleChange = useCallback((e: React.ChangeEvent) => { + const value = e.target.value + if (isNumber) { + let numberValue = parseInt(value, 10) // integer only + if (isNaN(numberValue)) { + onChange('') + return + } + if (numberValue < MIN_VALUE) + numberValue = MIN_VALUE + + onChange(numberValue) + return + } + onChange(value) + }, [isNumber, onChange]) + + const otherOption = (() => { + if (isNumber) { + return { + min: MIN_VALUE, + } + } + return { + + } + })() + return ( + + ) +} +export default React.memo(Input) diff --git a/web/app/components/datasets/create/website/jina-reader/base/options-wrap.tsx b/web/app/components/datasets/create/website/jina-reader/base/options-wrap.tsx new file mode 100644 index 0000000000..652401a20f --- /dev/null +++ b/web/app/components/datasets/create/website/jina-reader/base/options-wrap.tsx @@ -0,0 +1,55 @@ +'use client' +import { useBoolean } from 'ahooks' +import type { FC } from 'react' +import React, { useEffect } from 'react' +import { useTranslation } from 'react-i18next' +import cn from '@/utils/classnames' +import { Settings04 } from '@/app/components/base/icons/src/vender/line/general' +import { ChevronRight } from '@/app/components/base/icons/src/vender/line/arrows' +const I18N_PREFIX = 'datasetCreation.stepOne.website' + +type Props = { + className?: string + children: React.ReactNode + controlFoldOptions?: number +} + +const OptionsWrap: FC = ({ + className = '', + children, + controlFoldOptions, +}) => { + const { t } = useTranslation() + + const [fold, { + toggle: foldToggle, + setTrue: foldHide, + }] = useBoolean(false) + + useEffect(() => { + if (controlFoldOptions) + foldHide() + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [controlFoldOptions]) + return ( +
+
+
+ +
{t(`${I18N_PREFIX}.options`)}
+
+ +
+ {!fold && ( +
+ {children} +
+ )} + +
+ ) +} +export default React.memo(OptionsWrap) diff --git a/web/app/components/datasets/create/website/jina-reader/base/url-input.tsx b/web/app/components/datasets/create/website/jina-reader/base/url-input.tsx new file mode 100644 index 0000000000..e6b0475874 --- /dev/null +++ b/web/app/components/datasets/create/website/jina-reader/base/url-input.tsx @@ -0,0 +1,48 @@ +'use client' +import type { FC } from 'react' +import React, { useCallback, useState } from 'react' +import { useTranslation } from 'react-i18next' +import Input from './input' +import Button from '@/app/components/base/button' + +const I18N_PREFIX = 'datasetCreation.stepOne.website' + +type Props = { + isRunning: boolean + onRun: (url: string) => void +} + +const UrlInput: FC = ({ + isRunning, + onRun, +}) => { + const { t } = useTranslation() + const [url, setUrl] = useState('') + const handleUrlChange = useCallback((url: string | number) => { + setUrl(url as string) + }, []) + const handleOnRun = useCallback(() => { + if (isRunning) + return + onRun(url) + }, [isRunning, onRun, url]) + + return ( +
+ + +
+ ) +} +export default React.memo(UrlInput) diff --git a/web/app/components/datasets/create/website/jina-reader/crawled-result-item.tsx b/web/app/components/datasets/create/website/jina-reader/crawled-result-item.tsx new file mode 100644 index 0000000000..5531d3e140 --- /dev/null +++ b/web/app/components/datasets/create/website/jina-reader/crawled-result-item.tsx @@ -0,0 +1,40 @@ +'use client' +import type { FC } from 'react' +import React, { useCallback } from 'react' +import { useTranslation } from 'react-i18next' +import cn from '@/utils/classnames' +import type { CrawlResultItem as CrawlResultItemType } from '@/models/datasets' +import Checkbox from '@/app/components/base/checkbox' + +type Props = { + payload: CrawlResultItemType + isChecked: boolean + isPreview: boolean + onCheckChange: (checked: boolean) => void + onPreview: () => void +} + +const CrawledResultItem: FC = ({ + isPreview, + payload, + isChecked, + onCheckChange, + onPreview, +}) => { + const { t } = useTranslation() + + const handleCheckChange = useCallback(() => { + onCheckChange(!isChecked) + }, [isChecked, onCheckChange]) + return ( +
+
+ +
{payload.title}
+
{t('datasetCreation.stepOne.website.preview')}
+
+
{payload.source_url}
+
+ ) +} +export default React.memo(CrawledResultItem) diff --git a/web/app/components/datasets/create/website/jina-reader/crawled-result.tsx b/web/app/components/datasets/create/website/jina-reader/crawled-result.tsx new file mode 100644 index 0000000000..2bd51e4d73 --- /dev/null +++ b/web/app/components/datasets/create/website/jina-reader/crawled-result.tsx @@ -0,0 +1,87 @@ +'use client' +import type { FC } from 'react' +import React, { useCallback } from 'react' +import { useTranslation } from 'react-i18next' +import CheckboxWithLabel from './base/checkbox-with-label' +import CrawledResultItem from './crawled-result-item' +import cn from '@/utils/classnames' +import type { CrawlResultItem } from '@/models/datasets' + +const I18N_PREFIX = 'datasetCreation.stepOne.website' + +type Props = { + className?: string + list: CrawlResultItem[] + checkedList: CrawlResultItem[] + onSelectedChange: (selected: CrawlResultItem[]) => void + onPreview: (payload: CrawlResultItem) => void + usedTime: number +} + +const CrawledResult: FC = ({ + className = '', + list, + checkedList, + onSelectedChange, + onPreview, + usedTime, +}) => { + const { t } = useTranslation() + + const isCheckAll = checkedList.length === list.length + + const handleCheckedAll = useCallback(() => { + if (!isCheckAll) + onSelectedChange(list) + + else + onSelectedChange([]) + }, [isCheckAll, list, onSelectedChange]) + + const handleItemCheckChange = useCallback((item: CrawlResultItem) => { + return (checked: boolean) => { + if (checked) + onSelectedChange([...checkedList, item]) + + else + onSelectedChange(checkedList.filter(checkedItem => checkedItem.source_url !== item.source_url)) + } + }, [checkedList, onSelectedChange]) + + const [previewIndex, setPreviewIndex] = React.useState(-1) + const handlePreview = useCallback((index: number) => { + return () => { + setPreviewIndex(index) + onPreview(list[index]) + } + }, [list, onPreview]) + + return ( +
+
+ +
{t(`${I18N_PREFIX}.scrapTimeInfo`, { + total: list.length, + time: usedTime.toFixed(1), + })}
+
+
+ {list.map((item, index) => ( + checkedItem.source_url === item.source_url)} + onCheckChange={handleItemCheckChange(item)} + /> + ))} +
+
+ ) +} +export default React.memo(CrawledResult) diff --git a/web/app/components/datasets/create/website/jina-reader/crawling.tsx b/web/app/components/datasets/create/website/jina-reader/crawling.tsx new file mode 100644 index 0000000000..ee26e7671a --- /dev/null +++ b/web/app/components/datasets/create/website/jina-reader/crawling.tsx @@ -0,0 +1,37 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import { useTranslation } from 'react-i18next' +import cn from '@/utils/classnames' +import { RowStruct } from '@/app/components/base/icons/src/public/other' + +type Props = { + className?: string + crawledNum: number + totalNum: number +} + +const Crawling: FC = ({ + className = '', + crawledNum, + totalNum, +}) => { + const { t } = useTranslation() + + return ( +
+
+ {t('datasetCreation.stepOne.website.totalPageScraped')} {crawledNum}/{totalNum} +
+ +
+ {['', '', '', ''].map((item, index) => ( +
+ +
+ ))} +
+
+ ) +} +export default React.memo(Crawling) diff --git a/web/app/components/datasets/create/website/jina-reader/mock-crawl-result.ts b/web/app/components/datasets/create/website/jina-reader/mock-crawl-result.ts new file mode 100644 index 0000000000..8fd5e6636f --- /dev/null +++ b/web/app/components/datasets/create/website/jina-reader/mock-crawl-result.ts @@ -0,0 +1,24 @@ +import type { CrawlResultItem } from '@/models/datasets' + +const result: CrawlResultItem[] = [ + { + title: 'Start the frontend Docker container separately', + markdown: 'Markdown 1', + description: 'Description 1', + source_url: 'https://example.com/1', + }, + { + title: 'Advanced Tool Integration', + markdown: 'Markdown 2', + description: 'Description 2', + source_url: 'https://example.com/2', + }, + { + title: 'Local Source Code Start | English | Dify', + markdown: 'Markdown 3', + description: 'Description 3', + source_url: 'https://example.com/3', + }, +] + +export default result From 59a32aaae69a9f218e1e36acdbf98ba7e7ddf54b Mon Sep 17 00:00:00 2001 From: Hash Brown Date: Fri, 25 Oct 2024 14:06:33 +0800 Subject: [PATCH 223/346] fix: exclude failed answer when sending messages (#9835) --- web/app/components/base/chat/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/app/components/base/chat/utils.ts b/web/app/components/base/chat/utils.ts index 9205225f9f..16357361cf 100644 --- a/web/app/components/base/chat/utils.ts +++ b/web/app/components/base/chat/utils.ts @@ -24,7 +24,7 @@ function getProcessedInputsFromUrlParams(): Record { function getLastAnswer(chatList: ChatItem[]) { for (let i = chatList.length - 1; i >= 0; i--) { const item = chatList[i] - if (item.isAnswer && !item.isOpeningStatement) + if (item.isAnswer && !item.id.startsWith('answer-placeholder-') && !item.isOpeningStatement) return item } return null From 1b5adf40da3a68613e8aa5a2ba8848e25ed5e964 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9D=9E=E6=B3=95=E6=93=8D=E4=BD=9C?= Date: Fri, 25 Oct 2024 14:59:55 +0800 Subject: [PATCH 224/346] fix: moonshot response_format raise error (#9847) --- api/core/model_runtime/model_providers/moonshot/llm/llm.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/api/core/model_runtime/model_providers/moonshot/llm/llm.py b/api/core/model_runtime/model_providers/moonshot/llm/llm.py index 01a2a07325..5c955c86d3 100644 --- a/api/core/model_runtime/model_providers/moonshot/llm/llm.py +++ b/api/core/model_runtime/model_providers/moonshot/llm/llm.py @@ -44,6 +44,9 @@ class MoonshotLargeLanguageModel(OAIAPICompatLargeLanguageModel): self._add_custom_parameters(credentials) self._add_function_call(model, credentials) user = user[:32] if user else None + # {"response_format": "json_object"} need convert to {"response_format": {"type": "json_object"}} + if "response_format" in model_parameters: + model_parameters["response_format"] = {"type": model_parameters.get("response_format")} return super()._invoke(model, credentials, prompt_messages, model_parameters, tools, stop, stream, user) def validate_credentials(self, model: str, credentials: dict) -> None: From 84a9d2d072cd501564b3121e2648593fcf779408 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9D=9E=E6=B3=95=E6=93=8D=E4=BD=9C?= Date: Fri, 25 Oct 2024 15:00:12 +0800 Subject: [PATCH 225/346] chore: code generator button should only display in code node (#9842) --- .../workflow/nodes/_base/components/editor/base.tsx | 10 +++++++--- .../_base/components/editor/code-editor/index.tsx | 3 +++ web/app/components/workflow/nodes/code/panel.tsx | 1 + 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/web/app/components/workflow/nodes/_base/components/editor/base.tsx b/web/app/components/workflow/nodes/_base/components/editor/base.tsx index 8799cd0cc7..cca565c39d 100644 --- a/web/app/components/workflow/nodes/_base/components/editor/base.tsx +++ b/web/app/components/workflow/nodes/_base/components/editor/base.tsx @@ -29,6 +29,7 @@ type Props = { codeLanguages: CodeLanguage fileList?: FileEntity[] showFileList?: boolean + showCodeGenerator?: boolean } const Base: FC = ({ @@ -44,6 +45,7 @@ const Base: FC = ({ codeLanguages, fileList = [], showFileList, + showCodeGenerator = false, }) => { const ref = useRef(null) const { @@ -76,9 +78,11 @@ const Base: FC = ({ e.stopPropagation() }}> {headerRight} -
- -
+ {showCodeGenerator && ( +
+ +
+ )} {!isCopied ? ( diff --git a/web/app/components/workflow/nodes/_base/components/editor/code-editor/index.tsx b/web/app/components/workflow/nodes/_base/components/editor/code-editor/index.tsx index f5be15a5d8..a31cde2c3c 100644 --- a/web/app/components/workflow/nodes/_base/components/editor/code-editor/index.tsx +++ b/web/app/components/workflow/nodes/_base/components/editor/code-editor/index.tsx @@ -31,6 +31,7 @@ export type Props = { noWrapper?: boolean isExpand?: boolean showFileList?: boolean + showCodeGenerator?: boolean } export const languageMap = { @@ -63,6 +64,7 @@ const CodeEditor: FC = ({ noWrapper, isExpand, showFileList, + showCodeGenerator = false, }) => { const [isFocus, setIsFocus] = React.useState(false) const [isMounted, setIsMounted] = React.useState(false) @@ -207,6 +209,7 @@ const CodeEditor: FC = ({ codeLanguages={language} fileList={fileList} showFileList={showFileList} + showCodeGenerator={showCodeGenerator} > {main} diff --git a/web/app/components/workflow/nodes/code/panel.tsx b/web/app/components/workflow/nodes/code/panel.tsx index 838e7190d3..d3e5e58634 100644 --- a/web/app/components/workflow/nodes/code/panel.tsx +++ b/web/app/components/workflow/nodes/code/panel.tsx @@ -92,6 +92,7 @@ const Panel: FC> = ({ language={inputs.code_language} value={inputs.code} onChange={handleCodeChange} + showCodeGenerator={true} />
From 7a0d0d9b963db748c9cd5ac6598ee2636a4a2f58 Mon Sep 17 00:00:00 2001 From: KVOJJJin Date: Fri, 25 Oct 2024 15:02:36 +0800 Subject: [PATCH 226/346] Fix: add check for maximum chunk length (#9837) --- web/app/components/datasets/create/step-two/index.tsx | 9 +++++++++ web/i18n/en-US/dataset-creation.ts | 1 + web/i18n/zh-Hans/dataset-creation.ts | 1 + 3 files changed, 11 insertions(+) diff --git a/web/app/components/datasets/create/step-two/index.tsx b/web/app/components/datasets/create/step-two/index.tsx index 718c412bd6..634f031134 100644 --- a/web/app/components/datasets/create/step-two/index.tsx +++ b/web/app/components/datasets/create/step-two/index.tsx @@ -212,6 +212,10 @@ const StepTwo = ({ } const confirmChangeCustomConfig = () => { + if (segmentationType === SegmentType.CUSTOM && max > 4000) { + Toast.notify({ type: 'error', message: t('datasetCreation.stepTwo.maxLengthCheck') }) + return + } setCustomFileIndexingEstimate(null) setShowPreview() fetchFileIndexingEstimate() @@ -339,6 +343,10 @@ const StepTwo = ({ Toast.notify({ type: 'error', message: t('datasetCreation.stepTwo.overlapCheck') }) return } + if (segmentationType === SegmentType.CUSTOM && max > 4000) { + Toast.notify({ type: 'error', message: t('datasetCreation.stepTwo.maxLengthCheck') }) + return + } if (isSetting) { params = { original_document_id: documentDetail?.id, @@ -663,6 +671,7 @@ const StepTwo = ({ className='h-9' placeholder={t('datasetCreation.stepTwo.maxLength') || ''} value={max} + max={4000} min={1} onChange={e => setMax(parseInt(e.target.value.replace(/^0+/, ''), 10))} /> diff --git a/web/i18n/en-US/dataset-creation.ts b/web/i18n/en-US/dataset-creation.ts index 1849b12757..de885671a7 100644 --- a/web/i18n/en-US/dataset-creation.ts +++ b/web/i18n/en-US/dataset-creation.ts @@ -103,6 +103,7 @@ const translation = { separatorTip: 'A delimiter is the character used to separate text. \\n\\n and \\n are commonly used delimiters for separating paragraphs and lines. Combined with commas (\\n\\n,\\n), paragraphs will be segmented by lines when exceeding the maximum chunk length. You can also use special delimiters defined by yourself (e.g. ***).', separatorPlaceholder: '\\n\\n for separating paragraphs; \\n for separating lines', maxLength: 'Maximum chunk length', + maxLengthCheck: 'Maximum chunk length should be less than 4000', overlap: 'Chunk overlap', overlapTip: 'Setting the chunk overlap can maintain the semantic relevance between them, enhancing the retrieve effect. It is recommended to set 10%-25% of the maximum chunk size.', overlapCheck: 'chunk overlap should not bigger than maximum chunk length', diff --git a/web/i18n/zh-Hans/dataset-creation.ts b/web/i18n/zh-Hans/dataset-creation.ts index 4f6786a191..fac809d7e2 100644 --- a/web/i18n/zh-Hans/dataset-creation.ts +++ b/web/i18n/zh-Hans/dataset-creation.ts @@ -103,6 +103,7 @@ const translation = { separatorTip: '分隔符是用于分隔文本的字符。\\n\\n 和 \\n 是常用于分隔段落和行的分隔符。用逗号连接分隔符(\\n\\n,\\n),当段落超过最大块长度时,会按行进行分割。你也可以使用自定义的特殊分隔符(例如 ***)。', separatorPlaceholder: '\\n\\n 用于分段;\\n 用于分行', maxLength: '分段最大长度', + maxLengthCheck: '分段最大长度不能大于 4000', overlap: '分段重叠长度', overlapTip: '设置分段之间的重叠长度可以保留分段之间的语义关系,提升召回效果。建议设置为最大分段长度的10%-25%', overlapCheck: '分段重叠长度不能大于分段最大长度', From 303bafb3ac5c6f089c8e99aa9ce6388209c78924 Mon Sep 17 00:00:00 2001 From: KVOJJJin Date: Fri, 25 Oct 2024 15:03:24 +0800 Subject: [PATCH 227/346] chore: update api docs (#9832) --- .../develop/template/template.en.mdx | 10 ++++++++-- .../develop/template/template.zh.mdx | 11 ++++++++++- .../template/template_advanced_chat.en.mdx | 18 ++++++++++++++---- .../template/template_advanced_chat.zh.mdx | 19 ++++++++++++++++--- .../develop/template/template_chat.en.mdx | 10 ++++++++-- .../develop/template/template_chat.zh.mdx | 11 ++++++++++- .../develop/template/template_workflow.en.mdx | 18 ++++++++++++++---- .../develop/template/template_workflow.zh.mdx | 18 ++++++++++++++---- 8 files changed, 94 insertions(+), 21 deletions(-) diff --git a/web/app/components/develop/template/template.en.mdx b/web/app/components/develop/template/template.en.mdx index a324bbefa8..61ecd7ae97 100755 --- a/web/app/components/develop/template/template.en.mdx +++ b/web/app/components/develop/template/template.en.mdx @@ -432,7 +432,10 @@ The text generation application offers non-session support and is ideal for tran - `number_limits` (int) Image number limit, default is 3 - `transfer_methods` (array[string]) List of transfer methods, remote_url, local_file, must choose one - `system_parameters` (object) System parameters - - `image_file_size_limit` (string) Image file upload size limit (MB) + - `file_size_limit` (int) Document upload size limit (MB) + - `image_file_size_limit` (int) Image file upload size limit (MB) + - `audio_file_size_limit` (int) Audio file upload size limit (MB) + - `video_file_size_limit` (int) Video file upload size limit (MB) @@ -484,7 +487,10 @@ The text generation application offers non-session support and is ideal for tran } }, "system_parameters": { - "image_file_size_limit": "10" + "file_size_limit": 15, + "image_file_size_limit": 10, + "audio_file_size_limit": 50, + "video_file_size_limit": 100 } } ``` diff --git a/web/app/components/develop/template/template.zh.mdx b/web/app/components/develop/template/template.zh.mdx index e593f013c2..d193b91816 100755 --- a/web/app/components/develop/template/template.zh.mdx +++ b/web/app/components/develop/template/template.zh.mdx @@ -406,7 +406,10 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx' - `number_limits` (int) 图片数量限制,默认 3 - `transfer_methods` (array[string]) 传递方式列表,remote_url , local_file,必选一个 - `system_parameters` (object) 系统参数 - - `image_file_size_limit` (string) 图片文件上传大小限制(MB) + - `file_size_limit` (int) 文档上传大小限制 (MB) + - `image_file_size_limit` (int) 图片文件上传大小限制(MB) + - `audio_file_size_limit` (int) 音频文件上传大小限制 (MB) + - `video_file_size_limit` (int) 视频文件上传大小限制 (MB) @@ -446,6 +449,12 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx' "local_file" ] } + }, + "system_parameters": { + "file_size_limit": 15, + "image_file_size_limit": 10, + "audio_file_size_limit": 50, + "video_file_size_limit": 100 } } ``` diff --git a/web/app/components/develop/template/template_advanced_chat.en.mdx b/web/app/components/develop/template/template_advanced_chat.en.mdx index 655b6efce1..71fa7c1a09 100644 --- a/web/app/components/develop/template/template_advanced_chat.en.mdx +++ b/web/app/components/develop/template/template_advanced_chat.en.mdx @@ -63,8 +63,12 @@ Chat applications support session persistence, allowing previous chat history to Conversation ID, to continue the conversation based on previous chat records, it is necessary to pass the previous message's conversation_id. - File list, suitable for inputting files (images) combined with text understanding and answering questions, available only when the model supports Vision capability. - - `type` (string) Supported type: `image` (currently only supports image type) + File list, suitable for inputting files combined with text understanding and answering questions, available only when the model supports Vision capability. + - `type` (string) Supported type: + - `document` ('TXT', 'MD', 'MARKDOWN', 'PDF', 'HTML', 'XLSX', 'XLS', 'DOCX', 'CSV', 'EML', 'MSG', 'PPTX', 'PPT', 'XML', 'EPUB') + - `image` ('JPG', 'JPEG', 'PNG', 'GIF', 'WEBP', 'SVG') + - `audio` ('MP3', 'M4A', 'WAV', 'WEBM', 'AMR') + - `video` ('MP4', 'MOV', 'MPEG', 'MPGA') - `transfer_method` (string) Transfer method, `remote_url` for image URL / `local_file` for file upload - `url` (string) Image URL (when the transfer method is `remote_url`) - `upload_file_id` (string) Uploaded file ID, which must be obtained by uploading through the File Upload API in advance (when the transfer method is `local_file`) @@ -972,7 +976,10 @@ Chat applications support session persistence, allowing previous chat history to - `number_limits` (int) Image number limit, default is 3 - `transfer_methods` (array[string]) List of transfer methods, remote_url, local_file, must choose one - `system_parameters` (object) System parameters - - `image_file_size_limit` (string) Image file upload size limit (MB) + - `file_size_limit` (int) Document upload size limit (MB) + - `image_file_size_limit` (int) Image file upload size limit (MB) + - `audio_file_size_limit` (int) Audio file upload size limit (MB) + - `video_file_size_limit` (int) Video file upload size limit (MB) @@ -1024,7 +1031,10 @@ Chat applications support session persistence, allowing previous chat history to } }, "system_parameters": { - "image_file_size_limit": "10" + "file_size_limit": 15, + "image_file_size_limit": 10, + "audio_file_size_limit": 50, + "video_file_size_limit": 100 } } ``` diff --git a/web/app/components/develop/template/template_advanced_chat.zh.mdx b/web/app/components/develop/template/template_advanced_chat.zh.mdx index 2aa42fbb19..32dcec135b 100755 --- a/web/app/components/develop/template/template_advanced_chat.zh.mdx +++ b/web/app/components/develop/template/template_advanced_chat.zh.mdx @@ -61,8 +61,12 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx' (选填)会话 ID,需要基于之前的聊天记录继续对话,必须传之前消息的 conversation_id。 - 上传的文件。 - - `type` (string) 支持类型:图片 `image`(目前仅支持图片格式) 。 + 文件列表,适用于传入文件结合文本理解并回答问题,仅当模型支持 Vision 能力时可用。 + - `type` (string) 支持类型: + - `document` 具体类型包含:'TXT', 'MD', 'MARKDOWN', 'PDF', 'HTML', 'XLSX', 'XLS', 'DOCX', 'CSV', 'EML', 'MSG', 'PPTX', 'PPT', 'XML', 'EPUB' + - `image` 具体类型包含:'JPG', 'JPEG', 'PNG', 'GIF', 'WEBP', 'SVG' + - `audio` 具体类型包含:'MP3', 'M4A', 'WAV', 'WEBM', 'AMR' + - `video` 具体类型包含:'MP4', 'MOV', 'MPEG', 'MPGA' - `transfer_method` (string) 传递方式: - `remote_url`: 图片地址。 - `local_file`: 上传文件。 @@ -1003,7 +1007,10 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx' - `number_limits` (int) 图片数量限制,默认 3 - `transfer_methods` (array[string]) 传递方式列表,remote_url , local_file,必选一个 - `system_parameters` (object) 系统参数 - - `image_file_size_limit` (string) 图片文件上传大小限制(MB) + - `file_size_limit` (int) Document upload size limit (MB) + - `image_file_size_limit` (int) Image file upload size limit (MB) + - `audio_file_size_limit` (int) Audio file upload size limit (MB) + - `video_file_size_limit` (int) Video file upload size limit (MB) @@ -1043,6 +1050,12 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx' "local_file" ] } + }, + "system_parameters": { + "file_size_limit": 15, + "image_file_size_limit": 10, + "audio_file_size_limit": 50, + "video_file_size_limit": 100 } } ``` diff --git a/web/app/components/develop/template/template_chat.en.mdx b/web/app/components/develop/template/template_chat.en.mdx index d6dfbaaaf9..907a1ab0b4 100644 --- a/web/app/components/develop/template/template_chat.en.mdx +++ b/web/app/components/develop/template/template_chat.en.mdx @@ -1007,7 +1007,10 @@ Chat applications support session persistence, allowing previous chat history to - `number_limits` (int) Image number limit, default is 3 - `transfer_methods` (array[string]) List of transfer methods, remote_url, local_file, must choose one - `system_parameters` (object) System parameters - - `image_file_size_limit` (string) Image file upload size limit (MB) + - `file_size_limit` (int) Document upload size limit (MB) + - `image_file_size_limit` (int) Image file upload size limit (MB) + - `audio_file_size_limit` (int) Audio file upload size limit (MB) + - `video_file_size_limit` (int) Video file upload size limit (MB) @@ -1059,7 +1062,10 @@ Chat applications support session persistence, allowing previous chat history to } }, "system_parameters": { - "image_file_size_limit": "10" + "file_size_limit": 15, + "image_file_size_limit": 10, + "audio_file_size_limit": 50, + "video_file_size_limit": 100 } } ``` diff --git a/web/app/components/develop/template/template_chat.zh.mdx b/web/app/components/develop/template/template_chat.zh.mdx index a91da81a1c..f6dc7daa1e 100644 --- a/web/app/components/develop/template/template_chat.zh.mdx +++ b/web/app/components/develop/template/template_chat.zh.mdx @@ -1017,7 +1017,10 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx' - `number_limits` (int) 图片数量限制,默认 3 - `transfer_methods` (array[string]) 传递方式列表,remote_url , local_file,必选一个 - `system_parameters` (object) 系统参数 - - `image_file_size_limit` (string) 图片文件上传大小限制(MB) + - `file_size_limit` (int) 文档上传大小限制 (MB) + - `image_file_size_limit` (int) 图片文件上传大小限制(MB) + - `audio_file_size_limit` (int) 音频文件上传大小限制 (MB) + - `video_file_size_limit` (int) 视频文件上传大小限制 (MB) @@ -1057,6 +1060,12 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx' "local_file" ] } + }, + "system_parameters": { + "file_size_limit": 15, + "image_file_size_limit": 10, + "audio_file_size_limit": 50, + "video_file_size_limit": 100 } } ``` diff --git a/web/app/components/develop/template/template_workflow.en.mdx b/web/app/components/develop/template/template_workflow.en.mdx index 5c712c2c29..db39e61e36 100644 --- a/web/app/components/develop/template/template_workflow.en.mdx +++ b/web/app/components/develop/template/template_workflow.en.mdx @@ -53,8 +53,12 @@ Workflow applications offers non-session support and is ideal for translation, a User identifier, used to define the identity of the end-user for retrieval and statistics. Should be uniquely defined by the developer within the application. - `files` (array[object]) Optional - File list, suitable for inputting files (images) combined with text understanding and answering questions, available only when the model supports Vision capability. - - `type` (string) Supported type: `image` (currently only supports image type) + File list, suitable for inputting files combined with text understanding and answering questions, available only when the model supports Vision capability. + - `type` (string) Supported type: + - `document` ('TXT', 'MD', 'MARKDOWN', 'PDF', 'HTML', 'XLSX', 'XLS', 'DOCX', 'CSV', 'EML', 'MSG', 'PPTX', 'PPT', 'XML', 'EPUB') + - `image` ('JPG', 'JPEG', 'PNG', 'GIF', 'WEBP', 'SVG') + - `audio` ('MP3', 'M4A', 'WAV', 'WEBM', 'AMR') + - `video` ('MP4', 'MOV', 'MPEG', 'MPGA') - `transfer_method` (string) Transfer method, `remote_url` for image URL / `local_file` for file upload - `url` (string) Image URL (when the transfer method is `remote_url`) - `upload_file_id` (string) Uploaded file ID, which must be obtained by uploading through the File Upload API in advance (when the transfer method is `local_file`) @@ -367,7 +371,10 @@ Workflow applications offers non-session support and is ideal for translation, a - `number_limits` (int) Image number limit, default is 3 - `transfer_methods` (array[string]) List of transfer methods, remote_url, local_file, must choose one - `system_parameters` (object) System parameters - - `image_file_size_limit` (string) Image file upload size limit (MB) + - `file_size_limit` (int) Document upload size limit (MB) + - `image_file_size_limit` (int) Image file upload size limit (MB) + - `audio_file_size_limit` (int) Audio file upload size limit (MB) + - `video_file_size_limit` (int) Video file upload size limit (MB) @@ -406,7 +413,10 @@ Workflow applications offers non-session support and is ideal for translation, a } }, "system_parameters": { - "image_file_size_limit": "10" + "file_size_limit": 15, + "image_file_size_limit": 10, + "audio_file_size_limit": 50, + "video_file_size_limit": 100 } } ``` diff --git a/web/app/components/develop/template/template_workflow.zh.mdx b/web/app/components/develop/template/template_workflow.zh.mdx index d7d672fbd0..6e4b5e0a40 100644 --- a/web/app/components/develop/template/template_workflow.zh.mdx +++ b/web/app/components/develop/template/template_workflow.zh.mdx @@ -51,8 +51,12 @@ Workflow 应用无会话支持,适合用于翻译/文章写作/总结 AI 等 用户标识,用于定义终端用户的身份,方便检索、统计。 由开发者定义规则,需保证用户标识在应用内唯一。 - `files` (array[object]) Optional - 文件列表,适用于传入文件(图片)结合文本理解并回答问题,仅当模型支持 Vision 能力时可用。 - - `type` (string) 支持类型:图片 `image`(目前仅支持图片格式)。 + 文件列表,适用于传入文件结合文本理解并回答问题,仅当模型支持 Vision 能力时可用。 + - `type` (string) 支持类型: + - `document` 具体类型包含:'TXT', 'MD', 'MARKDOWN', 'PDF', 'HTML', 'XLSX', 'XLS', 'DOCX', 'CSV', 'EML', 'MSG', 'PPTX', 'PPT', 'XML', 'EPUB' + - `image` 具体类型包含:'JPG', 'JPEG', 'PNG', 'GIF', 'WEBP', 'SVG' + - `audio` 具体类型包含:'MP3', 'M4A', 'WAV', 'WEBM', 'AMR' + - `video` 具体类型包含:'MP4', 'MOV', 'MPEG', 'MPGA' - `transfer_method` (string) 传递方式,`remote_url` 图片地址 / `local_file` 上传文件 - `url` (string) 图片地址(仅当传递方式为 `remote_url` 时) - `upload_file_id` (string) (string) 上传文件 ID(仅当传递方式为 `local_file` 时) @@ -363,7 +367,10 @@ Workflow 应用无会话支持,适合用于翻译/文章写作/总结 AI 等 - `number_limits` (int) 图片数量限制,默认 3 - `transfer_methods` (array[string]) 传递方式列表,remote_url , local_file,必选一个 - `system_parameters` (object) 系统参数 - - `image_file_size_limit` (string) 图片文件上传大小限制(MB) + - `file_size_limit` (int) 文档上传大小限制 (MB) + - `image_file_size_limit` (int) 图片文件上传大小限制(MB) + - `audio_file_size_limit` (int) 音频文件上传大小限制 (MB) + - `video_file_size_limit` (int) 视频文件上传大小限制 (MB) @@ -402,7 +409,10 @@ Workflow 应用无会话支持,适合用于翻译/文章写作/总结 AI 等 } }, "system_parameters": { - "image_file_size_limit": "10" + "file_size_limit": 15, + "image_file_size_limit": 10, + "audio_file_size_limit": 50, + "video_file_size_limit": 100 } } ``` From 60ddcdf9605d4b7985dfdc993dd58a3d56fbd502 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 25 Oct 2024 15:19:05 +0800 Subject: [PATCH 228/346] chore: translate i18n files (#9853) Co-authored-by: crazywoola <100913391+crazywoola@users.noreply.github.com> --- web/i18n/de-DE/dataset-creation.ts | 1 + web/i18n/es-ES/dataset-creation.ts | 1 + web/i18n/fa-IR/dataset-creation.ts | 1 + web/i18n/fr-FR/dataset-creation.ts | 1 + web/i18n/hi-IN/dataset-creation.ts | 1 + web/i18n/it-IT/dataset-creation.ts | 1 + web/i18n/ja-JP/dataset-creation.ts | 1 + web/i18n/ko-KR/dataset-creation.ts | 1 + web/i18n/pl-PL/dataset-creation.ts | 1 + web/i18n/pt-BR/dataset-creation.ts | 1 + web/i18n/ro-RO/dataset-creation.ts | 1 + web/i18n/ru-RU/dataset-creation.ts | 1 + web/i18n/tr-TR/dataset-creation.ts | 1 + web/i18n/uk-UA/dataset-creation.ts | 1 + web/i18n/vi-VN/dataset-creation.ts | 1 + web/i18n/zh-Hant/dataset-creation.ts | 1 + 16 files changed, 16 insertions(+) diff --git a/web/i18n/de-DE/dataset-creation.ts b/web/i18n/de-DE/dataset-creation.ts index 334f6d43bd..18f08814cb 100644 --- a/web/i18n/de-DE/dataset-creation.ts +++ b/web/i18n/de-DE/dataset-creation.ts @@ -142,6 +142,7 @@ const translation = { websiteSource: 'Preprocess-Website', webpageUnit: 'Seiten', separatorTip: 'Ein Trennzeichen ist das Zeichen, das zum Trennen von Text verwendet wird. \\n\\n und \\n sind häufig verwendete Trennzeichen zum Trennen von Absätzen und Zeilen. In Kombination mit Kommas (\\n\\n,\\n) werden Absätze nach Zeilen segmentiert, wenn die maximale Blocklänge überschritten wird. Sie können auch spezielle, von Ihnen selbst definierte Trennzeichen verwenden (z. B. ***).', + maxLengthCheck: 'Die maximale Stücklänge sollte weniger als 4000 betragen', }, stepThree: { creationTitle: '🎉 Wissen erstellt', diff --git a/web/i18n/es-ES/dataset-creation.ts b/web/i18n/es-ES/dataset-creation.ts index 913c230b2b..02415b4359 100644 --- a/web/i18n/es-ES/dataset-creation.ts +++ b/web/i18n/es-ES/dataset-creation.ts @@ -147,6 +147,7 @@ const translation = { retrievalSettingTip: 'Para cambiar el método de índice, por favor ve a la ', datasetSettingLink: 'configuración del conocimiento.', separatorTip: 'Un delimitador es el carácter que se utiliza para separar el texto. \\n\\n y \\n son delimitadores comúnmente utilizados para separar párrafos y líneas. Combinado con comas (\\n\\n,\\n), los párrafos se segmentarán por líneas cuando excedan la longitud máxima del fragmento. También puede utilizar delimitadores especiales definidos por usted mismo (por ejemplo, ***).', + maxLengthCheck: 'La longitud máxima del fragmento debe ser inferior a 4000', }, stepThree: { creationTitle: '🎉 Conocimiento creado', diff --git a/web/i18n/fa-IR/dataset-creation.ts b/web/i18n/fa-IR/dataset-creation.ts index 48882f45cf..195d968228 100644 --- a/web/i18n/fa-IR/dataset-creation.ts +++ b/web/i18n/fa-IR/dataset-creation.ts @@ -147,6 +147,7 @@ const translation = { retrievalSettingTip: 'برای تغییر روش شاخص، لطفاً به', datasetSettingLink: 'تنظیمات دانش بروید.', separatorTip: 'جداکننده نویسه ای است که برای جداسازی متن استفاده می شود. \\n\\n و \\n معمولا برای جداسازی پاراگراف ها و خطوط استفاده می شوند. همراه با کاما (\\n\\n,\\n)، پاراگراف ها زمانی که از حداکثر طول تکه فراتر می روند، با خطوط تقسیم بندی می شوند. همچنین می توانید از جداکننده های خاصی که توسط خودتان تعریف شده اند استفاده کنید (مثلا ***).', + maxLengthCheck: 'حداکثر طول تکه باید کمتر از 4000 باشد', }, stepThree: { creationTitle: ' دانش ایجاد شد', diff --git a/web/i18n/fr-FR/dataset-creation.ts b/web/i18n/fr-FR/dataset-creation.ts index 302e0796cb..0c866d51e6 100644 --- a/web/i18n/fr-FR/dataset-creation.ts +++ b/web/i18n/fr-FR/dataset-creation.ts @@ -142,6 +142,7 @@ const translation = { webpageUnit: 'Pages', websiteSource: 'Site web de prétraitement', separatorTip: 'Un délimiteur est le caractère utilisé pour séparer le texte. \\n\\n et \\n sont des délimiteurs couramment utilisés pour séparer les paragraphes et les lignes. Combiné à des virgules (\\n\\n,\\n), les paragraphes seront segmentés par des lignes lorsqu’ils dépasseront la longueur maximale des morceaux. Vous pouvez également utiliser des délimiteurs spéciaux définis par vous-même (par exemple ***).', + maxLengthCheck: 'La longueur maximale des morceaux doit être inférieure à 4000', }, stepThree: { creationTitle: '🎉 Connaissance créée', diff --git a/web/i18n/hi-IN/dataset-creation.ts b/web/i18n/hi-IN/dataset-creation.ts index 36986d0f86..a242eebb24 100644 --- a/web/i18n/hi-IN/dataset-creation.ts +++ b/web/i18n/hi-IN/dataset-creation.ts @@ -164,6 +164,7 @@ const translation = { retrievalSettingTip: 'इंडेक्स विधि बदलने के लिए, कृपया जाएं ', datasetSettingLink: 'ज्ञान सेटिंग्स।', separatorTip: 'एक सीमांकक पाठ को अलग करने के लिए उपयोग किया जाने वाला वर्ण है। \\n\\n और \\n आमतौर पर पैराग्राफ और लाइनों को अलग करने के लिए उपयोग किए जाने वाले सीमांकक हैं। अल्पविराम (\\n\\n,\\n) के साथ संयुक्त, अधिकतम खंड लंबाई से अधिक होने पर अनुच्छेदों को पंक्तियों द्वारा खंडित किया जाएगा। आप स्वयं द्वारा परिभाषित विशेष सीमांकक का भी उपयोग कर सकते हैं (उदा. ***).', + maxLengthCheck: 'अधिकतम चंक लंबाई 4000 से कम होनी चाहिए', }, stepThree: { creationTitle: '🎉 ज्ञान बनाया गया', diff --git a/web/i18n/it-IT/dataset-creation.ts b/web/i18n/it-IT/dataset-creation.ts index f46101257c..ebbe34f143 100644 --- a/web/i18n/it-IT/dataset-creation.ts +++ b/web/i18n/it-IT/dataset-creation.ts @@ -167,6 +167,7 @@ const translation = { retrievalSettingTip: 'Per cambiare il metodo di indicizzazione, vai alle ', datasetSettingLink: 'impostazioni della Conoscenza.', separatorTip: 'Un delimitatore è il carattere utilizzato per separare il testo. \\n\\n e \\n sono delimitatori comunemente usati per separare paragrafi e righe. In combinazione con le virgole (\\n\\n,\\n), i paragrafi verranno segmentati per righe quando superano la lunghezza massima del blocco. È inoltre possibile utilizzare delimitatori speciali definiti dall\'utente (ad es. ***).', + maxLengthCheck: 'La lunghezza massima del blocco deve essere inferiore a 4000', }, stepThree: { creationTitle: '🎉 Conoscenza creata', diff --git a/web/i18n/ja-JP/dataset-creation.ts b/web/i18n/ja-JP/dataset-creation.ts index 570876c4b4..597ec5f8f1 100644 --- a/web/i18n/ja-JP/dataset-creation.ts +++ b/web/i18n/ja-JP/dataset-creation.ts @@ -147,6 +147,7 @@ const translation = { retrievalSettingTip: '検索方法を変更するには、', datasetSettingLink: 'ナレッジ設定', separatorTip: '区切り文字は、テキストを区切るために使用される文字です。\\n\\n と \\n は、段落と行を区切るために一般的に使用される区切り記号です。カンマ (\\n\\n,\\n) と組み合わせると、最大チャンク長を超えると、段落は行で区切られます。自分で定義した特別な区切り文字を使用することもできます(例:***)。', + maxLengthCheck: 'チャンクの最大長は 4000 未満にする必要があります', }, stepThree: { creationTitle: '🎉 ナレッジが作成されました', diff --git a/web/i18n/ko-KR/dataset-creation.ts b/web/i18n/ko-KR/dataset-creation.ts index 69d6cf7a55..52f7aff75d 100644 --- a/web/i18n/ko-KR/dataset-creation.ts +++ b/web/i18n/ko-KR/dataset-creation.ts @@ -142,6 +142,7 @@ const translation = { webpageUnit: '페이지', websiteSource: '웹 사이트 전처리', separatorTip: '구분 기호는 텍스트를 구분하는 데 사용되는 문자입니다. \\n\\n 및 \\n은 단락과 줄을 구분하는 데 일반적으로 사용되는 구분 기호입니다. 쉼표(\\n\\n,\\n)와 함께 사용하면 최대 청크 길이를 초과할 경우 단락이 줄로 분할됩니다. 직접 정의한 특수 구분 기호(예: ***)를 사용할 수도 있습니다.', + maxLengthCheck: '최대 청크 길이는 4000 미만이어야 합니다.', }, stepThree: { creationTitle: '🎉 지식이 생성되었습니다', diff --git a/web/i18n/pl-PL/dataset-creation.ts b/web/i18n/pl-PL/dataset-creation.ts index fa08dcd2f5..81adff6336 100644 --- a/web/i18n/pl-PL/dataset-creation.ts +++ b/web/i18n/pl-PL/dataset-creation.ts @@ -155,6 +155,7 @@ const translation = { webpageUnit: 'Stron', websiteSource: 'Witryna internetowa przetwarzania wstępnego', separatorTip: 'Ogranicznik to znak używany do oddzielania tekstu. \\n\\n i \\n są powszechnie używanymi ogranicznikami do oddzielania akapitów i wierszy. W połączeniu z przecinkami (\\n\\n,\\n), akapity będą segmentowane wierszami po przekroczeniu maksymalnej długości fragmentu. Możesz również skorzystać ze zdefiniowanych przez siebie specjalnych ograniczników (np. ***).', + maxLengthCheck: 'Maksymalna długość porcji powinna być mniejsza niż 4000', }, stepThree: { creationTitle: '🎉 Utworzono Wiedzę', diff --git a/web/i18n/pt-BR/dataset-creation.ts b/web/i18n/pt-BR/dataset-creation.ts index c9aeff1971..5ab2456562 100644 --- a/web/i18n/pt-BR/dataset-creation.ts +++ b/web/i18n/pt-BR/dataset-creation.ts @@ -142,6 +142,7 @@ const translation = { websiteSource: 'Site de pré-processamento', webpageUnit: 'Páginas', separatorTip: 'Um delimitador é o caractere usado para separar o texto. \\n\\n e \\n são delimitadores comumente usados para separar parágrafos e linhas. Combinado com vírgulas (\\n\\n,\\n), os parágrafos serão segmentados por linhas ao exceder o comprimento máximo do bloco. Você também pode usar delimitadores especiais definidos por você (por exemplo, ***).', + maxLengthCheck: 'O comprimento máximo do chunk deve ser inferior a 4000', }, stepThree: { creationTitle: '🎉 Conhecimento criado', diff --git a/web/i18n/ro-RO/dataset-creation.ts b/web/i18n/ro-RO/dataset-creation.ts index 2505348e70..2f474f440a 100644 --- a/web/i18n/ro-RO/dataset-creation.ts +++ b/web/i18n/ro-RO/dataset-creation.ts @@ -142,6 +142,7 @@ const translation = { webpageUnit: 'Pagini', websiteSource: 'Site-ul web de preprocesare', separatorTip: 'Un delimitator este caracterul folosit pentru a separa textul. \\n\\n și \\n sunt delimitatori utilizați în mod obișnuit pentru separarea paragrafelor și liniilor. Combinate cu virgule (\\n\\n,\\n), paragrafele vor fi segmentate pe linii atunci când depășesc lungimea maximă a bucății. De asemenea, puteți utiliza delimitatori speciali definiți de dumneavoastră (de exemplu, ***).', + maxLengthCheck: 'Lungimea maximă a bucății trebuie să fie mai mică de 4000', }, stepThree: { creationTitle: '🎉 Cunoștință creată', diff --git a/web/i18n/ru-RU/dataset-creation.ts b/web/i18n/ru-RU/dataset-creation.ts index ffa7f961d0..66d92bd2b4 100644 --- a/web/i18n/ru-RU/dataset-creation.ts +++ b/web/i18n/ru-RU/dataset-creation.ts @@ -147,6 +147,7 @@ const translation = { retrievalSettingTip: 'Чтобы изменить метод индексации, пожалуйста, перейдите в ', datasetSettingLink: 'настройки базы знаний.', separatorTip: 'Разделитель — это символ, используемый для разделения текста. \\n\\n и \\n — это часто используемые разделители для разделения абзацев и строк. В сочетании с запятыми (\\n\\n,\\n) абзацы будут сегментированы по строкам, если максимальная длина блока превышает их. Вы также можете использовать специальные разделители, определенные вами (например, ***).', + maxLengthCheck: 'Максимальная длина блока должна быть меньше 4000', }, stepThree: { creationTitle: '🎉 База знаний создана', diff --git a/web/i18n/tr-TR/dataset-creation.ts b/web/i18n/tr-TR/dataset-creation.ts index 90ccecf285..1d5dd19634 100644 --- a/web/i18n/tr-TR/dataset-creation.ts +++ b/web/i18n/tr-TR/dataset-creation.ts @@ -147,6 +147,7 @@ const translation = { retrievalSettingTip: 'Dizin yöntemini değiştirmek için, lütfen', datasetSettingLink: 'Bilgi ayarlarına gidin.', separatorTip: 'Sınırlayıcı, metni ayırmak için kullanılan karakterdir. \\n\\n ve \\n, paragrafları ve satırları ayırmak için yaygın olarak kullanılan sınırlayıcılardır. Virgüllerle (\\n\\n,\\n) birleştirildiğinde, paragraflar maksimum öbek uzunluğunu aştığında satırlarla bölünür. Kendiniz tarafından tanımlanan özel sınırlayıcıları da kullanabilirsiniz (örn.', + maxLengthCheck: 'Maksimum yığın uzunluğu 4000\'den az olmalıdır', }, stepThree: { creationTitle: '🎉 Bilgi oluşturuldu', diff --git a/web/i18n/uk-UA/dataset-creation.ts b/web/i18n/uk-UA/dataset-creation.ts index 57f51971cb..e78934c9e9 100644 --- a/web/i18n/uk-UA/dataset-creation.ts +++ b/web/i18n/uk-UA/dataset-creation.ts @@ -142,6 +142,7 @@ const translation = { webpageUnit: 'Сторінок', websiteSource: 'Веб-сайт попередньої обробки', separatorTip: 'Роздільник – це символ, який використовується для поділу тексту. \\n\\n та \\n є часто використовуваними роздільниками для відокремлення абзаців та рядків. У поєднанні з комами (\\n\\n,\\n) абзаци будуть розділені лініями, якщо вони перевищують максимальну довжину фрагмента. Ви також можете використовувати спеціальні роздільники, визначені вами (наприклад, ***).', + maxLengthCheck: 'Максимальна довжина шматка має бути меншою за 4000', }, stepThree: { creationTitle: '🎉 Знання створено', diff --git a/web/i18n/vi-VN/dataset-creation.ts b/web/i18n/vi-VN/dataset-creation.ts index a2e87d667e..3dc26bee46 100644 --- a/web/i18n/vi-VN/dataset-creation.ts +++ b/web/i18n/vi-VN/dataset-creation.ts @@ -142,6 +142,7 @@ const translation = { websiteSource: 'Trang web tiền xử lý', webpageUnit: 'Trang', separatorTip: 'Dấu phân cách là ký tự được sử dụng để phân tách văn bản. \\n\\n và \\n là dấu phân cách thường được sử dụng để tách các đoạn văn và dòng. Kết hợp với dấu phẩy (\\n\\n,\\n), các đoạn văn sẽ được phân đoạn theo các dòng khi vượt quá độ dài đoạn tối đa. Bạn cũng có thể sử dụng dấu phân cách đặc biệt do chính bạn xác định (ví dụ: ***).', + maxLengthCheck: 'Chiều dài đoạn tối đa phải nhỏ hơn 4000', }, stepThree: { creationTitle: '🎉 Kiến thức đã được tạo', diff --git a/web/i18n/zh-Hant/dataset-creation.ts b/web/i18n/zh-Hant/dataset-creation.ts index 265731d1f8..02374573cf 100644 --- a/web/i18n/zh-Hant/dataset-creation.ts +++ b/web/i18n/zh-Hant/dataset-creation.ts @@ -142,6 +142,7 @@ const translation = { websiteSource: '預處理網站', webpageUnit: '頁面', separatorTip: '分隔符是用於分隔文字的字元。\\n\\n 和 \\n 是分隔段落和行的常用分隔符。與逗號 (\\n\\n,\\n) 組合使用時,當超過最大區塊長度時,段落將按行分段。您也可以使用自定義的特殊分隔符(例如 ***)。', + maxLengthCheck: '塊最大長度應小於 4000', }, stepThree: { creationTitle: '🎉 知識庫已建立', From 4693080ce01d63513b6dae15fa01a6d694d57815 Mon Sep 17 00:00:00 2001 From: yuanboao <79826960+yuanboao@users.noreply.github.com> Date: Fri, 25 Oct 2024 15:34:58 +0800 Subject: [PATCH 229/346] Marking the last piece of data on each page is a duplicate issue, which can be solved by adding the id field to the order by rig and using a unique field (#9799) Signed-off-by: root Co-authored-by: root --- api/services/annotation_service.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/services/annotation_service.py b/api/services/annotation_service.py index 3cc6c51c2d..915d37ec03 100644 --- a/api/services/annotation_service.py +++ b/api/services/annotation_service.py @@ -132,14 +132,14 @@ class AppAnnotationService: MessageAnnotation.content.ilike("%{}%".format(keyword)), ) ) - .order_by(MessageAnnotation.created_at.desc()) + .order_by(MessageAnnotation.created_at.desc(), MessageAnnotation.id.desc()) .paginate(page=page, per_page=limit, max_per_page=100, error_out=False) ) else: annotations = ( db.session.query(MessageAnnotation) .filter(MessageAnnotation.app_id == app_id) - .order_by(MessageAnnotation.created_at.desc()) + .order_by(MessageAnnotation.created_at.desc(), MessageAnnotation.id.desc()) .paginate(page=page, per_page=limit, max_per_page=100, error_out=False) ) return annotations.items, annotations.total From fb218f8b1074dd57b2d62ce0c73ca35642a64543 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9D=9E=E6=B3=95=E6=93=8D=E4=BD=9C?= Date: Fri, 25 Oct 2024 15:37:29 +0800 Subject: [PATCH 230/346] feat: allow answer node use chat_var and env_var (#9226) --- web/app/components/workflow/nodes/answer/panel.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/app/components/workflow/nodes/answer/panel.tsx b/web/app/components/workflow/nodes/answer/panel.tsx index acfcff66fb..b8fe5f5997 100644 --- a/web/app/components/workflow/nodes/answer/panel.tsx +++ b/web/app/components/workflow/nodes/answer/panel.tsx @@ -23,8 +23,8 @@ const Panel: FC> = ({ const { availableVars, availableNodesWithParent } = useAvailableVarList(id, { onlyLeafNodeVar: false, - hideChatVar: true, - hideEnv: true, + hideChatVar: false, + hideEnv: false, filterVar, }) From c777d55a1c14bbbb443018323c8e7cb51c5c5e65 Mon Sep 17 00:00:00 2001 From: Joel Date: Fri, 25 Oct 2024 16:46:02 +0800 Subject: [PATCH 231/346] feat: marketplace install --- .../install-plugin/base/check-task-status.ts | 55 ++++++++++++++++ .../install-from-local-package/index.tsx | 6 +- .../steps/install.tsx | 35 +++++++++-- .../install-from-marketplace/index.tsx | 13 ++-- .../steps/install.tsx | 46 +++++++++++--- .../components/plugins/plugin-page/index.tsx | 7 ++- web/app/components/plugins/types.ts | 63 +++++++++++++------ web/service/plugins.ts | 16 +++++ 8 files changed, 201 insertions(+), 40 deletions(-) create mode 100644 web/app/components/plugins/install-plugin/base/check-task-status.ts diff --git a/web/app/components/plugins/install-plugin/base/check-task-status.ts b/web/app/components/plugins/install-plugin/base/check-task-status.ts new file mode 100644 index 0000000000..365bd9cf36 --- /dev/null +++ b/web/app/components/plugins/install-plugin/base/check-task-status.ts @@ -0,0 +1,55 @@ +import { checkTaskStatus as fetchCheckTaskStatus } from '@/service/plugins' +import type { PluginStatus } from '../../types' +import { TaskStatus } from '../../types' + +const INTERVAL = 10 * 1000 // 10 seconds + +interface Params { + taskId: string + pluginUniqueIdentifier: string +} + +function checkTaskStatus() { + let nextStatus = TaskStatus.running + let isStop = false + + const doCheckStatus = async ({ + taskId, + pluginUniqueIdentifier, + }: Params) => { + if (isStop) return + const { plugins } = await fetchCheckTaskStatus(taskId) + const plugin = plugins.find((p: PluginStatus) => p.plugin_unique_identifier === pluginUniqueIdentifier) + if (!plugin) { + nextStatus = TaskStatus.failed + Promise.reject(new Error('Plugin package not found')) + return + } + nextStatus = plugin.status + if (nextStatus === TaskStatus.running) { + setTimeout(async () => { + await doCheckStatus({ + taskId, + pluginUniqueIdentifier, + }) + }, INTERVAL) + return + } + if (nextStatus === TaskStatus.failed) { + Promise.reject(plugin.message) + return + } + return ({ + status: nextStatus, + }) + } + + return { + check: doCheckStatus, + stop: () => { + isStop = true + }, + } +} + +export default checkTaskStatus diff --git a/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx b/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx index bbfc195a4d..7d89ede48b 100644 --- a/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx +++ b/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx @@ -11,7 +11,7 @@ import { useTranslation } from 'react-i18next' const i18nPrefix = 'plugin.installModal' -type InstallFromLocalPackageProps = { +interface InstallFromLocalPackageProps { file: File onSuccess: () => void onClose: () => void @@ -56,8 +56,10 @@ const InstallFromLocalPackage: React.FC = ({ setStep(InstallStep.installed) }, []) - const handleFailed = useCallback(() => { + const handleFailed = useCallback((errorMsg?: string) => { setStep(InstallStep.installFailed) + if (errorMsg) + setErrorMsg(errorMsg) }, []) return ( diff --git a/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx b/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx index 4d58ab3cb7..08b21ad1ff 100644 --- a/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx +++ b/web/app/components/plugins/install-plugin/install-from-local-package/steps/install.tsx @@ -5,20 +5,20 @@ import type { PluginDeclaration } from '../../../types' import Card from '../../../card' import { pluginManifestToCardPluginProps } from '../../utils' import Button from '@/app/components/base/button' -import { sleep } from '@/utils' import { Trans, useTranslation } from 'react-i18next' import { RiLoader2Line } from '@remixicon/react' import Badge, { BadgeState } from '@/app/components/base/badge/index' import { installPackageFromLocal } from '@/service/plugins' +import checkTaskStatus from '../../base/check-task-status' const i18nPrefix = 'plugin.installModal' -type Props = { +interface Props { uniqueIdentifier: string payload: PluginDeclaration onCancel: () => void onInstalled: () => void - onFailed: () => void + onFailed: (message?: string) => void } const Installed: FC = ({ @@ -30,18 +30,41 @@ const Installed: FC = ({ }) => { const { t } = useTranslation() const [isInstalling, setIsInstalling] = React.useState(false) + const { + check, + stop, + } = checkTaskStatus() + + const handleCancel = () => { + stop() + onCancel() + } const handleInstall = async () => { if (isInstalling) return setIsInstalling(true) try { - await installPackageFromLocal(uniqueIdentifier) + const { + all_installed: isInstalled, + task_id: taskId, + } = await installPackageFromLocal(uniqueIdentifier) + if (isInstalled) { + onInstalled() + return + } + await check({ + taskId, + pluginUniqueIdentifier: uniqueIdentifier, + }) onInstalled() } catch (e) { + if (typeof e === 'string') { + onFailed(e) + return + } onFailed() } - await sleep(1500) } return ( @@ -67,7 +90,7 @@ const Installed: FC = ({ {/* Action Buttons */}
{!isInstalling && ( - )} diff --git a/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx b/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx index 26b0d117e8..16126e30a0 100644 --- a/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx +++ b/web/app/components/plugins/install-plugin/install-from-marketplace/index.tsx @@ -10,15 +10,15 @@ import { useTranslation } from 'react-i18next' const i18nPrefix = 'plugin.installModal' -type InstallFromMarketplaceProps = { - packageId: string +interface InstallFromMarketplaceProps { + uniqueIdentifier: string manifest: PluginDeclaration onSuccess: () => void onClose: () => void } const InstallFromMarketplace: React.FC = ({ - packageId, + uniqueIdentifier, manifest, onSuccess, onClose, @@ -26,6 +26,7 @@ const InstallFromMarketplace: React.FC = ({ const { t } = useTranslation() // readyToInstall -> check installed -> installed/failed const [step, setStep] = useState(InstallStep.readyToInstall) + const [errorMsg, setErrorMsg] = useState(null) // TODO: check installed in beta version. @@ -41,8 +42,10 @@ const InstallFromMarketplace: React.FC = ({ setStep(InstallStep.installed) }, []) - const handleFailed = useCallback(() => { + const handleFailed = useCallback((errorMsg?: string) => { setStep(InstallStep.installFailed) + if (errorMsg) + setErrorMsg(errorMsg) }, []) return ( @@ -60,6 +63,7 @@ const InstallFromMarketplace: React.FC = ({ { step === InstallStep.readyToInstall && ( = ({ ) diff --git a/web/app/components/plugins/install-plugin/install-from-marketplace/steps/install.tsx b/web/app/components/plugins/install-plugin/install-from-marketplace/steps/install.tsx index df5a551339..3fb83e6e7b 100644 --- a/web/app/components/plugins/install-plugin/install-from-marketplace/steps/install.tsx +++ b/web/app/components/plugins/install-plugin/install-from-marketplace/steps/install.tsx @@ -6,21 +6,24 @@ import type { PluginDeclaration } from '../../../types' import Card from '../../../card' import { pluginManifestToCardPluginProps } from '../../utils' import Button from '@/app/components/base/button' -import { sleep } from '@/utils' import { useTranslation } from 'react-i18next' import { RiLoader2Line } from '@remixicon/react' import Badge, { BadgeState } from '@/app/components/base/badge/index' +import { installPackageFromMarketPlace } from '@/service/plugins' +import checkTaskStatus from '../../base/check-task-status' const i18nPrefix = 'plugin.installModal' -type Props = { +interface Props { + uniqueIdentifier: string payload: PluginDeclaration onCancel: () => void onInstalled: () => void - onFailed: () => void + onFailed: (message?: string) => void } const Installed: FC = ({ + uniqueIdentifier, payload, onCancel, onInstalled, @@ -28,13 +31,42 @@ const Installed: FC = ({ }) => { const { t } = useTranslation() const [isInstalling, setIsInstalling] = React.useState(false) + const { + check, + stop, + } = checkTaskStatus() + + const handleCancel = () => { + stop() + onCancel() + } const handleInstall = async () => { if (isInstalling) return setIsInstalling(true) - await sleep(1500) - onInstalled() - // onFailed() + + try { + const { + all_installed: isInstalled, + task_id: taskId, + } = await installPackageFromMarketPlace(uniqueIdentifier) + if (isInstalled) { + onInstalled() + return + } + await check({ + taskId, + pluginUniqueIdentifier: uniqueIdentifier, + }) + onInstalled() + } + catch (e) { + if (typeof e === 'string') { + onFailed(e) + return + } + onFailed() + } } const toInstallVersion = '1.3.0' @@ -77,7 +109,7 @@ const Installed: FC = ({ {/* Action Buttons */}
{!isInstalling && ( - )} diff --git a/web/app/components/plugins/plugin-page/index.tsx b/web/app/components/plugins/plugin-page/index.tsx index 7335dfbb16..fc15fdc81a 100644 --- a/web/app/components/plugins/plugin-page/index.tsx +++ b/web/app/components/plugins/plugin-page/index.tsx @@ -35,7 +35,7 @@ import { sleep } from '@/utils' const PACKAGE_IDS_KEY = 'package-ids' -export type PluginPageProps = { +export interface PluginPageProps { plugins: React.ReactNode marketplace: React.ReactNode } @@ -74,6 +74,9 @@ const PluginPage = ({ (async () => { await sleep(100) if (packageId) { + // setManifest(toolNotionManifest) + // TODO + // const data = await fetchManifest(encodeURIComponent(packageId)) setManifest(toolNotionManifest) showInstallFromMarketplace() } @@ -229,7 +232,7 @@ const PluginPage = ({ isShowInstallFromMarketplace && ( diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts index ba430a87c3..89c557eec7 100644 --- a/web/app/components/plugins/types.ts +++ b/web/app/components/plugins/types.ts @@ -15,7 +15,7 @@ export enum PluginSource { debugging = 'remote', } -export type PluginToolDeclaration = { +export interface PluginToolDeclaration { identity: { author: string name: string @@ -27,17 +27,17 @@ export type PluginToolDeclaration = { credentials_schema: ToolCredential[] // TODO } -export type PluginEndpointDeclaration = { +export interface PluginEndpointDeclaration { settings: ToolCredential[] endpoints: EndpointItem[] } -export type EndpointItem = { +export interface EndpointItem { path: string method: string } -export type EndpointListItem = { +export interface EndpointListItem { id: string created_at: string updated_at: string @@ -53,7 +53,7 @@ export type EndpointListItem = { } // Plugin manifest -export type PluginDeclaration = { +export interface PluginDeclaration { version: string author: string icon: string @@ -70,7 +70,7 @@ export type PluginDeclaration = { model: any // TODO } -export type PluginDetail = { +export interface PluginDetail { id: string created_at: string updated_at: string @@ -87,7 +87,7 @@ export type PluginDetail = { meta?: any } -export type Plugin = { +export interface Plugin { type: PluginType org: string name: string @@ -113,7 +113,7 @@ export enum PermissionType { noOne = 'noOne', } -export type Permissions = { +export interface Permissions { canManagement: PermissionType canDebugger: PermissionType } @@ -125,7 +125,7 @@ export enum InstallStepFromGitHub { installed = 'installed', } -export type InstallState = { +export interface InstallState { step: InstallStepFromGitHub repoUrl: string selectedVersion: string @@ -133,34 +133,34 @@ export type InstallState = { releases: GitHubRepoReleaseResponse[] } -export type GitHubUrlInfo = { +export interface GitHubUrlInfo { isValid: boolean owner?: string repo?: string } // endpoint -export type CreateEndpointRequest = { +export interface CreateEndpointRequest { plugin_unique_identifier: string settings: Record name: string } -export type EndpointOperationResponse = { +export interface EndpointOperationResponse { result: 'success' | 'error' } -export type EndpointsRequest = { +export interface EndpointsRequest { limit: number page: number plugin_id: string } -export type EndpointsResponse = { +export interface EndpointsResponse { endpoints: EndpointListItem[] has_more: boolean limit: number total: number page: number } -export type UpdateEndpointRequest = { +export interface UpdateEndpointRequest { endpoint_id: string settings: Record name: string @@ -175,23 +175,48 @@ export enum InstallStep { installFailed = 'failed', } -export type GitHubAsset = { +export interface GitHubAsset { id: number name: string browser_download_url: string } -export type GitHubRepoReleaseResponse = { +export interface GitHubRepoReleaseResponse { tag_name: string assets: GitHubAsset[] } -export type InstallPackageResponse = { +export interface InstallPackageResponse { plugin_unique_identifier: string + all_installed: boolean + task_id: string } -export type DebugInfo = { +export interface DebugInfo { key: string host: string port: number } + +export enum TaskStatus { + running = 'running', + success = 'success', + failed = 'failed', +} + +export interface PluginStatus { + plugin_unique_identifier: string + plugin_id: string + status: TaskStatus + message: string +} + +export interface TaskStatusResponse { + id: string + created_at: string + updated_at: string + status: string + total_plugins: number + completed_plugins: number + plugins: PluginStatus[] +} diff --git a/web/service/plugins.ts b/web/service/plugins.ts index 655825004d..77664cb8a2 100644 --- a/web/service/plugins.ts +++ b/web/service/plugins.ts @@ -6,6 +6,8 @@ import type { EndpointsRequest, EndpointsResponse, InstallPackageResponse, + PluginDeclaration, + TaskStatusResponse, UpdateEndpointRequest, } from '@/app/components/plugins/types' import type { DebugInfo as DebugInfoTypes } from '@/app/components/plugins/types' @@ -69,6 +71,16 @@ export const installPackageFromLocal = async (uniqueIdentifier: string) => { }) } +export const fetchManifest = async (uniqueIdentifier: string) => { + return get(`/workspaces/current/plugin/fetch-manifest?plugin_unique_identifier=${uniqueIdentifier}`) +} + +export const installPackageFromMarketPlace = async (uniqueIdentifier: string) => { + return post('/workspaces/current/plugin/install/marketplace', { + body: { plugin_unique_identifiers: [uniqueIdentifier] }, + }) +} + export const fetchMarketplaceCollections: Fetcher = ({ url }) => { return get(url) } @@ -76,3 +88,7 @@ export const fetchMarketplaceCollections: Fetcher = ({ url }) => { return get(url) } + +export const checkTaskStatus = async (taskId: string) => { + return get(`/workspaces/current/plugin/tasks/${taskId}`) +} From fd437ff4c59d9aa9b1e0ba7a5c3a71ef852623dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9D=9E=E6=B3=95=E6=93=8D=E4=BD=9C?= Date: Fri, 25 Oct 2024 16:58:50 +0800 Subject: [PATCH 232/346] fix: segement settings of documents raise error (#8971) --- .../datasets/documents/detail/settings/index.tsx | 14 ++++++++------ web/models/datasets.ts | 5 ++++- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/web/app/components/datasets/documents/detail/settings/index.tsx b/web/app/components/datasets/documents/detail/settings/index.tsx index def00ad37b..b264665458 100644 --- a/web/app/components/datasets/documents/detail/settings/index.tsx +++ b/web/app/components/datasets/documents/detail/settings/index.tsx @@ -5,7 +5,7 @@ import { useBoolean } from 'ahooks' import { useContext } from 'use-context-selector' import { useRouter } from 'next/navigation' import DatasetDetailContext from '@/context/dataset-detail' -import type { FullDocumentDetail } from '@/models/datasets' +import type { CrawlOptions, CustomFile, FullDocumentDetail } from '@/models/datasets' import type { MetadataType } from '@/service/datasets' import { fetchDocumentDetail } from '@/service/datasets' @@ -15,6 +15,7 @@ import AccountSetting from '@/app/components/header/account-setting' import AppUnavailable from '@/app/components/base/app-unavailable' import { useDefaultModel } from '@/app/components/header/account-setting/model-provider-page/hooks' import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations' +import type { NotionPage } from '@/models/common' type DocumentSettingsProps = { datasetId: string @@ -40,7 +41,7 @@ const DocumentSettings = ({ datasetId, documentId }: DocumentSettingsProps) => { page_id: documentDetail?.data_source_info.notion_page_id, page_name: documentDetail?.name, page_icon: documentDetail?.data_source_info.notion_page_icon, - type: documentDetail?.data_source_info.type, + type: documentDetail?.data_source_type, } }, [documentDetail]) useEffect(() => { @@ -72,7 +73,7 @@ const DocumentSettings = ({ datasetId, documentId }: DocumentSettingsProps) => { onSetting={showSetAPIKey} datasetId={datasetId} dataSourceType={documentDetail.data_source_type} - notionPages={[currentPage]} + notionPages={[currentPage as unknown as NotionPage]} websitePages={[ { title: documentDetail.name, @@ -81,12 +82,13 @@ const DocumentSettings = ({ datasetId, documentId }: DocumentSettingsProps) => { description: '', }, ]} - fireCrawlJobId={documentDetail.data_source_info?.job_id} - crawlOptions={documentDetail.data_source_info} + websiteCrawlProvider={documentDetail.data_source_info?.provider} + websiteCrawlJobId={documentDetail.data_source_info?.job_id} + crawlOptions={documentDetail.data_source_info as unknown as CrawlOptions} indexingType={indexingTechnique || ''} isSetting documentDetail={documentDetail} - files={[documentDetail.data_source_info.upload_file]} + files={[documentDetail.data_source_info.upload_file as CustomFile]} onSave={saveHandler} onCancel={cancelHandler} /> diff --git a/web/models/datasets.ts b/web/models/datasets.ts index 1ecaa3e10b..95c7ce45de 100644 --- a/web/models/datasets.ts +++ b/web/models/datasets.ts @@ -1,4 +1,4 @@ -import type { DataSourceNotionPage } from './common' +import type { DataSourceNotionPage, DataSourceProvider } from './common' import type { AppIconType, AppMode, RetrievalConfig } from '@/types/app' import type { Tag } from '@/app/components/base/tag-management/constant' @@ -230,6 +230,9 @@ export type DataSourceInfo = { extension: string } notion_page_icon?: string + notion_workspace_id?: string + notion_page_id?: string + provider?: DataSourceProvider job_id: string url: string } From caf7bc856956b4b472f5921a6fc22b0b74c72c85 Mon Sep 17 00:00:00 2001 From: Jyong <76649700+JohnJyong@users.noreply.github.com> Date: Fri, 25 Oct 2024 17:15:44 +0800 Subject: [PATCH 233/346] upgrade nltk, unstructured and starlette (#9860) --- api/poetry.lock | 320 ++++++++++++++++++++++++++------------------- api/pyproject.toml | 5 +- 2 files changed, 191 insertions(+), 134 deletions(-) diff --git a/api/poetry.lock b/api/poetry.lock index a0d418ba7b..618dbb4033 100644 --- a/api/poetry.lock +++ b/api/poetry.lock @@ -847,13 +847,13 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] [[package]] name = "botocore" -version = "1.35.46" +version = "1.35.47" description = "Low-level, data-driven core of boto 3." optional = false python-versions = ">=3.8" files = [ - {file = "botocore-1.35.46-py3-none-any.whl", hash = "sha256:8bbc9a55cae65a8db7f2e33ff087f4dbfc13fce868e8e3c5273ce9af367a555a"}, - {file = "botocore-1.35.46.tar.gz", hash = "sha256:8c0ff5fdd611a28f5752189d171c69690dbc484fa06d74376890bb0543ec3dc1"}, + {file = "botocore-1.35.47-py3-none-any.whl", hash = "sha256:05f4493119a96799ff84d43e78691efac3177e1aec8840cca99511de940e342a"}, + {file = "botocore-1.35.47.tar.gz", hash = "sha256:f8f703463d3cd8b6abe2bedc443a7ab29f0e2ff1588a2e83164b108748645547"}, ] [package.dependencies] @@ -2342,6 +2342,20 @@ files = [ {file = "et_xmlfile-1.1.0.tar.gz", hash = "sha256:8eb9e2bc2f8c97e37a2dc85a09ecdcdec9d8a396530a6d5a33b30b9a92da0c5c"}, ] +[[package]] +name = "eval-type-backport" +version = "0.2.0" +description = "Like `typing._eval_type`, but lets older Python versions use newer typing features." +optional = false +python-versions = ">=3.8" +files = [ + {file = "eval_type_backport-0.2.0-py3-none-any.whl", hash = "sha256:ac2f73d30d40c5a30a80b8739a789d6bb5e49fdffa66d7912667e2015d9c9933"}, + {file = "eval_type_backport-0.2.0.tar.gz", hash = "sha256:68796cfbc7371ebf923f03bdf7bef415f3ec098aeced24e054b253a0e78f7b37"}, +] + +[package.extras] +tests = ["pytest"] + [[package]] name = "exceptiongroup" version = "1.2.2" @@ -4279,6 +4293,17 @@ files = [ [package.dependencies] ply = "*" +[[package]] +name = "jsonpath-python" +version = "1.0.6" +description = "A more powerful JSONPath implementation in modern python" +optional = false +python-versions = ">=3.6" +files = [ + {file = "jsonpath-python-1.0.6.tar.gz", hash = "sha256:dd5be4a72d8a2995c3f583cf82bf3cd1a9544cfdabf2d22595b67aff07349666"}, + {file = "jsonpath_python-1.0.6-py3-none-any.whl", hash = "sha256:1e3b78df579f5efc23565293612decee04214609208a2335884b3ee3f786b575"}, +] + [[package]] name = "jsonschema" version = "4.23.0" @@ -5265,23 +5290,6 @@ files = [ msal = ">=1.29,<2" portalocker = ">=1.4,<3" -[[package]] -name = "msg-parser" -version = "1.2.0" -description = "This module enables reading, parsing and converting Microsoft Outlook MSG E-Mail files." -optional = false -python-versions = ">=3.4" -files = [ - {file = "msg_parser-1.2.0-py2.py3-none-any.whl", hash = "sha256:d47a2f0b2a359cb189fad83cc991b63ea781ecc70d91410324273fbf93e95375"}, - {file = "msg_parser-1.2.0.tar.gz", hash = "sha256:0de858d4fcebb6c8f6f028da83a17a20fe01cdce67c490779cf43b3b0162aa66"}, -] - -[package.dependencies] -olefile = ">=0.46" - -[package.extras] -rtf = ["compressed-rtf (>=1.0.5)"] - [[package]] name = "msrest" version = "0.7.1" @@ -5457,6 +5465,17 @@ files = [ {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, ] +[[package]] +name = "nest-asyncio" +version = "1.6.0" +description = "Patch asyncio to allow nested event loops" +optional = false +python-versions = ">=3.5" +files = [ + {file = "nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c"}, + {file = "nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe"}, +] + [[package]] name = "newspaper3k" version = "0.2.8" @@ -5485,13 +5504,13 @@ tldextract = ">=2.0.1" [[package]] name = "nltk" -version = "3.8.1" +version = "3.9.1" description = "Natural Language Toolkit" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "nltk-3.8.1-py3-none-any.whl", hash = "sha256:fd5c9109f976fa86bcadba8f91e47f5e9293bd034474752e92a520f81c93dda5"}, - {file = "nltk-3.8.1.zip", hash = "sha256:1834da3d0682cba4f2cede2f9aad6b0fafb6461ba451db0efb6f9c39798d64d3"}, + {file = "nltk-3.9.1-py3-none-any.whl", hash = "sha256:4fa26829c5b00715afe3061398a8989dc643b92ce7dd93fb4585a70930d168a1"}, + {file = "nltk-3.9.1.tar.gz", hash = "sha256:87d127bd3de4bd89a4f81265e5fa59cb1b199b27440175370f7417d2bc7ae868"}, ] [package.dependencies] @@ -5780,13 +5799,13 @@ sympy = "*" [[package]] name = "openai" -version = "1.52.1" +version = "1.52.2" description = "The official Python library for the openai API" optional = false python-versions = ">=3.7.1" files = [ - {file = "openai-1.52.1-py3-none-any.whl", hash = "sha256:f23e83df5ba04ee0e82c8562571e8cb596cd88f9a84ab783e6c6259e5ffbfb4a"}, - {file = "openai-1.52.1.tar.gz", hash = "sha256:383b96c7e937cbec23cad5bf5718085381e4313ca33c5c5896b54f8e1b19d144"}, + {file = "openai-1.52.2-py3-none-any.whl", hash = "sha256:57e9e37bc407f39bb6ec3a27d7e8fb9728b2779936daa1fcf95df17d3edfaccc"}, + {file = "openai-1.52.2.tar.gz", hash = "sha256:87b7d0f69d85f5641678d414b7ee3082363647a5c66a462ed7f3ccb59582da0d"}, ] [package.dependencies] @@ -6638,13 +6657,13 @@ wcwidth = "*" [[package]] name = "proto-plus" -version = "1.24.0" +version = "1.25.0" description = "Beautiful, Pythonic protocol buffers." optional = false python-versions = ">=3.7" files = [ - {file = "proto-plus-1.24.0.tar.gz", hash = "sha256:30b72a5ecafe4406b0d339db35b56c4059064e69227b8c3bda7462397f966445"}, - {file = "proto_plus-1.24.0-py3-none-any.whl", hash = "sha256:402576830425e5f6ce4c2a6702400ac79897dab0b4343821aa5188b0fab81a12"}, + {file = "proto_plus-1.25.0-py3-none-any.whl", hash = "sha256:c91fc4a65074ade8e458e95ef8bac34d4008daa7cce4a12d6707066fca648961"}, + {file = "proto_plus-1.25.0.tar.gz", hash = "sha256:fbb17f57f7bd05a68b7707e745e26528b0b3c34e378db91eef93912c54982d91"}, ] [package.dependencies] @@ -7240,6 +7259,27 @@ files = [ [package.extras] diagrams = ["jinja2", "railroad-diagrams"] +[[package]] +name = "pypdf" +version = "5.0.1" +description = "A pure-python PDF library capable of splitting, merging, cropping, and transforming PDF files" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pypdf-5.0.1-py3-none-any.whl", hash = "sha256:ff8a32da6c7a63fea9c32fa4dd837cdd0db7966adf6c14f043e3f12592e992db"}, + {file = "pypdf-5.0.1.tar.gz", hash = "sha256:a361c3c372b4a659f9c8dd438d5ce29a753c79c620dc6e1fd66977651f5547ea"}, +] + +[package.dependencies] +typing_extensions = {version = ">=4.0", markers = "python_version < \"3.11\""} + +[package.extras] +crypto = ["PyCryptodome", "cryptography"] +dev = ["black", "flit", "pip-tools", "pre-commit (<2.18.0)", "pytest-cov", "pytest-socket", "pytest-timeout", "pytest-xdist", "wheel"] +docs = ["myst_parser", "sphinx", "sphinx_rtd_theme"] +full = ["Pillow (>=8.0.0)", "PyCryptodome", "cryptography"] +image = ["Pillow (>=8.0.0)"] + [[package]] name = "pypdfium2" version = "4.17.0" @@ -7495,13 +7535,13 @@ files = [ [[package]] name = "python-dateutil" -version = "2.9.0.post0" +version = "2.8.2" description = "Extensions to the standard Python datetime module" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ - {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, - {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, + {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, + {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, ] [package.dependencies] @@ -7562,19 +7602,36 @@ files = [ ] [[package]] -name = "python-pptx" -version = "0.6.23" -description = "Generate and manipulate Open XML PowerPoint (.pptx) files" +name = "python-oxmsg" +version = "0.0.1" +description = "Extract attachments from Outlook .msg files." optional = false -python-versions = "*" +python-versions = ">=3.9" files = [ - {file = "python-pptx-0.6.23.tar.gz", hash = "sha256:587497ff28e779ab18dbb074f6d4052893c85dedc95ed75df319364f331fedee"}, - {file = "python_pptx-0.6.23-py3-none-any.whl", hash = "sha256:dd0527194627a2b7cc05f3ba23ecaa2d9a0d5ac9b6193a28ed1b7a716f4217d4"}, + {file = "python_oxmsg-0.0.1-py3-none-any.whl", hash = "sha256:8ea7d5dda1bc161a413213da9e18ed152927c1fda2feaf5d1f02192d8ad45eea"}, + {file = "python_oxmsg-0.0.1.tar.gz", hash = "sha256:b65c1f93d688b85a9410afa824192a1ddc39da359b04a0bd2cbd3874e84d4994"}, +] + +[package.dependencies] +click = "*" +olefile = "*" +typing-extensions = ">=4.9.0" + +[[package]] +name = "python-pptx" +version = "1.0.2" +description = "Create, read, and update PowerPoint 2007+ (.pptx) files." +optional = false +python-versions = ">=3.8" +files = [ + {file = "python_pptx-1.0.2-py3-none-any.whl", hash = "sha256:160838e0b8565a8b1f67947675886e9fea18aa5e795db7ae531606d68e785cba"}, + {file = "python_pptx-1.0.2.tar.gz", hash = "sha256:479a8af0eaf0f0d76b6f00b0887732874ad2e3188230315290cd1f9dd9cc7095"}, ] [package.dependencies] lxml = ">=3.1.0" Pillow = ">=3.3.2" +typing-extensions = ">=4.9.0" XlsxWriter = ">=0.5.7" [[package]] @@ -9143,13 +9200,13 @@ test = ["pytest", "tornado (>=4.5)", "typeguard"] [[package]] name = "tencentcloud-sdk-python-common" -version = "3.0.1256" +version = "3.0.1257" description = "Tencent Cloud Common SDK for Python" optional = false python-versions = "*" files = [ - {file = "tencentcloud-sdk-python-common-3.0.1256.tar.gz", hash = "sha256:83c7b4154f502d67741486cbeae99e734aaf0bfe7eb2cdc9e77916cce9017f17"}, - {file = "tencentcloud_sdk_python_common-3.0.1256-py2.py3-none-any.whl", hash = "sha256:2639f3510743003add35f97c7717680ff357b5324ce3bd67466c19dafe4e7f0b"}, + {file = "tencentcloud-sdk-python-common-3.0.1257.tar.gz", hash = "sha256:e10b155d598a60c43a491be10f40f7dae5774a2187d55f2da83bdb559434f3c4"}, + {file = "tencentcloud_sdk_python_common-3.0.1257-py2.py3-none-any.whl", hash = "sha256:f474a2969f3cbff91f45780f18bfbb90ab53f66c0085c4e9b4e07c2fcf0e71d9"}, ] [package.dependencies] @@ -9157,17 +9214,17 @@ requests = ">=2.16.0" [[package]] name = "tencentcloud-sdk-python-hunyuan" -version = "3.0.1256" +version = "3.0.1257" description = "Tencent Cloud Hunyuan SDK for Python" optional = false python-versions = "*" files = [ - {file = "tencentcloud-sdk-python-hunyuan-3.0.1256.tar.gz", hash = "sha256:bbc72cd4ef8aacde6ff186521be9ba62eb795eab673fa8e87a4e51e91d33cb95"}, - {file = "tencentcloud_sdk_python_hunyuan-3.0.1256-py2.py3-none-any.whl", hash = "sha256:fbc2e66aac8a9279c560e041a843c2a6884c9145846e6215cde59fa0a127e7e1"}, + {file = "tencentcloud-sdk-python-hunyuan-3.0.1257.tar.gz", hash = "sha256:4d38505089bed70dda1f806f8c4835f8a8c520efa86dcecfef444045c21b695d"}, + {file = "tencentcloud_sdk_python_hunyuan-3.0.1257-py2.py3-none-any.whl", hash = "sha256:c9089d3e49304c9c20e7465c82372b2cd234e67f63efdffb6798a4093b3a97c6"}, ] [package.dependencies] -tencentcloud-sdk-python-common = "3.0.1256" +tencentcloud-sdk-python-common = "3.0.1257" [[package]] name = "threadpoolctl" @@ -9703,13 +9760,13 @@ files = [ [[package]] name = "unstructured" -version = "0.10.30" +version = "0.16.1" description = "A library that prepares raw documents for downstream ML tasks." optional = false -python-versions = ">=3.7.0" +python-versions = "<3.13,>=3.9.0" files = [ - {file = "unstructured-0.10.30-py3-none-any.whl", hash = "sha256:0615f14daa37450e9c0fcf3c3fd178c3a06b6b8d006a36d1a5e54dbe487aa6b6"}, - {file = "unstructured-0.10.30.tar.gz", hash = "sha256:a86c3d15c572a28322d83cb5ecf0ac7a24f1c36864fb7c68df096de8a1acc106"}, + {file = "unstructured-0.16.1-py3-none-any.whl", hash = "sha256:7512281a2917809a563cbb186876b77d5a361e1f3089eca61e9219aecd1218f9"}, + {file = "unstructured-0.16.1.tar.gz", hash = "sha256:03608b5189a004412cd618ce2d083ff926c56dbbca41b41c92e08ffa9e2bac3a"}, ] [package.dependencies] @@ -9719,71 +9776,70 @@ chardet = "*" dataclasses-json = "*" emoji = "*" filetype = "*" +html5lib = "*" langdetect = "*" lxml = "*" markdown = {version = "*", optional = true, markers = "extra == \"md\""} -msg-parser = {version = "*", optional = true, markers = "extra == \"msg\""} nltk = "*" -numpy = "*" +numpy = "<2" +psutil = "*" pypandoc = {version = "*", optional = true, markers = "extra == \"epub\""} -python-docx = {version = ">=1.1.0", optional = true, markers = "extra == \"docx\""} +python-docx = {version = ">=1.1.2", optional = true, markers = "extra == \"docx\""} python-iso639 = "*" python-magic = "*" -python-pptx = {version = "<=0.6.23", optional = true, markers = "extra == \"ppt\" or extra == \"pptx\""} +python-oxmsg = "*" +python-pptx = {version = ">=1.0.1", optional = true, markers = "extra == \"ppt\" or extra == \"pptx\""} rapidfuzz = "*" requests = "*" -tabulate = "*" +tqdm = "*" typing-extensions = "*" +unstructured-client = "*" +wrapt = "*" [package.extras] -airtable = ["pyairtable"] -all-docs = ["markdown", "msg-parser", "networkx", "onnx", "openpyxl", "pandas", "pdf2image", "pdfminer.six", "pypandoc", "python-docx (>=1.1.0)", "python-pptx (<=0.6.23)", "unstructured-inference (==0.7.11)", "unstructured.pytesseract (>=0.3.12)", "xlrd"] -azure = ["adlfs", "fsspec (==2023.9.1)"] -azure-cognitive-search = ["azure-search-documents"] -bedrock = ["boto3", "langchain"] -biomed = ["bs4"] -box = ["boxfs", "fsspec (==2023.9.1)"] -confluence = ["atlassian-python-api"] +all-docs = ["effdet", "google-cloud-vision", "markdown", "networkx", "onnx", "openpyxl", "pandas", "pdf2image", "pdfminer.six", "pi-heif", "pikepdf", "pypandoc", "pypdf", "python-docx (>=1.1.2)", "python-pptx (>=1.0.1)", "unstructured-inference (==0.8.0)", "unstructured.pytesseract (>=0.3.12)", "xlrd"] csv = ["pandas"] -delta-table = ["deltalake", "fsspec (==2023.9.1)"] -discord = ["discord-py"] -doc = ["python-docx (>=1.1.0)"] -docx = ["python-docx (>=1.1.0)"] -dropbox = ["dropboxdrivefs", "fsspec (==2023.9.1)"] -elasticsearch = ["elasticsearch", "jq"] -embed-huggingface = ["huggingface", "langchain", "sentence-transformers"] +doc = ["python-docx (>=1.1.2)"] +docx = ["python-docx (>=1.1.2)"] epub = ["pypandoc"] -gcs = ["bs4", "fsspec (==2023.9.1)", "gcsfs"] -github = ["pygithub (>1.58.0)"] -gitlab = ["python-gitlab"] -google-drive = ["google-api-python-client"] huggingface = ["langdetect", "sacremoses", "sentencepiece", "torch", "transformers"] -image = ["onnx", "pdf2image", "pdfminer.six", "unstructured-inference (==0.7.11)", "unstructured.pytesseract (>=0.3.12)"] -jira = ["atlassian-python-api"] -local-inference = ["markdown", "msg-parser", "networkx", "onnx", "openpyxl", "pandas", "pdf2image", "pdfminer.six", "pypandoc", "python-docx (>=1.1.0)", "python-pptx (<=0.6.23)", "unstructured-inference (==0.7.11)", "unstructured.pytesseract (>=0.3.12)", "xlrd"] +image = ["effdet", "google-cloud-vision", "onnx", "pdf2image", "pdfminer.six", "pi-heif", "pikepdf", "pypdf", "unstructured-inference (==0.8.0)", "unstructured.pytesseract (>=0.3.12)"] +local-inference = ["effdet", "google-cloud-vision", "markdown", "networkx", "onnx", "openpyxl", "pandas", "pdf2image", "pdfminer.six", "pi-heif", "pikepdf", "pypandoc", "pypdf", "python-docx (>=1.1.2)", "python-pptx (>=1.0.1)", "unstructured-inference (==0.8.0)", "unstructured.pytesseract (>=0.3.12)", "xlrd"] md = ["markdown"] -msg = ["msg-parser"] -notion = ["htmlBuilder", "notion-client"] -odt = ["pypandoc", "python-docx (>=1.1.0)"] -onedrive = ["Office365-REST-Python-Client (<2.4.3)", "bs4", "msal"] -openai = ["langchain", "openai", "tiktoken"] +odt = ["pypandoc", "python-docx (>=1.1.2)"] org = ["pypandoc"] -outlook = ["Office365-REST-Python-Client (<2.4.3)", "msal"] -paddleocr = ["unstructured.paddleocr (==2.6.1.3)"] -pdf = ["onnx", "pdf2image", "pdfminer.six", "unstructured-inference (==0.7.11)", "unstructured.pytesseract (>=0.3.12)"] -ppt = ["python-pptx (<=0.6.23)"] -pptx = ["python-pptx (<=0.6.23)"] -reddit = ["praw"] +paddleocr = ["paddlepaddle (==3.0.0b1)", "unstructured.paddleocr (==2.8.1.0)"] +pdf = ["effdet", "google-cloud-vision", "onnx", "pdf2image", "pdfminer.six", "pi-heif", "pikepdf", "pypdf", "unstructured-inference (==0.8.0)", "unstructured.pytesseract (>=0.3.12)"] +ppt = ["python-pptx (>=1.0.1)"] +pptx = ["python-pptx (>=1.0.1)"] rst = ["pypandoc"] rtf = ["pypandoc"] -s3 = ["fsspec (==2023.9.1)", "s3fs"] -salesforce = ["simple-salesforce"] -sharepoint = ["Office365-REST-Python-Client (<2.4.3)", "msal"] -slack = ["slack-sdk"] tsv = ["pandas"] -wikipedia = ["wikipedia"] xlsx = ["networkx", "openpyxl", "pandas", "xlrd"] +[[package]] +name = "unstructured-client" +version = "0.26.1" +description = "Python Client SDK for Unstructured API" +optional = false +python-versions = "<4.0,>=3.8" +files = [ + {file = "unstructured_client-0.26.1-py3-none-any.whl", hash = "sha256:b8b839d477122bab3f37242cbe44b39f7eb7b564b07b53500321f953710119b6"}, + {file = "unstructured_client-0.26.1.tar.gz", hash = "sha256:907cceb470529b45b0fddb2d0f1bbf4d6568f347c757ab68639a7bb620ec2484"}, +] + +[package.dependencies] +cryptography = ">=3.1" +eval-type-backport = ">=0.2.0,<0.3.0" +httpx = ">=0.27.0" +jsonpath-python = ">=1.0.6,<2.0.0" +nest-asyncio = ">=1.6.0" +pydantic = ">=2.9.0,<2.10.0" +pypdf = ">=4.0" +python-dateutil = "2.8.2" +requests-toolbelt = ">=1.0.0" +typing-inspect = ">=0.9.0,<0.10.0" + [[package]] name = "upstash-vector" version = "0.6.0" @@ -10643,48 +10699,48 @@ test = ["zope.testrunner"] [[package]] name = "zope-interface" -version = "7.1.0" +version = "7.1.1" description = "Interfaces for Python" optional = false python-versions = ">=3.8" files = [ - {file = "zope.interface-7.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2bd9e9f366a5df08ebbdc159f8224904c1c5ce63893984abb76954e6fbe4381a"}, - {file = "zope.interface-7.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:661d5df403cd3c5b8699ac480fa7f58047a3253b029db690efa0c3cf209993ef"}, - {file = "zope.interface-7.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91b6c30689cfd87c8f264acb2fc16ad6b3c72caba2aec1bf189314cf1a84ca33"}, - {file = "zope.interface-7.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b6a4924f5bad9fe21d99f66a07da60d75696a136162427951ec3cb223a5570d"}, - {file = "zope.interface-7.1.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80a3c00b35f6170be5454b45abe2719ea65919a2f09e8a6e7b1362312a872cd3"}, - {file = "zope.interface-7.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:b936d61dbe29572fd2cfe13e30b925e5383bed1aba867692670f5a2a2eb7b4e9"}, - {file = "zope.interface-7.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0ac20581fc6cd7c754f6dff0ae06fedb060fa0e9ea6309d8be8b2701d9ea51c4"}, - {file = "zope.interface-7.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:848b6fa92d7c8143646e64124ed46818a0049a24ecc517958c520081fd147685"}, - {file = "zope.interface-7.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec1ef1fdb6f014d5886b97e52b16d0f852364f447d2ab0f0c6027765777b6667"}, - {file = "zope.interface-7.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3bcff5c09d0215f42ba64b49205a278e44413d9bf9fa688fd9e42bfe472b5f4f"}, - {file = "zope.interface-7.1.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07add15de0cc7e69917f7d286b64d54125c950aeb43efed7a5ea7172f000fbc1"}, - {file = "zope.interface-7.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:9940d5bc441f887c5f375ec62bcf7e7e495a2d5b1da97de1184a88fb567f06af"}, - {file = "zope.interface-7.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f245d039f72e6f802902375755846f5de1ee1e14c3e8736c078565599bcab621"}, - {file = "zope.interface-7.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6159e767d224d8f18deff634a1d3722e68d27488c357f62ebeb5f3e2f5288b1f"}, - {file = "zope.interface-7.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e956b1fd7f3448dd5e00f273072e73e50dfafcb35e4227e6d5af208075593c9"}, - {file = "zope.interface-7.1.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff115ef91c0eeac69cd92daeba36a9d8e14daee445b504eeea2b1c0b55821984"}, - {file = "zope.interface-7.1.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bec001798ab62c3fc5447162bf48496ae9fba02edc295a9e10a0b0c639a6452e"}, - {file = "zope.interface-7.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:124149e2d42067b9c6597f4dafdc7a0983d0163868f897b7bb5dc850b14f9a87"}, - {file = "zope.interface-7.1.0-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:9733a9a0f94ef53d7aa64661811b20875b5bc6039034c6e42fb9732170130573"}, - {file = "zope.interface-7.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5fcf379b875c610b5a41bc8a891841533f98de0520287d7f85e25386cd10d3e9"}, - {file = "zope.interface-7.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0a45b5af9f72c805ee668d1479480ca85169312211bed6ed18c343e39307d5f"}, - {file = "zope.interface-7.1.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4af4a12b459a273b0b34679a5c3dc5e34c1847c3dd14a628aa0668e19e638ea2"}, - {file = "zope.interface-7.1.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a735f82d2e3ed47ca01a20dfc4c779b966b16352650a8036ab3955aad151ed8a"}, - {file = "zope.interface-7.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:5501e772aff595e3c54266bc1bfc5858e8f38974ce413a8f1044aae0f32a83a3"}, - {file = "zope.interface-7.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ec59fe53db7d32abb96c6d4efeed84aab4a7c38c62d7a901a9b20c09dd936e7a"}, - {file = "zope.interface-7.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e53c291debef523b09e1fe3dffe5f35dde164f1c603d77f770b88a1da34b7ed6"}, - {file = "zope.interface-7.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:711eebc77f2092c6a8b304bad0b81a6ce3cf5490b25574e7309fbc07d881e3af"}, - {file = "zope.interface-7.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a00ead2e24c76436e1b457a5132d87f83858330f6c923640b7ef82d668525d1"}, - {file = "zope.interface-7.1.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e28ea0bc4b084fc93a483877653a033062435317082cdc6388dec3438309faf"}, - {file = "zope.interface-7.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:27cfb5205d68b12682b6e55ab8424662d96e8ead19550aad0796b08dd2c9a45e"}, - {file = "zope.interface-7.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9e3e48f3dea21c147e1b10c132016cb79af1159facca9736d231694ef5a740a8"}, - {file = "zope.interface-7.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a99240b1d02dc469f6afbe7da1bf617645e60290c272968f4e53feec18d7dce8"}, - {file = "zope.interface-7.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc8a318162123eddbdf22fcc7b751288ce52e4ad096d3766ff1799244352449d"}, - {file = "zope.interface-7.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7b25db127db3e6b597c5f74af60309c4ad65acd826f89609662f0dc33a54728"}, - {file = "zope.interface-7.1.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2a29ac607e970b5576547f0e3589ec156e04de17af42839eedcf478450687317"}, - {file = "zope.interface-7.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:a14c9decf0eb61e0892631271d500c1e306c7b6901c998c7035e194d9150fdd1"}, - {file = "zope_interface-7.1.0.tar.gz", hash = "sha256:3f005869a1a05e368965adb2075f97f8ee9a26c61898a9e52a9764d93774f237"}, + {file = "zope.interface-7.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6650bd56ef350d37c8baccfd3ee8a0483ed6f8666e641e4b9ae1a1827b79f9e5"}, + {file = "zope.interface-7.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:84e87eba6b77a3af187bae82d8de1a7c208c2a04ec9f6bd444fd091b811ad92e"}, + {file = "zope.interface-7.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c4e1b4c06d9abd1037c088dae1566c85f344a3e6ae4350744c3f7f7259d9c67"}, + {file = "zope.interface-7.1.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7cd5e3d910ac87652a09f6e5db8e41bc3b49cf08ddd2d73d30afc644801492cd"}, + {file = "zope.interface-7.1.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca95594d936ee349620900be5b46c0122a1ff6ce42d7d5cb2cf09dc84071ef16"}, + {file = "zope.interface-7.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:ad339509dcfbbc99bf8e147db6686249c4032f26586699ec4c82f6e5909c9fe2"}, + {file = "zope.interface-7.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3e59f175e868f856a77c0a77ba001385c377df2104fdbda6b9f99456a01e102a"}, + {file = "zope.interface-7.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0de23bcb93401994ea00bc5c677ef06d420340ac0a4e9c10d80e047b9ce5af3f"}, + {file = "zope.interface-7.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cdb7e7e5524b76d3ec037c1d81a9e2c7457b240fd4cb0a2476b65c3a5a6c81f"}, + {file = "zope.interface-7.1.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3603ef82a9920bd0bfb505423cb7e937498ad971ad5a6141841e8f76d2fd5446"}, + {file = "zope.interface-7.1.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f1d52d052355e0c5c89e0630dd2ff7c0b823fd5f56286a663e92444761b35e25"}, + {file = "zope.interface-7.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:179ad46ece518c9084cb272e4a69d266b659f7f8f48e51706746c2d8a426433e"}, + {file = "zope.interface-7.1.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e6503534b52bb1720ace9366ee30838a58a3413d3e197512f3338c8f34b5d89d"}, + {file = "zope.interface-7.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f85b290e5b8b11814efb0d004d8ce6c9a483c35c462e8d9bf84abb93e79fa770"}, + {file = "zope.interface-7.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d029fac6a80edae80f79c37e5e3abfa92968fe921886139b3ee470a1b177321a"}, + {file = "zope.interface-7.1.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5836b8fb044c6e75ba34dfaabc602493019eadfa0faf6ff25f4c4c356a71a853"}, + {file = "zope.interface-7.1.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7395f13533318f150ee72adb55b29284b16e73b6d5f02ab21f173b3e83f242b8"}, + {file = "zope.interface-7.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:1d0e23c6b746eb8ce04573cc47bcac60961ac138885d207bd6f57e27a1431ae8"}, + {file = "zope.interface-7.1.1-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:9fad9bd5502221ab179f13ea251cb30eef7cf65023156967f86673aff54b53a0"}, + {file = "zope.interface-7.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:55c373becbd36a44d0c9be1d5271422fdaa8562d158fb44b4192297b3c67096c"}, + {file = "zope.interface-7.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed1df8cc01dd1e3970666a7370b8bfc7457371c58ba88c57bd5bca17ab198053"}, + {file = "zope.interface-7.1.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99c14f0727c978639139e6cad7a60e82b7720922678d75aacb90cf4ef74a068c"}, + {file = "zope.interface-7.1.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9b1eed7670d564f1025d7cda89f99f216c30210e42e95de466135be0b4a499d9"}, + {file = "zope.interface-7.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:3defc925c4b22ac1272d544a49c6ba04c3eefcce3200319ee1be03d9270306dd"}, + {file = "zope.interface-7.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8d0fe45be57b5219aa4b96e846631c04615d5ef068146de5a02ccd15c185321f"}, + {file = "zope.interface-7.1.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bcbeb44fc16e0078b3b68a95e43f821ae34dcbf976dde6985141838a5f23dd3d"}, + {file = "zope.interface-7.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c8e7b05dc6315a193cceaec071cc3cf1c180cea28808ccded0b1283f1c38ba73"}, + {file = "zope.interface-7.1.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2d553e02b68c0ea5a226855f02edbc9eefd99f6a8886fa9f9bdf999d77f46585"}, + {file = "zope.interface-7.1.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81744a7e61b598ebcf4722ac56a7a4f50502432b5b4dc7eb29075a89cf82d029"}, + {file = "zope.interface-7.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:7720322763aceb5e0a7cadcc38c67b839efe599f0887cbf6c003c55b1458c501"}, + {file = "zope.interface-7.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1a2ed0852c25950cf430067f058f8d98df6288502ac313861d9803fe7691a9b3"}, + {file = "zope.interface-7.1.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9595e478047ce752b35cfa221d7601a5283ccdaab40422e0dc1d4a334c70f580"}, + {file = "zope.interface-7.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2317e1d4dba68203a5227ea3057f9078ec9376275f9700086b8f0ffc0b358e1b"}, + {file = "zope.interface-7.1.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6821ef9870f32154da873fcde439274f99814ea452dd16b99fa0b66345c4b6b"}, + {file = "zope.interface-7.1.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:190eeec67e023d5aac54d183fa145db0b898664234234ac54643a441da434616"}, + {file = "zope.interface-7.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:d17e7fc814eaab93409b80819fd6d30342844345c27f3bc3c4b43c2425a8d267"}, + {file = "zope.interface-7.1.1.tar.gz", hash = "sha256:4284d664ef0ff7b709836d4de7b13d80873dc5faeffc073abdb280058bfac5e3"}, ] [package.dependencies] @@ -10810,4 +10866,4 @@ cffi = ["cffi (>=1.11)"] [metadata] lock-version = "2.0" python-versions = ">=3.10,<3.13" -content-hash = "32fd52006f75e42fbc8f787e559a72f4e033383c73225231e4ecadabfec926f7" +content-hash = "1b268122d3d4771ba219f0e983322e0454b7b8644dba35da38d7d950d489e1ba" diff --git a/api/pyproject.toml b/api/pyproject.toml index e9529a192e..a549601535 100644 --- a/api/pyproject.toml +++ b/api/pyproject.toml @@ -172,11 +172,12 @@ sagemaker = "2.231.0" scikit-learn = "~1.5.1" sentry-sdk = { version = "~1.44.1", extras = ["flask"] } sqlalchemy = "~2.0.29" +starlette = "0.41.0" tencentcloud-sdk-python-hunyuan = "~3.0.1158" tiktoken = "~0.8.0" tokenizers = "~0.15.0" transformers = "~4.35.0" -unstructured = { version = "~0.10.27", extras = ["docx", "epub", "md", "msg", "ppt", "pptx"] } +unstructured = { version = "~0.16.1", extras = ["docx", "epub", "md", "msg", "ppt", "pptx"] } validators = "0.21.0" volcengine-python-sdk = {extras = ["ark"], version = "~1.0.98"} websocket-client = "~1.7.0" @@ -206,7 +207,7 @@ duckduckgo-search = "~6.3.0" jsonpath-ng = "1.6.1" matplotlib = "~3.8.2" newspaper3k = "0.2.8" -nltk = "3.8.1" +nltk = "3.9.1" numexpr = "~2.9.0" pydub = "~0.25.1" qrcode = "~7.4.2" From eec63b112fabac6834f5c004ea4a632362bd07b0 Mon Sep 17 00:00:00 2001 From: zhuhao <37029601+hwzhuhao@users.noreply.github.com> Date: Fri, 25 Oct 2024 17:16:07 +0800 Subject: [PATCH 234/346] chore: add default value for redis configuration (#9864) --- api/.env.example | 9 +++++++++ docker/.env.example | 3 +++ docker/docker-compose.yaml | 8 ++++---- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/api/.env.example b/api/.env.example index 960d8b1879..184a811c51 100644 --- a/api/.env.example +++ b/api/.env.example @@ -31,8 +31,17 @@ REDIS_HOST=localhost REDIS_PORT=6379 REDIS_USERNAME= REDIS_PASSWORD=difyai123456 +REDIS_USE_SSL=false REDIS_DB=0 +# redis Sentinel configuration. +REDIS_USE_SENTINEL=false +REDIS_SENTINELS= +REDIS_SENTINEL_SERVICE_NAME= +REDIS_SENTINEL_USERNAME= +REDIS_SENTINEL_PASSWORD= +REDIS_SENTINEL_SOCKET_TIMEOUT=0.1 + # PostgreSQL database configuration DB_USERNAME=postgres DB_PASSWORD=difyai123456 diff --git a/docker/.env.example b/docker/.env.example index 0a9e0814c7..49ce48a20d 100644 --- a/docker/.env.example +++ b/docker/.env.example @@ -222,6 +222,7 @@ REDIS_PORT=6379 REDIS_USERNAME= REDIS_PASSWORD=difyai123456 REDIS_USE_SSL=false +REDIS_DB=0 # Whether to use Redis Sentinel mode. # If set to true, the application will automatically discover and connect to the master node through Sentinel. @@ -273,6 +274,7 @@ CONSOLE_CORS_ALLOW_ORIGINS=* # Supported values are `local` , `s3` , `azure-blob` , `google-storage`, `tencent-cos`, `huawei-obs`, `volcengine-tos`, `baidu-obs`, `supabase` # Default: `local` STORAGE_TYPE=local +STORAGE_LOCAL_PATH=storage # S3 Configuration # Whether to use AWS managed IAM roles for authenticating with the S3 service. @@ -591,6 +593,7 @@ MAIL_DEFAULT_SEND_FROM= # API-Key for the Resend email provider, used when MAIL_TYPE is `resend`. RESEND_API_KEY=your-resend-api-key +RESEND_API_URL=https://api.resend.com # SMTP server configuration, used when MAIL_TYPE is `smtp` SMTP_SERVER= diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml index 24e1328e95..d43bd5e2d1 100644 --- a/docker/docker-compose.yaml +++ b/docker/docker-compose.yaml @@ -43,14 +43,14 @@ x-shared-env: &shared-api-worker-env REDIS_USERNAME: ${REDIS_USERNAME:-} REDIS_PASSWORD: ${REDIS_PASSWORD:-difyai123456} REDIS_USE_SSL: ${REDIS_USE_SSL:-false} - REDIS_DB: 0 + REDIS_DB: ${REDIS_DB:-0} REDIS_USE_SENTINEL: ${REDIS_USE_SENTINEL:-false} REDIS_SENTINELS: ${REDIS_SENTINELS:-} REDIS_SENTINEL_SERVICE_NAME: ${REDIS_SENTINEL_SERVICE_NAME:-} REDIS_SENTINEL_USERNAME: ${REDIS_SENTINEL_USERNAME:-} REDIS_SENTINEL_PASSWORD: ${REDIS_SENTINEL_PASSWORD:-} - ACCESS_TOKEN_EXPIRE_MINUTES: ${ACCESS_TOKEN_EXPIRE_MINUTES:-60} REDIS_SENTINEL_SOCKET_TIMEOUT: ${REDIS_SENTINEL_SOCKET_TIMEOUT:-0.1} + ACCESS_TOKEN_EXPIRE_MINUTES: ${ACCESS_TOKEN_EXPIRE_MINUTES:-60} CELERY_BROKER_URL: ${CELERY_BROKER_URL:-redis://:difyai123456@redis:6379/1} BROKER_USE_SSL: ${BROKER_USE_SSL:-false} CELERY_USE_SENTINEL: ${CELERY_USE_SENTINEL:-false} @@ -59,7 +59,7 @@ x-shared-env: &shared-api-worker-env WEB_API_CORS_ALLOW_ORIGINS: ${WEB_API_CORS_ALLOW_ORIGINS:-*} CONSOLE_CORS_ALLOW_ORIGINS: ${CONSOLE_CORS_ALLOW_ORIGINS:-*} STORAGE_TYPE: ${STORAGE_TYPE:-local} - STORAGE_LOCAL_PATH: storage + STORAGE_LOCAL_PATH: ${STORAGE_LOCAL_PATH:-storage} S3_USE_AWS_MANAGED_IAM: ${S3_USE_AWS_MANAGED_IAM:-false} S3_ENDPOINT: ${S3_ENDPOINT:-} S3_BUCKET_NAME: ${S3_BUCKET_NAME:-} @@ -208,7 +208,7 @@ x-shared-env: &shared-api-worker-env SMTP_USE_TLS: ${SMTP_USE_TLS:-true} SMTP_OPPORTUNISTIC_TLS: ${SMTP_OPPORTUNISTIC_TLS:-false} RESEND_API_KEY: ${RESEND_API_KEY:-your-resend-api-key} - RESEND_API_URL: https://api.resend.com + RESEND_API_URL: ${RESEND_API_URL:-https://api.resend.com} INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: ${INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH:-1000} INVITE_EXPIRY_HOURS: ${INVITE_EXPIRY_HOURS:-72} RESET_PASSWORD_TOKEN_EXPIRY_MINUTES: ${RESET_PASSWORD_TOKEN_EXPIRY_MINUTES:-5} From 92e4b3304c861ceee343629b2f507cc3739d0370 Mon Sep 17 00:00:00 2001 From: AkaraChen Date: Fri, 25 Oct 2024 17:48:26 +0800 Subject: [PATCH 235/346] build: update deps build: update sass build: update lodash-es build: update qs & js-cookie --- web/package.json | 16 ++++++++-------- web/pnpm-lock.yaml | 26 +++++++++++++------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/web/package.json b/web/package.json index 2f5065a642..d12d11204c 100644 --- a/web/package.json +++ b/web/package.json @@ -58,7 +58,7 @@ "i18next-resources-to-backend": "^1.1.3", "immer": "^9.0.19", "js-audio-recorder": "^1.0.7", - "js-cookie": "^3.0.1", + "js-cookie": "^3.0.5", "jwt-decode": "^4.0.0", "katex": "^0.16.10", "lamejs": "^1.2.1", @@ -69,7 +69,7 @@ "next": "^14.1.1", "pinyin-pro": "^3.23.0", "qrcode.react": "^3.1.0", - "qs": "^6.11.1", + "qs": "^6.13.0", "rc-textarea": "^1.5.2", "react": "~18.2.0", "react-18-input-autosize": "^3.0.0", @@ -98,7 +98,7 @@ "remark-math": "^5.1.1", "scheduler": "^0.23.0", "server-only": "^0.0.1", - "sharp": "^0.33.2", + "sharp": "^0.33.5", "sortablejs": "^1.15.0", "swr": "^2.1.0", "tailwind-merge": "^2.4.0", @@ -114,7 +114,7 @@ "@eslint-react/eslint-plugin": "^1.15.0", "@eslint/eslintrc": "^3.1.0", "@eslint/js": "^9.13.0", - "@faker-js/faker": "^7.6.0", + "@faker-js/faker": "^9.0.3", "@rgrove/parse-xml": "^4.1.0", "@storybook/addon-essentials": "^8.3.6", "@storybook/addon-interactions": "^8.3.6", @@ -131,11 +131,11 @@ "@types/crypto-js": "^4.1.1", "@types/dagre": "^0.7.52", "@types/jest": "^29.5.12", - "@types/js-cookie": "^3.0.3", - "@types/lodash-es": "^4.17.7", + "@types/js-cookie": "^3.0.6", + "@types/lodash-es": "^4.17.12", "@types/negotiator": "^0.6.1", "@types/node": "18.15.0", - "@types/qs": "^6.9.7", + "@types/qs": "^6.9.16", "@types/react": "~18.2.0", "@types/react-dom": "~18.2.0", "@types/react-slider": "^1.3.1", @@ -160,7 +160,7 @@ "lint-staged": "^15.2.10", "magicast": "^0.3.4", "postcss": "^8.4.31", - "sass": "^1.61.0", + "sass": "^1.80.3", "storybook": "^8.3.6", "tailwindcss": "^3.4.4", "ts-node": "^10.9.2", diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index 9af099a780..0914dbb971 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -116,7 +116,7 @@ importers: specifier: ^1.0.7 version: 1.0.7 js-cookie: - specifier: ^3.0.1 + specifier: ^3.0.5 version: 3.0.5 jwt-decode: specifier: ^4.0.0 @@ -149,7 +149,7 @@ importers: specifier: ^3.1.0 version: 3.2.0(react@18.2.0) qs: - specifier: ^6.11.1 + specifier: ^6.13.0 version: 6.13.0 rc-textarea: specifier: ^1.5.2 @@ -236,7 +236,7 @@ importers: specifier: ^0.0.1 version: 0.0.1 sharp: - specifier: ^0.33.2 + specifier: ^0.33.5 version: 0.33.5 sortablejs: specifier: ^1.15.0 @@ -279,8 +279,8 @@ importers: specifier: ^9.13.0 version: 9.13.0 '@faker-js/faker': - specifier: ^7.6.0 - version: 7.6.0 + specifier: ^9.0.3 + version: 9.0.3 '@rgrove/parse-xml': specifier: ^4.1.0 version: 4.1.0 @@ -330,10 +330,10 @@ importers: specifier: ^29.5.12 version: 29.5.13 '@types/js-cookie': - specifier: ^3.0.3 + specifier: ^3.0.6 version: 3.0.6 '@types/lodash-es': - specifier: ^4.17.7 + specifier: ^4.17.12 version: 4.17.12 '@types/negotiator': specifier: ^0.6.1 @@ -342,7 +342,7 @@ importers: specifier: 18.15.0 version: 18.15.0 '@types/qs': - specifier: ^6.9.7 + specifier: ^6.9.16 version: 6.9.16 '@types/react': specifier: ~18.2.0 @@ -417,7 +417,7 @@ importers: specifier: ^8.4.31 version: 8.4.47 sass: - specifier: ^1.61.0 + specifier: ^1.80.3 version: 1.80.3 storybook: specifier: ^8.3.6 @@ -1405,9 +1405,9 @@ packages: resolution: {integrity: sha512-HFZ4Mp26nbWk9d/BpvP0YNL6W4UoZF0VFcTw/aPPA8RpOxeFQgK+ClABGgAUXs9Y/RGX/l1vOmrqz1MQt9MNuw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@faker-js/faker@7.6.0': - resolution: {integrity: sha512-XK6BTq1NDMo9Xqw/YkYyGjSsg44fbNwYRx7QK2CuoQgyy+f1rrTDHoExVM5PsyXCtfl2vs2vVJ0MN0yN6LppRw==} - engines: {node: '>=14.0.0', npm: '>=6.0.0'} + '@faker-js/faker@9.0.3': + resolution: {integrity: sha512-lWrrK4QNlFSU+13PL9jMbMKLJYXDFu3tQfayBsMXX7KL/GiQeqfB1CzHkqD5UHBUtPAuPo6XwGbMFNdVMZObRA==} + engines: {node: '>=18.0.0', npm: '>=9.0.0'} '@floating-ui/core@1.6.8': resolution: {integrity: sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==} @@ -9313,7 +9313,7 @@ snapshots: dependencies: levn: 0.4.1 - '@faker-js/faker@7.6.0': {} + '@faker-js/faker@9.0.3': {} '@floating-ui/core@1.6.8': dependencies: From 0e2b38dddc6c1b71dfb21d41a1b52a73a725bf85 Mon Sep 17 00:00:00 2001 From: AkaraChen Date: Fri, 25 Oct 2024 18:03:25 +0800 Subject: [PATCH 236/346] build: update qrcode.react --- web/app/components/base/qrcode/index.tsx | 4 ++-- web/package.json | 2 +- web/pnpm-lock.yaml | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/web/app/components/base/qrcode/index.tsx b/web/app/components/base/qrcode/index.tsx index c9323992e9..c5549192cf 100644 --- a/web/app/components/base/qrcode/index.tsx +++ b/web/app/components/base/qrcode/index.tsx @@ -1,11 +1,11 @@ 'use client' import React, { useEffect, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' -import QRCode from 'qrcode.react' +import { QRCodeCanvas as QRCode } from 'qrcode.react' import QrcodeStyle from './style.module.css' import Tooltip from '@/app/components/base/tooltip' -type Props = { +interface Props { content: string selectorId: string className?: string diff --git a/web/package.json b/web/package.json index d12d11204c..c038cd1d33 100644 --- a/web/package.json +++ b/web/package.json @@ -68,7 +68,7 @@ "negotiator": "^0.6.3", "next": "^14.1.1", "pinyin-pro": "^3.23.0", - "qrcode.react": "^3.1.0", + "qrcode.react": "^4.1.0", "qs": "^6.13.0", "rc-textarea": "^1.5.2", "react": "~18.2.0", diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index 0914dbb971..7a20401293 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -146,8 +146,8 @@ importers: specifier: ^3.23.0 version: 3.25.0 qrcode.react: - specifier: ^3.1.0 - version: 3.2.0(react@18.2.0) + specifier: ^4.1.0 + version: 4.1.0(react@18.2.0) qs: specifier: ^6.13.0 version: 6.13.0 @@ -6644,8 +6644,8 @@ packages: pure-rand@6.1.0: resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} - qrcode.react@3.2.0: - resolution: {integrity: sha512-YietHHltOHA4+l5na1srdaMx4sVSOjV9tamHs+mwiLWAMr6QVACRUw1Neax5CptFILcNoITctJY0Ipyn5enQ8g==} + qrcode.react@4.1.0: + resolution: {integrity: sha512-uqXVIIVD/IPgWLYxbOczCNAQw80XCM/LulYDADF+g2xDsPj5OoRwSWtIS4jGyp295wyjKstfG1qIv/I2/rNWpQ==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -16229,7 +16229,7 @@ snapshots: pure-rand@6.1.0: {} - qrcode.react@3.2.0(react@18.2.0): + qrcode.react@4.1.0(react@18.2.0): dependencies: react: 18.2.0 From ace7ffab5f37e381ea173f2813cf688dff322be1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9D=9E=E6=B3=95=E6=93=8D=E4=BD=9C?= Date: Fri, 25 Oct 2024 18:48:07 +0800 Subject: [PATCH 237/346] feat: support comfyui workflow tool image generate image (#9871) --- .../builtin/comfyui/tools/comfyui_client.py | 37 ++++++++++++------- .../builtin/comfyui/tools/comfyui_workflow.py | 8 ++-- .../comfyui/tools/comfyui_workflow.yaml | 7 ++++ 3 files changed, 35 insertions(+), 17 deletions(-) diff --git a/api/core/tools/provider/builtin/comfyui/tools/comfyui_client.py b/api/core/tools/provider/builtin/comfyui/tools/comfyui_client.py index a41d34d40f..d4bf713441 100644 --- a/api/core/tools/provider/builtin/comfyui/tools/comfyui_client.py +++ b/api/core/tools/provider/builtin/comfyui/tools/comfyui_client.py @@ -1,3 +1,5 @@ +import base64 +import io import json import random import uuid @@ -6,45 +8,48 @@ import httpx from websocket import WebSocket from yarl import URL +from core.file.file_manager import _get_encoded_string +from core.file.models import File + class ComfyUiClient: def __init__(self, base_url: str): self.base_url = URL(base_url) - def get_history(self, prompt_id: str): + def get_history(self, prompt_id: str) -> dict: res = httpx.get(str(self.base_url / "history"), params={"prompt_id": prompt_id}) history = res.json()[prompt_id] return history - def get_image(self, filename: str, subfolder: str, folder_type: str): + def get_image(self, filename: str, subfolder: str, folder_type: str) -> bytes: response = httpx.get( str(self.base_url / "view"), params={"filename": filename, "subfolder": subfolder, "type": folder_type}, ) return response.content - def upload_image(self, input_path: str, name: str, image_type: str = "input", overwrite: bool = False): - # plan to support img2img in dify 0.10.0 - with open(input_path, "rb") as file: - files = {"image": (name, file, "image/png")} - data = {"type": image_type, "overwrite": str(overwrite).lower()} + def upload_image(self, image_file: File) -> dict: + image_content = base64.b64decode(_get_encoded_string(image_file)) + file = io.BytesIO(image_content) + files = {"image": (image_file.filename, file, image_file.mime_type), "overwrite": "true"} + res = httpx.post(str(self.base_url / "upload/image"), files=files) + return res.json() - res = httpx.post(str(self.base_url / "upload/image"), data=data, files=files) - return res - - def queue_prompt(self, client_id: str, prompt: dict): + def queue_prompt(self, client_id: str, prompt: dict) -> str: res = httpx.post(str(self.base_url / "prompt"), json={"client_id": client_id, "prompt": prompt}) prompt_id = res.json()["prompt_id"] return prompt_id - def open_websocket_connection(self): + def open_websocket_connection(self) -> tuple[WebSocket, str]: client_id = str(uuid.uuid4()) ws = WebSocket() ws_address = f"ws://{self.base_url.authority}/ws?clientId={client_id}" ws.connect(ws_address) return ws, client_id - def set_prompt(self, origin_prompt: dict, positive_prompt: str, negative_prompt: str = ""): + def set_prompt( + self, origin_prompt: dict, positive_prompt: str, negative_prompt: str = "", image_name: str = "" + ) -> dict: """ find the first KSampler, then can find the prompt node through it. """ @@ -58,6 +63,10 @@ class ComfyUiClient: if negative_prompt != "": negative_input_id = prompt.get(k_sampler)["inputs"]["negative"][0] prompt.get(negative_input_id)["inputs"]["text"] = negative_prompt + + if image_name != "": + image_loader = [key for key, value in id_to_class_type.items() if value == "LoadImage"][0] + prompt.get(image_loader)["inputs"]["image"] = image_name return prompt def track_progress(self, prompt: dict, ws: WebSocket, prompt_id: str): @@ -89,7 +98,7 @@ class ComfyUiClient: else: continue - def generate_image_by_prompt(self, prompt: dict): + def generate_image_by_prompt(self, prompt: dict) -> list[bytes]: try: ws, client_id = self.open_websocket_connection() prompt_id = self.queue_prompt(client_id, prompt) diff --git a/api/core/tools/provider/builtin/comfyui/tools/comfyui_workflow.py b/api/core/tools/provider/builtin/comfyui/tools/comfyui_workflow.py index e4df9f8c3b..11320d5d0f 100644 --- a/api/core/tools/provider/builtin/comfyui/tools/comfyui_workflow.py +++ b/api/core/tools/provider/builtin/comfyui/tools/comfyui_workflow.py @@ -2,10 +2,9 @@ import json from typing import Any from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.provider.builtin.comfyui.tools.comfyui_client import ComfyUiClient from core.tools.tool.builtin_tool import BuiltinTool -from .comfyui_client import ComfyUiClient - class ComfyUIWorkflowTool(BuiltinTool): def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage | list[ToolInvokeMessage]: @@ -14,13 +13,16 @@ class ComfyUIWorkflowTool(BuiltinTool): positive_prompt = tool_parameters.get("positive_prompt") negative_prompt = tool_parameters.get("negative_prompt") workflow = tool_parameters.get("workflow_json") + image_name = "" + if image := tool_parameters.get("image"): + image_name = comfyui.upload_image(image).get("name") try: origin_prompt = json.loads(workflow) except: return self.create_text_message("the Workflow JSON is not correct") - prompt = comfyui.set_prompt(origin_prompt, positive_prompt, negative_prompt) + prompt = comfyui.set_prompt(origin_prompt, positive_prompt, negative_prompt, image_name) images = comfyui.generate_image_by_prompt(prompt) result = [] for img in images: diff --git a/api/core/tools/provider/builtin/comfyui/tools/comfyui_workflow.yaml b/api/core/tools/provider/builtin/comfyui/tools/comfyui_workflow.yaml index 6342d6d468..55fcdad825 100644 --- a/api/core/tools/provider/builtin/comfyui/tools/comfyui_workflow.yaml +++ b/api/core/tools/provider/builtin/comfyui/tools/comfyui_workflow.yaml @@ -24,6 +24,13 @@ parameters: zh_Hans: 负面提示词 llm_description: Negative prompt, you should describe the image you don't want to generate as a list of words as possible as detailed, the prompt must be written in English. form: llm + - name: image + type: file + label: + en_US: Input Image + zh_Hans: 输入的图片 + llm_description: The input image, used to transfer to the comfyui workflow to generate another image. + form: llm - name: workflow_json type: string required: true From f7aacefcd6888d6773d63042b20bcc4aeb75a473 Mon Sep 17 00:00:00 2001 From: crazywoola <100913391+crazywoola@users.noreply.github.com> Date: Fri, 25 Oct 2024 21:51:59 +0800 Subject: [PATCH 238/346] feat: support button in markdown (#9876) --- web/app/components/base/markdown.tsx | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/web/app/components/base/markdown.tsx b/web/app/components/base/markdown.tsx index dbe4087882..33ff23d3b7 100644 --- a/web/app/components/base/markdown.tsx +++ b/web/app/components/base/markdown.tsx @@ -20,6 +20,7 @@ import { useChatContext } from '@/app/components/base/chat/chat/context' import VideoGallery from '@/app/components/base/video-gallery' import AudioGallery from '@/app/components/base/audio-gallery' import SVGRenderer from '@/app/components/base/svg-gallery' +import Button from '@/app/components/base/button' // Available language https://github.com/react-syntax-highlighter/react-syntax-highlighter/blob/master/AVAILABLE_LANGUAGES_HLJS.MD const capitalizationLanguageNameMap: Record = { @@ -240,6 +241,22 @@ const Link = ({ node, ...props }: any) => { } } +const MarkdownButton = ({ node }: any) => { + const { onSend } = useChatContext() + const variant = node.properties.dataVariant + const message = node.properties.dataMessage + const size = node.properties.dataSize + + return +} +MarkdownButton.displayName = 'MarkdownButton' + export function Markdown(props: { content: string; className?: string }) { const latexContent = preprocessLaTeX(props.content) return ( @@ -271,6 +288,7 @@ export function Markdown(props: { content: string; className?: string }) { audio: AudioBlock, a: Link, p: Paragraph, + button: MarkdownButton, }} linkTarget='_blank' > From 17cacf258eb94865b45993d96cd870f9fa694012 Mon Sep 17 00:00:00 2001 From: virgosoy Date: Fri, 25 Oct 2024 22:32:41 +0800 Subject: [PATCH 239/346] fix: wrong element object (#9868) --- api/core/rag/extractor/word_extractor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/core/rag/extractor/word_extractor.py b/api/core/rag/extractor/word_extractor.py index a5375991b4..ae3c25125c 100644 --- a/api/core/rag/extractor/word_extractor.py +++ b/api/core/rag/extractor/word_extractor.py @@ -234,7 +234,7 @@ class WordExtractor(BaseExtractor): def parse_paragraph(paragraph): paragraph_content = [] for run in paragraph.runs: - if hasattr(run.element, "tag") and isinstance(element.tag, str) and run.element.tag.endswith("r"): + if hasattr(run.element, "tag") and isinstance(run.element.tag, str) and run.element.tag.endswith("r"): drawing_elements = run.element.findall( ".//{http://schemas.openxmlformats.org/wordprocessingml/2006/main}drawing" ) From 72ea3d6b98157bc6e360ba5b7c1a8c4137d78243 Mon Sep 17 00:00:00 2001 From: -LAN- Date: Fri, 25 Oct 2024 22:33:34 +0800 Subject: [PATCH 240/346] fix(workflow): Take back LLM streaming output after IF-ELSE (#9875) --- api/core/workflow/graph_engine/graph_engine.py | 13 ++++++------- .../nodes/answer/answer_stream_generate_router.py | 8 ++++---- .../nodes/answer/answer_stream_processor.py | 2 +- .../workflow/nodes/answer/base_stream_processor.py | 1 - api/core/workflow/nodes/answer/entities.py | 3 ++- 5 files changed, 13 insertions(+), 14 deletions(-) diff --git a/api/core/workflow/graph_engine/graph_engine.py b/api/core/workflow/graph_engine/graph_engine.py index ada0b14ce4..8f58af00ef 100644 --- a/api/core/workflow/graph_engine/graph_engine.py +++ b/api/core/workflow/graph_engine/graph_engine.py @@ -130,15 +130,14 @@ class GraphEngine: yield GraphRunStartedEvent() try: - stream_processor_cls: type[AnswerStreamProcessor | EndStreamProcessor] if self.init_params.workflow_type == WorkflowType.CHAT: - stream_processor_cls = AnswerStreamProcessor + stream_processor = AnswerStreamProcessor( + graph=self.graph, variable_pool=self.graph_runtime_state.variable_pool + ) else: - stream_processor_cls = EndStreamProcessor - - stream_processor = stream_processor_cls( - graph=self.graph, variable_pool=self.graph_runtime_state.variable_pool - ) + stream_processor = EndStreamProcessor( + graph=self.graph, variable_pool=self.graph_runtime_state.variable_pool + ) # run graph generator = stream_processor.process(self._run(start_node_id=self.graph.root_node_id)) diff --git a/api/core/workflow/nodes/answer/answer_stream_generate_router.py b/api/core/workflow/nodes/answer/answer_stream_generate_router.py index bce28c5fcb..bc4b056148 100644 --- a/api/core/workflow/nodes/answer/answer_stream_generate_router.py +++ b/api/core/workflow/nodes/answer/answer_stream_generate_router.py @@ -149,10 +149,10 @@ class AnswerStreamGeneratorRouter: source_node_id = edge.source_node_id source_node_type = node_id_config_mapping[source_node_id].get("data", {}).get("type") if source_node_type in { - NodeType.ANSWER.value, - NodeType.IF_ELSE.value, - NodeType.QUESTION_CLASSIFIER.value, - NodeType.ITERATION.value, + NodeType.ANSWER, + NodeType.IF_ELSE, + NodeType.QUESTION_CLASSIFIER, + NodeType.ITERATION, }: answer_dependencies[answer_node_id].append(source_node_id) else: diff --git a/api/core/workflow/nodes/answer/answer_stream_processor.py b/api/core/workflow/nodes/answer/answer_stream_processor.py index e3889941ca..8a768088da 100644 --- a/api/core/workflow/nodes/answer/answer_stream_processor.py +++ b/api/core/workflow/nodes/answer/answer_stream_processor.py @@ -22,7 +22,7 @@ class AnswerStreamProcessor(StreamProcessor): super().__init__(graph, variable_pool) self.generate_routes = graph.answer_stream_generate_routes self.route_position = {} - for answer_node_id, route_chunks in self.generate_routes.answer_generate_route.items(): + for answer_node_id in self.generate_routes.answer_generate_route: self.route_position[answer_node_id] = 0 self.current_stream_chunk_generating_node_ids: dict[str, list[str]] = {} diff --git a/api/core/workflow/nodes/answer/base_stream_processor.py b/api/core/workflow/nodes/answer/base_stream_processor.py index 52d0358c76..36c3fe180a 100644 --- a/api/core/workflow/nodes/answer/base_stream_processor.py +++ b/api/core/workflow/nodes/answer/base_stream_processor.py @@ -41,7 +41,6 @@ class StreamProcessor(ABC): continue else: unreachable_first_node_ids.append(edge.target_node_id) - unreachable_first_node_ids.extend(self._fetch_node_ids_in_reachable_branch(edge.target_node_id)) for node_id in unreachable_first_node_ids: self._remove_node_ids_in_unreachable_branch(node_id, reachable_node_ids) diff --git a/api/core/workflow/nodes/answer/entities.py b/api/core/workflow/nodes/answer/entities.py index e543d02dd7..a05cc44c99 100644 --- a/api/core/workflow/nodes/answer/entities.py +++ b/api/core/workflow/nodes/answer/entities.py @@ -1,3 +1,4 @@ +from collections.abc import Sequence from enum import Enum from pydantic import BaseModel, Field @@ -32,7 +33,7 @@ class VarGenerateRouteChunk(GenerateRouteChunk): type: GenerateRouteChunk.ChunkType = GenerateRouteChunk.ChunkType.VAR """generate route chunk type""" - value_selector: list[str] = Field(..., description="value selector") + value_selector: Sequence[str] = Field(..., description="value selector") class TextGenerateRouteChunk(GenerateRouteChunk): From a17f169e01fce82da678825007320e3983230e4f Mon Sep 17 00:00:00 2001 From: G81192 <41994631+G81192@users.noreply.github.com> Date: Fri, 25 Oct 2024 23:04:00 +0800 Subject: [PATCH 241/346] =?UTF-8?q?fix=20users=20had=20already=20joined=20?= =?UTF-8?q?a=20workspace,=20but=20the=20system=20still=20first=20=E2=80=A6?= =?UTF-8?q?=20(#9834)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: yong.zhang --- api/services/account_service.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/api/services/account_service.py b/api/services/account_service.py index 412685147c..27b1540c8d 100644 --- a/api/services/account_service.py +++ b/api/services/account_service.py @@ -505,9 +505,7 @@ class TenantService: def create_owner_tenant_if_not_exist( account: Account, name: Optional[str] = None, is_setup: Optional[bool] = False ): - """Create owner tenant if not exist""" - if not FeatureService.get_system_features().is_allow_create_workspace and not is_setup: - raise WorkSpaceNotAllowedCreateError() + """Check if user have a workspace or not""" available_ta = ( TenantAccountJoin.query.filter_by(account_id=account.id).order_by(TenantAccountJoin.id.asc()).first() ) @@ -515,6 +513,10 @@ class TenantService: if available_ta: return + """Create owner tenant if not exist""" + if not FeatureService.get_system_features().is_allow_create_workspace and not is_setup: + raise WorkSpaceNotAllowedCreateError() + if name: tenant = TenantService.create_tenant(name=name, is_setup=is_setup) else: From 227f49a0cc5a9073e88445dc2055b340a5fce89c Mon Sep 17 00:00:00 2001 From: kurokobo Date: Sat, 26 Oct 2024 11:43:47 +0900 Subject: [PATCH 242/346] docs: improve api documentation for advanced chat and workflow (#9882) --- .../template/template_advanced_chat.en.mdx | 8 +- .../template/template_advanced_chat.zh.mdx | 5 +- .../develop/template/template_workflow.en.mdx | 76 +++++++++++++++++++ .../develop/template/template_workflow.zh.mdx | 74 ++++++++++++++++++ 4 files changed, 158 insertions(+), 5 deletions(-) diff --git a/web/app/components/develop/template/template_advanced_chat.en.mdx b/web/app/components/develop/template/template_advanced_chat.en.mdx index 71fa7c1a09..7d80367ce4 100644 --- a/web/app/components/develop/template/template_advanced_chat.en.mdx +++ b/web/app/components/develop/template/template_advanced_chat.en.mdx @@ -47,7 +47,9 @@ Chat applications support session persistence, allowing previous chat history to Allows the entry of various variable values defined by the App. - The `inputs` parameter contains multiple key/value pairs, with each key corresponding to a specific variable and each value being the specific value for that variable. Default `{}` + The `inputs` parameter contains multiple key/value pairs, with each key corresponding to a specific variable and each value being the specific value for that variable. + If the variable is of file type, specify an object that has the keys described in `files` below. + Default `{}` The mode of response return, supporting: @@ -307,8 +309,8 @@ Chat applications support session persistence, allowing previous chat history to /> - Upload a file (currently only images are supported) for use when sending messages, enabling multimodal understanding of images and text. - Supports png, jpg, jpeg, webp, gif formats. + Upload a file for use when sending messages, enabling multimodal understanding of images and text. + Supports any formats that are supported by your application. Uploaded files are for use by the current end-user only. ### Request Body diff --git a/web/app/components/develop/template/template_advanced_chat.zh.mdx b/web/app/components/develop/template/template_advanced_chat.zh.mdx index 32dcec135b..690d700f05 100755 --- a/web/app/components/develop/template/template_advanced_chat.zh.mdx +++ b/web/app/components/develop/template/template_advanced_chat.zh.mdx @@ -46,6 +46,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx' 允许传入 App 定义的各变量值。 inputs 参数包含了多组键值对(Key/Value pairs),每组的键对应一个特定变量,每组的值则是该变量的具体值。 + 如果变量是文件类型,请指定一个包含以下 `files` 中所述键的对象。 默认 `{}` @@ -317,8 +318,8 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx' /> - 上传文件(目前仅支持图片)并在发送消息时使用,可实现图文多模态理解。 - 支持 png, jpg, jpeg, webp, gif 格式。 + 上传文件并在发送消息时使用,可实现图文多模态理解。 + 支持您的应用程序所支持的所有格式。 上传的文件仅供当前终端用户使用。 ### Request Body diff --git a/web/app/components/develop/template/template_workflow.en.mdx b/web/app/components/develop/template/template_workflow.en.mdx index db39e61e36..6cb02bf844 100644 --- a/web/app/components/develop/template/template_workflow.en.mdx +++ b/web/app/components/develop/template/template_workflow.en.mdx @@ -44,6 +44,7 @@ Workflow applications offers non-session support and is ideal for translation, a Allows the entry of various variable values defined by the App. The `inputs` parameter contains multiple key/value pairs, with each key corresponding to a specific variable and each value being the specific value for that variable. The workflow application requires at least one key/value pair to be inputted. + If the variable is of File type, specify an object that has the keys described in `files` below. - `response_mode` (string) Required The mode of response return, supporting: - `streaming` Streaming mode (recommended), implements a typewriter-like output through SSE ([Server-Sent Events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events)). @@ -328,6 +329,81 @@ Workflow applications offers non-session support and is ideal for translation, a --- + + + + Upload a file for use when sending messages, enabling multimodal understanding of images and text. + Supports any formats that are supported by your workflow. + Uploaded files are for use by the current end-user only. + + ### Request Body + This interface requires a `multipart/form-data` request. + - `file` (File) Required + The file to be uploaded. + - `user` (string) Required + User identifier, defined by the developer's rules, must be unique within the application. + + ### Response + After a successful upload, the server will return the file's ID and related information. + - `id` (uuid) ID + - `name` (string) File name + - `size` (int) File size (bytes) + - `extension` (string) File extension + - `mime_type` (string) File mime-type + - `created_by` (uuid) End-user ID + - `created_at` (timestamp) Creation timestamp, e.g., 1705395332 + + ### Errors + - 400, `no_file_uploaded`, a file must be provided + - 400, `too_many_files`, currently only one file is accepted + - 400, `unsupported_preview`, the file does not support preview + - 400, `unsupported_estimate`, the file does not support estimation + - 413, `file_too_large`, the file is too large + - 415, `unsupported_file_type`, unsupported extension, currently only document files are accepted + - 503, `s3_connection_failed`, unable to connect to S3 service + - 503, `s3_permission_denied`, no permission to upload files to S3 + - 503, `s3_file_too_large`, file exceeds S3 size limit + - 500, internal server error + + + + + ### Request Example + + + ```bash {{ title: 'cURL' }} + curl -X POST '${props.appDetail.api_base_url}/files/upload' \ + --header 'Authorization: Bearer {api_key}' \ + --form 'file=@"/path/to/file"' + ``` + + + + + ### Response Example + + ```json {{ title: 'Response' }} + { + "id": "72fa9618-8f89-4a37-9b33-7e1178a24a67", + "name": "example.png", + "size": 1024, + "extension": "png", + "mime_type": "image/png", + "created_by": "6ad1ab0a-73ff-4ac1-b9e4-cdb312f71f13", + "created_at": 1577836800, + } + ``` + + + + +--- + + + + 上传文件并在发送消息时使用,可实现图文多模态理解。 + 支持您的工作流程所支持的任何格式。 + 上传的文件仅供当前终端用户使用。 + + ### Request Body + 该接口需使用 `multipart/form-data` 进行请求。 + + + 要上传的文件。 + + + 用户标识,用于定义终端用户的身份,必须和发送消息接口传入 user 保持一致。 + + + + ### Response + 成功上传后,服务器会返回文件的 ID 和相关信息。 + - `id` (uuid) ID + - `name` (string) 文件名 + - `size` (int) 文件大小(byte) + - `extension` (string) 文件后缀 + - `mime_type` (string) 文件 mime-type + - `created_by` (uuid) 上传人 ID + - `created_at` (timestamp) 上传时间 + + ### Errors + - 400,`no_file_uploaded`,必须提供文件 + - 400,`too_many_files`,目前只接受一个文件 + - 400,`unsupported_preview`,该文件不支持预览 + - 400,`unsupported_estimate`,该文件不支持估算 + - 413,`file_too_large`,文件太大 + - 415,`unsupported_file_type`,不支持的扩展名,当前只接受文档类文件 + - 503,`s3_connection_failed`,无法连接到 S3 服务 + - 503,`s3_permission_denied`,无权限上传文件到 S3 + - 503,`s3_file_too_large`,文件超出 S3 大小限制 + + + + + + ```bash {{ title: 'cURL' }} + curl -X POST '${props.appDetail.api_base_url}/files/upload' \ + --header 'Authorization: Bearer {api_key}' \ + --form 'file=@"/path/to/file"' + ``` + + + + + ```json {{ title: 'Response' }} + { + "id": "72fa9618-8f89-4a37-9b33-7e1178a24a67", + "name": "example.png", + "size": 1024, + "extension": "png", + "mime_type": "image/png", + "created_by": 123, + "created_at": 1577836800, + } + ``` + + + +--- + Date: Sat, 26 Oct 2024 14:04:15 +0800 Subject: [PATCH 243/346] Update README.md (#9886) --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index f6d14bb840..ca499eacae 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ ![cover-v5-optimized](https://github.com/langgenius/dify/assets/13230914/f9e19af5-61ba-4119-b926-d10c4c06ebab) +📌 [Introducing Dify Workflow File Upload: Google NotebookLM Podcast Demo](https://dify.ai/blog/introducing-dify-workflow-file-upload-a-demo-on-ai-podcast) +

Dify Cloud · Self-hosting · From 2b66c1358b813889f46de7a2421a69f0cfd5579f Mon Sep 17 00:00:00 2001 From: Joshua <138381132+leilei-jiang@users.noreply.github.com> Date: Sat, 26 Oct 2024 14:32:50 +0800 Subject: [PATCH 244/346] Update README.md (#9889) --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ca499eacae..ddc8108c62 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ ![cover-v5-optimized](https://github.com/langgenius/dify/assets/13230914/f9e19af5-61ba-4119-b926-d10c4c06ebab) -📌 [Introducing Dify Workflow File Upload: Google NotebookLM Podcast Demo](https://dify.ai/blog/introducing-dify-workflow-file-upload-a-demo-on-ai-podcast) +

+ 📌 [Dify Workflow File Upload: Recreating Google NotebookLM Podcast](https://dify.ai/blog/introducing-dify-workflow-file-upload-a-demo-on-ai-podcast) +

Dify Cloud · From f8210b353e8986d4840fbe99fae98debf4fa7892 Mon Sep 17 00:00:00 2001 From: Joshua <138381132+leilei-jiang@users.noreply.github.com> Date: Sat, 26 Oct 2024 14:47:08 +0800 Subject: [PATCH 245/346] Update README.md (#9890) --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ddc8108c62..171073bfdb 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ ![cover-v5-optimized](https://github.com/langgenius/dify/assets/13230914/f9e19af5-61ba-4119-b926-d10c4c06ebab) -

- 📌 [Dify Workflow File Upload: Recreating Google NotebookLM Podcast](https://dify.ai/blog/introducing-dify-workflow-file-upload-a-demo-on-ai-podcast) -

+
+ 📌 [Introducing Dify Workflow File Upload: Recreate Google NotebookLM Podcast](https://dify.ai/blog/introducing-dify-workflow-file-upload-a-demo-on-ai-podcast) +

Dify Cloud · From 11447324fffe87ec988c0a20e47740025ccc4638 Mon Sep 17 00:00:00 2001 From: Joshua <138381132+leilei-jiang@users.noreply.github.com> Date: Sat, 26 Oct 2024 14:56:27 +0800 Subject: [PATCH 246/346] Update README.md (#9891) --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 171073bfdb..cd783501e2 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ ![cover-v5-optimized](https://github.com/langgenius/dify/assets/13230914/f9e19af5-61ba-4119-b926-d10c4c06ebab) -

- 📌 [Introducing Dify Workflow File Upload: Recreate Google NotebookLM Podcast](https://dify.ai/blog/introducing-dify-workflow-file-upload-a-demo-on-ai-podcast) -
+

+ 📌 Introducing Dify Workflow File Upload: Recreate Google NotebookLM Podcast +

Dify Cloud · From dd3ac7a2c9555eb5841dc4ab459f3d82de839c8b Mon Sep 17 00:00:00 2001 From: -LAN- Date: Sat, 26 Oct 2024 15:35:57 +0800 Subject: [PATCH 247/346] fix(api): add signature generation for image previews (#9893) --- api/models/dataset.py | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/api/models/dataset.py b/api/models/dataset.py index 459bfa47c0..a1a626d7e4 100644 --- a/api/models/dataset.py +++ b/api/models/dataset.py @@ -560,10 +560,28 @@ class DocumentSegment(db.Model): ) def get_sign_content(self): - pattern = r"/files/([a-f0-9\-]+)/file-preview" - text = self.content - matches = re.finditer(pattern, text) signed_urls = [] + text = self.content + + # For data before v0.10.0 + pattern = r"/files/([a-f0-9\-]+)/image-preview" + matches = re.finditer(pattern, text) + for match in matches: + upload_file_id = match.group(1) + nonce = os.urandom(16).hex() + timestamp = str(int(time.time())) + data_to_sign = f"image-preview|{upload_file_id}|{timestamp}|{nonce}" + secret_key = dify_config.SECRET_KEY.encode() if dify_config.SECRET_KEY else b"" + sign = hmac.new(secret_key, data_to_sign.encode(), hashlib.sha256).digest() + encoded_sign = base64.urlsafe_b64encode(sign).decode() + + params = f"timestamp={timestamp}&nonce={nonce}&sign={encoded_sign}" + signed_url = f"{match.group(0)}?{params}" + signed_urls.append((match.start(), match.end(), signed_url)) + + # For data after v0.10.0 + pattern = r"/files/([a-f0-9\-]+)/file-preview" + matches = re.finditer(pattern, text) for match in matches: upload_file_id = match.group(1) nonce = os.urandom(16).hex() From 216442ddc15f27230a3d1f2e25eebfc023d9ac17 Mon Sep 17 00:00:00 2001 From: Zixuan Cheng <61724187+Theysua@users.noreply.github.com> Date: Sat, 26 Oct 2024 05:29:48 -0700 Subject: [PATCH 248/346] feat(workflow): Support JSON type in document extractor node (#9899) Co-authored-by: -LAN- --- .../workflow/nodes/document_extractor/node.py | 72 ++++++++++--------- .../nodes/test_document_extractor_node.py | 2 +- 2 files changed, 41 insertions(+), 33 deletions(-) diff --git a/api/core/workflow/nodes/document_extractor/node.py b/api/core/workflow/nodes/document_extractor/node.py index b4ffee1f13..9e09b6d29a 100644 --- a/api/core/workflow/nodes/document_extractor/node.py +++ b/api/core/workflow/nodes/document_extractor/node.py @@ -1,5 +1,6 @@ import csv import io +import json import docx import pandas as pd @@ -77,34 +78,31 @@ class DocumentExtractorNode(BaseNode[DocumentExtractorNodeData]): def _extract_text_by_mime_type(*, file_content: bytes, mime_type: str) -> str: """Extract text from a file based on its MIME type.""" - if mime_type.startswith("text/plain") or mime_type in {"text/html", "text/htm", "text/markdown", "text/xml"}: - return _extract_text_from_plain_text(file_content) - elif mime_type == "application/pdf": - return _extract_text_from_pdf(file_content) - elif mime_type in { - "application/vnd.openxmlformats-officedocument.wordprocessingml.document", - "application/msword", - }: - return _extract_text_from_doc(file_content) - elif mime_type == "text/csv": - return _extract_text_from_csv(file_content) - elif mime_type in { - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", - "application/vnd.ms-excel", - }: - return _extract_text_from_excel(file_content) - elif mime_type == "application/vnd.ms-powerpoint": - return _extract_text_from_ppt(file_content) - elif mime_type == "application/vnd.openxmlformats-officedocument.presentationml.presentation": - return _extract_text_from_pptx(file_content) - elif mime_type == "application/epub+zip": - return _extract_text_from_epub(file_content) - elif mime_type == "message/rfc822": - return _extract_text_from_eml(file_content) - elif mime_type == "application/vnd.ms-outlook": - return _extract_text_from_msg(file_content) - else: - raise UnsupportedFileTypeError(f"Unsupported MIME type: {mime_type}") + match mime_type: + case "text/plain" | "text/html" | "text/htm" | "text/markdown" | "text/xml": + return _extract_text_from_plain_text(file_content) + case "application/pdf": + return _extract_text_from_pdf(file_content) + case "application/vnd.openxmlformats-officedocument.wordprocessingml.document" | "application/msword": + return _extract_text_from_doc(file_content) + case "text/csv": + return _extract_text_from_csv(file_content) + case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" | "application/vnd.ms-excel": + return _extract_text_from_excel(file_content) + case "application/vnd.ms-powerpoint": + return _extract_text_from_ppt(file_content) + case "application/vnd.openxmlformats-officedocument.presentationml.presentation": + return _extract_text_from_pptx(file_content) + case "application/epub+zip": + return _extract_text_from_epub(file_content) + case "message/rfc822": + return _extract_text_from_eml(file_content) + case "application/vnd.ms-outlook": + return _extract_text_from_msg(file_content) + case "application/json": + return _extract_text_from_json(file_content) + case _: + raise UnsupportedFileTypeError(f"Unsupported MIME type: {mime_type}") def _extract_text_by_file_extension(*, file_content: bytes, file_extension: str) -> str: @@ -112,6 +110,8 @@ def _extract_text_by_file_extension(*, file_content: bytes, file_extension: str) match file_extension: case ".txt" | ".markdown" | ".md" | ".html" | ".htm" | ".xml": return _extract_text_from_plain_text(file_content) + case ".json": + return _extract_text_from_json(file_content) case ".pdf": return _extract_text_from_pdf(file_content) case ".doc" | ".docx": @@ -141,6 +141,14 @@ def _extract_text_from_plain_text(file_content: bytes) -> str: raise TextExtractionError("Failed to decode plain text file") from e +def _extract_text_from_json(file_content: bytes) -> str: + try: + json_data = json.loads(file_content.decode("utf-8")) + return json.dumps(json_data, indent=2, ensure_ascii=False) + except (UnicodeDecodeError, json.JSONDecodeError) as e: + raise TextExtractionError(f"Failed to decode or parse JSON file: {e}") from e + + def _extract_text_from_pdf(file_content: bytes) -> str: try: pdf_file = io.BytesIO(file_content) @@ -183,13 +191,13 @@ def _download_file_content(file: File) -> bytes: def _extract_text_from_file(file: File): - if file.mime_type is None: - raise UnsupportedFileTypeError("Unable to determine file type: MIME type is missing") file_content = _download_file_content(file) - if file.transfer_method == FileTransferMethod.REMOTE_URL: + if file.extension: + extracted_text = _extract_text_by_file_extension(file_content=file_content, file_extension=file.extension) + elif file.mime_type: extracted_text = _extract_text_by_mime_type(file_content=file_content, mime_type=file.mime_type) else: - extracted_text = _extract_text_by_file_extension(file_content=file_content, file_extension=file.extension) + raise UnsupportedFileTypeError("Unable to determine file type: MIME type or file extension is missing") return extracted_text diff --git a/api/tests/unit_tests/core/workflow/nodes/test_document_extractor_node.py b/api/tests/unit_tests/core/workflow/nodes/test_document_extractor_node.py index a141fa9a13..4f1f8f05c8 100644 --- a/api/tests/unit_tests/core/workflow/nodes/test_document_extractor_node.py +++ b/api/tests/unit_tests/core/workflow/nodes/test_document_extractor_node.py @@ -125,7 +125,7 @@ def test_run_extract_text( result = document_extractor_node._run() assert isinstance(result, NodeRunResult) - assert result.status == WorkflowNodeExecutionStatus.SUCCEEDED + assert result.status == WorkflowNodeExecutionStatus.SUCCEEDED, result.error assert result.outputs is not None assert result.outputs["text"] == expected_text From 22776f24abc9342cb18be48db640348fc49b06e7 Mon Sep 17 00:00:00 2001 From: ice yao Date: Sun, 27 Oct 2024 11:56:17 +0800 Subject: [PATCH 249/346] chore: Extract common functions of the base model in Azure OpenAI Provider (#9907) --- .../azure_openai/azure_openai.yaml | 3 +++ .../model_providers/azure_openai/llm/llm.py | 27 +++++++------------ 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/api/core/model_runtime/model_providers/azure_openai/azure_openai.yaml b/api/core/model_runtime/model_providers/azure_openai/azure_openai.yaml index 093f57c51e..1ef5e83abc 100644 --- a/api/core/model_runtime/model_providers/azure_openai/azure_openai.yaml +++ b/api/core/model_runtime/model_providers/azure_openai/azure_openai.yaml @@ -53,6 +53,9 @@ model_credential_schema: type: select required: true options: + - label: + en_US: 2024-10-01-preview + value: 2024-10-01-preview - label: en_US: 2024-09-01-preview value: 2024-09-01-preview diff --git a/api/core/model_runtime/model_providers/azure_openai/llm/llm.py b/api/core/model_runtime/model_providers/azure_openai/llm/llm.py index 4f46fb81f8..1cd4823e13 100644 --- a/api/core/model_runtime/model_providers/azure_openai/llm/llm.py +++ b/api/core/model_runtime/model_providers/azure_openai/llm/llm.py @@ -45,9 +45,7 @@ class AzureOpenAILargeLanguageModel(_CommonAzureOpenAI, LargeLanguageModel): stream: bool = True, user: Optional[str] = None, ) -> Union[LLMResult, Generator]: - base_model_name = credentials.get("base_model_name") - if not base_model_name: - raise ValueError("Base Model Name is required") + base_model_name = self._get_base_model_name(credentials) ai_model_entity = self._get_ai_model_entity(base_model_name=base_model_name, model=model) if ai_model_entity and ai_model_entity.entity.model_properties.get(ModelPropertyKey.MODE) == LLMMode.CHAT.value: @@ -81,9 +79,7 @@ class AzureOpenAILargeLanguageModel(_CommonAzureOpenAI, LargeLanguageModel): prompt_messages: list[PromptMessage], tools: Optional[list[PromptMessageTool]] = None, ) -> int: - base_model_name = credentials.get("base_model_name") - if not base_model_name: - raise ValueError("Base Model Name is required") + base_model_name = self._get_base_model_name(credentials) model_entity = self._get_ai_model_entity(base_model_name=base_model_name, model=model) if not model_entity: raise ValueError(f"Base Model Name {base_model_name} is invalid") @@ -108,9 +104,7 @@ class AzureOpenAILargeLanguageModel(_CommonAzureOpenAI, LargeLanguageModel): if "base_model_name" not in credentials: raise CredentialsValidateFailedError("Base Model Name is required") - base_model_name = credentials.get("base_model_name") - if not base_model_name: - raise CredentialsValidateFailedError("Base Model Name is required") + base_model_name = self._get_base_model_name(credentials) ai_model_entity = self._get_ai_model_entity(base_model_name=base_model_name, model=model) if not ai_model_entity: @@ -149,9 +143,7 @@ class AzureOpenAILargeLanguageModel(_CommonAzureOpenAI, LargeLanguageModel): raise CredentialsValidateFailedError(str(ex)) def get_customizable_model_schema(self, model: str, credentials: dict) -> Optional[AIModelEntity]: - base_model_name = credentials.get("base_model_name") - if not base_model_name: - raise ValueError("Base Model Name is required") + base_model_name = self._get_base_model_name(credentials) ai_model_entity = self._get_ai_model_entity(base_model_name=base_model_name, model=model) return ai_model_entity.entity if ai_model_entity else None @@ -308,11 +300,6 @@ class AzureOpenAILargeLanguageModel(_CommonAzureOpenAI, LargeLanguageModel): if tools: extra_model_kwargs["tools"] = [helper.dump_model(PromptMessageFunction(function=tool)) for tool in tools] - # extra_model_kwargs['functions'] = [{ - # "name": tool.name, - # "description": tool.description, - # "parameters": tool.parameters - # } for tool in tools] if stop: extra_model_kwargs["stop"] = stop @@ -769,3 +756,9 @@ class AzureOpenAILargeLanguageModel(_CommonAzureOpenAI, LargeLanguageModel): ai_model_entity_copy.entity.label.en_US = model ai_model_entity_copy.entity.label.zh_Hans = model return ai_model_entity_copy + + def _get_base_model_name(self, credentials: dict) -> str: + base_model_name = credentials.get("base_model_name") + if not base_model_name: + raise ValueError("Base Model Name is required") + return base_model_name From 8bb5b943d7aa50c0adad5d0a9e7b0049da48b568 Mon Sep 17 00:00:00 2001 From: zhuhao <37029601+hwzhuhao@users.noreply.github.com> Date: Sun, 27 Oct 2024 11:56:29 +0800 Subject: [PATCH 250/346] fix(tools): remove the undefined variable parameter_type (#9908) --- api/core/tools/entities/tool_entities.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/core/tools/entities/tool_entities.py b/api/core/tools/entities/tool_entities.py index 9a31e673d3..d8637fd2cb 100644 --- a/api/core/tools/entities/tool_entities.py +++ b/api/core/tools/entities/tool_entities.py @@ -204,7 +204,7 @@ class ToolParameter(BaseModel): return str(value) except Exception: - raise ValueError(f"The tool parameter value {value} is not in correct type of {parameter_type}.") + raise ValueError(f"The tool parameter value {value} is not in correct type.") class ToolParameterForm(Enum): SCHEMA = "schema" # should be set while adding tool From aa11141660077618c7ee7f66c1d53017f4c2d4e5 Mon Sep 17 00:00:00 2001 From: zhuhao <37029601+hwzhuhao@users.noreply.github.com> Date: Sun, 27 Oct 2024 21:17:36 +0800 Subject: [PATCH 251/346] feat: add stable-diffusion-3-5-large for the text-to-image tool with siliconflow (#9909) --- .../builtin/siliconflow/tools/stable_diffusion.py | 14 +++++++++----- .../siliconflow/tools/stable_diffusion.yaml | 3 +++ 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/api/core/tools/provider/builtin/siliconflow/tools/stable_diffusion.py b/api/core/tools/provider/builtin/siliconflow/tools/stable_diffusion.py index d6a0b03d1b..db43790c06 100644 --- a/api/core/tools/provider/builtin/siliconflow/tools/stable_diffusion.py +++ b/api/core/tools/provider/builtin/siliconflow/tools/stable_diffusion.py @@ -5,9 +5,12 @@ import requests from core.tools.entities.tool_entities import ToolInvokeMessage from core.tools.tool.builtin_tool import BuiltinTool -SDURL = { - "sd_3": "https://api.siliconflow.cn/v1/stabilityai/stable-diffusion-3-medium/text-to-image", - "sd_xl": "https://api.siliconflow.cn/v1/stabilityai/stable-diffusion-xl-base-1.0/text-to-image", +SILICONFLOW_API_URL = "https://api.siliconflow.cn/v1/image/generations" + +SD_MODELS = { + "sd_3": "stabilityai/stable-diffusion-3-medium", + "sd_xl": "stabilityai/stable-diffusion-xl-base-1.0", + "sd_3.5_large": "stabilityai/stable-diffusion-3-5-large", } @@ -22,9 +25,10 @@ class StableDiffusionTool(BuiltinTool): } model = tool_parameters.get("model", "sd_3") - url = SDURL.get(model) + sd_model = SD_MODELS.get(model) payload = { + "model": sd_model, "prompt": tool_parameters.get("prompt"), "negative_prompt": tool_parameters.get("negative_prompt", ""), "image_size": tool_parameters.get("image_size", "1024x1024"), @@ -34,7 +38,7 @@ class StableDiffusionTool(BuiltinTool): "num_inference_steps": tool_parameters.get("num_inference_steps", 20), } - response = requests.post(url, json=payload, headers=headers) + response = requests.post(SILICONFLOW_API_URL, json=payload, headers=headers) if response.status_code != 200: return self.create_text_message(f"Got Error Response:{response.text}") diff --git a/api/core/tools/provider/builtin/siliconflow/tools/stable_diffusion.yaml b/api/core/tools/provider/builtin/siliconflow/tools/stable_diffusion.yaml index dce10adc87..b330c92e16 100644 --- a/api/core/tools/provider/builtin/siliconflow/tools/stable_diffusion.yaml +++ b/api/core/tools/provider/builtin/siliconflow/tools/stable_diffusion.yaml @@ -40,6 +40,9 @@ parameters: - value: sd_xl label: en_US: Stable Diffusion XL + - value: sd_3.5_large + label: + en_US: Stable Diffusion 3.5 Large default: sd_3 label: en_US: Choose Image Model From 7c8c15ef1a83a47d19a15e89f1453074da40be98 Mon Sep 17 00:00:00 2001 From: Joel Date: Mon, 28 Oct 2024 10:56:31 +0800 Subject: [PATCH 252/346] test no use rule --- .../_base/components/variable/var-reference-vars.tsx | 4 ++-- web/eslint.config.mjs | 2 +- web/pnpm-lock.yaml | 12 +++++++++++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/web/app/components/workflow/nodes/_base/components/variable/var-reference-vars.tsx b/web/app/components/workflow/nodes/_base/components/variable/var-reference-vars.tsx index 808e9e2670..dae4418fed 100644 --- a/web/app/components/workflow/nodes/_base/components/variable/var-reference-vars.tsx +++ b/web/app/components/workflow/nodes/_base/components/variable/var-reference-vars.tsx @@ -132,7 +132,7 @@ const Item: FC = ({ zIndex: 100, }}> {(isObj && !isFile) && ( - + // eslint-disable-next-line ts/no-use-before-define = ({ /> )} {isFile && ( - + // eslint-disable-next-line ts/no-use-before-define =4'} hasBin: true + mime@4.0.4: + resolution: {integrity: sha512-v8yqInVjhXyqP6+Kw4fV3ZzeMRqEW6FotRsKXjRS5VMTNIuXsdRoAvklpoRgSqXm6o9VNH4/C0mgedko9DdLsQ==} + engines: {node: '>=16'} + hasBin: true + mimic-fn@2.1.0: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} @@ -15635,6 +15643,8 @@ snapshots: mime@1.6.0: {} + mime@4.0.4: {} + mimic-fn@2.1.0: {} mimic-fn@4.0.0: {} From c760902e729216a031f9edf8211d016b4f590fa3 Mon Sep 17 00:00:00 2001 From: Joel Date: Mon, 28 Oct 2024 10:56:52 +0800 Subject: [PATCH 253/346] chore: remove useless rule --- web/eslint.config.mjs | 1 - 1 file changed, 1 deletion(-) diff --git a/web/eslint.config.mjs b/web/eslint.config.mjs index bee77a10d9..6416e3e9a1 100644 --- a/web/eslint.config.mjs +++ b/web/eslint.config.mjs @@ -63,7 +63,6 @@ export default combine( overrides: { // useful, but big change 'ts/no-empty-object-type': 'off', - // 'ts/no-use-before-define': 'off' }, }), unicorn(), From f0f1bfa5d989835068a5d51e39ef0600ae4de8c3 Mon Sep 17 00:00:00 2001 From: AkaraChen Date: Mon, 28 Oct 2024 11:00:44 +0800 Subject: [PATCH 254/346] build: fix eslint --- web/eslint.config.mjs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/web/eslint.config.mjs b/web/eslint.config.mjs index 6416e3e9a1..2f51cfaca3 100644 --- a/web/eslint.config.mjs +++ b/web/eslint.config.mjs @@ -61,6 +61,9 @@ export default combine( }), typescript({ overrides: { + // original config + 'ts/consistent-type-definitions': ['warn', 'type'], + // useful, but big change 'ts/no-empty-object-type': 'off', }, From 9633c5dab6ebd48236bb988e991955321a57f168 Mon Sep 17 00:00:00 2001 From: Joe <79627742+ZhouhaoJiang@users.noreply.github.com> Date: Mon, 28 Oct 2024 11:48:16 +0800 Subject: [PATCH 255/346] fix: enterprise create workspace (#9921) --- api/controllers/inner_api/workspace/workspace.py | 2 +- api/services/account_service.py | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/api/controllers/inner_api/workspace/workspace.py b/api/controllers/inner_api/workspace/workspace.py index 914b60f263..fee840b30d 100644 --- a/api/controllers/inner_api/workspace/workspace.py +++ b/api/controllers/inner_api/workspace/workspace.py @@ -21,7 +21,7 @@ class EnterpriseWorkspace(Resource): if account is None: return {"message": "owner account not found."}, 404 - tenant = TenantService.create_tenant(args["name"]) + tenant = TenantService.create_tenant(args["name"], is_from_dashboard=True) TenantService.create_tenant_member(tenant, account, role="owner") tenant_was_created.send(tenant) diff --git a/api/services/account_service.py b/api/services/account_service.py index 27b1540c8d..dceca06185 100644 --- a/api/services/account_service.py +++ b/api/services/account_service.py @@ -486,9 +486,13 @@ def _get_login_cache_key(*, account_id: str, token: str): class TenantService: @staticmethod - def create_tenant(name: str, is_setup: Optional[bool] = False) -> Tenant: + def create_tenant(name: str, is_setup: Optional[bool] = False, is_from_dashboard: Optional[bool] = False) -> Tenant: """Create tenant""" - if not FeatureService.get_system_features().is_allow_create_workspace and not is_setup: + if ( + not FeatureService.get_system_features().is_allow_create_workspace + and not is_setup + and not is_from_dashboard + ): from controllers.console.error import NotAllowedCreateWorkspace raise NotAllowedCreateWorkspace() From 0d85d44de5021ac1aea934ef825a7f1329277778 Mon Sep 17 00:00:00 2001 From: StyleZhang Date: Mon, 28 Oct 2024 11:50:26 +0800 Subject: [PATCH 256/346] feat: marketplace list --- .../components/plugins/marketplace/index.tsx | 23 +- .../plugins/marketplace/list/index.tsx | 225 +++--------------- .../marketplace/list/list-with-collection.tsx | 48 ++++ .../plugins/marketplace/list/list-wrapper.tsx | 22 ++ 4 files changed, 129 insertions(+), 189 deletions(-) create mode 100644 web/app/components/plugins/marketplace/list/list-with-collection.tsx create mode 100644 web/app/components/plugins/marketplace/list/list-wrapper.tsx diff --git a/web/app/components/plugins/marketplace/index.tsx b/web/app/components/plugins/marketplace/index.tsx index e85411c1ed..d8843ce97c 100644 --- a/web/app/components/plugins/marketplace/index.tsx +++ b/web/app/components/plugins/marketplace/index.tsx @@ -1,18 +1,35 @@ +import type { Plugin } from '../types' import { MarketplaceContextProvider } from './context' import Description from './description' import IntersectionLine from './intersection-line' import SearchBox from './search-box' import PluginTypeSwitch from './plugin-type-switch' -import List from './list' +import ListWrapper from './list/list-wrapper' +import type { MarketplaceCollection } from './types' + +const Marketplace = async () => { + const marketplaceCollectionsData = await globalThis.fetch('https://marketplace.dify.dev/api/v1/collections') + const marketplaceCollectionsDataJson = await marketplaceCollectionsData.json() + const marketplaceCollections = marketplaceCollectionsDataJson.data.collections + const marketplaceCollectionPluginsMap = {} as Record + await Promise.all(marketplaceCollections.map(async (collection: MarketplaceCollection) => { + const marketplaceCollectionPluginsData = await globalThis.fetch(`https://marketplace.dify.dev/api/v1/collections/${collection.name}/plugins`) + const marketplaceCollectionPluginsDataJson = await marketplaceCollectionPluginsData.json() + const plugins = marketplaceCollectionPluginsDataJson.data.plugins + + marketplaceCollectionPluginsMap[collection.name] = plugins + })) -const Marketplace = () => { return ( - + ) } diff --git a/web/app/components/plugins/marketplace/list/index.tsx b/web/app/components/plugins/marketplace/list/index.tsx index a805522b43..604211fb5b 100644 --- a/web/app/components/plugins/marketplace/list/index.tsx +++ b/web/app/components/plugins/marketplace/list/index.tsx @@ -1,197 +1,50 @@ 'use client' +import type { Plugin } from '../../types' +import type { MarketplaceCollection } from '../types' +import ListWithCollection from './list-with-collection' import Card from '@/app/components/plugins/card' import CardMoreInfo from '@/app/components/plugins/card/card-more-info' -import { toolNotion } from '@/app/components/plugins/card/card-mock' -const List = () => { +interface ListProps { + marketplaceCollections: MarketplaceCollection[] + marketplaceCollectionPluginsMap: Record + plugins?: Plugin[] +} +const List = ({ + marketplaceCollections, + marketplaceCollectionPluginsMap, + plugins, +}: ListProps) => { return (

-
-
Featured
-
Our top picks to get you started
-
- - } + { + !plugins && ( + - + ) + } + { + plugins && ( +
+ { + plugins.map(plugin => ( + + } + /> + )) } - /> - - } - /> - - } - /> - - } - /> -
-
-
-
Popular
-
Explore the library and discover the incredible work of our community
-
- - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> -
-
+
+ ) + }
) } diff --git a/web/app/components/plugins/marketplace/list/list-with-collection.tsx b/web/app/components/plugins/marketplace/list/list-with-collection.tsx new file mode 100644 index 0000000000..9009b7a799 --- /dev/null +++ b/web/app/components/plugins/marketplace/list/list-with-collection.tsx @@ -0,0 +1,48 @@ +'use client' +import type { MarketplaceCollection } from '../types' +import type { Plugin } from '@/app/components/plugins/types' +import Card from '@/app/components/plugins/card' +import CardMoreInfo from '@/app/components/plugins/card/card-more-info' + +interface ListWithCollectionProps { + marketplaceCollections: MarketplaceCollection[] + marketplaceCollectionPluginsMap: Record +} +const ListWithCollection = ({ + marketplaceCollections, + marketplaceCollectionPluginsMap, +}: ListWithCollectionProps) => { + return ( + <> + { + marketplaceCollections.map(collection => ( +
+
{collection.name}
+
{collection.description}
+
+ { + marketplaceCollectionPluginsMap[collection.name].map(plugin => ( + + } + /> + )) + } +
+
+ )) + } + + ) +} + +export default ListWithCollection diff --git a/web/app/components/plugins/marketplace/list/list-wrapper.tsx b/web/app/components/plugins/marketplace/list/list-wrapper.tsx new file mode 100644 index 0000000000..0de2fa2c06 --- /dev/null +++ b/web/app/components/plugins/marketplace/list/list-wrapper.tsx @@ -0,0 +1,22 @@ +'use client' +import type { Plugin } from '../../types' +import type { MarketplaceCollection } from '../types' +import List from './index' + +interface ListWrapperProps { + marketplaceCollections: MarketplaceCollection[] + marketplaceCollectionPluginsMap: Record +} +const ListWrapper = ({ + marketplaceCollections, + marketplaceCollectionPluginsMap, +}: ListWrapperProps) => { + return ( + + ) +} + +export default ListWrapper From af680848957ef26eb78d8ba209608476056617cc Mon Sep 17 00:00:00 2001 From: Jyong <76649700+JohnJyong@users.noreply.github.com> Date: Mon, 28 Oct 2024 13:52:35 +0800 Subject: [PATCH 257/346] add document lock for multi-thread (#9873) --- api/services/dataset_service.py | 312 ++++++++++++++++---------------- 1 file changed, 157 insertions(+), 155 deletions(-) diff --git a/api/services/dataset_service.py b/api/services/dataset_service.py index ca084bde56..414ef0224a 100644 --- a/api/services/dataset_service.py +++ b/api/services/dataset_service.py @@ -760,166 +760,168 @@ class DocumentService: ) db.session.add(dataset_process_rule) db.session.commit() - position = DocumentService.get_documents_position(dataset.id) - document_ids = [] - duplicate_document_ids = [] - if document_data["data_source"]["type"] == "upload_file": - upload_file_list = document_data["data_source"]["info_list"]["file_info_list"]["file_ids"] - for file_id in upload_file_list: - file = ( - db.session.query(UploadFile) - .filter(UploadFile.tenant_id == dataset.tenant_id, UploadFile.id == file_id) - .first() - ) - - # raise error if file not found - if not file: - raise FileNotExistsError() - - file_name = file.name - data_source_info = { - "upload_file_id": file_id, - } - # check duplicate - if document_data.get("duplicate", False): - document = Document.query.filter_by( - dataset_id=dataset.id, - tenant_id=current_user.current_tenant_id, - data_source_type="upload_file", - enabled=True, - name=file_name, - ).first() - if document: - document.dataset_process_rule_id = dataset_process_rule.id - document.updated_at = datetime.datetime.utcnow() - document.created_from = created_from - document.doc_form = document_data["doc_form"] - document.doc_language = document_data["doc_language"] - document.data_source_info = json.dumps(data_source_info) - document.batch = batch - document.indexing_status = "waiting" - db.session.add(document) - documents.append(document) - duplicate_document_ids.append(document.id) - continue - document = DocumentService.build_document( - dataset, - dataset_process_rule.id, - document_data["data_source"]["type"], - document_data["doc_form"], - document_data["doc_language"], - data_source_info, - created_from, - position, - account, - file_name, - batch, - ) - db.session.add(document) - db.session.flush() - document_ids.append(document.id) - documents.append(document) - position += 1 - elif document_data["data_source"]["type"] == "notion_import": - notion_info_list = document_data["data_source"]["info_list"]["notion_info_list"] - exist_page_ids = [] - exist_document = {} - documents = Document.query.filter_by( - dataset_id=dataset.id, - tenant_id=current_user.current_tenant_id, - data_source_type="notion_import", - enabled=True, - ).all() - if documents: - for document in documents: - data_source_info = json.loads(document.data_source_info) - exist_page_ids.append(data_source_info["notion_page_id"]) - exist_document[data_source_info["notion_page_id"]] = document.id - for notion_info in notion_info_list: - workspace_id = notion_info["workspace_id"] - data_source_binding = DataSourceOauthBinding.query.filter( - db.and_( - DataSourceOauthBinding.tenant_id == current_user.current_tenant_id, - DataSourceOauthBinding.provider == "notion", - DataSourceOauthBinding.disabled == False, - DataSourceOauthBinding.source_info["workspace_id"] == f'"{workspace_id}"', + lock_name = "add_document_lock_dataset_id_{}".format(dataset.id) + with redis_client.lock(lock_name, timeout=600): + position = DocumentService.get_documents_position(dataset.id) + document_ids = [] + duplicate_document_ids = [] + if document_data["data_source"]["type"] == "upload_file": + upload_file_list = document_data["data_source"]["info_list"]["file_info_list"]["file_ids"] + for file_id in upload_file_list: + file = ( + db.session.query(UploadFile) + .filter(UploadFile.tenant_id == dataset.tenant_id, UploadFile.id == file_id) + .first() ) - ).first() - if not data_source_binding: - raise ValueError("Data source binding not found.") - for page in notion_info["pages"]: - if page["page_id"] not in exist_page_ids: - data_source_info = { - "notion_workspace_id": workspace_id, - "notion_page_id": page["page_id"], - "notion_page_icon": page["page_icon"], - "type": page["type"], - } - document = DocumentService.build_document( - dataset, - dataset_process_rule.id, - document_data["data_source"]["type"], - document_data["doc_form"], - document_data["doc_language"], - data_source_info, - created_from, - position, - account, - page["page_name"], - batch, + + # raise error if file not found + if not file: + raise FileNotExistsError() + + file_name = file.name + data_source_info = { + "upload_file_id": file_id, + } + # check duplicate + if document_data.get("duplicate", False): + document = Document.query.filter_by( + dataset_id=dataset.id, + tenant_id=current_user.current_tenant_id, + data_source_type="upload_file", + enabled=True, + name=file_name, + ).first() + if document: + document.dataset_process_rule_id = dataset_process_rule.id + document.updated_at = datetime.datetime.utcnow() + document.created_from = created_from + document.doc_form = document_data["doc_form"] + document.doc_language = document_data["doc_language"] + document.data_source_info = json.dumps(data_source_info) + document.batch = batch + document.indexing_status = "waiting" + db.session.add(document) + documents.append(document) + duplicate_document_ids.append(document.id) + continue + document = DocumentService.build_document( + dataset, + dataset_process_rule.id, + document_data["data_source"]["type"], + document_data["doc_form"], + document_data["doc_language"], + data_source_info, + created_from, + position, + account, + file_name, + batch, + ) + db.session.add(document) + db.session.flush() + document_ids.append(document.id) + documents.append(document) + position += 1 + elif document_data["data_source"]["type"] == "notion_import": + notion_info_list = document_data["data_source"]["info_list"]["notion_info_list"] + exist_page_ids = [] + exist_document = {} + documents = Document.query.filter_by( + dataset_id=dataset.id, + tenant_id=current_user.current_tenant_id, + data_source_type="notion_import", + enabled=True, + ).all() + if documents: + for document in documents: + data_source_info = json.loads(document.data_source_info) + exist_page_ids.append(data_source_info["notion_page_id"]) + exist_document[data_source_info["notion_page_id"]] = document.id + for notion_info in notion_info_list: + workspace_id = notion_info["workspace_id"] + data_source_binding = DataSourceOauthBinding.query.filter( + db.and_( + DataSourceOauthBinding.tenant_id == current_user.current_tenant_id, + DataSourceOauthBinding.provider == "notion", + DataSourceOauthBinding.disabled == False, + DataSourceOauthBinding.source_info["workspace_id"] == f'"{workspace_id}"', ) - db.session.add(document) - db.session.flush() - document_ids.append(document.id) - documents.append(document) - position += 1 + ).first() + if not data_source_binding: + raise ValueError("Data source binding not found.") + for page in notion_info["pages"]: + if page["page_id"] not in exist_page_ids: + data_source_info = { + "notion_workspace_id": workspace_id, + "notion_page_id": page["page_id"], + "notion_page_icon": page["page_icon"], + "type": page["type"], + } + document = DocumentService.build_document( + dataset, + dataset_process_rule.id, + document_data["data_source"]["type"], + document_data["doc_form"], + document_data["doc_language"], + data_source_info, + created_from, + position, + account, + page["page_name"], + batch, + ) + db.session.add(document) + db.session.flush() + document_ids.append(document.id) + documents.append(document) + position += 1 + else: + exist_document.pop(page["page_id"]) + # delete not selected documents + if len(exist_document) > 0: + clean_notion_document_task.delay(list(exist_document.values()), dataset.id) + elif document_data["data_source"]["type"] == "website_crawl": + website_info = document_data["data_source"]["info_list"]["website_info_list"] + urls = website_info["urls"] + for url in urls: + data_source_info = { + "url": url, + "provider": website_info["provider"], + "job_id": website_info["job_id"], + "only_main_content": website_info.get("only_main_content", False), + "mode": "crawl", + } + if len(url) > 255: + document_name = url[:200] + "..." else: - exist_document.pop(page["page_id"]) - # delete not selected documents - if len(exist_document) > 0: - clean_notion_document_task.delay(list(exist_document.values()), dataset.id) - elif document_data["data_source"]["type"] == "website_crawl": - website_info = document_data["data_source"]["info_list"]["website_info_list"] - urls = website_info["urls"] - for url in urls: - data_source_info = { - "url": url, - "provider": website_info["provider"], - "job_id": website_info["job_id"], - "only_main_content": website_info.get("only_main_content", False), - "mode": "crawl", - } - if len(url) > 255: - document_name = url[:200] + "..." - else: - document_name = url - document = DocumentService.build_document( - dataset, - dataset_process_rule.id, - document_data["data_source"]["type"], - document_data["doc_form"], - document_data["doc_language"], - data_source_info, - created_from, - position, - account, - document_name, - batch, - ) - db.session.add(document) - db.session.flush() - document_ids.append(document.id) - documents.append(document) - position += 1 - db.session.commit() + document_name = url + document = DocumentService.build_document( + dataset, + dataset_process_rule.id, + document_data["data_source"]["type"], + document_data["doc_form"], + document_data["doc_language"], + data_source_info, + created_from, + position, + account, + document_name, + batch, + ) + db.session.add(document) + db.session.flush() + document_ids.append(document.id) + documents.append(document) + position += 1 + db.session.commit() - # trigger async task - if document_ids: - document_indexing_task.delay(dataset.id, document_ids) - if duplicate_document_ids: - duplicate_document_indexing_task.delay(dataset.id, duplicate_document_ids) + # trigger async task + if document_ids: + document_indexing_task.delay(dataset.id, document_ids) + if duplicate_document_ids: + duplicate_document_indexing_task.delay(dataset.id, duplicate_document_ids) - return documents, batch + return documents, batch @staticmethod def check_documents_upload_quota(count: int, features: FeatureModel): From aafa4a3c8bf93676743167c8f69c63b27719c1e5 Mon Sep 17 00:00:00 2001 From: seikyo-cho-lvgs Date: Mon, 28 Oct 2024 14:53:04 +0900 Subject: [PATCH 258/346] Remove invalid languages error (#9928) Co-authored-by: crazywoola <427733928@qq.com> --- web/i18n/server.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/web/i18n/server.ts b/web/i18n/server.ts index 933899e6a1..e976f3ed41 100644 --- a/web/i18n/server.ts +++ b/web/i18n/server.ts @@ -47,10 +47,8 @@ export const getLocaleOnServer = (): Locale => { } // Validate languages - if (!Array.isArray(languages) || languages.length === 0 || !languages.every(lang => typeof lang === 'string' && /^[\w-]+$/.test(lang))) { - console.error(`Invalid languages: ${languages}`) + if (!Array.isArray(languages) || languages.length === 0 || !languages.every(lang => typeof lang === 'string' && /^[\w-]+$/.test(lang))) languages = [i18n.defaultLocale] - } // match locale const matchedLocale = match(languages, locales, i18n.defaultLocale) as Locale From 1db4139b5a6a9a7534fdb158951667574768bfbb Mon Sep 17 00:00:00 2001 From: AkaraChen Date: Mon, 28 Oct 2024 15:24:44 +0800 Subject: [PATCH 259/346] build: update deps build: update classnames build: update types build: update uuid build: update emoji-mart build: update use-context-selector build: update ui component deps --- web/package.json | 50 ++++++++--------- web/pnpm-lock.yaml | 136 ++++++++++++++++++++++++--------------------- 2 files changed, 99 insertions(+), 87 deletions(-) diff --git a/web/package.json b/web/package.json index 8910b34128..558c45bb28 100644 --- a/web/package.json +++ b/web/package.json @@ -26,7 +26,7 @@ "dependencies": { "@babel/runtime": "^7.22.3", "@dagrejs/dagre": "^1.1.2", - "@emoji-mart/data": "^1.1.2", + "@emoji-mart/data": "^1.2.1", "@floating-ui/react": "^0.25.2", "@formatjs/intl-localematcher": "^0.5.4", "@headlessui/react": "^1.7.13", @@ -43,15 +43,15 @@ "@svgdotjs/svg.js": "^3.2.4", "@tailwindcss/line-clamp": "^0.4.4", "@tailwindcss/typography": "^0.5.9", - "ahooks": "^3.7.5", + "ahooks": "^3.8.1", "class-variance-authority": "^0.7.0", - "classnames": "^2.3.2", + "classnames": "^2.5.1", "copy-to-clipboard": "^3.3.3", "crypto-js": "^4.2.0", - "dayjs": "^1.11.7", + "dayjs": "^1.11.13", "echarts": "^5.4.1", "echarts-for-react": "^3.0.2", - "emoji-mart": "^5.5.2", + "emoji-mart": "^5.6.0", "fast-deep-equal": "^3.1.3", "globals": "^15.11.0", "i18next": "^22.4.13", @@ -68,15 +68,15 @@ "mime": "^4.0.4", "negotiator": "^0.6.3", "next": "^14.2.10", - "pinyin-pro": "^3.23.0", + "pinyin-pro": "^3.25.0", "qrcode.react": "^4.1.0", "qs": "^6.13.0", - "rc-textarea": "^1.5.2", + "rc-textarea": "^1.8.2", "react": "~18.2.0", "react-18-input-autosize": "^3.0.0", "react-dom": "~18.2.0", "react-easy-crop": "^5.0.8", - "react-error-boundary": "^4.0.2", + "react-error-boundary": "^4.1.2", "react-headless-pagination": "^1.1.4", "react-hook-form": "^7.51.4", "react-i18next": "^12.2.0", @@ -84,11 +84,11 @@ "react-markdown": "^8.0.6", "react-multi-email": "^1.0.14", "react-papaparse": "^4.1.0", - "react-slider": "^2.0.4", + "react-slider": "^2.0.6", "react-sortablejs": "^6.1.4", - "react-syntax-highlighter": "^15.5.0", + "react-syntax-highlighter": "^15.6.1", "react-tooltip": "5.8.3", - "react-window": "^1.8.9", + "react-window": "^1.8.10", "react-window-infinite-loader": "^1.0.9", "reactflow": "^11.11.3", "recordrtc": "^5.6.2", @@ -100,11 +100,11 @@ "scheduler": "^0.23.0", "server-only": "^0.0.1", "sharp": "^0.33.5", - "sortablejs": "^1.15.0", + "sortablejs": "^1.15.3", "swr": "^2.1.0", "tailwind-merge": "^2.4.0", - "use-context-selector": "^1.4.1", - "uuid": "^9.0.1", + "use-context-selector": "^2.0.0", + "uuid": "^10.0.0", "zod": "^3.23.6", "zundo": "^2.1.0", "zustand": "^4.5.2" @@ -129,9 +129,9 @@ "@testing-library/dom": "^10.4.0", "@testing-library/jest-dom": "^6.6.2", "@testing-library/react": "^16.0.1", - "@types/crypto-js": "^4.1.1", + "@types/crypto-js": "^4.2.2", "@types/dagre": "^0.7.52", - "@types/jest": "^29.5.12", + "@types/jest": "^29.5.13", "@types/js-cookie": "^3.0.6", "@types/lodash-es": "^4.17.12", "@types/negotiator": "^0.6.1", @@ -139,16 +139,16 @@ "@types/qs": "^6.9.16", "@types/react": "~18.2.0", "@types/react-dom": "~18.2.0", - "@types/react-slider": "^1.3.1", - "@types/react-syntax-highlighter": "^15.5.6", - "@types/react-window": "^1.8.5", - "@types/react-window-infinite-loader": "^1.0.6", - "@types/recordrtc": "^5.6.11", + "@types/react-slider": "^1.3.6", + "@types/react-syntax-highlighter": "^15.5.13", + "@types/react-window": "^1.8.8", + "@types/react-window-infinite-loader": "^1.0.9", + "@types/recordrtc": "^5.6.14", "@types/sortablejs": "^1.15.1", - "@types/uuid": "^9.0.8", + "@types/uuid": "^10.0.0", "autoprefixer": "^10.4.14", "bing-translate-api": "^4.0.2", - "code-inspector-plugin": "^0.13.0", + "code-inspector-plugin": "^0.17.4", "cross-env": "^7.0.3", "eslint": "^9.13.0", "eslint-config-next": "^15.0.0", @@ -166,7 +166,7 @@ "tailwindcss": "^3.4.4", "ts-node": "^10.9.2", "typescript": "4.9.5", - "uglify-js": "^3.17.4" + "uglify-js": "^3.19.3" }, "resolutions": { "@types/react": "~18.2.0", @@ -181,4 +181,4 @@ "eslint --fix" ] } -} \ No newline at end of file +} diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index 1f0a2a1c18..ed50dd143f 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -20,7 +20,7 @@ importers: specifier: ^1.1.2 version: 1.1.4 '@emoji-mart/data': - specifier: ^1.1.2 + specifier: ^1.2.1 version: 1.2.1 '@floating-ui/react': specifier: ^0.25.2 @@ -71,13 +71,13 @@ importers: specifier: ^0.5.9 version: 0.5.15(tailwindcss@3.4.14(ts-node@10.9.2(@types/node@18.15.0)(typescript@4.9.5))) ahooks: - specifier: ^3.7.5 + specifier: ^3.8.1 version: 3.8.1(react@18.2.0) class-variance-authority: specifier: ^0.7.0 version: 0.7.0 classnames: - specifier: ^2.3.2 + specifier: ^2.5.1 version: 2.5.1 copy-to-clipboard: specifier: ^3.3.3 @@ -86,7 +86,7 @@ importers: specifier: ^4.2.0 version: 4.2.0 dayjs: - specifier: ^1.11.7 + specifier: ^1.11.13 version: 1.11.13 echarts: specifier: ^5.4.1 @@ -95,7 +95,7 @@ importers: specifier: ^3.0.2 version: 3.0.2(echarts@5.5.1)(react@18.2.0) emoji-mart: - specifier: ^5.5.2 + specifier: ^5.6.0 version: 5.6.0 fast-deep-equal: specifier: ^3.1.3 @@ -146,7 +146,7 @@ importers: specifier: ^14.2.10 version: 14.2.15(@babel/core@7.25.8)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.80.3) pinyin-pro: - specifier: ^3.23.0 + specifier: ^3.25.0 version: 3.25.0 qrcode.react: specifier: ^4.1.0 @@ -155,7 +155,7 @@ importers: specifier: ^6.13.0 version: 6.13.0 rc-textarea: - specifier: ^1.5.2 + specifier: ^1.8.2 version: 1.8.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react: specifier: ~18.2.0 @@ -170,7 +170,7 @@ importers: specifier: ^5.0.8 version: 5.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react-error-boundary: - specifier: ^4.0.2 + specifier: ^4.1.2 version: 4.1.2(react@18.2.0) react-headless-pagination: specifier: ^1.1.4 @@ -194,19 +194,19 @@ importers: specifier: ^4.1.0 version: 4.4.0 react-slider: - specifier: ^2.0.4 + specifier: ^2.0.6 version: 2.0.6(react@18.2.0) react-sortablejs: specifier: ^6.1.4 version: 6.1.4(@types/sortablejs@1.15.8)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sortablejs@1.15.3) react-syntax-highlighter: - specifier: ^15.5.0 + specifier: ^15.6.1 version: 15.6.1(react@18.2.0) react-tooltip: specifier: 5.8.3 version: 5.8.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react-window: - specifier: ^1.8.9 + specifier: ^1.8.10 version: 1.8.10(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react-window-infinite-loader: specifier: ^1.0.9 @@ -242,7 +242,7 @@ importers: specifier: ^0.33.5 version: 0.33.5 sortablejs: - specifier: ^1.15.0 + specifier: ^1.15.3 version: 1.15.3 swr: specifier: ^2.1.0 @@ -251,11 +251,11 @@ importers: specifier: ^2.4.0 version: 2.5.4 use-context-selector: - specifier: ^1.4.1 - version: 1.4.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(scheduler@0.23.2) + specifier: ^2.0.0 + version: 2.0.0(react@18.2.0)(scheduler@0.23.2) uuid: - specifier: ^9.0.1 - version: 9.0.1 + specifier: ^10.0.0 + version: 10.0.0 zod: specifier: ^3.23.6 version: 3.23.8 @@ -324,13 +324,13 @@ importers: specifier: ^16.0.1 version: 16.0.1(@testing-library/dom@10.4.0)(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@types/crypto-js': - specifier: ^4.1.1 + specifier: ^4.2.2 version: 4.2.2 '@types/dagre': specifier: ^0.7.52 version: 0.7.52 '@types/jest': - specifier: ^29.5.12 + specifier: ^29.5.13 version: 29.5.13 '@types/js-cookie': specifier: ^3.0.6 @@ -354,26 +354,26 @@ importers: specifier: ~18.2.0 version: 18.2.25 '@types/react-slider': - specifier: ^1.3.1 + specifier: ^1.3.6 version: 1.3.6 '@types/react-syntax-highlighter': - specifier: ^15.5.6 + specifier: ^15.5.13 version: 15.5.13 '@types/react-window': - specifier: ^1.8.5 + specifier: ^1.8.8 version: 1.8.8 '@types/react-window-infinite-loader': - specifier: ^1.0.6 + specifier: ^1.0.9 version: 1.0.9 '@types/recordrtc': - specifier: ^5.6.11 + specifier: ^5.6.14 version: 5.6.14 '@types/sortablejs': specifier: ^1.15.1 version: 1.15.8 '@types/uuid': - specifier: ^9.0.8 - version: 9.0.8 + specifier: ^10.0.0 + version: 10.0.0 autoprefixer: specifier: ^10.4.14 version: 10.4.20(postcss@8.4.47) @@ -381,8 +381,8 @@ importers: specifier: ^4.0.2 version: 4.0.2 code-inspector-plugin: - specifier: ^0.13.0 - version: 0.13.0 + specifier: ^0.17.4 + version: 0.17.4 cross-env: specifier: ^7.0.3 version: 7.0.3 @@ -435,7 +435,7 @@ importers: specifier: 4.9.5 version: 4.9.5 uglify-js: - specifier: ^3.17.4 + specifier: ^3.19.3 version: 3.19.3 packages: @@ -2699,6 +2699,9 @@ packages: '@types/unist@3.0.3': resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + '@types/uuid@10.0.0': + resolution: {integrity: sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==} + '@types/uuid@9.0.8': resolution: {integrity: sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==} @@ -3435,11 +3438,11 @@ packages: resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} - code-inspector-core@0.13.0: - resolution: {integrity: sha512-oYPNLdJjn3SY50YtF3IuxZOKLBNwzXSRPOqiXVnZFceMz9Ar6ugP3+zj7HszouxrsLFb2dVtlv//5wr4+cq62A==} + code-inspector-core@0.17.4: + resolution: {integrity: sha512-Pp8Ct/nxNddCiLJYd8XhHMRMkDk1lgbKMcRDolxmpunv8JZYE0K2HGPaei2w/TM9GhUHeKfT6j3dEG3W5y+Mlg==} - code-inspector-plugin@0.13.0: - resolution: {integrity: sha512-v4mq5hhHkyMmutembTzREVsFeZ/+KsCwfx20+0gTqm1Il/M1T4d2BCv9mZ4ivie3GvvDMt/pVz1iBBVP3SuzJA==} + code-inspector-plugin@0.17.4: + resolution: {integrity: sha512-aIM8wcO0eNoY+tlXXU+xwcTnUN96jmfglWFi1A1Vmqs5gew8k54709a95dJ6wa+gOHD5I3cw+Qh3xtoikHi9KA==} collect-v8-coverage@1.0.2: resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} @@ -4100,6 +4103,9 @@ packages: resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} engines: {node: '>= 0.4'} + esbuild-code-inspector-plugin@0.17.4: + resolution: {integrity: sha512-gqgcEPgtcJyjBVId9av8QaTGlMnX75/aV8iLn4bjRPpOWX9hqSS5jUhHlIJHisptSuWPYeCyvduHEblAcKsHzA==} + esbuild-register@3.6.0: resolution: {integrity: sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==} peerDependencies: @@ -7837,18 +7843,11 @@ packages: resolution: {integrity: sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==} engines: {node: '>= 0.4'} - use-context-selector@1.4.4: - resolution: {integrity: sha512-pS790zwGxxe59GoBha3QYOwk8AFGp4DN6DOtH+eoqVmgBBRXVx4IlPDhJmmMiNQAgUaLlP+58aqRC3A4rdaSjg==} + use-context-selector@2.0.0: + resolution: {integrity: sha512-owfuSmUNd3eNp3J9CdDl0kMgfidV+MkDvHPpvthN5ThqM+ibMccNE0k+Iq7TWC6JPFvGZqanqiGCuQx6DyV24g==} peerDependencies: - react: '>=16.8.0' - react-dom: '*' - react-native: '*' + react: '>=18.0.0' scheduler: '>=0.19.0' - peerDependenciesMeta: - react-dom: - optional: true - react-native: - optional: true use-strict@1.0.1: resolution: {integrity: sha512-IeiWvvEXfW5ltKVMkxq6FvNf2LojMKvB2OCeja6+ct24S1XOmQw2dGr2JyndwACWAGJva9B7yPHwAmeA9QCqAQ==} @@ -7871,6 +7870,10 @@ packages: resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} engines: {node: '>= 0.4.0'} + uuid@10.0.0: + resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==} + hasBin: true + uuid@9.0.1: resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} hasBin: true @@ -7912,8 +7915,8 @@ packages: vfile@6.0.3: resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} - vite-code-inspector-plugin@0.13.0: - resolution: {integrity: sha512-hvIn9G+IFzQHVVynWh2wGTBHo51CBJRqQBzYryeuuaL0BK0w8my2/tlpSAae5ofQxOBXBMhyXC2gWgYUJnNWrA==} + vite-code-inspector-plugin@0.17.4: + resolution: {integrity: sha512-Zvpy/0hc55k8OV7+I63vAI0oERLUvGS/kXb3mwEkan3VsVgifDLqtvhjTuo7Teem/KqQec+4civ9Xg2DEyCmew==} vm-browserify@1.1.2: resolution: {integrity: sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==} @@ -7949,8 +7952,8 @@ packages: resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} engines: {node: '>=12'} - webpack-code-inspector-plugin@0.13.0: - resolution: {integrity: sha512-T3ZZ84NX0cVmwff5zyYhB9OuroZYsyaQpSgFicgiuYAWCsQePYApM/R3bHdvcECkBXO50hAVtr9SjWRTu1+Ntg==} + webpack-code-inspector-plugin@0.17.4: + resolution: {integrity: sha512-bhoRXBEjC2VS2oQ/CV1QToOYiGKUYKYWXxyBfdBamZSbknQlIZC5q53aehzu/AVphVxrfWmvW+vth/PBSY0BAw==} webpack-dev-middleware@6.1.3: resolution: {integrity: sha512-A4ChP0Qj8oGociTs6UdlRUGANIGrCDL3y+pmQMc+dSsraXHCatFpmMey4mYELA+juqwUqwQsUgJJISXl1KWmiw==} @@ -11020,6 +11023,8 @@ snapshots: '@types/unist@3.0.3': {} + '@types/uuid@10.0.0': {} + '@types/uuid@9.0.8': {} '@types/yargs-parser@21.0.3': {} @@ -11904,20 +11909,21 @@ snapshots: co@4.6.0: {} - code-inspector-core@0.13.0: + code-inspector-core@0.17.4: dependencies: '@vue/compiler-dom': 3.5.12 - chalk: 4.1.1 + chalk: 4.1.2 portfinder: 1.0.32 transitivePeerDependencies: - supports-color - code-inspector-plugin@0.13.0: + code-inspector-plugin@0.17.4: dependencies: chalk: 4.1.1 - code-inspector-core: 0.13.0 - vite-code-inspector-plugin: 0.13.0 - webpack-code-inspector-plugin: 0.13.0 + code-inspector-core: 0.17.4 + esbuild-code-inspector-plugin: 0.17.4 + vite-code-inspector-plugin: 0.17.4 + webpack-code-inspector-plugin: 0.17.4 transitivePeerDependencies: - supports-color @@ -12640,6 +12646,12 @@ snapshots: is-date-object: 1.0.5 is-symbol: 1.0.4 + esbuild-code-inspector-plugin@0.17.4: + dependencies: + code-inspector-core: 0.17.4 + transitivePeerDependencies: + - supports-color + esbuild-register@3.6.0(esbuild@0.23.1): dependencies: debug: 4.3.7 @@ -12743,7 +12755,7 @@ snapshots: debug: 4.3.7 enhanced-resolve: 5.17.1 eslint: 9.13.0(jiti@1.21.6) - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.13.0(jiti@1.21.6)) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@4.3.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-plugin-import@2.31.0)(eslint@9.13.0(jiti@1.21.6)))(eslint@9.13.0(jiti@1.21.6)) fast-glob: 3.3.2 get-tsconfig: 4.8.1 is-bun-module: 1.2.1 @@ -12761,7 +12773,7 @@ snapshots: dependencies: eslint: 9.13.0(jiti@1.21.6) - eslint-module-utils@2.12.0(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.13.0(jiti@1.21.6)): + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@4.3.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-plugin-import@2.31.0)(eslint@9.13.0(jiti@1.21.6)))(eslint@9.13.0(jiti@1.21.6)): dependencies: debug: 3.2.7 optionalDependencies: @@ -12817,7 +12829,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.13.0(jiti@1.21.6) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3)(eslint@9.13.0(jiti@1.21.6)) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.11.0(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import-x@4.3.1(eslint@9.13.0(jiti@1.21.6))(typescript@4.9.5))(eslint-plugin-import@2.31.0)(eslint@9.13.0(jiti@1.21.6)))(eslint@9.13.0(jiti@1.21.6)) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3 @@ -17596,12 +17608,10 @@ snapshots: punycode: 1.4.1 qs: 6.13.0 - use-context-selector@1.4.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(scheduler@0.23.2): + use-context-selector@2.0.0(react@18.2.0)(scheduler@0.23.2): dependencies: react: 18.2.0 scheduler: 0.23.2 - optionalDependencies: - react-dom: 18.2.0(react@18.2.0) use-strict@1.0.1: {} @@ -17623,6 +17633,8 @@ snapshots: utils-merge@1.0.1: {} + uuid@10.0.0: {} + uuid@9.0.1: {} uvu@0.5.6: @@ -17679,9 +17691,9 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.2 - vite-code-inspector-plugin@0.13.0: + vite-code-inspector-plugin@0.17.4: dependencies: - code-inspector-core: 0.13.0 + code-inspector-core: 0.17.4 transitivePeerDependencies: - supports-color @@ -17721,9 +17733,9 @@ snapshots: webidl-conversions@7.0.0: {} - webpack-code-inspector-plugin@0.13.0: + webpack-code-inspector-plugin@0.17.4: dependencies: - code-inspector-core: 0.13.0 + code-inspector-core: 0.17.4 transitivePeerDependencies: - supports-color From ed7f74c99c87f052f633fe3aa9d7a0bfe73fad71 Mon Sep 17 00:00:00 2001 From: AkaraChen Date: Mon, 28 Oct 2024 15:32:39 +0800 Subject: [PATCH 260/346] build: update i18n pkg --- web/package.json | 10 +++++----- web/pnpm-lock.yaml | 38 +++++++++++++++++++------------------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/web/package.json b/web/package.json index 558c45bb28..aa9c4953ca 100644 --- a/web/package.json +++ b/web/package.json @@ -28,7 +28,7 @@ "@dagrejs/dagre": "^1.1.2", "@emoji-mart/data": "^1.2.1", "@floating-ui/react": "^0.25.2", - "@formatjs/intl-localematcher": "^0.5.4", + "@formatjs/intl-localematcher": "^0.5.6", "@headlessui/react": "^1.7.13", "@heroicons/react": "^2.0.16", "@hookform/resolvers": "^3.3.4", @@ -54,8 +54,8 @@ "emoji-mart": "^5.6.0", "fast-deep-equal": "^3.1.3", "globals": "^15.11.0", - "i18next": "^22.4.13", - "i18next-resources-to-backend": "^1.1.3", + "i18next": "^23.16.4", + "i18next-resources-to-backend": "^1.2.1", "immer": "^9.0.19", "js-audio-recorder": "^1.0.7", "js-cookie": "^3.0.5", @@ -79,7 +79,7 @@ "react-error-boundary": "^4.1.2", "react-headless-pagination": "^1.1.4", "react-hook-form": "^7.51.4", - "react-i18next": "^12.2.0", + "react-i18next": "^15.1.0", "react-infinite-scroll-component": "^6.1.0", "react-markdown": "^8.0.6", "react-multi-email": "^1.0.14", @@ -134,7 +134,7 @@ "@types/jest": "^29.5.13", "@types/js-cookie": "^3.0.6", "@types/lodash-es": "^4.17.12", - "@types/negotiator": "^0.6.1", + "@types/negotiator": "^0.6.3", "@types/node": "18.15.0", "@types/qs": "^6.9.16", "@types/react": "~18.2.0", diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index ed50dd143f..040f88e83f 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -26,8 +26,8 @@ importers: specifier: ^0.25.2 version: 0.25.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@formatjs/intl-localematcher': - specifier: ^0.5.4 - version: 0.5.5 + specifier: ^0.5.6 + version: 0.5.6 '@headlessui/react': specifier: ^1.7.13 version: 1.7.19(react-dom@18.2.0(react@18.2.0))(react@18.2.0) @@ -104,10 +104,10 @@ importers: specifier: ^15.11.0 version: 15.11.0 i18next: - specifier: ^22.4.13 - version: 22.5.1 + specifier: ^23.16.4 + version: 23.16.4 i18next-resources-to-backend: - specifier: ^1.1.3 + specifier: ^1.2.1 version: 1.2.1 immer: specifier: ^9.0.19 @@ -179,8 +179,8 @@ importers: specifier: ^7.51.4 version: 7.53.1(react@18.2.0) react-i18next: - specifier: ^12.2.0 - version: 12.3.1(i18next@22.5.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + specifier: ^15.1.0 + version: 15.1.0(i18next@23.16.4)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react-infinite-scroll-component: specifier: ^6.1.0 version: 6.1.0(react@18.2.0) @@ -339,7 +339,7 @@ importers: specifier: ^4.17.12 version: 4.17.12 '@types/negotiator': - specifier: ^0.6.1 + specifier: ^0.6.3 version: 0.6.3 '@types/node': specifier: 18.15.0 @@ -1439,8 +1439,8 @@ packages: '@floating-ui/utils@0.2.8': resolution: {integrity: sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==} - '@formatjs/intl-localematcher@0.5.5': - resolution: {integrity: sha512-t5tOGMgZ/i5+ALl2/offNqAQq/lfUnKLEw0mXQI4N4bqpedhrSE+fyKLpwnd22sK0dif6AV+ufQcTsKShB9J1g==} + '@formatjs/intl-localematcher@0.5.6': + resolution: {integrity: sha512-roz1+Ba5e23AHX6KUAWmLEyTRZegM5YDuxuvkHCyK3RJddf/UXB2f+s7pOMm9ktfPGla0g+mQXOn5vsuYirnaA==} '@headlessui/react@1.7.19': resolution: {integrity: sha512-Ll+8q3OlMJfJbAKM/+/Y2q6PPYbryqNTXDbryx7SXLIDamkF6iQFbriYHga0dY44PvDhvvBWCx1Xj4U5+G4hOw==} @@ -4982,8 +4982,8 @@ packages: i18next-resources-to-backend@1.2.1: resolution: {integrity: sha512-okHbVA+HZ7n1/76MsfhPqDou0fptl2dAlhRDu2ideXloRRduzHsqDOznJBef+R3DFZnbvWoBW+KxJ7fnFjd6Yw==} - i18next@22.5.1: - resolution: {integrity: sha512-8TGPgM3pAD+VRsMtUMNknRz3kzqwp/gPALrWMsDnmC1mKqJwpWyooQRLMcbTwq8z8YwSmuj+ZYvc+xCuEpkssA==} + i18next@23.16.4: + resolution: {integrity: sha512-9NIYBVy9cs4wIqzurf7nLXPyf3R78xYbxExVqHLK9od3038rjpyOEzW+XB130kZ1N4PZ9inTtJ471CRJ4Ituyg==} iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} @@ -6791,10 +6791,10 @@ packages: peerDependencies: react: ^16.8.0 || ^17 || ^18 || ^19 - react-i18next@12.3.1: - resolution: {integrity: sha512-5v8E2XjZDFzK7K87eSwC7AJcAkcLt5xYZ4+yTPDAW1i7C93oOY1dnr4BaQM7un4Hm+GmghuiPvevWwlca5PwDA==} + react-i18next@15.1.0: + resolution: {integrity: sha512-zj3nJynMnZsy2gPZiOTC7XctCY5eQGqT3tcKMmfJWC9FMvgd+960w/adq61j8iPzpwmsXejqID9qC3Mqu1Xu2Q==} peerDependencies: - i18next: '>= 19.0.0' + i18next: '>= 23.2.3' react: '>= 16.8.0' react-dom: '*' react-native: '*' @@ -9357,7 +9357,7 @@ snapshots: '@floating-ui/utils@0.2.8': {} - '@formatjs/intl-localematcher@0.5.5': + '@formatjs/intl-localematcher@0.5.6': dependencies: tslib: 2.8.0 @@ -13924,7 +13924,7 @@ snapshots: dependencies: '@babel/runtime': 7.25.7 - i18next@22.5.1: + i18next@23.16.4: dependencies: '@babel/runtime': 7.25.7 @@ -16399,11 +16399,11 @@ snapshots: dependencies: react: 18.2.0 - react-i18next@12.3.1(i18next@22.5.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + react-i18next@15.1.0(i18next@23.16.4)(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: '@babel/runtime': 7.25.7 html-parse-stringify: 3.0.1 - i18next: 22.5.1 + i18next: 23.16.4 react: 18.2.0 optionalDependencies: react-dom: 18.2.0(react@18.2.0) From 15c33ba7f3ea3ad800e244ad1fdddedbc02c7588 Mon Sep 17 00:00:00 2001 From: AkaraChen Date: Mon, 28 Oct 2024 15:33:22 +0800 Subject: [PATCH 261/346] build: update lexical deps --- web/package.json | 4 +- web/pnpm-lock.yaml | 288 +++++++++++++++++++++++---------------------- 2 files changed, 147 insertions(+), 145 deletions(-) diff --git a/web/package.json b/web/package.json index aa9c4953ca..5e95840017 100644 --- a/web/package.json +++ b/web/package.json @@ -32,7 +32,7 @@ "@headlessui/react": "^1.7.13", "@heroicons/react": "^2.0.16", "@hookform/resolvers": "^3.3.4", - "@lexical/react": "^0.16.0", + "@lexical/react": "^0.18.0", "@mdx-js/loader": "^2.3.0", "@mdx-js/react": "^2.3.0", "@monaco-editor/react": "^4.6.0", @@ -62,7 +62,7 @@ "jwt-decode": "^4.0.0", "katex": "^0.16.10", "lamejs": "^1.2.1", - "lexical": "^0.16.0", + "lexical": "^0.18.0", "lodash-es": "^4.17.21", "mermaid": "10.9.3", "mime": "^4.0.4", diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index 040f88e83f..fbfa835fb2 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -38,8 +38,8 @@ importers: specifier: ^3.3.4 version: 3.9.0(react-hook-form@7.53.1(react@18.2.0)) '@lexical/react': - specifier: ^0.16.0 - version: 0.16.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(yjs@13.6.20) + specifier: ^0.18.0 + version: 0.18.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(yjs@13.6.20) '@mdx-js/loader': specifier: ^2.3.0 version: 2.3.0(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3)) @@ -128,8 +128,8 @@ importers: specifier: ^1.2.1 version: 1.2.1 lexical: - specifier: ^0.16.0 - version: 0.16.1 + specifier: ^0.18.0 + version: 0.18.0 lodash-es: specifier: ^4.17.21 version: 4.17.21 @@ -1682,74 +1682,74 @@ packages: '@jridgewell/trace-mapping@0.3.9': resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} - '@lexical/clipboard@0.16.1': - resolution: {integrity: sha512-0dWs/SwKS5KPpuf6fUVVt9vSCl6HAqcDGhSITw/okv0rrIlXTUT6WhVsMJtXfFxTyVvwMeOecJHvQH3i/jRQtA==} + '@lexical/clipboard@0.18.0': + resolution: {integrity: sha512-ybc+hx14wj0n2ZjdOkLcZ02MRB3UprXjpLDXlByFIuVcZpUxVcp3NzA0UBPOKXYKvdt0bmgjnAsFWM5OSbwS0w==} - '@lexical/code@0.16.1': - resolution: {integrity: sha512-pOC28rRZ2XkmI2nIJm50DbKaCJtk5D0o7r6nORYp4i0z+lxt5Sf2m82DL9ksUHJRqKy87pwJDpoWvJ2SAI0ohw==} + '@lexical/code@0.18.0': + resolution: {integrity: sha512-VB8fRHIrB8QTqyZUvGBMVWP2tpKe3ArOjPdWAqgrS8MVFldqUhuTHcW+XJFkVxcEBYCXynNT29YRYtQhfQ+vDQ==} - '@lexical/devtools-core@0.16.1': - resolution: {integrity: sha512-8CvGERGL7ySDVGLU+YPeq+JupIXsOFlXa3EuJ88koLKqXxYenwMleZgGqayFp6lCP78xqPKnATVeoOZUt/NabQ==} + '@lexical/devtools-core@0.18.0': + resolution: {integrity: sha512-gVgtEkLwGjz1frOmDpFJzDPFxPgAcC9n5ZaaZWHo5GLcptnQmkuLm1t+UInQWujXhFmcyJzfiqDaMJ8EIcb2Ww==} peerDependencies: react: '>=17.x' react-dom: '>=17.x' - '@lexical/dragon@0.16.1': - resolution: {integrity: sha512-Rvd60GIYN5kpjjBumS34EnNbBaNsoseI0AlzOdtIV302jiHPCLH0noe9kxzu9nZy+MZmjZy8Dx2zTbQT2mueRw==} + '@lexical/dragon@0.18.0': + resolution: {integrity: sha512-toD/y2/TgtG+eFVKXf65kDk/Mv02FwgmcGH18nyAabZnO1TLBaMYPkGFdTTZ8hVmQxqIu9nZuLWUbdIBMs8UWw==} - '@lexical/hashtag@0.16.1': - resolution: {integrity: sha512-G+YOxStAKs3q1utqm9KR4D4lCkwIH52Rctm4RgaVTI+4lvTaybeDRGFV75P/pI/qlF7/FvAYHTYEzCjtC3GNMQ==} + '@lexical/hashtag@0.18.0': + resolution: {integrity: sha512-bm+Sv7keguVYbUY0ngd+iAv2Owd3dePzdVkzkmw9Al8GPXkE5ll8fjq6Xjw2u3OVhf+9pTnesIo/AS7H+h0exw==} - '@lexical/history@0.16.1': - resolution: {integrity: sha512-WQhScx0TJeKSQAnEkRpIaWdUXqirrNrom2MxbBUc/32zEUMm9FzV7nRGknvUabEFUo7vZq6xTZpOExQJqHInQA==} + '@lexical/history@0.18.0': + resolution: {integrity: sha512-c87J4ke1Sae03coElJay2Ikac/4OcA2OmhtNbt2gAi/XBtcsP4mPuz1yZfZf9XIe+weekObgjinvZekQ2AFw0g==} - '@lexical/html@0.16.1': - resolution: {integrity: sha512-vbtAdCvQ3PaAqa5mFmtmrvbiAvjCu1iXBAJ0bsHqFXCF2Sba5LwHVe8dUAOTpfEZEMbiHfjul6b5fj4vNPGF2A==} + '@lexical/html@0.18.0': + resolution: {integrity: sha512-8lhba1DFnnobXgYm4Rk5Gr2tZedD4Gl6A/NKCt7whO/CET63vT3UnK2ggcVVgtIJG530Cv0bdZoJbJu5DauI5w==} - '@lexical/link@0.16.1': - resolution: {integrity: sha512-zG36gEnEqbIe6tK/MhXi7wn/XMY/zdivnPcOY5WyC3derkEezeLSSIFsC1u5UNeK5pbpNMSy4LDpLhi1Ww4Y5w==} + '@lexical/link@0.18.0': + resolution: {integrity: sha512-GCYcbNTSTwJk0lr+GMc8nn6Meq44BZs3QL2d1B0skpZAspd8yI53sRS6HDy5P+jW5P0dzyZr/XJAU4U+7zsEEg==} - '@lexical/list@0.16.1': - resolution: {integrity: sha512-i9YhLAh5N6YO9dP+R1SIL9WEdCKeTiQQYVUzj84vDvX5DIBxMPUjTmMn3LXu9T+QO3h1s2L/vJusZASrl45eAw==} + '@lexical/list@0.18.0': + resolution: {integrity: sha512-DEWs9Scbg3+STZeE2O0OoG8SWnKnxQccObBzyeHRjn4GAN6JA7lgcAzfrdgp0fNWTbMM/ku876MmXKGnqhvg9Q==} - '@lexical/mark@0.16.1': - resolution: {integrity: sha512-CZRGMLcxn5D+jzf1XnH+Z+uUugmpg1mBwTbGybCPm8UWpBrKDHkrscfMgWz62iRWz0cdVjM5+0zWpNElxFTRjQ==} + '@lexical/mark@0.18.0': + resolution: {integrity: sha512-QA4YWfTP5WWnCnoH/RmfcsSZyhhd7oeFWDpfP7S8Bbmhz6kiPwGcsVr+uRQBBT56AqEX167xX2rX8JR6FiYZqA==} - '@lexical/markdown@0.16.1': - resolution: {integrity: sha512-0sBLttMvfQO/hVaIqpHdvDowpgV2CoRuWo2CNwvRLZPPWvPVjL4Nkb73wmi8zAZsAOTbX2aw+g4m/+k5oJqNig==} + '@lexical/markdown@0.18.0': + resolution: {integrity: sha512-uSWwcK8eJw5C+waEhU5WoX8W+JxNZbKuFnZwsn5nsp+iQgqMj4qY6g0yJub4sq8vvh6jjl4vVXhXTq2up9aykw==} - '@lexical/offset@0.16.1': - resolution: {integrity: sha512-/i2J04lQmFeydUZIF8tKXLQTXiJDTQ6GRnkfv1OpxU4amc0rwGa7+qAz/PuF1n58rP6InpLmSHxgY5JztXa2jw==} + '@lexical/offset@0.18.0': + resolution: {integrity: sha512-KGlboyLSxQAH5PMOlJmyvHlbYXZneVnKiHpfyBV5IUX5kuyB/eZbQEYcJP9saekfQ5Xb1FWXWmsZEo+sWtrrZA==} - '@lexical/overflow@0.16.1': - resolution: {integrity: sha512-xh5YpoxwA7K4wgMQF/Sjl8sdjaxqesLCtH5ZrcMsaPlmucDIEEs+i8xxk+kDUTEY7y+3FvRxs4lGNgX8RVWkvQ==} + '@lexical/overflow@0.18.0': + resolution: {integrity: sha512-3ATTwttVgZtVLq60ZUWbpbXBbpuMa3PZD5CxSP3nulviL+2I4phvacV4WUN+8wMeq+PGmuarl+cYfrFL02ii3g==} - '@lexical/plain-text@0.16.1': - resolution: {integrity: sha512-GjY4ylrBZIaAVIF8IFnmW0XGyHAuRmWA6gKB8iTTlsjgFrCHFIYC74EeJSp309O0Hflg9rRBnKoX1TYruFHVwA==} + '@lexical/plain-text@0.18.0': + resolution: {integrity: sha512-L6yQpiwW0ZacY1oNwvRBxSuW2TZaUcveZLheJc8JzGcZoVxzII/CAbLZG8691VbNuKsbOURiNXZIsgwujKmo4Q==} - '@lexical/react@0.16.1': - resolution: {integrity: sha512-SsGgLt9iKfrrMRy9lFb6ROVPUYOgv6b+mCn9Al+TLqs/gBReDBi3msA7m526nrtBUKYUnjHdQ1QXIJzuKgOxcg==} + '@lexical/react@0.18.0': + resolution: {integrity: sha512-DLvIbTsjvFIFqm+9zvAjEwuZHAbSxzZf1AGqf1lLctlL/Ran0f+8EZOv5jttELTe7xISZ2+xSXTLRfyxhNwGXQ==} peerDependencies: react: '>=17.x' react-dom: '>=17.x' - '@lexical/rich-text@0.16.1': - resolution: {integrity: sha512-4uEVXJur7tdSbqbmsToCW4YVm0AMh4y9LK077Yq2O9hSuA5dqpI8UbTDnxZN2D7RfahNvwlqp8eZKFB1yeiJGQ==} + '@lexical/rich-text@0.18.0': + resolution: {integrity: sha512-xMANCB7WueMsmWK8qxik5FZN4ApyaHWHQILS9r4FTbdv/DlNepsR7Pt8kg2317xZ56NAueQLIdyyKYXG1nBrHw==} - '@lexical/selection@0.16.1': - resolution: {integrity: sha512-+nK3RvXtyQvQDq7AZ46JpphmM33pwuulwiRfeXR5T9iFQTtgWOEjsAi/KKX7vGm70BxACfiSxy5QCOgBWFwVJg==} + '@lexical/selection@0.18.0': + resolution: {integrity: sha512-mJoMhmxeZLfM9K2JMYETs9u179IkHQUlgtYG5GZJHjKx2iUn+9KvJ9RVssq+Lusi7C/N42wWPGNHDPdUvFtxXg==} - '@lexical/table@0.16.1': - resolution: {integrity: sha512-GWb0/MM1sVXpi1p2HWWOBldZXASMQ4c6WRNYnRmq7J/aB5N66HqQgJGKp3m66Kz4k1JjhmZfPs7F018qIBhnFQ==} + '@lexical/table@0.18.0': + resolution: {integrity: sha512-TeTAnuFAAgVjm1QE8adRB3GFWN+DUUiS4vzGq+ynPRCtNdpmW27NmTkRMyxKsetUtt7nIFfj4DvLvor4RwqIpA==} - '@lexical/text@0.16.1': - resolution: {integrity: sha512-Os/nKQegORTrKKN6vL3/FMVszyzyqaotlisPynvTaHTUC+yY4uyjM2hlF93i5a2ixxyiPLF9bDroxUP96TMPXg==} + '@lexical/text@0.18.0': + resolution: {integrity: sha512-MTHSBeq3K0+lqSsP5oysBMnY4tPVhB8kAa2xBnEc3dYgXFxEEvJwZahbHNX93EPObtJkxXfUuI63Al4G3lYK8A==} - '@lexical/utils@0.16.1': - resolution: {integrity: sha512-BVyJxDQi/rIxFTDjf2zE7rMDKSuEaeJ4dybHRa/hRERt85gavGByQawSLeQlTjLaYLVsy+x7wCcqh2fNhlLf0g==} + '@lexical/utils@0.18.0': + resolution: {integrity: sha512-4s9dVpBZjqIaA/1q2GtfWFjKsv2Wqhjer0Zw2mcl1TIVN0zreXxcTKN316QppAWmSQJxVGvkWHjjaZJwl6/TSw==} - '@lexical/yjs@0.16.1': - resolution: {integrity: sha512-QHw1bmzB/IypIV1tRWMH4hhwE1xX7wV+HxbzBS8oJAkoU5AYXM/kyp/sQicgqiwVfpai1Px7zatOoUDFgbyzHQ==} + '@lexical/yjs@0.18.0': + resolution: {integrity: sha512-rl7Rl9XIb3ygQEEHOFtACdXs3BE+UUUmdyNqB6kK9A6IRGz+w4Azp+qzt8It/t+c0oaSYHpAtcLNXg1amJz+kA==} peerDependencies: yjs: '>=13.5.22' @@ -5579,8 +5579,8 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} - lexical@0.16.1: - resolution: {integrity: sha512-+R05d3+N945OY8pTUjTqQrWoApjC+ctzvjnmNETtx9WmVAaiW0tQVG+AYLt5pDGY8dQXtd4RPorvnxBTECt9SA==} + lexical@0.18.0: + resolution: {integrity: sha512-3K/B0RpzjoW+Wj2E455wWXxkqxqK8UgdIiuqkOqdOsoSSo5mCkHOU6eVw7Nlmlr1MFvAMzGmz4RPn8NZaLQ2Mw==} lib0@0.2.98: resolution: {integrity: sha512-XteTiNO0qEXqqweWx+b21p/fBnNHUA1NwAtJNJek1oPrewEZs2uiT4gWivHKr9GqCjDPAhchz0UQO8NwU3bBNA==} @@ -9670,149 +9670,151 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 - '@lexical/clipboard@0.16.1': + '@lexical/clipboard@0.18.0': dependencies: - '@lexical/html': 0.16.1 - '@lexical/list': 0.16.1 - '@lexical/selection': 0.16.1 - '@lexical/utils': 0.16.1 - lexical: 0.16.1 + '@lexical/html': 0.18.0 + '@lexical/list': 0.18.0 + '@lexical/selection': 0.18.0 + '@lexical/utils': 0.18.0 + lexical: 0.18.0 - '@lexical/code@0.16.1': + '@lexical/code@0.18.0': dependencies: - '@lexical/utils': 0.16.1 - lexical: 0.16.1 + '@lexical/utils': 0.18.0 + lexical: 0.18.0 prismjs: 1.29.0 - '@lexical/devtools-core@0.16.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + '@lexical/devtools-core@0.18.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': dependencies: - '@lexical/html': 0.16.1 - '@lexical/link': 0.16.1 - '@lexical/mark': 0.16.1 - '@lexical/table': 0.16.1 - '@lexical/utils': 0.16.1 - lexical: 0.16.1 + '@lexical/html': 0.18.0 + '@lexical/link': 0.18.0 + '@lexical/mark': 0.18.0 + '@lexical/table': 0.18.0 + '@lexical/utils': 0.18.0 + lexical: 0.18.0 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - '@lexical/dragon@0.16.1': + '@lexical/dragon@0.18.0': dependencies: - lexical: 0.16.1 + lexical: 0.18.0 - '@lexical/hashtag@0.16.1': + '@lexical/hashtag@0.18.0': dependencies: - '@lexical/utils': 0.16.1 - lexical: 0.16.1 + '@lexical/utils': 0.18.0 + lexical: 0.18.0 - '@lexical/history@0.16.1': + '@lexical/history@0.18.0': dependencies: - '@lexical/utils': 0.16.1 - lexical: 0.16.1 + '@lexical/utils': 0.18.0 + lexical: 0.18.0 - '@lexical/html@0.16.1': + '@lexical/html@0.18.0': dependencies: - '@lexical/selection': 0.16.1 - '@lexical/utils': 0.16.1 - lexical: 0.16.1 + '@lexical/selection': 0.18.0 + '@lexical/utils': 0.18.0 + lexical: 0.18.0 - '@lexical/link@0.16.1': + '@lexical/link@0.18.0': dependencies: - '@lexical/utils': 0.16.1 - lexical: 0.16.1 + '@lexical/utils': 0.18.0 + lexical: 0.18.0 - '@lexical/list@0.16.1': + '@lexical/list@0.18.0': dependencies: - '@lexical/utils': 0.16.1 - lexical: 0.16.1 + '@lexical/utils': 0.18.0 + lexical: 0.18.0 - '@lexical/mark@0.16.1': + '@lexical/mark@0.18.0': dependencies: - '@lexical/utils': 0.16.1 - lexical: 0.16.1 + '@lexical/utils': 0.18.0 + lexical: 0.18.0 - '@lexical/markdown@0.16.1': + '@lexical/markdown@0.18.0': dependencies: - '@lexical/code': 0.16.1 - '@lexical/link': 0.16.1 - '@lexical/list': 0.16.1 - '@lexical/rich-text': 0.16.1 - '@lexical/text': 0.16.1 - '@lexical/utils': 0.16.1 - lexical: 0.16.1 + '@lexical/code': 0.18.0 + '@lexical/link': 0.18.0 + '@lexical/list': 0.18.0 + '@lexical/rich-text': 0.18.0 + '@lexical/text': 0.18.0 + '@lexical/utils': 0.18.0 + lexical: 0.18.0 - '@lexical/offset@0.16.1': + '@lexical/offset@0.18.0': dependencies: - lexical: 0.16.1 + lexical: 0.18.0 - '@lexical/overflow@0.16.1': + '@lexical/overflow@0.18.0': dependencies: - lexical: 0.16.1 + lexical: 0.18.0 - '@lexical/plain-text@0.16.1': + '@lexical/plain-text@0.18.0': dependencies: - '@lexical/clipboard': 0.16.1 - '@lexical/selection': 0.16.1 - '@lexical/utils': 0.16.1 - lexical: 0.16.1 + '@lexical/clipboard': 0.18.0 + '@lexical/selection': 0.18.0 + '@lexical/utils': 0.18.0 + lexical: 0.18.0 - '@lexical/react@0.16.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(yjs@13.6.20)': + '@lexical/react@0.18.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(yjs@13.6.20)': dependencies: - '@lexical/clipboard': 0.16.1 - '@lexical/code': 0.16.1 - '@lexical/devtools-core': 0.16.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) - '@lexical/dragon': 0.16.1 - '@lexical/hashtag': 0.16.1 - '@lexical/history': 0.16.1 - '@lexical/link': 0.16.1 - '@lexical/list': 0.16.1 - '@lexical/mark': 0.16.1 - '@lexical/markdown': 0.16.1 - '@lexical/overflow': 0.16.1 - '@lexical/plain-text': 0.16.1 - '@lexical/rich-text': 0.16.1 - '@lexical/selection': 0.16.1 - '@lexical/table': 0.16.1 - '@lexical/text': 0.16.1 - '@lexical/utils': 0.16.1 - '@lexical/yjs': 0.16.1(yjs@13.6.20) - lexical: 0.16.1 + '@lexical/clipboard': 0.18.0 + '@lexical/code': 0.18.0 + '@lexical/devtools-core': 0.18.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@lexical/dragon': 0.18.0 + '@lexical/hashtag': 0.18.0 + '@lexical/history': 0.18.0 + '@lexical/link': 0.18.0 + '@lexical/list': 0.18.0 + '@lexical/mark': 0.18.0 + '@lexical/markdown': 0.18.0 + '@lexical/overflow': 0.18.0 + '@lexical/plain-text': 0.18.0 + '@lexical/rich-text': 0.18.0 + '@lexical/selection': 0.18.0 + '@lexical/table': 0.18.0 + '@lexical/text': 0.18.0 + '@lexical/utils': 0.18.0 + '@lexical/yjs': 0.18.0(yjs@13.6.20) + lexical: 0.18.0 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) react-error-boundary: 3.1.4(react@18.2.0) transitivePeerDependencies: - yjs - '@lexical/rich-text@0.16.1': + '@lexical/rich-text@0.18.0': dependencies: - '@lexical/clipboard': 0.16.1 - '@lexical/selection': 0.16.1 - '@lexical/utils': 0.16.1 - lexical: 0.16.1 + '@lexical/clipboard': 0.18.0 + '@lexical/selection': 0.18.0 + '@lexical/utils': 0.18.0 + lexical: 0.18.0 - '@lexical/selection@0.16.1': + '@lexical/selection@0.18.0': dependencies: - lexical: 0.16.1 + lexical: 0.18.0 - '@lexical/table@0.16.1': + '@lexical/table@0.18.0': dependencies: - '@lexical/utils': 0.16.1 - lexical: 0.16.1 + '@lexical/clipboard': 0.18.0 + '@lexical/utils': 0.18.0 + lexical: 0.18.0 - '@lexical/text@0.16.1': + '@lexical/text@0.18.0': dependencies: - lexical: 0.16.1 + lexical: 0.18.0 - '@lexical/utils@0.16.1': + '@lexical/utils@0.18.0': dependencies: - '@lexical/list': 0.16.1 - '@lexical/selection': 0.16.1 - '@lexical/table': 0.16.1 - lexical: 0.16.1 + '@lexical/list': 0.18.0 + '@lexical/selection': 0.18.0 + '@lexical/table': 0.18.0 + lexical: 0.18.0 - '@lexical/yjs@0.16.1(yjs@13.6.20)': + '@lexical/yjs@0.18.0(yjs@13.6.20)': dependencies: - '@lexical/offset': 0.16.1 - lexical: 0.16.1 + '@lexical/offset': 0.18.0 + '@lexical/selection': 0.18.0 + lexical: 0.18.0 yjs: 13.6.20 '@mdx-js/loader@2.3.0(webpack@5.95.0(esbuild@0.23.1)(uglify-js@3.19.3))': @@ -14693,7 +14695,7 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 - lexical@0.16.1: {} + lexical@0.18.0: {} lib0@0.2.98: dependencies: From 705946cc40515614d94377bfea288a59703de98f Mon Sep 17 00:00:00 2001 From: Joel Date: Mon, 28 Oct 2024 15:36:28 +0800 Subject: [PATCH 262/346] fix: tool var type error (#9937) --- .../workflow/nodes/tool/components/input-var-list.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/app/components/workflow/nodes/tool/components/input-var-list.tsx b/web/app/components/workflow/nodes/tool/components/input-var-list.tsx index 9d9940b8e9..e47082f4b7 100644 --- a/web/app/components/workflow/nodes/tool/components/input-var-list.tsx +++ b/web/app/components/workflow/nodes/tool/components/input-var-list.tsx @@ -72,7 +72,7 @@ const InputVarList: FC = ({ } else { draft[variable] = { - type: varKindType, + type: VarKindType.variable, value: varValue, } } @@ -171,7 +171,7 @@ const InputVarList: FC = ({ value={varInput?.type === VarKindType.constant ? (varInput?.value || '') : (varInput?.value || [])} onChange={handleNotMixedTypeChange(variable)} onOpen={handleOpen(index)} - defaultVarKindType={varInput?.type} + defaultVarKindType={VarKindType.variable} filterVar={isNumber ? filterVar : undefined} availableVars={isSelect ? availableVars : undefined} schema={schema} From c13dc620656903e0cdbe973fd0164a0771ec4a39 Mon Sep 17 00:00:00 2001 From: Hanqing Zhao Date: Mon, 28 Oct 2024 16:31:58 +0800 Subject: [PATCH 263/346] Modify and add jp translation (#9930) --- web/i18n/ja-JP/app-annotation.ts | 2 ++ web/i18n/ja-JP/app-debug.ts | 57 ++++++++++++++++++++++++++++-- web/i18n/ja-JP/dataset-settings.ts | 2 +- web/i18n/ja-JP/dataset.ts | 2 +- web/i18n/ja-JP/workflow.ts | 38 ++++++++++---------- 5 files changed, 78 insertions(+), 23 deletions(-) diff --git a/web/i18n/ja-JP/app-annotation.ts b/web/i18n/ja-JP/app-annotation.ts index 6c6c98cdd0..f34d8d2acd 100644 --- a/web/i18n/ja-JP/app-annotation.ts +++ b/web/i18n/ja-JP/app-annotation.ts @@ -9,6 +9,8 @@ const translation = { table: { header: { question: '質問', + match: 'マッチ', + response: '応答', answer: '回答', createdAt: '作成日時', hits: 'ヒット数', diff --git a/web/i18n/ja-JP/app-debug.ts b/web/i18n/ja-JP/app-debug.ts index 0ba4c35b0d..620d9b2f55 100644 --- a/web/i18n/ja-JP/app-debug.ts +++ b/web/i18n/ja-JP/app-debug.ts @@ -150,7 +150,7 @@ const translation = { title: '会話履歴', description: '会話の役割に接頭辞名を設定します', tip: '会話履歴は有効になっていません。上記のプロンプトに を追加してください。', - learnMore: '詳細', + learnMore: '詳細を見る', editModal: { title: '会話役割名の編集', userPrefix: 'ユーザー接頭辞', @@ -163,6 +163,7 @@ const translation = { moderation: { title: 'コンテンツのモデレーション', description: 'モデレーションAPIを使用するか、機密語リストを維持することで、モデルの出力を安全にします。', + contentEnableLabel: 'モデレート・コンテンツを有効にする', allEnabled: '入力/出力コンテンツが有効になっています', inputEnabled: '入力コンテンツが有効になっています', outputEnabled: '出力コンテンツが有効になっています', @@ -198,6 +199,25 @@ const translation = { }, }, }, + fileUpload: { + title: 'ファイル アップロード', + description: 'チャットの入力ボックスは画像やドキュメントやその他のファイルのアップロードをサポートします。', + supportedTypes: 'サポートされるファイルのタイプ', + numberLimit: '最大アップロード数', + modalTitle: 'ファイル アップロード設置', + }, + imageUpload: { + title: '画像アップロード', + description: '画像アップロードをサポートする', + supportedTypes: 'サポートされるファイルのタイプ', + numberLimit: '最大アップロード数', + modalTitle: '画像アップロード設置', + }, + bar: { + empty: 'Webアプリのユーザーエクスペリアンスを強化させる機能を有効にする', + enableText: '有効な機能', + manage: '管理', + }, }, codegen: { title: 'コードジェネレーター', @@ -278,6 +298,10 @@ const translation = { waitForBatchResponse: 'バッチタスクへの応答が完了するまでお待ちください。', notSelectModel: 'モデルを選択してください', waitForImgUpload: '画像のアップロードが完了するまでお待ちください', + waitForFileUpload: 'ファイルのアップロードが完了するまでお待ちください', + }, + warningMessage: { + timeoutExceeded: 'タイムアウトのため結果が表示されません。完全な結果を手にいれるためには、ログを参照してください。', }, chatSubTitle: '手順', completionSubTitle: '接頭辞プロンプト', @@ -319,6 +343,8 @@ const translation = { 'paragraph': '段落', 'select': '選択', 'number': '数値', + 'single-file': '単一ファイル', + 'multi-files': 'ファイルリスト', 'notSet': '設定されていません。プレフィックスのプロンプトで {{input}} を入力してみてください。', 'stringTitle': 'フォームテキストボックスオプション', 'maxLength': '最大長', @@ -330,6 +356,31 @@ const translation = { 'inputPlaceholder': '入力してください', 'content': 'コンテンツ', 'required': '必須', + 'file': { + supportFileTypes: 'サッポトされたファイルタイプ', + image: { + name: '画像', + }, + audio: { + name: '音声', + }, + document: { + name: 'ドキュメント', + }, + video: { + name: '映像', + }, + custom: { + name: '他のファイルタイプ', + description: '他のファイルタイプを指定する。', + createPlaceholder: '+ 拡張子, 例:.doc', + }, + }, + 'uploadFileTypes': 'アップロードされたファイルのタイプ', + 'localUpload': 'ローカル アップロード', + 'both': '両方', + 'maxNumberOfUploads': 'アップロードの最大数', + 'maxNumberTip': 'ドキュメント < {{docLimit}}, 画像 < {{imgLimit}}, 音声 < {{audioLimit}}, 映像 < {{videoLimit}}', 'errorMsg': { varNameRequired: '変数名は必須です', labelNameRequired: 'ラベル名は必須です', @@ -341,6 +392,7 @@ const translation = { vision: { name: 'ビジョン', description: 'ビジョンを有効にすると、モデルが画像を受け取り、それに関する質問に答えることができます。', + onlySupportVisionModelTip: 'ビジョンモデルのみをサポート', settings: '設定', visionSettings: { title: 'ビジョン設定', @@ -369,7 +421,7 @@ const translation = { voice: '音声', autoPlay: '自動再生', autoPlayEnabled: '開ける', - autoPlayDisabled: '關閉', + autoPlayDisabled: '閉じる', }, }, openingStatement: { @@ -408,6 +460,7 @@ const translation = { run: '実行', }, result: '出力テキスト', + noResult: '出力はここに表示されます。', datasetConfig: { settingTitle: 'リトリーバル設定', knowledgeTip: 'ナレッジを追加するには「+」ボタンをクリックしてください', diff --git a/web/i18n/ja-JP/dataset-settings.ts b/web/i18n/ja-JP/dataset-settings.ts index 1eb3dabb74..f0b8c76a24 100644 --- a/web/i18n/ja-JP/dataset-settings.ts +++ b/web/i18n/ja-JP/dataset-settings.ts @@ -24,7 +24,7 @@ const translation = { embeddingModelTipLink: '設定', retrievalSetting: { title: '検索設定', - learnMore: '詳細を学ぶ', + learnMore: '詳細を見る', description: ' 検索方法についての詳細', longDescription: ' 検索方法についての詳細については、いつでもナレッジの設定で変更できます。', }, diff --git a/web/i18n/ja-JP/dataset.ts b/web/i18n/ja-JP/dataset.ts index d995509a3f..f15f0dfb1a 100644 --- a/web/i18n/ja-JP/dataset.ts +++ b/web/i18n/ja-JP/dataset.ts @@ -101,7 +101,7 @@ const translation = { end: '.次に、対応するナレッジIDを見つけて、左側のフォームに入力します。すべての情報が正しい場合は、接続ボタンをクリックした後、ナレッジベースの検索テストに自動的にジャンプします。', }, title: '外部ナレッジベースに接続する方法', - learnMore: '詳細情報', + learnMore: '詳細を見る', }, connectHelper: { helper2: '取得機能のみがサポートされています', diff --git a/web/i18n/ja-JP/workflow.ts b/web/i18n/ja-JP/workflow.ts index 632e5712e5..b6c7786081 100644 --- a/web/i18n/ja-JP/workflow.ts +++ b/web/i18n/ja-JP/workflow.ts @@ -19,6 +19,10 @@ const translation = { goBackToEdit: '編集に戻る', conversationLog: '会話ログ', features: '機能', + featuresDescription: 'Webアプリのユーザーエクスペリエンスを強化する', + ImageUploadLegacyTip: '開始フォームでファイルタイプ変数を作成できるようになりました。まもなく、画像アップロード機能のサポートは終了いたします。', + fileUploadTip: '画像アップロード機能がファイルのアップロード機能にアップグレードされました。', + featuresDocLink: '詳細を見る', debugAndPreview: 'プレビュー', restart: '再起動', currentDraft: '現在の下書き', @@ -55,7 +59,7 @@ const translation = { viewOnly: '表示のみ', showRunHistory: '実行履歴を表示', enableJinja: 'Jinjaテンプレートのサポートを有効にする', - learnMore: '詳細を学ぶ', + learnMore: '詳細を見る', copy: 'コピー', duplicate: '複製', addBlock: 'ブロックを追加', @@ -95,10 +99,6 @@ const translation = { addParallelNode: '並列ノードを追加', parallel: '並列', branch: 'ブランチ', - fileUploadTip: '画像のアップロード機能がファイルのアップロードにアップグレードされました。', - featuresDocLink: '詳細情報', - ImageUploadLegacyTip: 'これで、開始フォームでファイルタイプ変数を作成できるようになりました。今後、画像のアップロード機能のサポートは終了いたします。', - featuresDescription: 'Webアプリのユーザーエクスペリエンスを強化', }, env: { envPanelTitle: '環境変数', @@ -229,8 +229,8 @@ const translation = { 'iteration-start': 'イテレーション開始', 'iteration': 'イテレーション', 'parameter-extractor': 'パラメーター抽出', - 'document-extractor': 'ドキュメントエクストラクター', - 'list-operator': 'リスト演算子', + 'document-extractor': 'テキスト抽出ツール', + 'list-operator': 'リスト処理', }, blocksAbout: { 'start': 'ワークフローの開始に必要なパラメータを定義します', @@ -248,7 +248,7 @@ const translation = { 'variable-aggregator': '複数のブランチの変数を1つの変数に集約し、下流のノードに対して統一された設定を行います。', 'iteration': 'リストオブジェクトに対して複数のステップを実行し、すべての結果が出力されるまで繰り返します。', 'parameter-extractor': '自然言語からツールの呼び出しやHTTPリクエストのための構造化されたパラメーターを抽出するためにLLMを使用します。', - 'document-extractor': 'アップロードされたドキュメントを LLM で簡単に理解できるテキスト コンテンツに解析するために使用されます。', + 'document-extractor': 'アップロードされたドキュメントを LLM で簡単に理解できるテキストのコンテンツに解析するために使用されます。', 'list-operator': '配列のコンテンツをフィルタリングまたはソートするために使用されます。', }, operator: { @@ -405,7 +405,7 @@ const translation = { writeLabel: '書き込みタイムアウト', writePlaceholder: '書き込みタイムアウトを秒で入力', }, - type: '種類', + type: 'タイプ', binaryFileVariable: 'バイナリファイル変数', }, code: { @@ -443,21 +443,21 @@ const translation = { 'null': 'null', 'not null': 'nullでない', 'regex match': '正規表現マッチ', - 'in': 'で', - 'not exists': '存在しません', - 'exists': '存在', + 'in': '含まれている', 'not in': '含まれていない', 'all of': 'すべての', + 'exists': '存在します', + 'not exists': '存在しません', }, enterValue: '値を入力', addCondition: '条件を追加', conditionNotSetup: '条件が設定されていません', selectVariable: '変数を選択...', optionName: { - audio: 'オーディオ', + audio: '音声', localUpload: 'ローカルアップロード', image: '画像', - video: 'ビデオ', + video: '映像', doc: 'ドキュメント', url: 'URL', }, @@ -583,7 +583,7 @@ const translation = { text: '抽出されたテキスト', }, inputVar: '入力変数', - learnMore: '詳細情報', + learnMore: '詳細を見る', supportFileTypes: 'サポートするファイルタイプ: {{types}}。', }, listFilter: { @@ -593,13 +593,13 @@ const translation = { result: 'フィルター結果', }, limit: 'トップN', - asc: 'ASCの', + asc: 'ASC', filterCondition: 'フィルター条件', filterConditionKey: 'フィルター条件キー', - orderBy: '注文順', + orderBy: '並べる順番', filterConditionComparisonValue: 'フィルター条件の値', - selectVariableKeyPlaceholder: 'サブ変数キーの選択', - filterConditionComparisonOperator: 'フィルター条件比較演算子', + selectVariableKeyPlaceholder: 'サブ変数キーを選択する', + filterConditionComparisonOperator: 'フィルター条件を比較オペレーター', inputVar: '入力変数', desc: 'DESC', }, From 0cec6195a3ca49e9c4da7b2e1779b2d73044a7be Mon Sep 17 00:00:00 2001 From: Joel Date: Mon, 28 Oct 2024 16:33:02 +0800 Subject: [PATCH 264/346] test --- .../provider/builtin/aliyuque/tools/base.py | 18 ++---- .../builtin/aliyuque/tools/delete_document.py | 3 +- .../tools/describe_book_index_page.py | 3 +- .../tools/describe_document_content.py | 6 +- .../aliyuque/tools/describe_documents.py | 3 +- .../builtin/aliyuque/tools/update_document.py | 3 +- .../workflow/nodes/document_extractor/node.py | 57 +++++++------------ .../nodes/test_document_extractor_node.py | 15 ++--- .../unit_tests/oss/__mock/volcengine_tos.py | 18 ++---- 9 files changed, 42 insertions(+), 84 deletions(-) diff --git a/api/core/tools/provider/builtin/aliyuque/tools/base.py b/api/core/tools/provider/builtin/aliyuque/tools/base.py index 0046931abd..edfb9fea8e 100644 --- a/api/core/tools/provider/builtin/aliyuque/tools/base.py +++ b/api/core/tools/provider/builtin/aliyuque/tools/base.py @@ -10,10 +10,8 @@ class AliYuqueTool: @staticmethod def auth(token): session = requests.Session() - session.headers.update( - {"Accept": "application/json", "X-Auth-Token": token}) - login = session.request( - "GET", AliYuqueTool.server_url + "/api/v2/user") + session.headers.update({"Accept": "application/json", "X-Auth-Token": token}) + login = session.request("GET", AliYuqueTool.server_url + "/api/v2/user") login.raise_for_status() resp = login.json() return resp @@ -22,12 +20,10 @@ class AliYuqueTool: if not token: raise Exception("token is required") session = requests.Session() - session.headers.update( - {"accept": "application/json", "X-Auth-Token": token}) + session.headers.update({"accept": "application/json", "X-Auth-Token": token}) new_params = {**tool_parameters} - replacements = {k: v for k, v in new_params.items() - if f"{{{k}}}" in path} + replacements = {k: v for k, v in new_params.items() if f"{{{k}}}" in path} for key, value in replacements.items(): path = path.replace(f"{{{key}}}", str(value)) @@ -39,10 +35,8 @@ class AliYuqueTool: "Content-Type": "application/json", } ) - response = session.request( - method.upper(), self.server_url + path, json=new_params) + response = session.request(method.upper(), self.server_url + path, json=new_params) else: - response = session.request( - method, self.server_url + path, params=new_params) + response = session.request(method, self.server_url + path, params=new_params) response.raise_for_status() return response.text diff --git a/api/core/tools/provider/builtin/aliyuque/tools/delete_document.py b/api/core/tools/provider/builtin/aliyuque/tools/delete_document.py index ddbfa43114..84237cec30 100644 --- a/api/core/tools/provider/builtin/aliyuque/tools/delete_document.py +++ b/api/core/tools/provider/builtin/aliyuque/tools/delete_document.py @@ -13,6 +13,5 @@ class AliYuqueDeleteDocumentTool(AliYuqueTool, BuiltinTool): if not token: raise Exception("token is required") return self.create_text_message( - self.request("DELETE", token, tool_parameters, - "/api/v2/repos/{book_id}/docs/{id}") + self.request("DELETE", token, tool_parameters, "/api/v2/repos/{book_id}/docs/{id}") ) diff --git a/api/core/tools/provider/builtin/aliyuque/tools/describe_book_index_page.py b/api/core/tools/provider/builtin/aliyuque/tools/describe_book_index_page.py index ec834dd640..c23d30059a 100644 --- a/api/core/tools/provider/builtin/aliyuque/tools/describe_book_index_page.py +++ b/api/core/tools/provider/builtin/aliyuque/tools/describe_book_index_page.py @@ -13,6 +13,5 @@ class AliYuqueDescribeBookIndexPageTool(AliYuqueTool, BuiltinTool): if not token: raise Exception("token is required") return self.create_text_message( - self.request("GET", token, tool_parameters, - "/api/v2/repos/{group_login}/{book_slug}/index_page") + self.request("GET", token, tool_parameters, "/api/v2/repos/{group_login}/{book_slug}/index_page") ) diff --git a/api/core/tools/provider/builtin/aliyuque/tools/describe_document_content.py b/api/core/tools/provider/builtin/aliyuque/tools/describe_document_content.py index 50a9b37cf6..4b793cd61f 100644 --- a/api/core/tools/provider/builtin/aliyuque/tools/describe_document_content.py +++ b/api/core/tools/provider/builtin/aliyuque/tools/describe_document_content.py @@ -33,16 +33,14 @@ class AliYuqueDescribeDocumentContentTool(AliYuqueTool, BuiltinTool): new_params["group_login"] = group_id new_params["book_slug"] = book_slug index_page = json.loads( - self.request("GET", token, new_params, - "/api/v2/repos/{group_login}/{book_slug}/index_page") + self.request("GET", token, new_params, "/api/v2/repos/{group_login}/{book_slug}/index_page") ) book_id = index_page.get("data", {}).get("book", {}).get("id") if not book_id: raise Exception(f"can not parse book_id from {index_page}") new_params["book_id"] = book_id new_params["id"] = doc_id - data = self.request("GET", token, new_params, - "/api/v2/repos/{book_id}/docs/{id}") + data = self.request("GET", token, new_params, "/api/v2/repos/{book_id}/docs/{id}") data = json.loads(data) body_only = tool_parameters.get("body_only") or "" if body_only.lower() == "true": diff --git a/api/core/tools/provider/builtin/aliyuque/tools/describe_documents.py b/api/core/tools/provider/builtin/aliyuque/tools/describe_documents.py index 75436e5b1b..7a45684bed 100644 --- a/api/core/tools/provider/builtin/aliyuque/tools/describe_documents.py +++ b/api/core/tools/provider/builtin/aliyuque/tools/describe_documents.py @@ -13,6 +13,5 @@ class AliYuqueDescribeDocumentsTool(AliYuqueTool, BuiltinTool): if not token: raise Exception("token is required") return self.create_text_message( - self.request("GET", token, tool_parameters, - "/api/v2/repos/{book_id}/docs/{id}") + self.request("GET", token, tool_parameters, "/api/v2/repos/{book_id}/docs/{id}") ) diff --git a/api/core/tools/provider/builtin/aliyuque/tools/update_document.py b/api/core/tools/provider/builtin/aliyuque/tools/update_document.py index a6bcb1fcc2..d7eba46ad9 100644 --- a/api/core/tools/provider/builtin/aliyuque/tools/update_document.py +++ b/api/core/tools/provider/builtin/aliyuque/tools/update_document.py @@ -13,6 +13,5 @@ class AliYuqueUpdateDocumentTool(AliYuqueTool, BuiltinTool): if not token: raise Exception("token is required") return self.create_text_message( - self.request("PUT", token, tool_parameters, - "/api/v2/repos/{book_id}/docs/{id}") + self.request("PUT", token, tool_parameters, "/api/v2/repos/{book_id}/docs/{id}") ) diff --git a/api/core/workflow/nodes/document_extractor/node.py b/api/core/workflow/nodes/document_extractor/node.py index 2520caf713..9e09b6d29a 100644 --- a/api/core/workflow/nodes/document_extractor/node.py +++ b/api/core/workflow/nodes/document_extractor/node.py @@ -35,8 +35,7 @@ class DocumentExtractorNode(BaseNode[DocumentExtractorNodeData]): def _run(self): variable_selector = self.node_data.variable_selector - variable = self.graph_runtime_state.variable_pool.get( - variable_selector) + variable = self.graph_runtime_state.variable_pool.get(variable_selector) if variable is None: error_message = f"File variable not found for selector: {variable_selector}" @@ -47,8 +46,7 @@ class DocumentExtractorNode(BaseNode[DocumentExtractorNodeData]): value = variable.value inputs = {"variable_selector": variable_selector} - process_data = {"documents": value if isinstance(value, list) else [ - value]} + process_data = {"documents": value if isinstance(value, list) else [value]} try: if isinstance(value, list): @@ -68,8 +66,7 @@ class DocumentExtractorNode(BaseNode[DocumentExtractorNodeData]): outputs={"text": extracted_text}, ) else: - raise DocumentExtractorError( - f"Unsupported variable type: {type(value)}") + raise DocumentExtractorError(f"Unsupported variable type: {type(value)}") except DocumentExtractorError as e: return NodeRunResult( status=WorkflowNodeExecutionStatus.FAILED, @@ -105,8 +102,7 @@ def _extract_text_by_mime_type(*, file_content: bytes, mime_type: str) -> str: case "application/json": return _extract_text_from_json(file_content) case _: - raise UnsupportedFileTypeError( - f"Unsupported MIME type: {mime_type}") + raise UnsupportedFileTypeError(f"Unsupported MIME type: {mime_type}") def _extract_text_by_file_extension(*, file_content: bytes, file_extension: str) -> str: @@ -135,8 +131,7 @@ def _extract_text_by_file_extension(*, file_content: bytes, file_extension: str) case ".msg": return _extract_text_from_msg(file_content) case _: - raise UnsupportedFileTypeError( - f"Unsupported Extension Type: {file_extension}") + raise UnsupportedFileTypeError(f"Unsupported Extension Type: {file_extension}") def _extract_text_from_plain_text(file_content: bytes) -> str: @@ -151,8 +146,7 @@ def _extract_text_from_json(file_content: bytes) -> str: json_data = json.loads(file_content.decode("utf-8")) return json.dumps(json_data, indent=2, ensure_ascii=False) except (UnicodeDecodeError, json.JSONDecodeError) as e: - raise TextExtractionError( - f"Failed to decode or parse JSON file: {e}") from e + raise TextExtractionError(f"Failed to decode or parse JSON file: {e}") from e def _extract_text_from_pdf(file_content: bytes) -> str: @@ -167,8 +161,7 @@ def _extract_text_from_pdf(file_content: bytes) -> str: page.close() return text except Exception as e: - raise TextExtractionError( - f"Failed to extract text from PDF: {str(e)}") from e + raise TextExtractionError(f"Failed to extract text from PDF: {str(e)}") from e def _extract_text_from_doc(file_content: bytes) -> str: @@ -177,8 +170,7 @@ def _extract_text_from_doc(file_content: bytes) -> str: doc = docx.Document(doc_file) return "\n".join([paragraph.text for paragraph in doc.paragraphs]) except Exception as e: - raise TextExtractionError( - f"Failed to extract text from DOC/DOCX: {str(e)}") from e + raise TextExtractionError(f"Failed to extract text from DOC/DOCX: {str(e)}") from e def _download_file_content(file: File) -> bytes: @@ -193,8 +185,7 @@ def _download_file_content(file: File) -> bytes: elif file.transfer_method == FileTransferMethod.LOCAL_FILE: return file_manager.download(file) else: - raise ValueError( - f"Unsupported transfer method: {file.transfer_method}") + raise ValueError(f"Unsupported transfer method: {file.transfer_method}") except Exception as e: raise FileDownloadError(f"Error downloading file: {str(e)}") from e @@ -202,14 +193,11 @@ def _download_file_content(file: File) -> bytes: def _extract_text_from_file(file: File): file_content = _download_file_content(file) if file.extension: - extracted_text = _extract_text_by_file_extension( - file_content=file_content, file_extension=file.extension) + extracted_text = _extract_text_by_file_extension(file_content=file_content, file_extension=file.extension) elif file.mime_type: - extracted_text = _extract_text_by_mime_type( - file_content=file_content, mime_type=file.mime_type) + extracted_text = _extract_text_by_mime_type(file_content=file_content, mime_type=file.mime_type) else: - raise UnsupportedFileTypeError( - "Unable to determine file type: MIME type or file extension is missing") + raise UnsupportedFileTypeError("Unable to determine file type: MIME type or file extension is missing") return extracted_text @@ -230,8 +218,7 @@ def _extract_text_from_csv(file_content: bytes) -> str: return markdown_table.strip() except Exception as e: - raise TextExtractionError( - f"Failed to extract text from CSV: {str(e)}") from e + raise TextExtractionError(f"Failed to extract text from CSV: {str(e)}") from e def _extract_text_from_excel(file_content: bytes) -> str: @@ -247,8 +234,7 @@ def _extract_text_from_excel(file_content: bytes) -> str: markdown_table = df.to_markdown(index=False) return markdown_table except Exception as e: - raise TextExtractionError( - f"Failed to extract text from Excel file: {str(e)}") from e + raise TextExtractionError(f"Failed to extract text from Excel file: {str(e)}") from e def _extract_text_from_ppt(file_content: bytes) -> str: @@ -257,8 +243,7 @@ def _extract_text_from_ppt(file_content: bytes) -> str: elements = partition_ppt(file=file) return "\n".join([getattr(element, "text", "") for element in elements]) except Exception as e: - raise TextExtractionError( - f"Failed to extract text from PPT: {str(e)}") from e + raise TextExtractionError(f"Failed to extract text from PPT: {str(e)}") from e def _extract_text_from_pptx(file_content: bytes) -> str: @@ -267,8 +252,7 @@ def _extract_text_from_pptx(file_content: bytes) -> str: elements = partition_pptx(file=file) return "\n".join([getattr(element, "text", "") for element in elements]) except Exception as e: - raise TextExtractionError( - f"Failed to extract text from PPTX: {str(e)}") from e + raise TextExtractionError(f"Failed to extract text from PPTX: {str(e)}") from e def _extract_text_from_epub(file_content: bytes) -> str: @@ -277,8 +261,7 @@ def _extract_text_from_epub(file_content: bytes) -> str: elements = partition_epub(file=file) return "\n".join([str(element) for element in elements]) except Exception as e: - raise TextExtractionError( - f"Failed to extract text from EPUB: {str(e)}") from e + raise TextExtractionError(f"Failed to extract text from EPUB: {str(e)}") from e def _extract_text_from_eml(file_content: bytes) -> str: @@ -287,8 +270,7 @@ def _extract_text_from_eml(file_content: bytes) -> str: elements = partition_email(file=file) return "\n".join([str(element) for element in elements]) except Exception as e: - raise TextExtractionError( - f"Failed to extract text from EML: {str(e)}") from e + raise TextExtractionError(f"Failed to extract text from EML: {str(e)}") from e def _extract_text_from_msg(file_content: bytes) -> str: @@ -297,5 +279,4 @@ def _extract_text_from_msg(file_content: bytes) -> str: elements = partition_msg(file=file) return "\n".join([str(element) for element in elements]) except Exception as e: - raise TextExtractionError( - f"Failed to extract text from MSG: {str(e)}") from e + raise TextExtractionError(f"Failed to extract text from MSG: {str(e)}") from e diff --git a/api/tests/unit_tests/core/workflow/nodes/test_document_extractor_node.py b/api/tests/unit_tests/core/workflow/nodes/test_document_extractor_node.py index 625ff560fc..4f1f8f05c8 100644 --- a/api/tests/unit_tests/core/workflow/nodes/test_document_extractor_node.py +++ b/api/tests/unit_tests/core/workflow/nodes/test_document_extractor_node.py @@ -65,8 +65,7 @@ def test_run_invalid_variable_type(document_extractor_node, mock_graph_runtime_s @pytest.mark.parametrize( ("mime_type", "file_content", "expected_text", "transfer_method", "extension"), [ - ("text/plain", b"Hello, world!", - ["Hello, world!"], FileTransferMethod.LOCAL_FILE, ".txt"), + ("text/plain", b"Hello, world!", ["Hello, world!"], FileTransferMethod.LOCAL_FILE, ".txt"), ( "application/pdf", b"%PDF-1.5\n%Test PDF content", @@ -81,8 +80,7 @@ def test_run_invalid_variable_type(document_extractor_node, mock_graph_runtime_s FileTransferMethod.REMOTE_URL, "", ), - ("text/plain", b"Remote content", - ["Remote content"], FileTransferMethod.REMOTE_URL, None), + ("text/plain", b"Remote content", ["Remote content"], FileTransferMethod.REMOTE_URL, None), ], ) def test_run_extract_text( @@ -119,12 +117,10 @@ def test_run_extract_text( if mime_type == "application/pdf": mock_pdf_extract = Mock(return_value=expected_text[0]) - monkeypatch.setattr( - "core.workflow.nodes.document_extractor.node._extract_text_from_pdf", mock_pdf_extract) + monkeypatch.setattr("core.workflow.nodes.document_extractor.node._extract_text_from_pdf", mock_pdf_extract) elif mime_type.startswith("application/vnd.openxmlformats"): mock_docx_extract = Mock(return_value=expected_text[0]) - monkeypatch.setattr( - "core.workflow.nodes.document_extractor.node._extract_text_from_doc", mock_docx_extract) + monkeypatch.setattr("core.workflow.nodes.document_extractor.node._extract_text_from_doc", mock_docx_extract) result = document_extractor_node._run() @@ -134,8 +130,7 @@ def test_run_extract_text( assert result.outputs["text"] == expected_text if transfer_method == FileTransferMethod.REMOTE_URL: - mock_ssrf_proxy_get.assert_called_once_with( - "https://example.com/file.txt") + mock_ssrf_proxy_get.assert_called_once_with("https://example.com/file.txt") elif transfer_method == FileTransferMethod.LOCAL_FILE: mock_download.assert_called_once_with(mock_file) diff --git a/api/tests/unit_tests/oss/__mock/volcengine_tos.py b/api/tests/unit_tests/oss/__mock/volcengine_tos.py index c2dfff0de3..1194a03258 100644 --- a/api/tests/unit_tests/oss/__mock/volcengine_tos.py +++ b/api/tests/unit_tests/oss/__mock/volcengine_tos.py @@ -77,18 +77,12 @@ MOCK = os.getenv("MOCK_SWITCH", "false").lower() == "true" @pytest.fixture def setup_volcengine_tos_mock(monkeypatch: MonkeyPatch): if MOCK: - monkeypatch.setattr(TosClientV2, "__init__", - MockVolcengineTosClass.__init__) - monkeypatch.setattr(TosClientV2, "put_object", - MockVolcengineTosClass.put_object) - monkeypatch.setattr(TosClientV2, "get_object", - MockVolcengineTosClass.get_object) - monkeypatch.setattr(TosClientV2, "get_object_to_file", - MockVolcengineTosClass.get_object_to_file) - monkeypatch.setattr(TosClientV2, "head_object", - MockVolcengineTosClass.head_object) - monkeypatch.setattr(TosClientV2, "delete_object", - MockVolcengineTosClass.delete_object) + monkeypatch.setattr(TosClientV2, "__init__", MockVolcengineTosClass.__init__) + monkeypatch.setattr(TosClientV2, "put_object", MockVolcengineTosClass.put_object) + monkeypatch.setattr(TosClientV2, "get_object", MockVolcengineTosClass.get_object) + monkeypatch.setattr(TosClientV2, "get_object_to_file", MockVolcengineTosClass.get_object_to_file) + monkeypatch.setattr(TosClientV2, "head_object", MockVolcengineTosClass.head_object) + monkeypatch.setattr(TosClientV2, "delete_object", MockVolcengineTosClass.delete_object) yield From c4d6f9e1797aa0133395a281b132737242f3ee7e Mon Sep 17 00:00:00 2001 From: AkaraChen Date: Mon, 28 Oct 2024 16:46:35 +0800 Subject: [PATCH 265/346] build: update react-easy-crop --- web/package.json | 2 +- web/pnpm-lock.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/web/package.json b/web/package.json index 5e95840017..162209c05b 100644 --- a/web/package.json +++ b/web/package.json @@ -75,7 +75,7 @@ "react": "~18.2.0", "react-18-input-autosize": "^3.0.0", "react-dom": "~18.2.0", - "react-easy-crop": "^5.0.8", + "react-easy-crop": "^5.1.0", "react-error-boundary": "^4.1.2", "react-headless-pagination": "^1.1.4", "react-hook-form": "^7.51.4", diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index fbfa835fb2..8ecd62395f 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -167,7 +167,7 @@ importers: specifier: ~18.2.0 version: 18.2.0(react@18.2.0) react-easy-crop: - specifier: ^5.0.8 + specifier: ^5.1.0 version: 5.1.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react-error-boundary: specifier: ^4.1.2 From 0ebd9856725e273621db5c7943a9e18e01991aeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=96=B9=E7=A8=8B?= Date: Mon, 28 Oct 2024 16:52:12 +0800 Subject: [PATCH 266/346] feat: add models for gitee.ai (#9490) --- .../gitee_ai/_assets/Gitee-AI-Logo-full.svg | 6 + .../gitee_ai/_assets/Gitee-AI-Logo.svg | 3 + .../model_providers/gitee_ai/_common.py | 47 +++++++ .../model_providers/gitee_ai/gitee_ai.py | 25 ++++ .../model_providers/gitee_ai/gitee_ai.yaml | 35 +++++ .../gitee_ai/llm/Qwen2-72B-Instruct.yaml | 105 ++++++++++++++ .../gitee_ai/llm/Qwen2-7B-Instruct.yaml | 105 ++++++++++++++ .../gitee_ai/llm/Yi-1.5-34B-Chat.yaml | 105 ++++++++++++++ .../gitee_ai/llm/_position.yaml | 7 + .../gitee_ai/llm/codegeex4-all-9b.yaml | 105 ++++++++++++++ .../llm/deepseek-coder-33B-instruct-chat.yaml | 105 ++++++++++++++ ...epseek-coder-33B-instruct-completions.yaml | 91 ++++++++++++ .../gitee_ai/llm/glm-4-9b-chat.yaml | 105 ++++++++++++++ .../model_providers/gitee_ai/llm/llm.py | 47 +++++++ .../gitee_ai/rerank/__init__.py | 0 .../gitee_ai/rerank/_position.yaml | 1 + .../gitee_ai/rerank/bge-reranker-v2-m3.yaml | 4 + .../model_providers/gitee_ai/rerank/rerank.py | 128 +++++++++++++++++ .../gitee_ai/speech2text/__init__.py | 0 .../gitee_ai/speech2text/_position.yaml | 2 + .../gitee_ai/speech2text/speech2text.py | 53 +++++++ .../gitee_ai/speech2text/whisper-base.yaml | 5 + .../gitee_ai/speech2text/whisper-large.yaml | 5 + .../gitee_ai/text_embedding/_position.yaml | 3 + .../text_embedding/bge-large-zh-v1.5.yaml | 8 ++ .../gitee_ai/text_embedding/bge-m3.yaml | 8 ++ .../text_embedding/bge-small-zh-v1.5.yaml | 8 ++ .../gitee_ai/text_embedding/text_embedding.py | 31 ++++ .../model_providers/gitee_ai/tts/ChatTTS.yaml | 11 ++ .../tts/FunAudioLLM-CosyVoice-300M.yaml | 11 ++ .../model_providers/gitee_ai/tts/__init__.py | 0 .../gitee_ai/tts/_position.yaml | 4 + .../gitee_ai/tts/fish-speech-1.2-sft.yaml | 11 ++ .../gitee_ai/tts/speecht5_tts.yaml | 11 ++ .../model_providers/gitee_ai/tts/tts.py | 79 +++++++++++ api/pytest.ini | 1 + api/tests/integration_tests/.env.example | 3 + .../model_runtime/gitee_ai/__init__.py | 0 .../model_runtime/gitee_ai/test_llm.py | 132 ++++++++++++++++++ .../model_runtime/gitee_ai/test_provider.py | 15 ++ .../model_runtime/gitee_ai/test_rerank.py | 47 +++++++ .../gitee_ai/test_speech2text.py | 45 ++++++ .../gitee_ai/test_text_embedding.py | 46 ++++++ .../model_runtime/gitee_ai/test_tts.py | 23 +++ 44 files changed, 1586 insertions(+) create mode 100644 api/core/model_runtime/model_providers/gitee_ai/_assets/Gitee-AI-Logo-full.svg create mode 100644 api/core/model_runtime/model_providers/gitee_ai/_assets/Gitee-AI-Logo.svg create mode 100644 api/core/model_runtime/model_providers/gitee_ai/_common.py create mode 100644 api/core/model_runtime/model_providers/gitee_ai/gitee_ai.py create mode 100644 api/core/model_runtime/model_providers/gitee_ai/gitee_ai.yaml create mode 100644 api/core/model_runtime/model_providers/gitee_ai/llm/Qwen2-72B-Instruct.yaml create mode 100644 api/core/model_runtime/model_providers/gitee_ai/llm/Qwen2-7B-Instruct.yaml create mode 100644 api/core/model_runtime/model_providers/gitee_ai/llm/Yi-1.5-34B-Chat.yaml create mode 100644 api/core/model_runtime/model_providers/gitee_ai/llm/_position.yaml create mode 100644 api/core/model_runtime/model_providers/gitee_ai/llm/codegeex4-all-9b.yaml create mode 100644 api/core/model_runtime/model_providers/gitee_ai/llm/deepseek-coder-33B-instruct-chat.yaml create mode 100644 api/core/model_runtime/model_providers/gitee_ai/llm/deepseek-coder-33B-instruct-completions.yaml create mode 100644 api/core/model_runtime/model_providers/gitee_ai/llm/glm-4-9b-chat.yaml create mode 100644 api/core/model_runtime/model_providers/gitee_ai/llm/llm.py create mode 100644 api/core/model_runtime/model_providers/gitee_ai/rerank/__init__.py create mode 100644 api/core/model_runtime/model_providers/gitee_ai/rerank/_position.yaml create mode 100644 api/core/model_runtime/model_providers/gitee_ai/rerank/bge-reranker-v2-m3.yaml create mode 100644 api/core/model_runtime/model_providers/gitee_ai/rerank/rerank.py create mode 100644 api/core/model_runtime/model_providers/gitee_ai/speech2text/__init__.py create mode 100644 api/core/model_runtime/model_providers/gitee_ai/speech2text/_position.yaml create mode 100644 api/core/model_runtime/model_providers/gitee_ai/speech2text/speech2text.py create mode 100644 api/core/model_runtime/model_providers/gitee_ai/speech2text/whisper-base.yaml create mode 100644 api/core/model_runtime/model_providers/gitee_ai/speech2text/whisper-large.yaml create mode 100644 api/core/model_runtime/model_providers/gitee_ai/text_embedding/_position.yaml create mode 100644 api/core/model_runtime/model_providers/gitee_ai/text_embedding/bge-large-zh-v1.5.yaml create mode 100644 api/core/model_runtime/model_providers/gitee_ai/text_embedding/bge-m3.yaml create mode 100644 api/core/model_runtime/model_providers/gitee_ai/text_embedding/bge-small-zh-v1.5.yaml create mode 100644 api/core/model_runtime/model_providers/gitee_ai/text_embedding/text_embedding.py create mode 100644 api/core/model_runtime/model_providers/gitee_ai/tts/ChatTTS.yaml create mode 100644 api/core/model_runtime/model_providers/gitee_ai/tts/FunAudioLLM-CosyVoice-300M.yaml create mode 100644 api/core/model_runtime/model_providers/gitee_ai/tts/__init__.py create mode 100644 api/core/model_runtime/model_providers/gitee_ai/tts/_position.yaml create mode 100644 api/core/model_runtime/model_providers/gitee_ai/tts/fish-speech-1.2-sft.yaml create mode 100644 api/core/model_runtime/model_providers/gitee_ai/tts/speecht5_tts.yaml create mode 100644 api/core/model_runtime/model_providers/gitee_ai/tts/tts.py create mode 100644 api/tests/integration_tests/model_runtime/gitee_ai/__init__.py create mode 100644 api/tests/integration_tests/model_runtime/gitee_ai/test_llm.py create mode 100644 api/tests/integration_tests/model_runtime/gitee_ai/test_provider.py create mode 100644 api/tests/integration_tests/model_runtime/gitee_ai/test_rerank.py create mode 100644 api/tests/integration_tests/model_runtime/gitee_ai/test_speech2text.py create mode 100644 api/tests/integration_tests/model_runtime/gitee_ai/test_text_embedding.py create mode 100644 api/tests/integration_tests/model_runtime/gitee_ai/test_tts.py diff --git a/api/core/model_runtime/model_providers/gitee_ai/_assets/Gitee-AI-Logo-full.svg b/api/core/model_runtime/model_providers/gitee_ai/_assets/Gitee-AI-Logo-full.svg new file mode 100644 index 0000000000..f9738b585b --- /dev/null +++ b/api/core/model_runtime/model_providers/gitee_ai/_assets/Gitee-AI-Logo-full.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/api/core/model_runtime/model_providers/gitee_ai/_assets/Gitee-AI-Logo.svg b/api/core/model_runtime/model_providers/gitee_ai/_assets/Gitee-AI-Logo.svg new file mode 100644 index 0000000000..1f51187f19 --- /dev/null +++ b/api/core/model_runtime/model_providers/gitee_ai/_assets/Gitee-AI-Logo.svg @@ -0,0 +1,3 @@ + + + diff --git a/api/core/model_runtime/model_providers/gitee_ai/_common.py b/api/core/model_runtime/model_providers/gitee_ai/_common.py new file mode 100644 index 0000000000..0750f3b75d --- /dev/null +++ b/api/core/model_runtime/model_providers/gitee_ai/_common.py @@ -0,0 +1,47 @@ +from dashscope.common.error import ( + AuthenticationError, + InvalidParameter, + RequestFailure, + ServiceUnavailableError, + UnsupportedHTTPMethod, + UnsupportedModel, +) + +from core.model_runtime.errors.invoke import ( + InvokeAuthorizationError, + InvokeBadRequestError, + InvokeConnectionError, + InvokeError, + InvokeRateLimitError, + InvokeServerUnavailableError, +) + + +class _CommonGiteeAI: + @property + def _invoke_error_mapping(self) -> dict[type[InvokeError], list[type[Exception]]]: + """ + Map model invoke error to unified error + The key is the error type thrown to the caller + The value is the error type thrown by the model, + which needs to be converted into a unified error type for the caller. + + :return: Invoke error mapping + """ + return { + InvokeConnectionError: [ + RequestFailure, + ], + InvokeServerUnavailableError: [ + ServiceUnavailableError, + ], + InvokeRateLimitError: [], + InvokeAuthorizationError: [ + AuthenticationError, + ], + InvokeBadRequestError: [ + InvalidParameter, + UnsupportedModel, + UnsupportedHTTPMethod, + ], + } diff --git a/api/core/model_runtime/model_providers/gitee_ai/gitee_ai.py b/api/core/model_runtime/model_providers/gitee_ai/gitee_ai.py new file mode 100644 index 0000000000..ca67594ce4 --- /dev/null +++ b/api/core/model_runtime/model_providers/gitee_ai/gitee_ai.py @@ -0,0 +1,25 @@ +import logging + +from core.model_runtime.entities.model_entities import ModelType +from core.model_runtime.errors.validate import CredentialsValidateFailedError +from core.model_runtime.model_providers.__base.model_provider import ModelProvider + +logger = logging.getLogger(__name__) + + +class GiteeAIProvider(ModelProvider): + def validate_provider_credentials(self, credentials: dict) -> None: + """ + Validate provider credentials + if validate failed, raise exception + + :param credentials: provider credentials, credentials form defined in `provider_credential_schema`. + """ + try: + model_instance = self.get_model_instance(ModelType.LLM) + model_instance.validate_credentials(model="Qwen2-7B-Instruct", credentials=credentials) + except CredentialsValidateFailedError as ex: + raise ex + except Exception as ex: + logger.exception(f"{self.get_provider_schema().provider} credentials validate failed") + raise ex diff --git a/api/core/model_runtime/model_providers/gitee_ai/gitee_ai.yaml b/api/core/model_runtime/model_providers/gitee_ai/gitee_ai.yaml new file mode 100644 index 0000000000..7f7d0f2e53 --- /dev/null +++ b/api/core/model_runtime/model_providers/gitee_ai/gitee_ai.yaml @@ -0,0 +1,35 @@ +provider: gitee_ai +label: + en_US: Gitee AI + zh_Hans: Gitee AI +description: + en_US: 快速体验大模型,领先探索 AI 开源世界 + zh_Hans: 快速体验大模型,领先探索 AI 开源世界 +icon_small: + en_US: Gitee-AI-Logo.svg +icon_large: + en_US: Gitee-AI-Logo-full.svg +help: + title: + en_US: Get your token from Gitee AI + zh_Hans: 从 Gitee AI 获取 token + url: + en_US: https://ai.gitee.com/dashboard/settings/tokens +supported_model_types: + - llm + - text-embedding + - rerank + - speech2text + - tts +configurate_methods: + - predefined-model +provider_credential_schema: + credential_form_schemas: + - variable: api_key + label: + en_US: API Key + type: secret-input + required: true + placeholder: + zh_Hans: 在此输入您的 API Key + en_US: Enter your API Key diff --git a/api/core/model_runtime/model_providers/gitee_ai/llm/Qwen2-72B-Instruct.yaml b/api/core/model_runtime/model_providers/gitee_ai/llm/Qwen2-72B-Instruct.yaml new file mode 100644 index 0000000000..0348438a75 --- /dev/null +++ b/api/core/model_runtime/model_providers/gitee_ai/llm/Qwen2-72B-Instruct.yaml @@ -0,0 +1,105 @@ +model: Qwen2-72B-Instruct +label: + zh_Hans: Qwen2-72B-Instruct + en_US: Qwen2-72B-Instruct +model_type: llm +features: + - agent-thought +model_properties: + mode: chat + context_size: 6400 +parameter_rules: + - name: stream + use_template: boolean + label: + en_US: "Stream" + zh_Hans: "流式" + type: boolean + default: true + required: true + help: + en_US: "Whether to return the results in batches through streaming. If set to true, the generated text will be pushed to the user in real time during the generation process." + zh_Hans: "是否通过流式分批返回结果。如果设置为 true,生成过程中实时地向用户推送每一部分生成的文本。" + + - name: max_tokens + use_template: max_tokens + label: + en_US: "Max Tokens" + zh_Hans: "最大Token数" + type: int + default: 512 + min: 1 + required: true + help: + en_US: "The maximum number of tokens that can be generated by the model varies depending on the model." + zh_Hans: "模型可生成的最大 token 个数,不同模型上限不同。" + + - name: temperature + use_template: temperature + label: + en_US: "Temperature" + zh_Hans: "采样温度" + type: float + default: 0.7 + min: 0.0 + max: 1.0 + precision: 1 + required: true + help: + en_US: "The randomness of the sampling temperature control output. The temperature value is within the range of [0.0, 1.0]. The higher the value, the more random and creative the output; the lower the value, the more stable it is. It is recommended to adjust either top_p or temperature parameters according to your needs to avoid adjusting both at the same time." + zh_Hans: "采样温度控制输出的随机性。温度值在 [0.0, 1.0] 范围内,值越高,输出越随机和创造性;值越低,输出越稳定。建议根据需求调整 top_p 或 temperature 参数,避免同时调整两者。" + + - name: top_p + use_template: top_p + label: + en_US: "Top P" + zh_Hans: "Top P" + type: float + default: 0.7 + min: 0.0 + max: 1.0 + precision: 1 + required: true + help: + en_US: "The value range of the sampling method is [0.0, 1.0]. The top_p value determines that the model selects tokens from the top p% of candidate words with the highest probability; when top_p is 0, this parameter is invalid. It is recommended to adjust either top_p or temperature parameters according to your needs to avoid adjusting both at the same time." + zh_Hans: "采样方法的取值范围为 [0.0,1.0]。top_p 值确定模型从概率最高的前p%的候选词中选取 tokens;当 top_p 为 0 时,此参数无效。建议根据需求调整 top_p 或 temperature 参数,避免同时调整两者。" + + - name: top_k + use_template: top_k + label: + en_US: "Top K" + zh_Hans: "Top K" + type: int + default: 50 + min: 0 + max: 100 + required: true + help: + en_US: "The value range is [0,100], which limits the model to only select from the top k words with the highest probability when choosing the next word at each step. The larger the value, the more diverse text generation will be." + zh_Hans: "取值范围为 [0,100],限制模型在每一步选择下一个词时,只从概率最高的前 k 个词中选取。数值越大,文本生成越多样。" + + - name: frequency_penalty + use_template: frequency_penalty + label: + en_US: "Frequency Penalty" + zh_Hans: "频率惩罚" + type: float + default: 0 + min: -1.0 + max: 1.0 + precision: 1 + required: false + help: + en_US: "Used to adjust the frequency of repeated content in automatically generated text. Positive numbers reduce repetition, while negative numbers increase repetition. After setting this parameter, if a word has already appeared in the text, the model will decrease the probability of choosing that word for subsequent generation." + zh_Hans: "用于调整自动生成文本中重复内容的频率。正数减少重复,负数增加重复。设置此参数后,如果一个词在文本中已经出现过,模型在后续生成中选择该词的概率会降低。" + + - name: user + use_template: text + label: + en_US: "User" + zh_Hans: "用户" + type: string + required: false + help: + en_US: "Used to track and differentiate conversation requests from different users." + zh_Hans: "用于追踪和区分不同用户的对话请求。" diff --git a/api/core/model_runtime/model_providers/gitee_ai/llm/Qwen2-7B-Instruct.yaml b/api/core/model_runtime/model_providers/gitee_ai/llm/Qwen2-7B-Instruct.yaml new file mode 100644 index 0000000000..ba1ad788f5 --- /dev/null +++ b/api/core/model_runtime/model_providers/gitee_ai/llm/Qwen2-7B-Instruct.yaml @@ -0,0 +1,105 @@ +model: Qwen2-7B-Instruct +label: + zh_Hans: Qwen2-7B-Instruct + en_US: Qwen2-7B-Instruct +model_type: llm +features: + - agent-thought +model_properties: + mode: chat + context_size: 32768 +parameter_rules: + - name: stream + use_template: boolean + label: + en_US: "Stream" + zh_Hans: "流式" + type: boolean + default: true + required: true + help: + en_US: "Whether to return the results in batches through streaming. If set to true, the generated text will be pushed to the user in real time during the generation process." + zh_Hans: "是否通过流式分批返回结果。如果设置为 true,生成过程中实时地向用户推送每一部分生成的文本。" + + - name: max_tokens + use_template: max_tokens + label: + en_US: "Max Tokens" + zh_Hans: "最大Token数" + type: int + default: 512 + min: 1 + required: true + help: + en_US: "The maximum number of tokens that can be generated by the model varies depending on the model." + zh_Hans: "模型可生成的最大 token 个数,不同模型上限不同。" + + - name: temperature + use_template: temperature + label: + en_US: "Temperature" + zh_Hans: "采样温度" + type: float + default: 0.7 + min: 0.0 + max: 1.0 + precision: 1 + required: true + help: + en_US: "The randomness of the sampling temperature control output. The temperature value is within the range of [0.0, 1.0]. The higher the value, the more random and creative the output; the lower the value, the more stable it is. It is recommended to adjust either top_p or temperature parameters according to your needs to avoid adjusting both at the same time." + zh_Hans: "采样温度控制输出的随机性。温度值在 [0.0, 1.0] 范围内,值越高,输出越随机和创造性;值越低,输出越稳定。建议根据需求调整 top_p 或 temperature 参数,避免同时调整两者。" + + - name: top_p + use_template: top_p + label: + en_US: "Top P" + zh_Hans: "Top P" + type: float + default: 0.7 + min: 0.0 + max: 1.0 + precision: 1 + required: true + help: + en_US: "The value range of the sampling method is [0.0, 1.0]. The top_p value determines that the model selects tokens from the top p% of candidate words with the highest probability; when top_p is 0, this parameter is invalid. It is recommended to adjust either top_p or temperature parameters according to your needs to avoid adjusting both at the same time." + zh_Hans: "采样方法的取值范围为 [0.0,1.0]。top_p 值确定模型从概率最高的前p%的候选词中选取 tokens;当 top_p 为 0 时,此参数无效。建议根据需求调整 top_p 或 temperature 参数,避免同时调整两者。" + + - name: top_k + use_template: top_k + label: + en_US: "Top K" + zh_Hans: "Top K" + type: int + default: 50 + min: 0 + max: 100 + required: true + help: + en_US: "The value range is [0,100], which limits the model to only select from the top k words with the highest probability when choosing the next word at each step. The larger the value, the more diverse text generation will be." + zh_Hans: "取值范围为 [0,100],限制模型在每一步选择下一个词时,只从概率最高的前 k 个词中选取。数值越大,文本生成越多样。" + + - name: frequency_penalty + use_template: frequency_penalty + label: + en_US: "Frequency Penalty" + zh_Hans: "频率惩罚" + type: float + default: 0 + min: -1.0 + max: 1.0 + precision: 1 + required: false + help: + en_US: "Used to adjust the frequency of repeated content in automatically generated text. Positive numbers reduce repetition, while negative numbers increase repetition. After setting this parameter, if a word has already appeared in the text, the model will decrease the probability of choosing that word for subsequent generation." + zh_Hans: "用于调整自动生成文本中重复内容的频率。正数减少重复,负数增加重复。设置此参数后,如果一个词在文本中已经出现过,模型在后续生成中选择该词的概率会降低。" + + - name: user + use_template: text + label: + en_US: "User" + zh_Hans: "用户" + type: string + required: false + help: + en_US: "Used to track and differentiate conversation requests from different users." + zh_Hans: "用于追踪和区分不同用户的对话请求。" diff --git a/api/core/model_runtime/model_providers/gitee_ai/llm/Yi-1.5-34B-Chat.yaml b/api/core/model_runtime/model_providers/gitee_ai/llm/Yi-1.5-34B-Chat.yaml new file mode 100644 index 0000000000..f7260c987b --- /dev/null +++ b/api/core/model_runtime/model_providers/gitee_ai/llm/Yi-1.5-34B-Chat.yaml @@ -0,0 +1,105 @@ +model: Yi-1.5-34B-Chat +label: + zh_Hans: Yi-1.5-34B-Chat + en_US: Yi-1.5-34B-Chat +model_type: llm +features: + - agent-thought +model_properties: + mode: chat + context_size: 4096 +parameter_rules: + - name: stream + use_template: boolean + label: + en_US: "Stream" + zh_Hans: "流式" + type: boolean + default: true + required: true + help: + en_US: "Whether to return the results in batches through streaming. If set to true, the generated text will be pushed to the user in real time during the generation process." + zh_Hans: "是否通过流式分批返回结果。如果设置为 true,生成过程中实时地向用户推送每一部分生成的文本。" + + - name: max_tokens + use_template: max_tokens + label: + en_US: "Max Tokens" + zh_Hans: "最大Token数" + type: int + default: 512 + min: 1 + required: true + help: + en_US: "The maximum number of tokens that can be generated by the model varies depending on the model." + zh_Hans: "模型可生成的最大 token 个数,不同模型上限不同。" + + - name: temperature + use_template: temperature + label: + en_US: "Temperature" + zh_Hans: "采样温度" + type: float + default: 0.7 + min: 0.0 + max: 1.0 + precision: 1 + required: true + help: + en_US: "The randomness of the sampling temperature control output. The temperature value is within the range of [0.0, 1.0]. The higher the value, the more random and creative the output; the lower the value, the more stable it is. It is recommended to adjust either top_p or temperature parameters according to your needs to avoid adjusting both at the same time." + zh_Hans: "采样温度控制输出的随机性。温度值在 [0.0, 1.0] 范围内,值越高,输出越随机和创造性;值越低,输出越稳定。建议根据需求调整 top_p 或 temperature 参数,避免同时调整两者。" + + - name: top_p + use_template: top_p + label: + en_US: "Top P" + zh_Hans: "Top P" + type: float + default: 0.7 + min: 0.0 + max: 1.0 + precision: 1 + required: true + help: + en_US: "The value range of the sampling method is [0.0, 1.0]. The top_p value determines that the model selects tokens from the top p% of candidate words with the highest probability; when top_p is 0, this parameter is invalid. It is recommended to adjust either top_p or temperature parameters according to your needs to avoid adjusting both at the same time." + zh_Hans: "采样方法的取值范围为 [0.0,1.0]。top_p 值确定模型从概率最高的前p%的候选词中选取 tokens;当 top_p 为 0 时,此参数无效。建议根据需求调整 top_p 或 temperature 参数,避免同时调整两者。" + + - name: top_k + use_template: top_k + label: + en_US: "Top K" + zh_Hans: "Top K" + type: int + default: 50 + min: 0 + max: 100 + required: true + help: + en_US: "The value range is [0,100], which limits the model to only select from the top k words with the highest probability when choosing the next word at each step. The larger the value, the more diverse text generation will be." + zh_Hans: "取值范围为 [0,100],限制模型在每一步选择下一个词时,只从概率最高的前 k 个词中选取。数值越大,文本生成越多样。" + + - name: frequency_penalty + use_template: frequency_penalty + label: + en_US: "Frequency Penalty" + zh_Hans: "频率惩罚" + type: float + default: 0 + min: -1.0 + max: 1.0 + precision: 1 + required: false + help: + en_US: "Used to adjust the frequency of repeated content in automatically generated text. Positive numbers reduce repetition, while negative numbers increase repetition. After setting this parameter, if a word has already appeared in the text, the model will decrease the probability of choosing that word for subsequent generation." + zh_Hans: "用于调整自动生成文本中重复内容的频率。正数减少重复,负数增加重复。设置此参数后,如果一个词在文本中已经出现过,模型在后续生成中选择该词的概率会降低。" + + - name: user + use_template: text + label: + en_US: "User" + zh_Hans: "用户" + type: string + required: false + help: + en_US: "Used to track and differentiate conversation requests from different users." + zh_Hans: "用于追踪和区分不同用户的对话请求。" diff --git a/api/core/model_runtime/model_providers/gitee_ai/llm/_position.yaml b/api/core/model_runtime/model_providers/gitee_ai/llm/_position.yaml new file mode 100644 index 0000000000..21f6120742 --- /dev/null +++ b/api/core/model_runtime/model_providers/gitee_ai/llm/_position.yaml @@ -0,0 +1,7 @@ +- Qwen2-7B-Instruct +- Qwen2-72B-Instruct +- Yi-1.5-34B-Chat +- glm-4-9b-chat +- deepseek-coder-33B-instruct-chat +- deepseek-coder-33B-instruct-completions +- codegeex4-all-9b diff --git a/api/core/model_runtime/model_providers/gitee_ai/llm/codegeex4-all-9b.yaml b/api/core/model_runtime/model_providers/gitee_ai/llm/codegeex4-all-9b.yaml new file mode 100644 index 0000000000..8632cd92ab --- /dev/null +++ b/api/core/model_runtime/model_providers/gitee_ai/llm/codegeex4-all-9b.yaml @@ -0,0 +1,105 @@ +model: codegeex4-all-9b +label: + zh_Hans: codegeex4-all-9b + en_US: codegeex4-all-9b +model_type: llm +features: + - agent-thought +model_properties: + mode: chat + context_size: 40960 +parameter_rules: + - name: stream + use_template: boolean + label: + en_US: "Stream" + zh_Hans: "流式" + type: boolean + default: true + required: true + help: + en_US: "Whether to return the results in batches through streaming. If set to true, the generated text will be pushed to the user in real time during the generation process." + zh_Hans: "是否通过流式分批返回结果。如果设置为 true,生成过程中实时地向用户推送每一部分生成的文本。" + + - name: max_tokens + use_template: max_tokens + label: + en_US: "Max Tokens" + zh_Hans: "最大Token数" + type: int + default: 512 + min: 1 + required: true + help: + en_US: "The maximum number of tokens that can be generated by the model varies depending on the model." + zh_Hans: "模型可生成的最大 token 个数,不同模型上限不同。" + + - name: temperature + use_template: temperature + label: + en_US: "Temperature" + zh_Hans: "采样温度" + type: float + default: 0.7 + min: 0.0 + max: 1.0 + precision: 1 + required: true + help: + en_US: "The randomness of the sampling temperature control output. The temperature value is within the range of [0.0, 1.0]. The higher the value, the more random and creative the output; the lower the value, the more stable it is. It is recommended to adjust either top_p or temperature parameters according to your needs to avoid adjusting both at the same time." + zh_Hans: "采样温度控制输出的随机性。温度值在 [0.0, 1.0] 范围内,值越高,输出越随机和创造性;值越低,输出越稳定。建议根据需求调整 top_p 或 temperature 参数,避免同时调整两者。" + + - name: top_p + use_template: top_p + label: + en_US: "Top P" + zh_Hans: "Top P" + type: float + default: 0.7 + min: 0.0 + max: 1.0 + precision: 1 + required: true + help: + en_US: "The value range of the sampling method is [0.0, 1.0]. The top_p value determines that the model selects tokens from the top p% of candidate words with the highest probability; when top_p is 0, this parameter is invalid. It is recommended to adjust either top_p or temperature parameters according to your needs to avoid adjusting both at the same time." + zh_Hans: "采样方法的取值范围为 [0.0,1.0]。top_p 值确定模型从概率最高的前p%的候选词中选取 tokens;当 top_p 为 0 时,此参数无效。建议根据需求调整 top_p 或 temperature 参数,避免同时调整两者。" + + - name: top_k + use_template: top_k + label: + en_US: "Top K" + zh_Hans: "Top K" + type: int + default: 50 + min: 0 + max: 100 + required: true + help: + en_US: "The value range is [0,100], which limits the model to only select from the top k words with the highest probability when choosing the next word at each step. The larger the value, the more diverse text generation will be." + zh_Hans: "取值范围为 [0,100],限制模型在每一步选择下一个词时,只从概率最高的前 k 个词中选取。数值越大,文本生成越多样。" + + - name: frequency_penalty + use_template: frequency_penalty + label: + en_US: "Frequency Penalty" + zh_Hans: "频率惩罚" + type: float + default: 0 + min: -1.0 + max: 1.0 + precision: 1 + required: false + help: + en_US: "Used to adjust the frequency of repeated content in automatically generated text. Positive numbers reduce repetition, while negative numbers increase repetition. After setting this parameter, if a word has already appeared in the text, the model will decrease the probability of choosing that word for subsequent generation." + zh_Hans: "用于调整自动生成文本中重复内容的频率。正数减少重复,负数增加重复。设置此参数后,如果一个词在文本中已经出现过,模型在后续生成中选择该词的概率会降低。" + + - name: user + use_template: text + label: + en_US: "User" + zh_Hans: "用户" + type: string + required: false + help: + en_US: "Used to track and differentiate conversation requests from different users." + zh_Hans: "用于追踪和区分不同用户的对话请求。" diff --git a/api/core/model_runtime/model_providers/gitee_ai/llm/deepseek-coder-33B-instruct-chat.yaml b/api/core/model_runtime/model_providers/gitee_ai/llm/deepseek-coder-33B-instruct-chat.yaml new file mode 100644 index 0000000000..2ac00761d5 --- /dev/null +++ b/api/core/model_runtime/model_providers/gitee_ai/llm/deepseek-coder-33B-instruct-chat.yaml @@ -0,0 +1,105 @@ +model: deepseek-coder-33B-instruct-chat +label: + zh_Hans: deepseek-coder-33B-instruct-chat + en_US: deepseek-coder-33B-instruct-chat +model_type: llm +features: + - agent-thought +model_properties: + mode: chat + context_size: 9000 +parameter_rules: + - name: stream + use_template: boolean + label: + en_US: "Stream" + zh_Hans: "流式" + type: boolean + default: true + required: true + help: + en_US: "Whether to return the results in batches through streaming. If set to true, the generated text will be pushed to the user in real time during the generation process." + zh_Hans: "是否通过流式分批返回结果。如果设置为 true,生成过程中实时地向用户推送每一部分生成的文本。" + + - name: max_tokens + use_template: max_tokens + label: + en_US: "Max Tokens" + zh_Hans: "最大Token数" + type: int + default: 512 + min: 1 + required: true + help: + en_US: "The maximum number of tokens that can be generated by the model varies depending on the model." + zh_Hans: "模型可生成的最大 token 个数,不同模型上限不同。" + + - name: temperature + use_template: temperature + label: + en_US: "Temperature" + zh_Hans: "采样温度" + type: float + default: 0.7 + min: 0.0 + max: 1.0 + precision: 1 + required: true + help: + en_US: "The randomness of the sampling temperature control output. The temperature value is within the range of [0.0, 1.0]. The higher the value, the more random and creative the output; the lower the value, the more stable it is. It is recommended to adjust either top_p or temperature parameters according to your needs to avoid adjusting both at the same time." + zh_Hans: "采样温度控制输出的随机性。温度值在 [0.0, 1.0] 范围内,值越高,输出越随机和创造性;值越低,输出越稳定。建议根据需求调整 top_p 或 temperature 参数,避免同时调整两者。" + + - name: top_p + use_template: top_p + label: + en_US: "Top P" + zh_Hans: "Top P" + type: float + default: 0.7 + min: 0.0 + max: 1.0 + precision: 1 + required: true + help: + en_US: "The value range of the sampling method is [0.0, 1.0]. The top_p value determines that the model selects tokens from the top p% of candidate words with the highest probability; when top_p is 0, this parameter is invalid. It is recommended to adjust either top_p or temperature parameters according to your needs to avoid adjusting both at the same time." + zh_Hans: "采样方法的取值范围为 [0.0,1.0]。top_p 值确定模型从概率最高的前p%的候选词中选取 tokens;当 top_p 为 0 时,此参数无效。建议根据需求调整 top_p 或 temperature 参数,避免同时调整两者。" + + - name: top_k + use_template: top_k + label: + en_US: "Top K" + zh_Hans: "Top K" + type: int + default: 50 + min: 0 + max: 100 + required: true + help: + en_US: "The value range is [0,100], which limits the model to only select from the top k words with the highest probability when choosing the next word at each step. The larger the value, the more diverse text generation will be." + zh_Hans: "取值范围为 [0,100],限制模型在每一步选择下一个词时,只从概率最高的前 k 个词中选取。数值越大,文本生成越多样。" + + - name: frequency_penalty + use_template: frequency_penalty + label: + en_US: "Frequency Penalty" + zh_Hans: "频率惩罚" + type: float + default: 0 + min: -1.0 + max: 1.0 + precision: 1 + required: false + help: + en_US: "Used to adjust the frequency of repeated content in automatically generated text. Positive numbers reduce repetition, while negative numbers increase repetition. After setting this parameter, if a word has already appeared in the text, the model will decrease the probability of choosing that word for subsequent generation." + zh_Hans: "用于调整自动生成文本中重复内容的频率。正数减少重复,负数增加重复。设置此参数后,如果一个词在文本中已经出现过,模型在后续生成中选择该词的概率会降低。" + + - name: user + use_template: text + label: + en_US: "User" + zh_Hans: "用户" + type: string + required: false + help: + en_US: "Used to track and differentiate conversation requests from different users." + zh_Hans: "用于追踪和区分不同用户的对话请求。" diff --git a/api/core/model_runtime/model_providers/gitee_ai/llm/deepseek-coder-33B-instruct-completions.yaml b/api/core/model_runtime/model_providers/gitee_ai/llm/deepseek-coder-33B-instruct-completions.yaml new file mode 100644 index 0000000000..7c364d89f7 --- /dev/null +++ b/api/core/model_runtime/model_providers/gitee_ai/llm/deepseek-coder-33B-instruct-completions.yaml @@ -0,0 +1,91 @@ +model: deepseek-coder-33B-instruct-completions +label: + zh_Hans: deepseek-coder-33B-instruct-completions + en_US: deepseek-coder-33B-instruct-completions +model_type: llm +features: + - agent-thought +model_properties: + mode: completion + context_size: 9000 +parameter_rules: + - name: stream + use_template: boolean + label: + en_US: "Stream" + zh_Hans: "流式" + type: boolean + default: true + required: true + help: + en_US: "Whether to return the results in batches through streaming. If set to true, the generated text will be pushed to the user in real time during the generation process." + zh_Hans: "是否通过流式分批返回结果。如果设置为 true,生成过程中实时地向用户推送每一部分生成的文本。" + + - name: max_tokens + use_template: max_tokens + label: + en_US: "Max Tokens" + zh_Hans: "最大Token数" + type: int + default: 512 + min: 1 + required: true + help: + en_US: "The maximum number of tokens that can be generated by the model varies depending on the model." + zh_Hans: "模型可生成的最大 token 个数,不同模型上限不同。" + + - name: temperature + use_template: temperature + label: + en_US: "Temperature" + zh_Hans: "采样温度" + type: float + default: 0.7 + min: 0.0 + max: 1.0 + precision: 1 + required: true + help: + en_US: "The randomness of the sampling temperature control output. The temperature value is within the range of [0.0, 1.0]. The higher the value, the more random and creative the output; the lower the value, the more stable it is. It is recommended to adjust either top_p or temperature parameters according to your needs to avoid adjusting both at the same time." + zh_Hans: "采样温度控制输出的随机性。温度值在 [0.0, 1.0] 范围内,值越高,输出越随机和创造性;值越低,输出越稳定。建议根据需求调整 top_p 或 temperature 参数,避免同时调整两者。" + + - name: top_p + use_template: top_p + label: + en_US: "Top P" + zh_Hans: "Top P" + type: float + default: 0.7 + min: 0.0 + max: 1.0 + precision: 1 + required: true + help: + en_US: "The value range of the sampling method is [0.0, 1.0]. The top_p value determines that the model selects tokens from the top p% of candidate words with the highest probability; when top_p is 0, this parameter is invalid. It is recommended to adjust either top_p or temperature parameters according to your needs to avoid adjusting both at the same time." + zh_Hans: "采样方法的取值范围为 [0.0,1.0]。top_p 值确定模型从概率最高的前p%的候选词中选取 tokens;当 top_p 为 0 时,此参数无效。建议根据需求调整 top_p 或 temperature 参数,避免同时调整两者。" + + - name: frequency_penalty + use_template: frequency_penalty + label: + en_US: "Frequency Penalty" + zh_Hans: "频率惩罚" + type: float + default: 0 + min: -1.0 + max: 1.0 + precision: 1 + required: false + help: + en_US: "Used to adjust the frequency of repeated content in automatically generated text. Positive numbers reduce repetition, while negative numbers increase repetition. After setting this parameter, if a word has already appeared in the text, the model will decrease the probability of choosing that word for subsequent generation." + zh_Hans: "用于调整自动生成文本中重复内容的频率。正数减少重复,负数增加重复。设置此参数后,如果一个词在文本中已经出现过,模型在后续生成中选择该词的概率会降低。" + + - name: user + use_template: text + label: + en_US: "User" + zh_Hans: "用户" + type: string + required: false + help: + en_US: "Used to track and differentiate conversation requests from different users." + zh_Hans: "用于追踪和区分不同用户的对话请求。" diff --git a/api/core/model_runtime/model_providers/gitee_ai/llm/glm-4-9b-chat.yaml b/api/core/model_runtime/model_providers/gitee_ai/llm/glm-4-9b-chat.yaml new file mode 100644 index 0000000000..2afe1cf959 --- /dev/null +++ b/api/core/model_runtime/model_providers/gitee_ai/llm/glm-4-9b-chat.yaml @@ -0,0 +1,105 @@ +model: glm-4-9b-chat +label: + zh_Hans: glm-4-9b-chat + en_US: glm-4-9b-chat +model_type: llm +features: + - agent-thought +model_properties: + mode: chat + context_size: 32768 +parameter_rules: + - name: stream + use_template: boolean + label: + en_US: "Stream" + zh_Hans: "流式" + type: boolean + default: true + required: true + help: + en_US: "Whether to return the results in batches through streaming. If set to true, the generated text will be pushed to the user in real time during the generation process." + zh_Hans: "是否通过流式分批返回结果。如果设置为 true,生成过程中实时地向用户推送每一部分生成的文本。" + + - name: max_tokens + use_template: max_tokens + label: + en_US: "Max Tokens" + zh_Hans: "最大Token数" + type: int + default: 512 + min: 1 + required: true + help: + en_US: "The maximum number of tokens that can be generated by the model varies depending on the model." + zh_Hans: "模型可生成的最大 token 个数,不同模型上限不同。" + + - name: temperature + use_template: temperature + label: + en_US: "Temperature" + zh_Hans: "采样温度" + type: float + default: 0.7 + min: 0.0 + max: 1.0 + precision: 1 + required: true + help: + en_US: "The randomness of the sampling temperature control output. The temperature value is within the range of [0.0, 1.0]. The higher the value, the more random and creative the output; the lower the value, the more stable it is. It is recommended to adjust either top_p or temperature parameters according to your needs to avoid adjusting both at the same time." + zh_Hans: "采样温度控制输出的随机性。温度值在 [0.0, 1.0] 范围内,值越高,输出越随机和创造性;值越低,输出越稳定。建议根据需求调整 top_p 或 temperature 参数,避免同时调整两者。" + + - name: top_p + use_template: top_p + label: + en_US: "Top P" + zh_Hans: "Top P" + type: float + default: 0.7 + min: 0.0 + max: 1.0 + precision: 1 + required: true + help: + en_US: "The value range of the sampling method is [0.0, 1.0]. The top_p value determines that the model selects tokens from the top p% of candidate words with the highest probability; when top_p is 0, this parameter is invalid. It is recommended to adjust either top_p or temperature parameters according to your needs to avoid adjusting both at the same time." + zh_Hans: "采样方法的取值范围为 [0.0,1.0]。top_p 值确定模型从概率最高的前p%的候选词中选取 tokens;当 top_p 为 0 时,此参数无效。建议根据需求调整 top_p 或 temperature 参数,避免同时调整两者。" + + - name: top_k + use_template: top_k + label: + en_US: "Top K" + zh_Hans: "Top K" + type: int + default: 50 + min: 0 + max: 100 + required: true + help: + en_US: "The value range is [0,100], which limits the model to only select from the top k words with the highest probability when choosing the next word at each step. The larger the value, the more diverse text generation will be." + zh_Hans: "取值范围为 [0,100],限制模型在每一步选择下一个词时,只从概率最高的前 k 个词中选取。数值越大,文本生成越多样。" + + - name: frequency_penalty + use_template: frequency_penalty + label: + en_US: "Frequency Penalty" + zh_Hans: "频率惩罚" + type: float + default: 0 + min: -1.0 + max: 1.0 + precision: 1 + required: false + help: + en_US: "Used to adjust the frequency of repeated content in automatically generated text. Positive numbers reduce repetition, while negative numbers increase repetition. After setting this parameter, if a word has already appeared in the text, the model will decrease the probability of choosing that word for subsequent generation." + zh_Hans: "用于调整自动生成文本中重复内容的频率。正数减少重复,负数增加重复。设置此参数后,如果一个词在文本中已经出现过,模型在后续生成中选择该词的概率会降低。" + + - name: user + use_template: text + label: + en_US: "User" + zh_Hans: "用户" + type: string + required: false + help: + en_US: "Used to track and differentiate conversation requests from different users." + zh_Hans: "用于追踪和区分不同用户的对话请求。" diff --git a/api/core/model_runtime/model_providers/gitee_ai/llm/llm.py b/api/core/model_runtime/model_providers/gitee_ai/llm/llm.py new file mode 100644 index 0000000000..b65db6f665 --- /dev/null +++ b/api/core/model_runtime/model_providers/gitee_ai/llm/llm.py @@ -0,0 +1,47 @@ +from collections.abc import Generator +from typing import Optional, Union + +from core.model_runtime.entities.llm_entities import LLMMode, LLMResult +from core.model_runtime.entities.message_entities import ( + PromptMessage, + PromptMessageTool, +) +from core.model_runtime.model_providers.openai_api_compatible.llm.llm import OAIAPICompatLargeLanguageModel + + +class GiteeAILargeLanguageModel(OAIAPICompatLargeLanguageModel): + MODEL_TO_IDENTITY: dict[str, str] = { + "Yi-1.5-34B-Chat": "Yi-34B-Chat", + "deepseek-coder-33B-instruct-completions": "deepseek-coder-33B-instruct", + "deepseek-coder-33B-instruct-chat": "deepseek-coder-33B-instruct", + } + + def _invoke( + self, + model: str, + credentials: dict, + prompt_messages: list[PromptMessage], + model_parameters: dict, + tools: Optional[list[PromptMessageTool]] = None, + stop: Optional[list[str]] = None, + stream: bool = True, + user: Optional[str] = None, + ) -> Union[LLMResult, Generator]: + self._add_custom_parameters(credentials, model, model_parameters) + return super()._invoke(model, credentials, prompt_messages, model_parameters, tools, stop, stream) + + def validate_credentials(self, model: str, credentials: dict) -> None: + self._add_custom_parameters(credentials, model, None) + super().validate_credentials(model, credentials) + + @staticmethod + def _add_custom_parameters(credentials: dict, model: str, model_parameters: dict) -> None: + if model is None: + model = "bge-large-zh-v1.5" + + model_identity = GiteeAILargeLanguageModel.MODEL_TO_IDENTITY.get(model, model) + credentials["endpoint_url"] = f"https://ai.gitee.com/api/serverless/{model_identity}/" + if model.endswith("completions"): + credentials["mode"] = LLMMode.COMPLETION.value + else: + credentials["mode"] = LLMMode.CHAT.value diff --git a/api/core/model_runtime/model_providers/gitee_ai/rerank/__init__.py b/api/core/model_runtime/model_providers/gitee_ai/rerank/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/api/core/model_runtime/model_providers/gitee_ai/rerank/_position.yaml b/api/core/model_runtime/model_providers/gitee_ai/rerank/_position.yaml new file mode 100644 index 0000000000..83162fd338 --- /dev/null +++ b/api/core/model_runtime/model_providers/gitee_ai/rerank/_position.yaml @@ -0,0 +1 @@ +- bge-reranker-v2-m3 diff --git a/api/core/model_runtime/model_providers/gitee_ai/rerank/bge-reranker-v2-m3.yaml b/api/core/model_runtime/model_providers/gitee_ai/rerank/bge-reranker-v2-m3.yaml new file mode 100644 index 0000000000..f0681641e1 --- /dev/null +++ b/api/core/model_runtime/model_providers/gitee_ai/rerank/bge-reranker-v2-m3.yaml @@ -0,0 +1,4 @@ +model: bge-reranker-v2-m3 +model_type: rerank +model_properties: + context_size: 1024 diff --git a/api/core/model_runtime/model_providers/gitee_ai/rerank/rerank.py b/api/core/model_runtime/model_providers/gitee_ai/rerank/rerank.py new file mode 100644 index 0000000000..231345c2f4 --- /dev/null +++ b/api/core/model_runtime/model_providers/gitee_ai/rerank/rerank.py @@ -0,0 +1,128 @@ +from typing import Optional + +import httpx + +from core.model_runtime.entities.common_entities import I18nObject +from core.model_runtime.entities.model_entities import AIModelEntity, FetchFrom, ModelPropertyKey, ModelType +from core.model_runtime.entities.rerank_entities import RerankDocument, RerankResult +from core.model_runtime.errors.invoke import ( + InvokeAuthorizationError, + InvokeBadRequestError, + InvokeConnectionError, + InvokeError, + InvokeRateLimitError, + InvokeServerUnavailableError, +) +from core.model_runtime.errors.validate import CredentialsValidateFailedError +from core.model_runtime.model_providers.__base.rerank_model import RerankModel + + +class GiteeAIRerankModel(RerankModel): + """ + Model class for rerank model. + """ + + def _invoke( + self, + model: str, + credentials: dict, + query: str, + docs: list[str], + score_threshold: Optional[float] = None, + top_n: Optional[int] = None, + user: Optional[str] = None, + ) -> RerankResult: + """ + Invoke rerank model + + :param model: model name + :param credentials: model credentials + :param query: search query + :param docs: docs for reranking + :param score_threshold: score threshold + :param top_n: top n documents to return + :param user: unique user id + :return: rerank result + """ + if len(docs) == 0: + return RerankResult(model=model, docs=[]) + + base_url = credentials.get("base_url", "https://ai.gitee.com/api/serverless") + base_url = base_url.removesuffix("/") + + try: + body = {"model": model, "query": query, "documents": docs} + if top_n is not None: + body["top_n"] = top_n + response = httpx.post( + f"{base_url}/{model}/rerank", + json=body, + headers={"Authorization": f"Bearer {credentials.get('api_key')}"}, + ) + + response.raise_for_status() + results = response.json() + + rerank_documents = [] + for result in results["results"]: + rerank_document = RerankDocument( + index=result["index"], + text=result["document"]["text"], + score=result["relevance_score"], + ) + if score_threshold is None or result["relevance_score"] >= score_threshold: + rerank_documents.append(rerank_document) + return RerankResult(model=model, docs=rerank_documents) + except httpx.HTTPStatusError as e: + raise InvokeServerUnavailableError(str(e)) + + def validate_credentials(self, model: str, credentials: dict) -> None: + """ + Validate model credentials + + :param model: model name + :param credentials: model credentials + :return: + """ + try: + self._invoke( + model=model, + credentials=credentials, + query="What is the capital of the United States?", + docs=[ + "Carson City is the capital city of the American state of Nevada. At the 2010 United States " + "Census, Carson City had a population of 55,274.", + "The Commonwealth of the Northern Mariana Islands is a group of islands in the Pacific Ocean that " + "are a political division controlled by the United States. Its capital is Saipan.", + ], + score_threshold=0.01, + ) + except Exception as ex: + raise CredentialsValidateFailedError(str(ex)) + + @property + def _invoke_error_mapping(self) -> dict[type[InvokeError], list[type[Exception]]]: + """ + Map model invoke error to unified error + """ + return { + InvokeConnectionError: [httpx.ConnectError], + InvokeServerUnavailableError: [httpx.RemoteProtocolError], + InvokeRateLimitError: [], + InvokeAuthorizationError: [httpx.HTTPStatusError], + InvokeBadRequestError: [httpx.RequestError], + } + + def get_customizable_model_schema(self, model: str, credentials: dict) -> AIModelEntity: + """ + generate custom model entities from credentials + """ + entity = AIModelEntity( + model=model, + label=I18nObject(en_US=model), + model_type=ModelType.RERANK, + fetch_from=FetchFrom.CUSTOMIZABLE_MODEL, + model_properties={ModelPropertyKey.CONTEXT_SIZE: int(credentials.get("context_size"))}, + ) + + return entity diff --git a/api/core/model_runtime/model_providers/gitee_ai/speech2text/__init__.py b/api/core/model_runtime/model_providers/gitee_ai/speech2text/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/api/core/model_runtime/model_providers/gitee_ai/speech2text/_position.yaml b/api/core/model_runtime/model_providers/gitee_ai/speech2text/_position.yaml new file mode 100644 index 0000000000..8e9b47598b --- /dev/null +++ b/api/core/model_runtime/model_providers/gitee_ai/speech2text/_position.yaml @@ -0,0 +1,2 @@ +- whisper-base +- whisper-large diff --git a/api/core/model_runtime/model_providers/gitee_ai/speech2text/speech2text.py b/api/core/model_runtime/model_providers/gitee_ai/speech2text/speech2text.py new file mode 100644 index 0000000000..5597f5b43e --- /dev/null +++ b/api/core/model_runtime/model_providers/gitee_ai/speech2text/speech2text.py @@ -0,0 +1,53 @@ +import os +from typing import IO, Optional + +import requests + +from core.model_runtime.errors.invoke import InvokeBadRequestError +from core.model_runtime.errors.validate import CredentialsValidateFailedError +from core.model_runtime.model_providers.__base.speech2text_model import Speech2TextModel +from core.model_runtime.model_providers.gitee_ai._common import _CommonGiteeAI + + +class GiteeAISpeech2TextModel(_CommonGiteeAI, Speech2TextModel): + """ + Model class for OpenAI Compatible Speech to text model. + """ + + def _invoke(self, model: str, credentials: dict, file: IO[bytes], user: Optional[str] = None) -> str: + """ + Invoke speech2text model + + :param model: model name + :param credentials: model credentials + :param file: audio file + :param user: unique user id + :return: text for given audio file + """ + # doc: https://ai.gitee.com/docs/openapi/serverless#tag/serverless/POST/{service}/speech-to-text + + endpoint_url = f"https://ai.gitee.com/api/serverless/{model}/speech-to-text" + files = [("file", file)] + _, file_ext = os.path.splitext(file.name) + headers = {"Content-Type": f"audio/{file_ext}", "Authorization": f"Bearer {credentials.get('api_key')}"} + response = requests.post(endpoint_url, headers=headers, files=files) + if response.status_code != 200: + raise InvokeBadRequestError(response.text) + response_data = response.json() + return response_data["text"] + + def validate_credentials(self, model: str, credentials: dict) -> None: + """ + Validate model credentials + + :param model: model name + :param credentials: model credentials + :return: + """ + try: + audio_file_path = self._get_demo_file_path() + + with open(audio_file_path, "rb") as audio_file: + self._invoke(model, credentials, audio_file) + except Exception as ex: + raise CredentialsValidateFailedError(str(ex)) diff --git a/api/core/model_runtime/model_providers/gitee_ai/speech2text/whisper-base.yaml b/api/core/model_runtime/model_providers/gitee_ai/speech2text/whisper-base.yaml new file mode 100644 index 0000000000..a50bf5fc2d --- /dev/null +++ b/api/core/model_runtime/model_providers/gitee_ai/speech2text/whisper-base.yaml @@ -0,0 +1,5 @@ +model: whisper-base +model_type: speech2text +model_properties: + file_upload_limit: 1 + supported_file_extensions: flac,mp3,mp4,mpeg,mpga,m4a,ogg,wav,webm diff --git a/api/core/model_runtime/model_providers/gitee_ai/speech2text/whisper-large.yaml b/api/core/model_runtime/model_providers/gitee_ai/speech2text/whisper-large.yaml new file mode 100644 index 0000000000..1be7b1a391 --- /dev/null +++ b/api/core/model_runtime/model_providers/gitee_ai/speech2text/whisper-large.yaml @@ -0,0 +1,5 @@ +model: whisper-large +model_type: speech2text +model_properties: + file_upload_limit: 1 + supported_file_extensions: flac,mp3,mp4,mpeg,mpga,m4a,ogg,wav,webm diff --git a/api/core/model_runtime/model_providers/gitee_ai/text_embedding/_position.yaml b/api/core/model_runtime/model_providers/gitee_ai/text_embedding/_position.yaml new file mode 100644 index 0000000000..e8abe6440d --- /dev/null +++ b/api/core/model_runtime/model_providers/gitee_ai/text_embedding/_position.yaml @@ -0,0 +1,3 @@ +- bge-large-zh-v1.5 +- bge-small-zh-v1.5 +- bge-m3 diff --git a/api/core/model_runtime/model_providers/gitee_ai/text_embedding/bge-large-zh-v1.5.yaml b/api/core/model_runtime/model_providers/gitee_ai/text_embedding/bge-large-zh-v1.5.yaml new file mode 100644 index 0000000000..9e3ca76e88 --- /dev/null +++ b/api/core/model_runtime/model_providers/gitee_ai/text_embedding/bge-large-zh-v1.5.yaml @@ -0,0 +1,8 @@ +model: bge-large-zh-v1.5 +label: + zh_Hans: bge-large-zh-v1.5 + en_US: bge-large-zh-v1.5 +model_type: text-embedding +model_properties: + context_size: 200000 + max_chunks: 20 diff --git a/api/core/model_runtime/model_providers/gitee_ai/text_embedding/bge-m3.yaml b/api/core/model_runtime/model_providers/gitee_ai/text_embedding/bge-m3.yaml new file mode 100644 index 0000000000..a7a99a98a3 --- /dev/null +++ b/api/core/model_runtime/model_providers/gitee_ai/text_embedding/bge-m3.yaml @@ -0,0 +1,8 @@ +model: bge-m3 +label: + zh_Hans: bge-m3 + en_US: bge-m3 +model_type: text-embedding +model_properties: + context_size: 200000 + max_chunks: 20 diff --git a/api/core/model_runtime/model_providers/gitee_ai/text_embedding/bge-small-zh-v1.5.yaml b/api/core/model_runtime/model_providers/gitee_ai/text_embedding/bge-small-zh-v1.5.yaml new file mode 100644 index 0000000000..bd760408fa --- /dev/null +++ b/api/core/model_runtime/model_providers/gitee_ai/text_embedding/bge-small-zh-v1.5.yaml @@ -0,0 +1,8 @@ +model: bge-small-zh-v1.5 +label: + zh_Hans: bge-small-zh-v1.5 + en_US: bge-small-zh-v1.5 +model_type: text-embedding +model_properties: + context_size: 200000 + max_chunks: 20 diff --git a/api/core/model_runtime/model_providers/gitee_ai/text_embedding/text_embedding.py b/api/core/model_runtime/model_providers/gitee_ai/text_embedding/text_embedding.py new file mode 100644 index 0000000000..b833c5652c --- /dev/null +++ b/api/core/model_runtime/model_providers/gitee_ai/text_embedding/text_embedding.py @@ -0,0 +1,31 @@ +from typing import Optional + +from core.entities.embedding_type import EmbeddingInputType +from core.model_runtime.entities.text_embedding_entities import TextEmbeddingResult +from core.model_runtime.model_providers.openai_api_compatible.text_embedding.text_embedding import ( + OAICompatEmbeddingModel, +) + + +class GiteeAIEmbeddingModel(OAICompatEmbeddingModel): + def _invoke( + self, + model: str, + credentials: dict, + texts: list[str], + user: Optional[str] = None, + input_type: EmbeddingInputType = EmbeddingInputType.DOCUMENT, + ) -> TextEmbeddingResult: + self._add_custom_parameters(credentials, model) + return super()._invoke(model, credentials, texts, user, input_type) + + def validate_credentials(self, model: str, credentials: dict) -> None: + self._add_custom_parameters(credentials, None) + super().validate_credentials(model, credentials) + + @staticmethod + def _add_custom_parameters(credentials: dict, model: str) -> None: + if model is None: + model = "bge-m3" + + credentials["endpoint_url"] = f"https://ai.gitee.com/api/serverless/{model}/v1/" diff --git a/api/core/model_runtime/model_providers/gitee_ai/tts/ChatTTS.yaml b/api/core/model_runtime/model_providers/gitee_ai/tts/ChatTTS.yaml new file mode 100644 index 0000000000..940391dfab --- /dev/null +++ b/api/core/model_runtime/model_providers/gitee_ai/tts/ChatTTS.yaml @@ -0,0 +1,11 @@ +model: ChatTTS +model_type: tts +model_properties: + default_voice: 'default' + voices: + - mode: 'default' + name: 'Default' + language: [ 'zh-Hans', 'en-US', 'de-DE', 'fr-FR', 'es-ES', 'it-IT', 'th-TH', 'id-ID' ] + word_limit: 3500 + audio_type: 'mp3' + max_workers: 5 diff --git a/api/core/model_runtime/model_providers/gitee_ai/tts/FunAudioLLM-CosyVoice-300M.yaml b/api/core/model_runtime/model_providers/gitee_ai/tts/FunAudioLLM-CosyVoice-300M.yaml new file mode 100644 index 0000000000..8fc5734801 --- /dev/null +++ b/api/core/model_runtime/model_providers/gitee_ai/tts/FunAudioLLM-CosyVoice-300M.yaml @@ -0,0 +1,11 @@ +model: FunAudioLLM-CosyVoice-300M +model_type: tts +model_properties: + default_voice: 'default' + voices: + - mode: 'default' + name: 'Default' + language: [ 'zh-Hans', 'en-US', 'de-DE', 'fr-FR', 'es-ES', 'it-IT', 'th-TH', 'id-ID' ] + word_limit: 3500 + audio_type: 'mp3' + max_workers: 5 diff --git a/api/core/model_runtime/model_providers/gitee_ai/tts/__init__.py b/api/core/model_runtime/model_providers/gitee_ai/tts/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/api/core/model_runtime/model_providers/gitee_ai/tts/_position.yaml b/api/core/model_runtime/model_providers/gitee_ai/tts/_position.yaml new file mode 100644 index 0000000000..13c6ec8454 --- /dev/null +++ b/api/core/model_runtime/model_providers/gitee_ai/tts/_position.yaml @@ -0,0 +1,4 @@ +- speecht5_tts +- ChatTTS +- fish-speech-1.2-sft +- FunAudioLLM-CosyVoice-300M diff --git a/api/core/model_runtime/model_providers/gitee_ai/tts/fish-speech-1.2-sft.yaml b/api/core/model_runtime/model_providers/gitee_ai/tts/fish-speech-1.2-sft.yaml new file mode 100644 index 0000000000..93cc28bc9d --- /dev/null +++ b/api/core/model_runtime/model_providers/gitee_ai/tts/fish-speech-1.2-sft.yaml @@ -0,0 +1,11 @@ +model: fish-speech-1.2-sft +model_type: tts +model_properties: + default_voice: 'default' + voices: + - mode: 'default' + name: 'Default' + language: [ 'zh-Hans', 'en-US', 'de-DE', 'fr-FR', 'es-ES', 'it-IT', 'th-TH', 'id-ID' ] + word_limit: 3500 + audio_type: 'mp3' + max_workers: 5 diff --git a/api/core/model_runtime/model_providers/gitee_ai/tts/speecht5_tts.yaml b/api/core/model_runtime/model_providers/gitee_ai/tts/speecht5_tts.yaml new file mode 100644 index 0000000000..f9c843bd41 --- /dev/null +++ b/api/core/model_runtime/model_providers/gitee_ai/tts/speecht5_tts.yaml @@ -0,0 +1,11 @@ +model: speecht5_tts +model_type: tts +model_properties: + default_voice: 'default' + voices: + - mode: 'default' + name: 'Default' + language: [ 'zh-Hans', 'en-US', 'de-DE', 'fr-FR', 'es-ES', 'it-IT', 'th-TH', 'id-ID' ] + word_limit: 3500 + audio_type: 'mp3' + max_workers: 5 diff --git a/api/core/model_runtime/model_providers/gitee_ai/tts/tts.py b/api/core/model_runtime/model_providers/gitee_ai/tts/tts.py new file mode 100644 index 0000000000..ed2bd5b13d --- /dev/null +++ b/api/core/model_runtime/model_providers/gitee_ai/tts/tts.py @@ -0,0 +1,79 @@ +from typing import Optional + +import requests + +from core.model_runtime.errors.invoke import InvokeBadRequestError +from core.model_runtime.errors.validate import CredentialsValidateFailedError +from core.model_runtime.model_providers.__base.tts_model import TTSModel +from core.model_runtime.model_providers.gitee_ai._common import _CommonGiteeAI + + +class GiteeAIText2SpeechModel(_CommonGiteeAI, TTSModel): + """ + Model class for OpenAI Speech to text model. + """ + + def _invoke( + self, model: str, tenant_id: str, credentials: dict, content_text: str, voice: str, user: Optional[str] = None + ) -> any: + """ + _invoke text2speech model + + :param model: model name + :param tenant_id: user tenant id + :param credentials: model credentials + :param content_text: text content to be translated + :param voice: model timbre + :param user: unique user id + :return: text translated to audio file + """ + return self._tts_invoke_streaming(model=model, credentials=credentials, content_text=content_text, voice=voice) + + def validate_credentials(self, model: str, credentials: dict) -> None: + """ + validate credentials text2speech model + + :param model: model name + :param credentials: model credentials + :return: text translated to audio file + """ + try: + self._tts_invoke_streaming( + model=model, + credentials=credentials, + content_text="Hello Dify!", + voice=self._get_model_default_voice(model, credentials), + ) + except Exception as ex: + raise CredentialsValidateFailedError(str(ex)) + + def _tts_invoke_streaming(self, model: str, credentials: dict, content_text: str, voice: str) -> any: + """ + _tts_invoke_streaming text2speech model + :param model: model name + :param credentials: model credentials + :param content_text: text content to be translated + :param voice: model timbre + :return: text translated to audio file + """ + try: + # doc: https://ai.gitee.com/docs/openapi/serverless#tag/serverless/POST/{service}/text-to-speech + endpoint_url = "https://ai.gitee.com/api/serverless/" + model + "/text-to-speech" + + headers = {"Content-Type": "application/json"} + api_key = credentials.get("api_key") + if api_key: + headers["Authorization"] = f"Bearer {api_key}" + + payload = {"inputs": content_text} + response = requests.post(endpoint_url, headers=headers, json=payload) + + if response.status_code != 200: + raise InvokeBadRequestError(response.text) + + data = response.content + + for i in range(0, len(data), 1024): + yield data[i : i + 1024] + except Exception as ex: + raise InvokeBadRequestError(str(ex)) diff --git a/api/pytest.ini b/api/pytest.ini index dcca08e2e5..a23a4b3f3d 100644 --- a/api/pytest.ini +++ b/api/pytest.ini @@ -27,3 +27,4 @@ env = XINFERENCE_GENERATION_MODEL_UID = generate XINFERENCE_RERANK_MODEL_UID = rerank XINFERENCE_SERVER_URL = http://a.abc.com:11451 + GITEE_AI_API_KEY = aaaaaaaaaaaaaaaaaaaa diff --git a/api/tests/integration_tests/.env.example b/api/tests/integration_tests/.env.example index 2d52399d29..6791cd891b 100644 --- a/api/tests/integration_tests/.env.example +++ b/api/tests/integration_tests/.env.example @@ -83,3 +83,6 @@ VOLC_EMBEDDING_ENDPOINT_ID= # 360 AI Credentials ZHINAO_API_KEY= + +# Gitee AI Credentials +GITEE_AI_API_KEY= diff --git a/api/tests/integration_tests/model_runtime/gitee_ai/__init__.py b/api/tests/integration_tests/model_runtime/gitee_ai/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/api/tests/integration_tests/model_runtime/gitee_ai/test_llm.py b/api/tests/integration_tests/model_runtime/gitee_ai/test_llm.py new file mode 100644 index 0000000000..753c52ce31 --- /dev/null +++ b/api/tests/integration_tests/model_runtime/gitee_ai/test_llm.py @@ -0,0 +1,132 @@ +import os +from collections.abc import Generator + +import pytest + +from core.model_runtime.entities.llm_entities import LLMResult, LLMResultChunk, LLMResultChunkDelta +from core.model_runtime.entities.message_entities import ( + AssistantPromptMessage, + PromptMessageTool, + SystemPromptMessage, + UserPromptMessage, +) +from core.model_runtime.entities.model_entities import AIModelEntity +from core.model_runtime.errors.validate import CredentialsValidateFailedError +from core.model_runtime.model_providers.gitee_ai.llm.llm import GiteeAILargeLanguageModel + + +def test_predefined_models(): + model = GiteeAILargeLanguageModel() + model_schemas = model.predefined_models() + + assert len(model_schemas) >= 1 + assert isinstance(model_schemas[0], AIModelEntity) + + +def test_validate_credentials_for_chat_model(): + model = GiteeAILargeLanguageModel() + + with pytest.raises(CredentialsValidateFailedError): + # model name to gpt-3.5-turbo because of mocking + model.validate_credentials(model="gpt-3.5-turbo", credentials={"api_key": "invalid_key"}) + + model.validate_credentials( + model="Qwen2-7B-Instruct", + credentials={"api_key": os.environ.get("GITEE_AI_API_KEY")}, + ) + + +def test_invoke_chat_model(): + model = GiteeAILargeLanguageModel() + + result = model.invoke( + model="Qwen2-7B-Instruct", + credentials={"api_key": os.environ.get("GITEE_AI_API_KEY")}, + prompt_messages=[ + SystemPromptMessage( + content="You are a helpful AI assistant.", + ), + UserPromptMessage(content="Hello World!"), + ], + model_parameters={ + "temperature": 0.0, + "top_p": 1.0, + "presence_penalty": 0.0, + "frequency_penalty": 0.0, + "max_tokens": 10, + "stream": False, + }, + stop=["How"], + stream=False, + user="foo", + ) + + assert isinstance(result, LLMResult) + assert len(result.message.content) > 0 + + +def test_invoke_stream_chat_model(): + model = GiteeAILargeLanguageModel() + + result = model.invoke( + model="Qwen2-7B-Instruct", + credentials={"api_key": os.environ.get("GITEE_AI_API_KEY")}, + prompt_messages=[ + SystemPromptMessage( + content="You are a helpful AI assistant.", + ), + UserPromptMessage(content="Hello World!"), + ], + model_parameters={"temperature": 0.0, "max_tokens": 100, "stream": False}, + stream=True, + user="foo", + ) + + assert isinstance(result, Generator) + + for chunk in result: + assert isinstance(chunk, LLMResultChunk) + assert isinstance(chunk.delta, LLMResultChunkDelta) + assert isinstance(chunk.delta.message, AssistantPromptMessage) + assert len(chunk.delta.message.content) > 0 if chunk.delta.finish_reason is None else True + if chunk.delta.finish_reason is not None: + assert chunk.delta.usage is not None + + +def test_get_num_tokens(): + model = GiteeAILargeLanguageModel() + + num_tokens = model.get_num_tokens( + model="Qwen2-7B-Instruct", + credentials={"api_key": os.environ.get("GITEE_AI_API_KEY")}, + prompt_messages=[UserPromptMessage(content="Hello World!")], + ) + + assert num_tokens == 10 + + num_tokens = model.get_num_tokens( + model="Qwen2-7B-Instruct", + credentials={"api_key": os.environ.get("GITEE_AI_API_KEY")}, + prompt_messages=[ + SystemPromptMessage( + content="You are a helpful AI assistant.", + ), + UserPromptMessage(content="Hello World!"), + ], + tools=[ + PromptMessageTool( + name="get_weather", + description="Determine weather in my location", + parameters={ + "type": "object", + "properties": { + "location": {"type": "string", "description": "The city and state e.g. San Francisco, CA"}, + "unit": {"type": "string", "enum": ["c", "f"]}, + }, + "required": ["location"], + }, + ), + ], + ) + + assert num_tokens == 77 diff --git a/api/tests/integration_tests/model_runtime/gitee_ai/test_provider.py b/api/tests/integration_tests/model_runtime/gitee_ai/test_provider.py new file mode 100644 index 0000000000..f12ed54a45 --- /dev/null +++ b/api/tests/integration_tests/model_runtime/gitee_ai/test_provider.py @@ -0,0 +1,15 @@ +import os + +import pytest + +from core.model_runtime.errors.validate import CredentialsValidateFailedError +from core.model_runtime.model_providers.gitee_ai.gitee_ai import GiteeAIProvider + + +def test_validate_provider_credentials(): + provider = GiteeAIProvider() + + with pytest.raises(CredentialsValidateFailedError): + provider.validate_provider_credentials(credentials={"api_key": "invalid_key"}) + + provider.validate_provider_credentials(credentials={"api_key": os.environ.get("GITEE_AI_API_KEY")}) diff --git a/api/tests/integration_tests/model_runtime/gitee_ai/test_rerank.py b/api/tests/integration_tests/model_runtime/gitee_ai/test_rerank.py new file mode 100644 index 0000000000..0e5914a61f --- /dev/null +++ b/api/tests/integration_tests/model_runtime/gitee_ai/test_rerank.py @@ -0,0 +1,47 @@ +import os + +import pytest + +from core.model_runtime.entities.rerank_entities import RerankResult +from core.model_runtime.errors.validate import CredentialsValidateFailedError +from core.model_runtime.model_providers.gitee_ai.rerank.rerank import GiteeAIRerankModel + + +def test_validate_credentials(): + model = GiteeAIRerankModel() + + with pytest.raises(CredentialsValidateFailedError): + model.validate_credentials( + model="bge-reranker-v2-m3", + credentials={"api_key": "invalid_key"}, + ) + + model.validate_credentials( + model="bge-reranker-v2-m3", + credentials={ + "api_key": os.environ.get("GITEE_AI_API_KEY"), + }, + ) + + +def test_invoke_model(): + model = GiteeAIRerankModel() + result = model.invoke( + model="bge-reranker-v2-m3", + credentials={ + "api_key": os.environ.get("GITEE_AI_API_KEY"), + }, + query="What is the capital of the United States?", + docs=[ + "Carson City is the capital city of the American state of Nevada. At the 2010 United States " + "Census, Carson City had a population of 55,274.", + "The Commonwealth of the Northern Mariana Islands is a group of islands in the Pacific Ocean that " + "are a political division controlled by the United States. Its capital is Saipan.", + ], + top_n=1, + score_threshold=0.01, + ) + + assert isinstance(result, RerankResult) + assert len(result.docs) == 1 + assert result.docs[0].score >= 0.01 diff --git a/api/tests/integration_tests/model_runtime/gitee_ai/test_speech2text.py b/api/tests/integration_tests/model_runtime/gitee_ai/test_speech2text.py new file mode 100644 index 0000000000..4a01453fdd --- /dev/null +++ b/api/tests/integration_tests/model_runtime/gitee_ai/test_speech2text.py @@ -0,0 +1,45 @@ +import os + +import pytest + +from core.model_runtime.errors.validate import CredentialsValidateFailedError +from core.model_runtime.model_providers.gitee_ai.speech2text.speech2text import GiteeAISpeech2TextModel + + +def test_validate_credentials(): + model = GiteeAISpeech2TextModel() + + with pytest.raises(CredentialsValidateFailedError): + model.validate_credentials( + model="whisper-base", + credentials={"api_key": "invalid_key"}, + ) + + model.validate_credentials( + model="whisper-base", + credentials={"api_key": os.environ.get("GITEE_AI_API_KEY")}, + ) + + +def test_invoke_model(): + model = GiteeAISpeech2TextModel() + + # Get the directory of the current file + current_dir = os.path.dirname(os.path.abspath(__file__)) + + # Get assets directory + assets_dir = os.path.join(os.path.dirname(current_dir), "assets") + + # Construct the path to the audio file + audio_file_path = os.path.join(assets_dir, "audio.mp3") + + # Open the file and get the file object + with open(audio_file_path, "rb") as audio_file: + file = audio_file + + result = model.invoke( + model="whisper-base", credentials={"api_key": os.environ.get("GITEE_AI_API_KEY")}, file=file + ) + + assert isinstance(result, str) + assert result == "1 2 3 4 5 6 7 8 9 10" diff --git a/api/tests/integration_tests/model_runtime/gitee_ai/test_text_embedding.py b/api/tests/integration_tests/model_runtime/gitee_ai/test_text_embedding.py new file mode 100644 index 0000000000..34648f0bc8 --- /dev/null +++ b/api/tests/integration_tests/model_runtime/gitee_ai/test_text_embedding.py @@ -0,0 +1,46 @@ +import os + +import pytest + +from core.model_runtime.entities.text_embedding_entities import TextEmbeddingResult +from core.model_runtime.errors.validate import CredentialsValidateFailedError +from core.model_runtime.model_providers.gitee_ai.text_embedding.text_embedding import GiteeAIEmbeddingModel + + +def test_validate_credentials(): + model = GiteeAIEmbeddingModel() + + with pytest.raises(CredentialsValidateFailedError): + model.validate_credentials(model="bge-large-zh-v1.5", credentials={"api_key": "invalid_key"}) + + model.validate_credentials(model="bge-large-zh-v1.5", credentials={"api_key": os.environ.get("GITEE_AI_API_KEY")}) + + +def test_invoke_model(): + model = GiteeAIEmbeddingModel() + + result = model.invoke( + model="bge-large-zh-v1.5", + credentials={ + "api_key": os.environ.get("GITEE_AI_API_KEY"), + }, + texts=["hello", "world"], + user="user", + ) + + assert isinstance(result, TextEmbeddingResult) + assert len(result.embeddings) == 2 + + +def test_get_num_tokens(): + model = GiteeAIEmbeddingModel() + + num_tokens = model.get_num_tokens( + model="bge-large-zh-v1.5", + credentials={ + "api_key": os.environ.get("GITEE_AI_API_KEY"), + }, + texts=["hello", "world"], + ) + + assert num_tokens == 2 diff --git a/api/tests/integration_tests/model_runtime/gitee_ai/test_tts.py b/api/tests/integration_tests/model_runtime/gitee_ai/test_tts.py new file mode 100644 index 0000000000..9f18161a7b --- /dev/null +++ b/api/tests/integration_tests/model_runtime/gitee_ai/test_tts.py @@ -0,0 +1,23 @@ +import os + +from core.model_runtime.model_providers.gitee_ai.tts.tts import GiteeAIText2SpeechModel + + +def test_invoke_model(): + model = GiteeAIText2SpeechModel() + + result = model.invoke( + model="speecht5_tts", + tenant_id="test", + credentials={ + "api_key": os.environ.get("GITEE_AI_API_KEY"), + }, + content_text="Hello, world!", + voice="", + ) + + content = b"" + for chunk in result: + content += chunk + + assert content != b"" From ddb960ddfbd47bfa58fbdb92f6d781c55a3978d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9D=9E=E6=B3=95=E6=93=8D=E4=BD=9C?= Date: Mon, 28 Oct 2024 16:52:57 +0800 Subject: [PATCH 267/346] feat: support Vectorizer can be used in workflow (#9932) --- api/core/agent/base_agent_runner.py | 12 +++++ api/core/file/file_manager.py | 12 ++++- .../builtin/vectorizer/tools/test_data.py | 1 - .../builtin/vectorizer/tools/vectorizer.py | 53 ++++++++++++------- .../builtin/vectorizer/tools/vectorizer.yaml | 15 +++--- .../provider/builtin/vectorizer/vectorizer.py | 10 +++- .../builtin/vectorizer/vectorizer.yaml | 8 --- api/core/tools/tool_manager.py | 14 +++-- 8 files changed, 82 insertions(+), 43 deletions(-) delete mode 100644 api/core/tools/provider/builtin/vectorizer/tools/test_data.py diff --git a/api/core/agent/base_agent_runner.py b/api/core/agent/base_agent_runner.py index 514dcfbd68..507455c176 100644 --- a/api/core/agent/base_agent_runner.py +++ b/api/core/agent/base_agent_runner.py @@ -165,6 +165,12 @@ class BaseAgentRunner(AppRunner): continue parameter_type = parameter.type.as_normal_type() + if parameter.type in { + ToolParameter.ToolParameterType.SYSTEM_FILES, + ToolParameter.ToolParameterType.FILE, + ToolParameter.ToolParameterType.FILES, + }: + continue enum = [] if parameter.type == ToolParameter.ToolParameterType.SELECT: enum = [option.value for option in parameter.options] @@ -250,6 +256,12 @@ class BaseAgentRunner(AppRunner): continue parameter_type = parameter.type.as_normal_type() + if parameter.type in { + ToolParameter.ToolParameterType.SYSTEM_FILES, + ToolParameter.ToolParameterType.FILE, + ToolParameter.ToolParameterType.FILES, + }: + continue enum = [] if parameter.type == ToolParameter.ToolParameterType.SELECT: enum = [option.value for option in parameter.options] diff --git a/api/core/file/file_manager.py b/api/core/file/file_manager.py index 0c6ce8ce75..b69d7a74c0 100644 --- a/api/core/file/file_manager.py +++ b/api/core/file/file_manager.py @@ -76,8 +76,16 @@ def to_prompt_message_content(f: File, /): def download(f: File, /): - upload_file = file_repository.get_upload_file(session=db.session(), file=f) - return _download_file_content(upload_file.key) + if f.transfer_method == FileTransferMethod.TOOL_FILE: + tool_file = file_repository.get_tool_file(session=db.session(), file=f) + return _download_file_content(tool_file.file_key) + elif f.transfer_method == FileTransferMethod.LOCAL_FILE: + upload_file = file_repository.get_upload_file(session=db.session(), file=f) + return _download_file_content(upload_file.key) + # remote file + response = ssrf_proxy.get(f.remote_url, follow_redirects=True) + response.raise_for_status() + return response.content def _download_file_content(path: str, /): diff --git a/api/core/tools/provider/builtin/vectorizer/tools/test_data.py b/api/core/tools/provider/builtin/vectorizer/tools/test_data.py deleted file mode 100644 index 8effa9818a..0000000000 --- a/api/core/tools/provider/builtin/vectorizer/tools/test_data.py +++ /dev/null @@ -1 +0,0 @@ -VECTORIZER_ICON_PNG = "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" # noqa: E501 diff --git a/api/core/tools/provider/builtin/vectorizer/tools/vectorizer.py b/api/core/tools/provider/builtin/vectorizer/tools/vectorizer.py index 4bd601c0bd..c722cd36c8 100644 --- a/api/core/tools/provider/builtin/vectorizer/tools/vectorizer.py +++ b/api/core/tools/provider/builtin/vectorizer/tools/vectorizer.py @@ -1,11 +1,12 @@ -from base64 import b64decode from typing import Any, Union from httpx import post +from core.file.enums import FileType +from core.file.file_manager import download +from core.tools.entities.common_entities import I18nObject from core.tools.entities.tool_entities import ToolInvokeMessage, ToolParameter -from core.tools.errors import ToolProviderCredentialValidationError -from core.tools.provider.builtin.vectorizer.tools.test_data import VECTORIZER_ICON_PNG +from core.tools.errors import ToolParameterValidationError from core.tools.tool.builtin_tool import BuiltinTool @@ -16,30 +17,30 @@ class VectorizerTool(BuiltinTool): """ invoke tools """ - api_key_name = self.runtime.credentials.get("api_key_name", None) - api_key_value = self.runtime.credentials.get("api_key_value", None) + api_key_name = self.runtime.credentials.get("api_key_name") + api_key_value = self.runtime.credentials.get("api_key_value") mode = tool_parameters.get("mode", "test") - if mode == "production": - mode = "preview" - - if not api_key_name or not api_key_value: - raise ToolProviderCredentialValidationError("Please input api key name and value") + # image file for workflow mode + image = tool_parameters.get("image") + if image and image.type != FileType.IMAGE: + raise ToolParameterValidationError("Not a valid image") + # image_id for agent mode image_id = tool_parameters.get("image_id", "") - if not image_id: - return self.create_text_message("Please input image id") - if image_id.startswith("__test_"): - image_binary = b64decode(VECTORIZER_ICON_PNG) - else: + if image_id: image_binary = self.get_variable_file(self.VariableKey.IMAGE) if not image_binary: return self.create_text_message("Image not found, please request user to generate image firstly.") + elif image: + image_binary = download(image) + else: + raise ToolParameterValidationError("Please provide either image or image_id") response = post( "https://vectorizer.ai/api/v1/vectorize", + data={"mode": mode}, files={"image": image_binary}, - data={"mode": mode} if mode == "test" else {}, auth=(api_key_name, api_key_value), timeout=30, ) @@ -59,11 +60,23 @@ class VectorizerTool(BuiltinTool): return [ ToolParameter.get_simple_instance( name="image_id", - llm_description=f"the image id that you want to vectorize, \ - and the image id should be specified in \ + llm_description=f"the image_id that you want to vectorize, \ + and the image_id should be specified in \ {[i.name for i in self.list_default_image_variables()]}", type=ToolParameter.ToolParameterType.SELECT, - required=True, + required=False, options=[i.name for i in self.list_default_image_variables()], - ) + ), + ToolParameter( + name="image", + label=I18nObject(en_US="image", zh_Hans="image"), + human_description=I18nObject( + en_US="The image to be converted.", + zh_Hans="要转换的图片。", + ), + type=ToolParameter.ToolParameterType.FILE, + form=ToolParameter.ToolParameterForm.LLM, + llm_description="you should not input this parameter. just input the image_id.", + required=False, + ), ] diff --git a/api/core/tools/provider/builtin/vectorizer/tools/vectorizer.yaml b/api/core/tools/provider/builtin/vectorizer/tools/vectorizer.yaml index 4b4fb9e245..0afd1c201f 100644 --- a/api/core/tools/provider/builtin/vectorizer/tools/vectorizer.yaml +++ b/api/core/tools/provider/builtin/vectorizer/tools/vectorizer.yaml @@ -4,14 +4,21 @@ identity: label: en_US: Vectorizer.AI zh_Hans: Vectorizer.AI - pt_BR: Vectorizer.AI description: human: en_US: Convert your PNG and JPG images to SVG vectors quickly and easily. Fully automatically. Using AI. zh_Hans: 一个将 PNG 和 JPG 图像快速轻松地转换为 SVG 矢量图的工具。 - pt_BR: Convert your PNG and JPG images to SVG vectors quickly and easily. Fully automatically. Using AI. llm: A tool for converting images to SVG vectors. you should input the image id as the input of this tool. the image id can be got from parameters. parameters: + - name: image + type: file + label: + en_US: image + human_description: + en_US: The image to be converted. + zh_Hans: 要转换的图片。 + llm_description: you should not input this parameter. just input the image_id. + form: llm - name: mode type: select required: true @@ -20,19 +27,15 @@ parameters: label: en_US: production zh_Hans: 生产模式 - pt_BR: production - value: test label: en_US: test zh_Hans: 测试模式 - pt_BR: test default: test label: en_US: Mode zh_Hans: 模式 - pt_BR: Mode human_description: en_US: It is free to integrate with and test out the API in test mode, no subscription required. zh_Hans: 在测试模式下,可以免费测试API。 - pt_BR: It is free to integrate with and test out the API in test mode, no subscription required. form: form diff --git a/api/core/tools/provider/builtin/vectorizer/vectorizer.py b/api/core/tools/provider/builtin/vectorizer/vectorizer.py index 3b868572f9..8140348723 100644 --- a/api/core/tools/provider/builtin/vectorizer/vectorizer.py +++ b/api/core/tools/provider/builtin/vectorizer/vectorizer.py @@ -1,5 +1,7 @@ from typing import Any +from core.file import File +from core.file.enums import FileTransferMethod, FileType from core.tools.errors import ToolProviderCredentialValidationError from core.tools.provider.builtin.vectorizer.tools.vectorizer import VectorizerTool from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController @@ -7,6 +9,12 @@ from core.tools.provider.builtin_tool_provider import BuiltinToolProviderControl class VectorizerProvider(BuiltinToolProviderController): def _validate_credentials(self, credentials: dict[str, Any]) -> None: + test_img = File( + tenant_id="__test_123", + remote_url="https://cloud.dify.ai/logo/logo-site.png", + type=FileType.IMAGE, + transfer_method=FileTransferMethod.REMOTE_URL, + ) try: VectorizerTool().fork_tool_runtime( runtime={ @@ -14,7 +22,7 @@ class VectorizerProvider(BuiltinToolProviderController): } ).invoke( user_id="", - tool_parameters={"mode": "test", "image_id": "__test_123"}, + tool_parameters={"mode": "test", "image": test_img}, ) except Exception as e: raise ToolProviderCredentialValidationError(str(e)) diff --git a/api/core/tools/provider/builtin/vectorizer/vectorizer.yaml b/api/core/tools/provider/builtin/vectorizer/vectorizer.yaml index 1257f8d285..94dae20876 100644 --- a/api/core/tools/provider/builtin/vectorizer/vectorizer.yaml +++ b/api/core/tools/provider/builtin/vectorizer/vectorizer.yaml @@ -4,11 +4,9 @@ identity: label: en_US: Vectorizer.AI zh_Hans: Vectorizer.AI - pt_BR: Vectorizer.AI description: en_US: Convert your PNG and JPG images to SVG vectors quickly and easily. Fully automatically. Using AI. zh_Hans: 一个将 PNG 和 JPG 图像快速轻松地转换为 SVG 矢量图的工具。 - pt_BR: Convert your PNG and JPG images to SVG vectors quickly and easily. Fully automatically. Using AI. icon: icon.png tags: - productivity @@ -20,15 +18,12 @@ credentials_for_provider: label: en_US: Vectorizer.AI API Key name zh_Hans: Vectorizer.AI API Key name - pt_BR: Vectorizer.AI API Key name placeholder: en_US: Please input your Vectorizer.AI ApiKey name zh_Hans: 请输入你的 Vectorizer.AI ApiKey name - pt_BR: Please input your Vectorizer.AI ApiKey name help: en_US: Get your Vectorizer.AI API Key from Vectorizer.AI. zh_Hans: 从 Vectorizer.AI 获取您的 Vectorizer.AI API Key。 - pt_BR: Get your Vectorizer.AI API Key from Vectorizer.AI. url: https://vectorizer.ai/api api_key_value: type: secret-input @@ -36,12 +31,9 @@ credentials_for_provider: label: en_US: Vectorizer.AI API Key zh_Hans: Vectorizer.AI API Key - pt_BR: Vectorizer.AI API Key placeholder: en_US: Please input your Vectorizer.AI ApiKey zh_Hans: 请输入你的 Vectorizer.AI ApiKey - pt_BR: Please input your Vectorizer.AI ApiKey help: en_US: Get your Vectorizer.AI API Key from Vectorizer.AI. zh_Hans: 从 Vectorizer.AI 获取您的 Vectorizer.AI API Key。 - pt_BR: Get your Vectorizer.AI API Key from Vectorizer.AI. diff --git a/api/core/tools/tool_manager.py b/api/core/tools/tool_manager.py index 9e984732b7..63f7775164 100644 --- a/api/core/tools/tool_manager.py +++ b/api/core/tools/tool_manager.py @@ -242,11 +242,15 @@ class ToolManager: parameters = tool_entity.get_all_runtime_parameters() for parameter in parameters: # check file types - if parameter.type in { - ToolParameter.ToolParameterType.SYSTEM_FILES, - ToolParameter.ToolParameterType.FILE, - ToolParameter.ToolParameterType.FILES, - }: + if ( + parameter.type + in { + ToolParameter.ToolParameterType.SYSTEM_FILES, + ToolParameter.ToolParameterType.FILE, + ToolParameter.ToolParameterType.FILES, + } + and parameter.required + ): raise ValueError(f"file type parameter {parameter.name} not supported in agent") if parameter.form == ToolParameter.ToolParameterForm.FORM: From 7056009b6adb60071b04d1441605cd0e886eb5e0 Mon Sep 17 00:00:00 2001 From: Xiao Ley Date: Mon, 28 Oct 2024 17:18:28 +0800 Subject: [PATCH 268/346] feat(tools): add Baidu translation tool (#9943) --- .../builtin/baidu_translate/_assets/icon.png | Bin 0 -> 16676 bytes .../_baidu_translate_tool_base.py | 11 + .../baidu_translate/baidu_translate.py | 17 ++ .../baidu_translate/baidu_translate.yaml | 39 +++ .../baidu_translate/tools/fieldtranslate.py | 78 +++++ .../baidu_translate/tools/fieldtranslate.yaml | 123 ++++++++ .../builtin/baidu_translate/tools/language.py | 95 ++++++ .../baidu_translate/tools/language.yaml | 43 +++ .../baidu_translate/tools/translate.py | 67 +++++ .../baidu_translate/tools/translate.yaml | 275 ++++++++++++++++++ 10 files changed, 748 insertions(+) create mode 100644 api/core/tools/provider/builtin/baidu_translate/_assets/icon.png create mode 100644 api/core/tools/provider/builtin/baidu_translate/_baidu_translate_tool_base.py create mode 100644 api/core/tools/provider/builtin/baidu_translate/baidu_translate.py create mode 100644 api/core/tools/provider/builtin/baidu_translate/baidu_translate.yaml create mode 100644 api/core/tools/provider/builtin/baidu_translate/tools/fieldtranslate.py create mode 100644 api/core/tools/provider/builtin/baidu_translate/tools/fieldtranslate.yaml create mode 100644 api/core/tools/provider/builtin/baidu_translate/tools/language.py create mode 100644 api/core/tools/provider/builtin/baidu_translate/tools/language.yaml create mode 100644 api/core/tools/provider/builtin/baidu_translate/tools/translate.py create mode 100644 api/core/tools/provider/builtin/baidu_translate/tools/translate.yaml diff --git a/api/core/tools/provider/builtin/baidu_translate/_assets/icon.png b/api/core/tools/provider/builtin/baidu_translate/_assets/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..8eb8f21513ba7d45de8204bfe64aa3cc1fd7fc26 GIT binary patch literal 16676 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 literal 0 HcmV?d00001 diff --git a/api/core/tools/provider/builtin/baidu_translate/_baidu_translate_tool_base.py b/api/core/tools/provider/builtin/baidu_translate/_baidu_translate_tool_base.py new file mode 100644 index 0000000000..ce907c3c61 --- /dev/null +++ b/api/core/tools/provider/builtin/baidu_translate/_baidu_translate_tool_base.py @@ -0,0 +1,11 @@ +from hashlib import md5 + + +class BaiduTranslateToolBase: + def _get_sign(self, appid, secret, salt, query): + """ + get baidu translate sign + """ + # concatenate the string in the order of appid+q+salt+secret + str = appid + query + salt + secret + return md5(str.encode("utf-8")).hexdigest() diff --git a/api/core/tools/provider/builtin/baidu_translate/baidu_translate.py b/api/core/tools/provider/builtin/baidu_translate/baidu_translate.py new file mode 100644 index 0000000000..cccd2f8c8f --- /dev/null +++ b/api/core/tools/provider/builtin/baidu_translate/baidu_translate.py @@ -0,0 +1,17 @@ +from typing import Any + +from core.tools.errors import ToolProviderCredentialValidationError +from core.tools.provider.builtin.baidu_translate.tools.translate import BaiduTranslateTool +from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController + + +class BaiduTranslateProvider(BuiltinToolProviderController): + def _validate_credentials(self, credentials: dict[str, Any]) -> None: + try: + BaiduTranslateTool().fork_tool_runtime( + runtime={ + "credentials": credentials, + } + ).invoke(user_id="", tool_parameters={"q": "这是一段测试文本", "from": "auto", "to": "en"}) + except Exception as e: + raise ToolProviderCredentialValidationError(str(e)) diff --git a/api/core/tools/provider/builtin/baidu_translate/baidu_translate.yaml b/api/core/tools/provider/builtin/baidu_translate/baidu_translate.yaml new file mode 100644 index 0000000000..06dadeeefc --- /dev/null +++ b/api/core/tools/provider/builtin/baidu_translate/baidu_translate.yaml @@ -0,0 +1,39 @@ +identity: + author: Xiao Ley + name: baidu_translate + label: + en_US: Baidu Translate + zh_Hans: 百度翻译 + description: + en_US: Translate text using Baidu + zh_Hans: 使用百度进行翻译 + icon: icon.png + tags: + - utilities +credentials_for_provider: + appid: + type: secret-input + required: true + label: + en_US: Baidu translate appid + zh_Hans: Baidu translate appid + placeholder: + en_US: Please input your Baidu translate appid + zh_Hans: 请输入你的百度翻译 appid + help: + en_US: Get your Baidu translate appid from Baidu translate + zh_Hans: 从百度翻译开放平台获取你的 appid + url: https://api.fanyi.baidu.com + secret: + type: secret-input + required: true + label: + en_US: Baidu translate secret + zh_Hans: Baidu translate secret + placeholder: + en_US: Please input your Baidu translate secret + zh_Hans: 请输入你的百度翻译 secret + help: + en_US: Get your Baidu translate secret from Baidu translate + zh_Hans: 从百度翻译开放平台获取你的 secret + url: https://api.fanyi.baidu.com diff --git a/api/core/tools/provider/builtin/baidu_translate/tools/fieldtranslate.py b/api/core/tools/provider/builtin/baidu_translate/tools/fieldtranslate.py new file mode 100644 index 0000000000..bce259f31d --- /dev/null +++ b/api/core/tools/provider/builtin/baidu_translate/tools/fieldtranslate.py @@ -0,0 +1,78 @@ +import random +from hashlib import md5 +from typing import Any, Union + +import requests + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.provider.builtin.baidu_translate._baidu_translate_tool_base import BaiduTranslateToolBase +from core.tools.tool.builtin_tool import BuiltinTool + + +class BaiduFieldTranslateTool(BuiltinTool, BaiduTranslateToolBase): + def _invoke( + self, + user_id: str, + tool_parameters: dict[str, Any], + ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: + """ + invoke tools + """ + BAIDU_FIELD_TRANSLATE_URL = "https://fanyi-api.baidu.com/api/trans/vip/fieldtranslate" + + appid = self.runtime.credentials.get("appid", "") + if not appid: + raise ValueError("invalid baidu translate appid") + + secret = self.runtime.credentials.get("secret", "") + if not secret: + raise ValueError("invalid baidu translate secret") + + q = tool_parameters.get("q", "") + if not q: + raise ValueError("Please input text to translate") + + from_ = tool_parameters.get("from", "") + if not from_: + raise ValueError("Please select source language") + + to = tool_parameters.get("to", "") + if not to: + raise ValueError("Please select destination language") + + domain = tool_parameters.get("domain", "") + if not domain: + raise ValueError("Please select domain") + + salt = str(random.randint(32768, 16777215)) + sign = self._get_sign(appid, secret, salt, q, domain) + + headers = {"Content-Type": "application/x-www-form-urlencoded"} + params = { + "q": q, + "from": from_, + "to": to, + "appid": appid, + "salt": salt, + "domain": domain, + "sign": sign, + "needIntervene": 1, + } + try: + response = requests.post(BAIDU_FIELD_TRANSLATE_URL, headers=headers, data=params) + result = response.json() + + if "trans_result" in result: + result_text = result["trans_result"][0]["dst"] + else: + result_text = f'{result["error_code"]}: {result["error_msg"]}' + + return self.create_text_message(str(result_text)) + except requests.RequestException as e: + raise ValueError(f"Translation service error: {e}") + except Exception: + raise ValueError("Translation service error, please check the network") + + def _get_sign(self, appid, secret, salt, query, domain): + str = appid + query + salt + domain + secret + return md5(str.encode("utf-8")).hexdigest() diff --git a/api/core/tools/provider/builtin/baidu_translate/tools/fieldtranslate.yaml b/api/core/tools/provider/builtin/baidu_translate/tools/fieldtranslate.yaml new file mode 100644 index 0000000000..de51fddbae --- /dev/null +++ b/api/core/tools/provider/builtin/baidu_translate/tools/fieldtranslate.yaml @@ -0,0 +1,123 @@ +identity: + name: field_translate + author: Xiao Ley + label: + en_US: Field translate + zh_Hans: 百度领域翻译 +description: + human: + en_US: A tool for Baidu Field translate (Currently, the fields of "novel" and "wiki" only support Chinese to English translation. If the language direction is set to English to Chinese, the default output will be a universal translation result). + zh_Hans: 百度领域翻译,提供多种领域的文本翻译(目前“网络文学领域”和“人文社科领域”仅支持中到英,如设置语言方向为英到中,则默认输出通用翻译结果) + llm: A tool for Baidu Field translate +parameters: + - name: q + type: string + required: true + label: + en_US: Text content + zh_Hans: 文本内容 + human_description: + en_US: Text content to be translated + zh_Hans: 需要翻译的文本内容 + llm_description: Text content to be translated + form: llm + - name: from + type: select + required: true + label: + en_US: source language + zh_Hans: 源语言 + human_description: + en_US: The source language of the input text + zh_Hans: 输入的文本的源语言 + default: auto + form: form + options: + - value: auto + label: + en_US: auto + zh_Hans: 自动检测 + - value: zh + label: + en_US: Chinese + zh_Hans: 中文 + - value: en + label: + en_US: English + zh_Hans: 英语 + - name: to + type: select + required: true + label: + en_US: destination language + zh_Hans: 目标语言 + human_description: + en_US: The destination language of the input text + zh_Hans: 输入文本的目标语言 + default: en + form: form + options: + - value: zh + label: + en_US: Chinese + zh_Hans: 中文 + - value: en + label: + en_US: English + zh_Hans: 英语 + - name: domain + type: select + required: true + label: + en_US: domain + zh_Hans: 领域 + human_description: + en_US: The domain of the input text + zh_Hans: 输入文本的领域 + default: novel + form: form + options: + - value: it + label: + en_US: it + zh_Hans: 信息技术领域 + - value: finance + label: + en_US: finance + zh_Hans: 金融财经领域 + - value: machinery + label: + en_US: machinery + zh_Hans: 机械制造领域 + - value: senimed + label: + en_US: senimed + zh_Hans: 生物医药领域 + - value: novel + label: + en_US: novel (only support Chinese to English translation) + zh_Hans: 网络文学领域(仅支持中到英) + - value: academic + label: + en_US: academic + zh_Hans: 学术论文领域 + - value: aerospace + label: + en_US: aerospace + zh_Hans: 航空航天领域 + - value: wiki + label: + en_US: wiki (only support Chinese to English translation) + zh_Hans: 人文社科领域(仅支持中到英) + - value: news + label: + en_US: news + zh_Hans: 新闻咨询领域 + - value: law + label: + en_US: law + zh_Hans: 法律法规领域 + - value: contract + label: + en_US: contract + zh_Hans: 合同领域 diff --git a/api/core/tools/provider/builtin/baidu_translate/tools/language.py b/api/core/tools/provider/builtin/baidu_translate/tools/language.py new file mode 100644 index 0000000000..3bbaee88b3 --- /dev/null +++ b/api/core/tools/provider/builtin/baidu_translate/tools/language.py @@ -0,0 +1,95 @@ +import random +from typing import Any, Union + +import requests + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.provider.builtin.baidu_translate._baidu_translate_tool_base import BaiduTranslateToolBase +from core.tools.tool.builtin_tool import BuiltinTool + + +class BaiduLanguageTool(BuiltinTool, BaiduTranslateToolBase): + def _invoke( + self, + user_id: str, + tool_parameters: dict[str, Any], + ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: + """ + invoke tools + """ + BAIDU_LANGUAGE_URL = "https://fanyi-api.baidu.com/api/trans/vip/language" + + appid = self.runtime.credentials.get("appid", "") + if not appid: + raise ValueError("invalid baidu translate appid") + + secret = self.runtime.credentials.get("secret", "") + if not secret: + raise ValueError("invalid baidu translate secret") + + q = tool_parameters.get("q", "") + if not q: + raise ValueError("Please input text to translate") + + description_language = tool_parameters.get("description_language", "English") + + salt = str(random.randint(32768, 16777215)) + sign = self._get_sign(appid, secret, salt, q) + + headers = {"Content-Type": "application/x-www-form-urlencoded"} + params = { + "q": q, + "appid": appid, + "salt": salt, + "sign": sign, + } + + try: + response = requests.post(BAIDU_LANGUAGE_URL, params=params, headers=headers) + result = response.json() + if "error_code" not in result: + raise ValueError("Translation service error, please check the network") + + result_text = "" + if result["error_code"] != 0: + result_text = f'{result["error_code"]}: {result["error_msg"]}' + else: + result_text = result["data"]["src"] + result_text = self.mapping_result(description_language, result_text) + + return self.create_text_message(result_text) + except requests.RequestException as e: + raise ValueError(f"Translation service error: {e}") + except Exception: + raise ValueError("Translation service error, please check the network") + + def mapping_result(self, description_language: str, result: str) -> str: + """ + mapping result + """ + mapping = { + "English": { + "zh": "Chinese", + "en": "English", + "jp": "Japanese", + "kor": "Korean", + "th": "Thai", + "vie": "Vietnamese", + "ru": "Russian", + }, + "Chinese": { + "zh": "中文", + "en": "英文", + "jp": "日文", + "kor": "韩文", + "th": "泰语", + "vie": "越南语", + "ru": "俄语", + }, + } + + language_mapping = mapping.get(description_language) + if not language_mapping: + return result + + return language_mapping.get(result, result) diff --git a/api/core/tools/provider/builtin/baidu_translate/tools/language.yaml b/api/core/tools/provider/builtin/baidu_translate/tools/language.yaml new file mode 100644 index 0000000000..60cca2e288 --- /dev/null +++ b/api/core/tools/provider/builtin/baidu_translate/tools/language.yaml @@ -0,0 +1,43 @@ +identity: + name: language + author: Xiao Ley + label: + en_US: Baidu Language + zh_Hans: 百度语种识别 +description: + human: + en_US: A tool for Baidu Language, support Chinese, English, Japanese, Korean, Thai, Vietnamese and Russian + zh_Hans: 使用百度进行语种识别,支持的语种:中文、英语、日语、韩语、泰语、越南语和俄语 + llm: A tool for Baidu Language +parameters: + - name: q + type: string + required: true + label: + en_US: Text content + zh_Hans: 文本内容 + human_description: + en_US: Text content to be recognized + zh_Hans: 需要识别语言的文本内容 + llm_description: Text content to be recognized + form: llm + - name: description_language + type: select + required: true + label: + en_US: Description language + zh_Hans: 描述语言 + human_description: + en_US: Describe the language used to identify the results + zh_Hans: 描述识别结果所用的语言 + default: Chinese + form: form + options: + - value: Chinese + label: + en_US: Chinese + zh_Hans: 中文 + - value: English + label: + en_US: English + zh_Hans: 英语 diff --git a/api/core/tools/provider/builtin/baidu_translate/tools/translate.py b/api/core/tools/provider/builtin/baidu_translate/tools/translate.py new file mode 100644 index 0000000000..7cd816a3bc --- /dev/null +++ b/api/core/tools/provider/builtin/baidu_translate/tools/translate.py @@ -0,0 +1,67 @@ +import random +from typing import Any, Union + +import requests + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.provider.builtin.baidu_translate._baidu_translate_tool_base import BaiduTranslateToolBase +from core.tools.tool.builtin_tool import BuiltinTool + + +class BaiduTranslateTool(BuiltinTool, BaiduTranslateToolBase): + def _invoke( + self, + user_id: str, + tool_parameters: dict[str, Any], + ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: + """ + invoke tools + """ + BAIDU_TRANSLATE_URL = "https://fanyi-api.baidu.com/api/trans/vip/translate" + + appid = self.runtime.credentials.get("appid", "") + if not appid: + raise ValueError("invalid baidu translate appid") + + secret = self.runtime.credentials.get("secret", "") + if not secret: + raise ValueError("invalid baidu translate secret") + + q = tool_parameters.get("q", "") + if not q: + raise ValueError("Please input text to translate") + + from_ = tool_parameters.get("from", "") + if not from_: + raise ValueError("Please select source language") + + to = tool_parameters.get("to", "") + if not to: + raise ValueError("Please select destination language") + + salt = str(random.randint(32768, 16777215)) + sign = self._get_sign(appid, secret, salt, q) + + headers = {"Content-Type": "application/x-www-form-urlencoded"} + params = { + "q": q, + "from": from_, + "to": to, + "appid": appid, + "salt": salt, + "sign": sign, + } + try: + response = requests.post(BAIDU_TRANSLATE_URL, params=params, headers=headers) + result = response.json() + + if "trans_result" in result: + result_text = result["trans_result"][0]["dst"] + else: + result_text = f'{result["error_code"]}: {result["error_msg"]}' + + return self.create_text_message(str(result_text)) + except requests.RequestException as e: + raise ValueError(f"Translation service error: {e}") + except Exception: + raise ValueError("Translation service error, please check the network") diff --git a/api/core/tools/provider/builtin/baidu_translate/tools/translate.yaml b/api/core/tools/provider/builtin/baidu_translate/tools/translate.yaml new file mode 100644 index 0000000000..c8ff32cb6b --- /dev/null +++ b/api/core/tools/provider/builtin/baidu_translate/tools/translate.yaml @@ -0,0 +1,275 @@ +identity: + name: translate + author: Xiao Ley + label: + en_US: Translate + zh_Hans: 百度翻译 +description: + human: + en_US: A tool for Baidu Translate + zh_Hans: 百度翻译 + llm: A tool for Baidu Translate +parameters: + - name: q + type: string + required: true + label: + en_US: Text content + zh_Hans: 文本内容 + human_description: + en_US: Text content to be translated + zh_Hans: 需要翻译的文本内容 + llm_description: Text content to be translated + form: llm + - name: from + type: select + required: true + label: + en_US: source language + zh_Hans: 源语言 + human_description: + en_US: The source language of the input text + zh_Hans: 输入的文本的源语言 + default: auto + form: form + options: + - value: auto + label: + en_US: auto + zh_Hans: 自动检测 + - value: zh + label: + en_US: Chinese + zh_Hans: 中文 + - value: en + label: + en_US: English + zh_Hans: 英语 + - value: cht + label: + en_US: Traditional Chinese + zh_Hans: 繁体中文 + - value: yue + label: + en_US: Yue + zh_Hans: 粤语 + - value: wyw + label: + en_US: Wyw + zh_Hans: 文言文 + - value: jp + label: + en_US: Japanese + zh_Hans: 日语 + - value: kor + label: + en_US: Korean + zh_Hans: 韩语 + - value: fra + label: + en_US: French + zh_Hans: 法语 + - value: spa + label: + en_US: Spanish + zh_Hans: 西班牙语 + - value: th + label: + en_US: Thai + zh_Hans: 泰语 + - value: ara + label: + en_US: Arabic + zh_Hans: 阿拉伯语 + - value: ru + label: + en_US: Russian + zh_Hans: 俄语 + - value: pt + label: + en_US: Portuguese + zh_Hans: 葡萄牙语 + - value: de + label: + en_US: German + zh_Hans: 德语 + - value: it + label: + en_US: Italian + zh_Hans: 意大利语 + - value: el + label: + en_US: Greek + zh_Hans: 希腊语 + - value: nl + label: + en_US: Dutch + zh_Hans: 荷兰语 + - value: pl + label: + en_US: Polish + zh_Hans: 波兰语 + - value: bul + label: + en_US: Bulgarian + zh_Hans: 保加利亚语 + - value: est + label: + en_US: Estonian + zh_Hans: 爱沙尼亚语 + - value: dan + label: + en_US: Danish + zh_Hans: 丹麦语 + - value: fin + label: + en_US: Finnish + zh_Hans: 芬兰语 + - value: cs + label: + en_US: Czech + zh_Hans: 捷克语 + - value: rom + label: + en_US: Romanian + zh_Hans: 罗马尼亚语 + - value: slo + label: + en_US: Slovak + zh_Hans: 斯洛文尼亚语 + - value: swe + label: + en_US: Swedish + zh_Hans: 瑞典语 + - value: hu + label: + en_US: Hungarian + zh_Hans: 匈牙利语 + - value: vie + label: + en_US: Vietnamese + zh_Hans: 越南语 + - name: to + type: select + required: true + label: + en_US: destination language + zh_Hans: 目标语言 + human_description: + en_US: The destination language of the input text + zh_Hans: 输入文本的目标语言 + default: en + form: form + options: + - value: zh + label: + en_US: Chinese + zh_Hans: 中文 + - value: en + label: + en_US: English + zh_Hans: 英语 + - value: cht + label: + en_US: Traditional Chinese + zh_Hans: 繁体中文 + - value: yue + label: + en_US: Yue + zh_Hans: 粤语 + - value: wyw + label: + en_US: Wyw + zh_Hans: 文言文 + - value: jp + label: + en_US: Japanese + zh_Hans: 日语 + - value: kor + label: + en_US: Korean + zh_Hans: 韩语 + - value: fra + label: + en_US: French + zh_Hans: 法语 + - value: spa + label: + en_US: Spanish + zh_Hans: 西班牙语 + - value: th + label: + en_US: Thai + zh_Hans: 泰语 + - value: ara + label: + en_US: Arabic + zh_Hans: 阿拉伯语 + - value: ru + label: + en_US: Russian + zh_Hans: 俄语 + - value: pt + label: + en_US: Portuguese + zh_Hans: 葡萄牙语 + - value: de + label: + en_US: German + zh_Hans: 德语 + - value: it + label: + en_US: Italian + zh_Hans: 意大利语 + - value: el + label: + en_US: Greek + zh_Hans: 希腊语 + - value: nl + label: + en_US: Dutch + zh_Hans: 荷兰语 + - value: pl + label: + en_US: Polish + zh_Hans: 波兰语 + - value: bul + label: + en_US: Bulgarian + zh_Hans: 保加利亚语 + - value: est + label: + en_US: Estonian + zh_Hans: 爱沙尼亚语 + - value: dan + label: + en_US: Danish + zh_Hans: 丹麦语 + - value: fin + label: + en_US: Finnish + zh_Hans: 芬兰语 + - value: cs + label: + en_US: Czech + zh_Hans: 捷克语 + - value: rom + label: + en_US: Romanian + zh_Hans: 罗马尼亚语 + - value: slo + label: + en_US: Slovak + zh_Hans: 斯洛文尼亚语 + - value: swe + label: + en_US: Swedish + zh_Hans: 瑞典语 + - value: hu + label: + en_US: Hungarian + zh_Hans: 匈牙利语 + - value: vie + label: + en_US: Vietnamese + zh_Hans: 越南语 From 4da0b706948a7623403ddc71804d1884644659c4 Mon Sep 17 00:00:00 2001 From: -LAN- Date: Mon, 28 Oct 2024 17:51:01 +0800 Subject: [PATCH 269/346] feat(http-request-executor): enhance file handling in HTTP requests (#9944) --- api/core/workflow/nodes/http_request/executor.py | 8 ++++++-- .../core/workflow/nodes/test_http_request_node.py | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/api/core/workflow/nodes/http_request/executor.py b/api/core/workflow/nodes/http_request/executor.py index 0270d7e0fd..6872478299 100644 --- a/api/core/workflow/nodes/http_request/executor.py +++ b/api/core/workflow/nodes/http_request/executor.py @@ -33,7 +33,7 @@ class Executor: params: Mapping[str, str] | None content: str | bytes | None data: Mapping[str, Any] | None - files: Mapping[str, bytes] | None + files: Mapping[str, tuple[str | None, bytes, str]] | None json: Any headers: dict[str, str] auth: HttpRequestNodeAuthorization @@ -141,7 +141,11 @@ class Executor: files = {k: self.variable_pool.get_file(selector) for k, selector in file_selectors.items()} files = {k: v for k, v in files.items() if v is not None} files = {k: variable.value for k, variable in files.items()} - files = {k: file_manager.download(v) for k, v in files.items() if v.related_id is not None} + files = { + k: (v.filename, file_manager.download(v), v.mime_type or "application/octet-stream") + for k, v in files.items() + if v.related_id is not None + } self.data = form_data self.files = files diff --git a/api/tests/unit_tests/core/workflow/nodes/test_http_request_node.py b/api/tests/unit_tests/core/workflow/nodes/test_http_request_node.py index 2a5fda48b1..720037d05f 100644 --- a/api/tests/unit_tests/core/workflow/nodes/test_http_request_node.py +++ b/api/tests/unit_tests/core/workflow/nodes/test_http_request_node.py @@ -192,7 +192,7 @@ def test_http_request_node_form_with_file(monkeypatch): def attr_checker(*args, **kwargs): assert kwargs["data"] == {"name": "test"} - assert kwargs["files"] == {"file": b"test"} + assert kwargs["files"] == {"file": (None, b"test", "application/octet-stream")} return httpx.Response(200, content=b"") monkeypatch.setattr( From 81d4d8cea1d6c37eb4f2d4cf142ad12a667efc91 Mon Sep 17 00:00:00 2001 From: Joel Date: Mon, 28 Oct 2024 18:01:33 +0800 Subject: [PATCH 270/346] fix: separator change add too many backslash (#9949) --- web/app/components/datasets/create/step-two/escape.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/app/components/datasets/create/step-two/escape.ts b/web/app/components/datasets/create/step-two/escape.ts index 098f43bc7f..2e1c3a9d73 100644 --- a/web/app/components/datasets/create/step-two/escape.ts +++ b/web/app/components/datasets/create/step-two/escape.ts @@ -3,7 +3,7 @@ function escape(input: string): string { return '' const res = input - .replaceAll('\\', '\\\\') + // .replaceAll('\\', '\\\\') // This would add too many backslashes .replaceAll('\0', '\\0') .replaceAll('\b', '\\b') .replaceAll('\f', '\\f') From adcd83f6a808e2d3a90a4844aca14441a8a9a49e Mon Sep 17 00:00:00 2001 From: AllenWriter Date: Mon, 28 Oct 2024 18:34:23 +0800 Subject: [PATCH 271/346] Docs: fix docs url (#9954) --- .../workflow/nodes/_base/hooks/use-node-help-link.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/web/app/components/workflow/nodes/_base/hooks/use-node-help-link.ts b/web/app/components/workflow/nodes/_base/hooks/use-node-help-link.ts index b5fe9554da..2ecdf101d2 100644 --- a/web/app/components/workflow/nodes/_base/hooks/use-node-help-link.ts +++ b/web/app/components/workflow/nodes/_base/hooks/use-node-help-link.ts @@ -23,8 +23,8 @@ export const useNodeHelpLink = (nodeType: BlockEnum) => { [BlockEnum.Code]: 'code', [BlockEnum.TemplateTransform]: 'template', [BlockEnum.VariableAssigner]: 'variable-assigner', - [BlockEnum.VariableAggregator]: 'variable-assigner', - [BlockEnum.Assigner]: 'variable-assignment', + [BlockEnum.VariableAggregator]: 'variable-aggregator', + [BlockEnum.Assigner]: 'variable-assigner', [BlockEnum.Iteration]: 'iteration', [BlockEnum.IterationStart]: 'iteration', [BlockEnum.ParameterExtractor]: 'parameter-extractor', @@ -46,8 +46,8 @@ export const useNodeHelpLink = (nodeType: BlockEnum) => { [BlockEnum.Code]: 'code', [BlockEnum.TemplateTransform]: 'template', [BlockEnum.VariableAssigner]: 'variable-assigner', - [BlockEnum.VariableAggregator]: 'variable-assigner', - [BlockEnum.Assigner]: 'variable-assignment', + [BlockEnum.VariableAggregator]: 'variable-aggregator', + [BlockEnum.Assigner]: 'variable-assigner', [BlockEnum.Iteration]: 'iteration', [BlockEnum.IterationStart]: 'iteration', [BlockEnum.ParameterExtractor]: 'parameter-extractor', From ca9e23d6ea52acbf598ac93c7d3e99e51bf47bd7 Mon Sep 17 00:00:00 2001 From: Joel Date: Mon, 28 Oct 2024 18:36:13 +0800 Subject: [PATCH 272/346] fix: check status --- .../install-plugin/base/check-task-status.ts | 5 +- .../plugin-page/install-plugin-dropdown.tsx | 16 +++++ web/app/components/plugins/types.ts | 58 ++++++++++--------- 3 files changed, 49 insertions(+), 30 deletions(-) diff --git a/web/app/components/plugins/install-plugin/base/check-task-status.ts b/web/app/components/plugins/install-plugin/base/check-task-status.ts index 365bd9cf36..96d6171aaf 100644 --- a/web/app/components/plugins/install-plugin/base/check-task-status.ts +++ b/web/app/components/plugins/install-plugin/base/check-task-status.ts @@ -4,7 +4,7 @@ import { TaskStatus } from '../../types' const INTERVAL = 10 * 1000 // 10 seconds -interface Params { +type Params = { taskId: string pluginUniqueIdentifier: string } @@ -18,7 +18,8 @@ function checkTaskStatus() { pluginUniqueIdentifier, }: Params) => { if (isStop) return - const { plugins } = await fetchCheckTaskStatus(taskId) + const res = await fetchCheckTaskStatus(taskId) + const { plugins } = res.task const plugin = plugins.find((p: PluginStatus) => p.plugin_unique_identifier === pluginUniqueIdentifier) if (!plugin) { nextStatus = TaskStatus.failed diff --git a/web/app/components/plugins/plugin-page/install-plugin-dropdown.tsx b/web/app/components/plugins/plugin-page/install-plugin-dropdown.tsx index 7a20d5b43e..605a9f36f0 100644 --- a/web/app/components/plugins/plugin-page/install-plugin-dropdown.tsx +++ b/web/app/components/plugins/plugin-page/install-plugin-dropdown.tsx @@ -37,6 +37,19 @@ const InstallPluginDropdown = ({ } } + // TODO TEST INSTALL : uninstall + // const [pluginLists, setPluginLists] = useState([]) + // useEffect(() => { + // (async () => { + // const list: any = await get('workspaces/current/plugin/list') + // })() + // }) + + // const handleUninstall = async (id: string) => { + // const res = await post('workspaces/current/plugin/uninstall', { body: { plugin_installation_id: id } }) + // console.log(res) + // } + return ( ) } + {/* {pluginLists.map((item: any) => ( +
handleUninstall(item.id)}>{item.name} 卸载
+ ))} */}
) } diff --git a/web/app/components/plugins/types.ts b/web/app/components/plugins/types.ts index 89c557eec7..663ae3900c 100644 --- a/web/app/components/plugins/types.ts +++ b/web/app/components/plugins/types.ts @@ -15,7 +15,7 @@ export enum PluginSource { debugging = 'remote', } -export interface PluginToolDeclaration { +export type PluginToolDeclaration = { identity: { author: string name: string @@ -27,17 +27,17 @@ export interface PluginToolDeclaration { credentials_schema: ToolCredential[] // TODO } -export interface PluginEndpointDeclaration { +export type PluginEndpointDeclaration = { settings: ToolCredential[] endpoints: EndpointItem[] } -export interface EndpointItem { +export type EndpointItem = { path: string method: string } -export interface EndpointListItem { +export type EndpointListItem = { id: string created_at: string updated_at: string @@ -53,7 +53,7 @@ export interface EndpointListItem { } // Plugin manifest -export interface PluginDeclaration { +export type PluginDeclaration = { version: string author: string icon: string @@ -70,7 +70,7 @@ export interface PluginDeclaration { model: any // TODO } -export interface PluginDetail { +export type PluginDetail = { id: string created_at: string updated_at: string @@ -87,7 +87,7 @@ export interface PluginDetail { meta?: any } -export interface Plugin { +export type Plugin = { type: PluginType org: string name: string @@ -113,7 +113,7 @@ export enum PermissionType { noOne = 'noOne', } -export interface Permissions { +export type Permissions = { canManagement: PermissionType canDebugger: PermissionType } @@ -125,7 +125,7 @@ export enum InstallStepFromGitHub { installed = 'installed', } -export interface InstallState { +export type InstallState = { step: InstallStepFromGitHub repoUrl: string selectedVersion: string @@ -133,34 +133,34 @@ export interface InstallState { releases: GitHubRepoReleaseResponse[] } -export interface GitHubUrlInfo { +export type GitHubUrlInfo = { isValid: boolean owner?: string repo?: string } // endpoint -export interface CreateEndpointRequest { +export type CreateEndpointRequest = { plugin_unique_identifier: string settings: Record name: string } -export interface EndpointOperationResponse { +export type EndpointOperationResponse = { result: 'success' | 'error' } -export interface EndpointsRequest { +export type EndpointsRequest = { limit: number page: number plugin_id: string } -export interface EndpointsResponse { +export type EndpointsResponse = { endpoints: EndpointListItem[] has_more: boolean limit: number total: number page: number } -export interface UpdateEndpointRequest { +export type UpdateEndpointRequest = { endpoint_id: string settings: Record name: string @@ -175,24 +175,24 @@ export enum InstallStep { installFailed = 'failed', } -export interface GitHubAsset { +export type GitHubAsset = { id: number name: string browser_download_url: string } -export interface GitHubRepoReleaseResponse { +export type GitHubRepoReleaseResponse = { tag_name: string assets: GitHubAsset[] } -export interface InstallPackageResponse { +export type InstallPackageResponse = { plugin_unique_identifier: string all_installed: boolean task_id: string } -export interface DebugInfo { +export type DebugInfo = { key: string host: string port: number @@ -204,19 +204,21 @@ export enum TaskStatus { failed = 'failed', } -export interface PluginStatus { +export type PluginStatus = { plugin_unique_identifier: string plugin_id: string status: TaskStatus message: string } -export interface TaskStatusResponse { - id: string - created_at: string - updated_at: string - status: string - total_plugins: number - completed_plugins: number - plugins: PluginStatus[] +export type TaskStatusResponse = { + task: { + id: string + created_at: string + updated_at: string + status: string + total_plugins: number + completed_plugins: number + plugins: PluginStatus[] + } } From badf9baf9bbe87a56c4343cfbbbf70fab0d567db Mon Sep 17 00:00:00 2001 From: Jyong <76649700+JohnJyong@users.noreply.github.com> Date: Mon, 28 Oct 2024 18:37:35 +0800 Subject: [PATCH 273/346] Fix/external api update (#9955) --- api/services/external_knowledge_service.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/api/services/external_knowledge_service.py b/api/services/external_knowledge_service.py index 4efdf8d7db..094772d674 100644 --- a/api/services/external_knowledge_service.py +++ b/api/services/external_knowledge_service.py @@ -6,6 +6,8 @@ from typing import Any, Optional, Union import httpx import validators +from constants import HIDDEN_VALUE + # from tasks.external_document_indexing_task import external_document_indexing_task from core.helper import ssrf_proxy from extensions.ext_database import db @@ -92,6 +94,8 @@ class ExternalDatasetService: ).first() if external_knowledge_api is None: raise ValueError("api template not found") + if args.get("settings") and args.get("settings").get("api_key") == HIDDEN_VALUE: + args.get("settings")["api_key"] = external_knowledge_api.settings_dict.get("api_key") external_knowledge_api.name = args.get("name") external_knowledge_api.description = args.get("description", "") From de57af46c03d65f1f0c951e8f530516ea450656d Mon Sep 17 00:00:00 2001 From: -LAN- Date: Mon, 28 Oct 2024 18:47:45 +0800 Subject: [PATCH 274/346] chore: update version to 0.10.2 in packaging and docker configurations (#9924) --- api/configs/packaging/__init__.py | 2 +- docker-legacy/docker-compose.yaml | 6 +++--- docker/docker-compose.yaml | 6 +++--- web/package.json | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/api/configs/packaging/__init__.py b/api/configs/packaging/__init__.py index 389a64f53e..3dc87e3058 100644 --- a/api/configs/packaging/__init__.py +++ b/api/configs/packaging/__init__.py @@ -9,7 +9,7 @@ class PackagingInfo(BaseSettings): CURRENT_VERSION: str = Field( description="Dify version", - default="0.10.1", + default="0.10.2", ) COMMIT_SHA: str = Field( diff --git a/docker-legacy/docker-compose.yaml b/docker-legacy/docker-compose.yaml index 17b788ff81..e3f1c3b761 100644 --- a/docker-legacy/docker-compose.yaml +++ b/docker-legacy/docker-compose.yaml @@ -2,7 +2,7 @@ version: '3' services: # API service api: - image: langgenius/dify-api:0.10.1 + image: langgenius/dify-api:0.10.2 restart: always environment: # Startup mode, 'api' starts the API server. @@ -227,7 +227,7 @@ services: # worker service # The Celery worker for processing the queue. worker: - image: langgenius/dify-api:0.10.1 + image: langgenius/dify-api:0.10.2 restart: always environment: CONSOLE_WEB_URL: '' @@ -396,7 +396,7 @@ services: # Frontend web application. web: - image: langgenius/dify-web:0.10.1 + image: langgenius/dify-web:0.10.2 restart: always environment: # The base URL of console application api server, refers to the Console base URL of WEB service if console domain is diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml index d43bd5e2d1..bf8a8b07e6 100644 --- a/docker/docker-compose.yaml +++ b/docker/docker-compose.yaml @@ -242,7 +242,7 @@ x-shared-env: &shared-api-worker-env services: # API service api: - image: langgenius/dify-api:0.10.1 + image: langgenius/dify-api:0.10.2 restart: always environment: # Use the shared environment variables. @@ -262,7 +262,7 @@ services: # worker service # The Celery worker for processing the queue. worker: - image: langgenius/dify-api:0.10.1 + image: langgenius/dify-api:0.10.2 restart: always environment: # Use the shared environment variables. @@ -281,7 +281,7 @@ services: # Frontend web application. web: - image: langgenius/dify-web:0.10.1 + image: langgenius/dify-web:0.10.2 restart: always environment: CONSOLE_API_URL: ${CONSOLE_API_URL:-} diff --git a/web/package.json b/web/package.json index e01603e8d4..04ef26afcd 100644 --- a/web/package.json +++ b/web/package.json @@ -1,6 +1,6 @@ { "name": "dify-web", - "version": "0.10.1", + "version": "0.10.2", "private": true, "engines": { "node": ">=18.17.0" From de850262b8633a00eefe99333658dbd08156e4bb Mon Sep 17 00:00:00 2001 From: crazywoola <100913391+crazywoola@users.noreply.github.com> Date: Mon, 28 Oct 2024 19:23:31 +0800 Subject: [PATCH 275/346] fix: button rendering when using streaming (#9957) --- web/app/components/base/markdown.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/app/components/base/markdown.tsx b/web/app/components/base/markdown.tsx index 33ff23d3b7..dde4bcf786 100644 --- a/web/app/components/base/markdown.tsx +++ b/web/app/components/base/markdown.tsx @@ -252,7 +252,7 @@ const MarkdownButton = ({ node }: any) => { className={cn('!h-8 !px-3 select-none')} onClick={() => onSend?.(message)} > - {node.children[0].value} + {node.children[0]?.value || ''} } MarkdownButton.displayName = 'MarkdownButton' From f47177ecb4c4b36df11c19f0ec866c2c5a162888 Mon Sep 17 00:00:00 2001 From: Jyong <76649700+JohnJyong@users.noreply.github.com> Date: Mon, 28 Oct 2024 23:04:54 +0800 Subject: [PATCH 276/346] add top_k for es full text search (#9963) --- .../rag/datasource/vdb/elasticsearch/elasticsearch_vector.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/core/rag/datasource/vdb/elasticsearch/elasticsearch_vector.py b/api/core/rag/datasource/vdb/elasticsearch/elasticsearch_vector.py index 052a187225..c62042af80 100644 --- a/api/core/rag/datasource/vdb/elasticsearch/elasticsearch_vector.py +++ b/api/core/rag/datasource/vdb/elasticsearch/elasticsearch_vector.py @@ -142,7 +142,7 @@ class ElasticSearchVector(BaseVector): def search_by_full_text(self, query: str, **kwargs: Any) -> list[Document]: query_str = {"match": {Field.CONTENT_KEY.value: query}} - results = self._client.search(index=self._collection_name, query=query_str) + results = self._client.search(index=self._collection_name, query=query_str, size=kwargs.get("top_k", 4)) docs = [] for hit in results["hits"]["hits"]: docs.append( From b6d045cebfd610de0d82c954fd75aefa9889a5e9 Mon Sep 17 00:00:00 2001 From: Wu Tianwei <30284043+WTW0313@users.noreply.github.com> Date: Tue, 29 Oct 2024 09:55:14 +0800 Subject: [PATCH 277/346] fix: Fix page logout issue due to refresh-token (#9970) --- web/hooks/use-refresh-token.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/web/hooks/use-refresh-token.ts b/web/hooks/use-refresh-token.ts index 293f3159de..53dc4faf00 100644 --- a/web/hooks/use-refresh-token.ts +++ b/web/hooks/use-refresh-token.ts @@ -41,6 +41,7 @@ const useRefreshToken = () => { return new Error('No access token or refresh token found') } if (localStorage?.getItem('is_refreshing') === '1') { + clearTimeout(timer.current) timer.current = setTimeout(() => { getNewAccessToken() }, 1000) @@ -61,12 +62,14 @@ const useRefreshToken = () => { localStorage?.setItem('console_token', access_token) localStorage?.setItem('refresh_token', refresh_token) const newTokenExpireTime = getExpireTime(access_token) + clearTimeout(timer.current) timer.current = setTimeout(() => { getNewAccessToken() }, newTokenExpireTime - advanceTime.current - getCurrentTimeStamp()) } else { const newTokenExpireTime = getExpireTime(currentAccessToken) + clearTimeout(timer.current) timer.current = setTimeout(() => { getNewAccessToken() }, newTokenExpireTime - advanceTime.current - getCurrentTimeStamp()) @@ -74,8 +77,15 @@ const useRefreshToken = () => { return null }, [getExpireTime, getCurrentTimeStamp, handleError]) + const handleVisibilityChange = useCallback(() => { + if (document.visibilityState === 'visible') + getNewAccessToken() + }, []) + useEffect(() => { + window.addEventListener('visibilitychange', handleVisibilityChange) return () => { + window.removeEventListener('visibilitychange', handleVisibilityChange) clearTimeout(timer.current) localStorage?.removeItem('is_refreshing') } From 61ff2fd0f3d5898db093fe31484751058cf5e553 Mon Sep 17 00:00:00 2001 From: ice yao Date: Tue, 29 Oct 2024 10:33:00 +0800 Subject: [PATCH 278/346] chore: Enable tencent cos test to run (#9971) --- .../unit_tests/oss/__mock/tencent_cos.py | 81 +++++++++++++++++++ .../unit_tests/oss/tencent_cos/__init__.py | 0 .../oss/tencent_cos/test_tencent_cos.py | 20 +++++ .../oss/volcengine_tos/test_volcengine_tos.py | 2 - 4 files changed, 101 insertions(+), 2 deletions(-) create mode 100644 api/tests/unit_tests/oss/__mock/tencent_cos.py create mode 100644 api/tests/unit_tests/oss/tencent_cos/__init__.py create mode 100644 api/tests/unit_tests/oss/tencent_cos/test_tencent_cos.py diff --git a/api/tests/unit_tests/oss/__mock/tencent_cos.py b/api/tests/unit_tests/oss/__mock/tencent_cos.py new file mode 100644 index 0000000000..5189b68e87 --- /dev/null +++ b/api/tests/unit_tests/oss/__mock/tencent_cos.py @@ -0,0 +1,81 @@ +import os +from unittest.mock import MagicMock + +import pytest +from _pytest.monkeypatch import MonkeyPatch +from qcloud_cos import CosS3Client +from qcloud_cos.streambody import StreamBody + +from tests.unit_tests.oss.__mock.base import ( + get_example_bucket, + get_example_data, + get_example_filename, + get_example_filepath, +) + + +class MockTencentCosClass: + def __init__(self, conf, retry=1, session=None): + self.bucket_name = get_example_bucket() + self.key = get_example_filename() + self.content = get_example_data() + self.filepath = get_example_filepath() + self.resp = { + "ETag": "ee8de918d05640145b18f70f4c3aa602", + "Server": "tencent-cos", + "x-cos-hash-crc64ecma": 16749565679157681890, + "x-cos-request-id": "NWU5MDNkYzlfNjRiODJhMDlfMzFmYzhfMTFm****", + } + + def put_object(self, Bucket, Body, Key, EnableMD5=False, **kwargs): # noqa: N803 + assert Bucket == self.bucket_name + assert Key == self.key + assert Body == self.content + return self.resp + + def get_object(self, Bucket, Key, KeySimplifyCheck=True, **kwargs): # noqa: N803 + assert Bucket == self.bucket_name + assert Key == self.key + + mock_stream_body = MagicMock(StreamBody) + mock_raw_stream = MagicMock() + mock_stream_body.get_raw_stream.return_value = mock_raw_stream + mock_raw_stream.read.return_value = self.content + + mock_stream_body.get_stream_to_file = MagicMock() + + def chunk_generator(chunk_size=2): + for i in range(0, len(self.content), chunk_size): + yield self.content[i : i + chunk_size] + + mock_stream_body.get_stream.return_value = chunk_generator(chunk_size=4096) + return {"Body": mock_stream_body} + + def object_exists(self, Bucket, Key): # noqa: N803 + assert Bucket == self.bucket_name + assert Key == self.key + return True + + def delete_object(self, Bucket, Key, **kwargs): # noqa: N803 + assert Bucket == self.bucket_name + assert Key == self.key + self.resp.update({"x-cos-delete-marker": True}) + return self.resp + + +MOCK = os.getenv("MOCK_SWITCH", "false").lower() == "true" + + +@pytest.fixture +def setup_tencent_cos_mock(monkeypatch: MonkeyPatch): + if MOCK: + monkeypatch.setattr(CosS3Client, "__init__", MockTencentCosClass.__init__) + monkeypatch.setattr(CosS3Client, "put_object", MockTencentCosClass.put_object) + monkeypatch.setattr(CosS3Client, "get_object", MockTencentCosClass.get_object) + monkeypatch.setattr(CosS3Client, "object_exists", MockTencentCosClass.object_exists) + monkeypatch.setattr(CosS3Client, "delete_object", MockTencentCosClass.delete_object) + + yield + + if MOCK: + monkeypatch.undo() diff --git a/api/tests/unit_tests/oss/tencent_cos/__init__.py b/api/tests/unit_tests/oss/tencent_cos/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/api/tests/unit_tests/oss/tencent_cos/test_tencent_cos.py b/api/tests/unit_tests/oss/tencent_cos/test_tencent_cos.py new file mode 100644 index 0000000000..303f0493bd --- /dev/null +++ b/api/tests/unit_tests/oss/tencent_cos/test_tencent_cos.py @@ -0,0 +1,20 @@ +from unittest.mock import patch + +import pytest +from qcloud_cos import CosConfig + +from extensions.storage.tencent_cos_storage import TencentCosStorage +from tests.unit_tests.oss.__mock.base import ( + BaseStorageTest, + get_example_bucket, +) +from tests.unit_tests.oss.__mock.tencent_cos import setup_tencent_cos_mock + + +class TestTencentCos(BaseStorageTest): + @pytest.fixture(autouse=True) + def setup_method(self, setup_tencent_cos_mock): + """Executed before each test method.""" + with patch.object(CosConfig, "__init__", return_value=None): + self.storage = TencentCosStorage() + self.storage.bucket_name = get_example_bucket() diff --git a/api/tests/unit_tests/oss/volcengine_tos/test_volcengine_tos.py b/api/tests/unit_tests/oss/volcengine_tos/test_volcengine_tos.py index 9f8aa158a9..5afbc9e8b4 100644 --- a/api/tests/unit_tests/oss/volcengine_tos/test_volcengine_tos.py +++ b/api/tests/unit_tests/oss/volcengine_tos/test_volcengine_tos.py @@ -1,5 +1,3 @@ -from collections.abc import Generator - import pytest from tos import TosClientV2 From eb698963555be44d8812bd53e6189117550aeeae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9D=9E=E6=B3=95=E6=93=8D=E4=BD=9C?= Date: Tue, 29 Oct 2024 10:33:15 +0800 Subject: [PATCH 279/346] fix: allow external knowledge api use simple host (#9966) --- api/services/external_knowledge_service.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/services/external_knowledge_service.py b/api/services/external_knowledge_service.py index 094772d674..b49738c61c 100644 --- a/api/services/external_knowledge_service.py +++ b/api/services/external_knowledge_service.py @@ -70,7 +70,7 @@ class ExternalDatasetService: endpoint = f"{settings['endpoint']}/retrieval" api_key = settings["api_key"] - if not validators.url(endpoint): + if not validators.url(endpoint, simple_host=True): raise ValueError(f"invalid endpoint: {endpoint}") try: response = httpx.post(endpoint, headers={"Authorization": f"Bearer {api_key}"}) From 9a65c3391b309f90d461d88b3ba1e0921a2f2ed2 Mon Sep 17 00:00:00 2001 From: StyleZhang Date: Tue, 29 Oct 2024 10:51:41 +0800 Subject: [PATCH 280/346] feat: marketplace list --- .../plugins/marketplace/context.tsx | 78 ++++++ .../marketplace/list/list-with-collection.tsx | 2 +- .../plugins/marketplace/list/list-wrapper.tsx | 6 +- .../marketplace/plugin-type-switch.tsx | 21 +- .../plugins/marketplace/search-box/index.tsx | 35 +-- .../marketplace/search-box/tags-filter.tsx | 26 +- .../components/plugins/marketplace/types.ts | 10 + web/app/components/tools/marketplace.tsx | 233 ------------------ web/app/components/tools/marketplace/hooks.ts | 35 +++ .../components/tools/marketplace/index.tsx | 48 ++++ 10 files changed, 204 insertions(+), 290 deletions(-) delete mode 100644 web/app/components/tools/marketplace.tsx create mode 100644 web/app/components/tools/marketplace/hooks.ts create mode 100644 web/app/components/tools/marketplace/index.tsx diff --git a/web/app/components/plugins/marketplace/context.tsx b/web/app/components/plugins/marketplace/context.tsx index bbadb4bf3a..8754b2c551 100644 --- a/web/app/components/plugins/marketplace/context.tsx +++ b/web/app/components/plugins/marketplace/context.tsx @@ -2,21 +2,42 @@ import type { ReactNode } from 'react' import { + useCallback, useState, } from 'react' import { createContext, useContextSelector, } from 'use-context-selector' +import { useDebounceFn } from 'ahooks' +import { PLUGIN_TYPE_SEARCH_MAP } from './plugin-type-switch' +import type { Plugin } from '../types' +import type { PluginsSearchParams } from './types' export type MarketplaceContextValue = { intersected: boolean setIntersected: (intersected: boolean) => void + searchPluginText: string + handleSearchPluginTextChange: (text: string) => void + filterPluginTags: string[] + handleFilterPluginTagsChange: (tags: string[]) => void + activePluginType: string + handleActivePluginTypeChange: (type: string) => void + plugins?: Plugin[] + setPlugins?: (plugins: Plugin[]) => void } export const MarketplaceContext = createContext({ intersected: true, setIntersected: () => {}, + searchPluginText: '', + handleSearchPluginTextChange: () => {}, + filterPluginTags: [], + handleFilterPluginTagsChange: () => {}, + activePluginType: PLUGIN_TYPE_SEARCH_MAP.all, + handleActivePluginTypeChange: () => {}, + plugins: undefined, + setPlugins: () => {}, }) type MarketplaceContextProviderProps = { @@ -31,12 +52,69 @@ export const MarketplaceContextProvider = ({ children, }: MarketplaceContextProviderProps) => { const [intersected, setIntersected] = useState(true) + const [searchPluginText, setSearchPluginText] = useState('') + const [filterPluginTags, setFilterPluginTags] = useState([]) + const [activePluginType, setActivePluginType] = useState(PLUGIN_TYPE_SEARCH_MAP.all) + const [plugins, setPlugins] = useState() + + const handleUpdatePlugins = useCallback((query: PluginsSearchParams) => { + const fetchPlugins = async () => { + const response = await fetch( + 'https://marketplace.dify.dev/api/v1/plugins/search/basic', + { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + query: query.query, + page: 1, + page_size: 10, + sort_by: query.sortBy, + sort_order: query.sortOrder, + category: query.category, + tag: query.tag, + }), + }, + ) + const data = await response.json() + setPlugins(data.data.plugins) + } + + fetchPlugins() + }, []) + + const { run: handleUpdatePluginsWithDebounced } = useDebounceFn(handleUpdatePlugins, { + wait: 500, + }) + + const handleSearchPluginTextChange = useCallback((text: string) => { + setSearchPluginText(text) + + handleUpdatePluginsWithDebounced({ query: text }) + }, [handleUpdatePluginsWithDebounced]) + + const handleFilterPluginTagsChange = useCallback((tags: string[]) => { + setFilterPluginTags(tags) + }, []) + + const handleActivePluginTypeChange = useCallback((type: string) => { + setActivePluginType(type) + }, []) return ( {children} diff --git a/web/app/components/plugins/marketplace/list/list-with-collection.tsx b/web/app/components/plugins/marketplace/list/list-with-collection.tsx index 9009b7a799..944b72a0e0 100644 --- a/web/app/components/plugins/marketplace/list/list-with-collection.tsx +++ b/web/app/components/plugins/marketplace/list/list-with-collection.tsx @@ -4,7 +4,7 @@ import type { Plugin } from '@/app/components/plugins/types' import Card from '@/app/components/plugins/card' import CardMoreInfo from '@/app/components/plugins/card/card-more-info' -interface ListWithCollectionProps { +type ListWithCollectionProps = { marketplaceCollections: MarketplaceCollection[] marketplaceCollectionPluginsMap: Record } diff --git a/web/app/components/plugins/marketplace/list/list-wrapper.tsx b/web/app/components/plugins/marketplace/list/list-wrapper.tsx index 0de2fa2c06..8272edf480 100644 --- a/web/app/components/plugins/marketplace/list/list-wrapper.tsx +++ b/web/app/components/plugins/marketplace/list/list-wrapper.tsx @@ -1,9 +1,10 @@ 'use client' import type { Plugin } from '../../types' import type { MarketplaceCollection } from '../types' +import { useMarketplaceContext } from '../context' import List from './index' -interface ListWrapperProps { +type ListWrapperProps = { marketplaceCollections: MarketplaceCollection[] marketplaceCollectionPluginsMap: Record } @@ -11,10 +12,13 @@ const ListWrapper = ({ marketplaceCollections, marketplaceCollectionPluginsMap, }: ListWrapperProps) => { + const plugins = useMarketplaceContext(s => s.plugins) + return ( ) } diff --git a/web/app/components/plugins/marketplace/plugin-type-switch.tsx b/web/app/components/plugins/marketplace/plugin-type-switch.tsx index 8f3c478c57..35f5349343 100644 --- a/web/app/components/plugins/marketplace/plugin-type-switch.tsx +++ b/web/app/components/plugins/marketplace/plugin-type-switch.tsx @@ -1,25 +1,22 @@ 'use client' -import { useState } from 'react' -import { PluginType } from '../types' import { RiArchive2Line, RiBrain2Line, RiHammerLine, RiPuzzle2Line, } from '@remixicon/react' +import { PluginType } from '../types' +import { useMarketplaceContext } from './context' import cn from '@/utils/classnames' -const PLUGIN_TYPE_SEARCH_MAP = { +export const PLUGIN_TYPE_SEARCH_MAP = { all: 'all', model: PluginType.model, tool: PluginType.tool, extension: PluginType.extension, bundle: 'bundle', } -type PluginTypeSwitchProps = { - onChange?: (type: string) => void -} const options = [ { value: PLUGIN_TYPE_SEARCH_MAP.all, @@ -47,10 +44,9 @@ const options = [ icon: , }, ] -const PluginTypeSwitch = ({ - onChange, -}: PluginTypeSwitchProps) => { - const [activeType, setActiveType] = useState(PLUGIN_TYPE_SEARCH_MAP.all) +const PluginTypeSwitch = () => { + const activePluginType = useMarketplaceContext(s => s.activePluginType) + const handleActivePluginTypeChange = useMarketplaceContext(s => s.handleActivePluginTypeChange) return (
{ - setActiveType(option.value) - onChange?.(option.value) + handleActivePluginTypeChange(option.value) }} > {option.icon} diff --git a/web/app/components/plugins/marketplace/search-box/index.tsx b/web/app/components/plugins/marketplace/search-box/index.tsx index 3115b87738..6878efdfa1 100644 --- a/web/app/components/plugins/marketplace/search-box/index.tsx +++ b/web/app/components/plugins/marketplace/search-box/index.tsx @@ -1,29 +1,14 @@ 'use client' - -import { - useCallback, - useState, -} from 'react' import { RiCloseLine } from '@remixicon/react' import { useMarketplaceContext } from '../context' import TagsFilter from './tags-filter' import ActionButton from '@/app/components/base/action-button' import cn from '@/utils/classnames' -type SearchBoxProps = { - onChange?: (searchText: string, tags: string[]) => void -} -const SearchBox = ({ - onChange, -}: SearchBoxProps) => { +const SearchBox = () => { const intersected = useMarketplaceContext(v => v.intersected) - const [searchText, setSearchText] = useState('') - const [selectedTags, setSelectedTags] = useState([]) - - const handleTagsChange = useCallback((tags: string[]) => { - setSelectedTags(tags) - onChange?.(searchText, tags) - }, [searchText, onChange]) + const searchPluginText = useMarketplaceContext(v => v.searchPluginText) + const handleSearchPluginTextChange = useMarketplaceContext(v => v.handleSearchPluginTextChange) return (
- +
{ - setSearchText(e.target.value) - onChange?.(e.target.value, selectedTags) + handleSearchPluginTextChange(e.target.value) }} /> { - searchText && ( - setSearchText('')}> + searchPluginText && ( + handleSearchPluginTextChange('')}> ) diff --git a/web/app/components/plugins/marketplace/search-box/tags-filter.tsx b/web/app/components/plugins/marketplace/search-box/tags-filter.tsx index 30337567b3..95d806c43b 100644 --- a/web/app/components/plugins/marketplace/search-box/tags-filter.tsx +++ b/web/app/components/plugins/marketplace/search-box/tags-filter.tsx @@ -6,6 +6,7 @@ import { RiCloseCircleFill, RiFilter3Line, } from '@remixicon/react' +import { useMarketplaceContext } from '../context' import { PortalToFollowElem, PortalToFollowElemContent, @@ -15,14 +16,9 @@ import Checkbox from '@/app/components/base/checkbox' import cn from '@/utils/classnames' import Input from '@/app/components/base/input' -type TagsFilterProps = { - value: string[] - onChange: (tags: string[]) => void -} -const TagsFilter = ({ - value, - onChange, -}: TagsFilterProps) => { +const TagsFilter = () => { + const filterPluginTags = useMarketplaceContext(v => v.filterPluginTags) + const handleFilterPluginTagsChange = useMarketplaceContext(v => v.handleFilterPluginTagsChange) const [open, setOpen] = useState(false) const [searchText, setSearchText] = useState('') const options = [ @@ -37,12 +33,12 @@ const TagsFilter = ({ ] const filteredOptions = options.filter(option => option.text.toLowerCase().includes(searchText.toLowerCase())) const handleCheck = (id: string) => { - if (value.includes(id)) - onChange(value.filter(tag => tag !== id)) + if (filterPluginTags.includes(id)) + handleFilterPluginTagsChange(filterPluginTags.filter((tag: string) => tag !== id)) else - onChange([...value, id]) + handleFilterPluginTagsChange([...filterPluginTags, id]) } - const selectedTagsLength = value.length + const selectedTagsLength = filterPluginTags.length return ( 2 && ( @@ -84,7 +80,7 @@ const TagsFilter = ({ !!selectedTagsLength && ( onChange([])} + onClick={() => handleFilterPluginTagsChange([])} /> ) } @@ -115,7 +111,7 @@ const TagsFilter = ({ >
{option.text} diff --git a/web/app/components/plugins/marketplace/types.ts b/web/app/components/plugins/marketplace/types.ts index 6af481cfb8..eea19b374c 100644 --- a/web/app/components/plugins/marketplace/types.ts +++ b/web/app/components/plugins/marketplace/types.ts @@ -17,3 +17,13 @@ export type MarketplaceCollectionPluginsResponse = { plugins: Plugin[] total: number } + +export type PluginsSearchParams = { + query: string + page?: number + pageSize?: number + sortBy?: string + sortOrder?: string + category?: string + tag?: string +} diff --git a/web/app/components/tools/marketplace.tsx b/web/app/components/tools/marketplace.tsx deleted file mode 100644 index 9608f4ac69..0000000000 --- a/web/app/components/tools/marketplace.tsx +++ /dev/null @@ -1,233 +0,0 @@ -import { RiArrowUpDoubleLine } from '@remixicon/react' -import Card from '@/app/components/plugins/card' -import CardMoreInfo from '@/app/components/plugins/card/card-more-info' -import { toolNotion } from '@/app/components/plugins/card/card-mock' -import { useGetLanguage } from '@/context/i18n' - -type MarketplaceProps = { - onMarketplaceScroll: () => void -} -const Marketplace = ({ - onMarketplaceScroll, -}: MarketplaceProps) => { - const locale = useGetLanguage() - - return ( -
- onMarketplaceScroll()} - /> -
-
More from Marketplace
-
- Discover - - models - - , - - tools - - , - - extensions - - and - - bundles - - in Dify Marketplace -
-
-
-
Featured
-
Our top picks to get you started
-
- - } - /> - - } - /> - - } - /> - - } - /> - - } - /> -
-
-
-
Popular
-
Explore the library and discover the incredible work of our community
-
- - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> -
-
-
- ) -} - -export default Marketplace diff --git a/web/app/components/tools/marketplace/hooks.ts b/web/app/components/tools/marketplace/hooks.ts new file mode 100644 index 0000000000..8f89aadfda --- /dev/null +++ b/web/app/components/tools/marketplace/hooks.ts @@ -0,0 +1,35 @@ +import { + useCallback, + useEffect, + useState, +} from 'react' +import type { Plugin } from '@/app/components/plugins/types' +import type { MarketplaceCollection } from '@/app/components/plugins/marketplace/types' + +export const useMarketplace = () => { + const [marketplaceCollections, setMarketplaceCollections] = useState([]) + const [marketplaceCollectionPluginsMap, setMarketplaceCollectionPluginsMap] = useState>({}) + const getMarketplaceCollections = useCallback(async () => { + const marketplaceCollectionsData = await globalThis.fetch('https://marketplace.dify.dev/api/v1/collections') + const marketplaceCollectionsDataJson = await marketplaceCollectionsData.json() + const marketplaceCollections = marketplaceCollectionsDataJson.data.collections + const marketplaceCollectionPluginsMap = {} as Record + await Promise.all(marketplaceCollections.map(async (collection: MarketplaceCollection) => { + const marketplaceCollectionPluginsData = await globalThis.fetch(`https://marketplace.dify.dev/api/v1/collections/${collection.name}/plugins`) + const marketplaceCollectionPluginsDataJson = await marketplaceCollectionPluginsData.json() + const plugins = marketplaceCollectionPluginsDataJson.data.plugins + + marketplaceCollectionPluginsMap[collection.name] = plugins + })) + setMarketplaceCollections(marketplaceCollections) + setMarketplaceCollectionPluginsMap(marketplaceCollectionPluginsMap) + }, []) + useEffect(() => { + getMarketplaceCollections() + }, [getMarketplaceCollections]) + + return { + marketplaceCollections, + marketplaceCollectionPluginsMap, + } +} diff --git a/web/app/components/tools/marketplace/index.tsx b/web/app/components/tools/marketplace/index.tsx new file mode 100644 index 0000000000..1d1a4c3c88 --- /dev/null +++ b/web/app/components/tools/marketplace/index.tsx @@ -0,0 +1,48 @@ +import { RiArrowUpDoubleLine } from '@remixicon/react' +import { useMarketplace } from './hooks' +import List from '@/app/components/plugins/marketplace/list' + +type MarketplaceProps = { + onMarketplaceScroll: () => void +} +const Marketplace = ({ + onMarketplaceScroll, +}: MarketplaceProps) => { + const { marketplaceCollections, marketplaceCollectionPluginsMap } = useMarketplace() + return ( +
+ onMarketplaceScroll()} + /> +
+
More from Marketplace
+
+ Discover + + models + + , + + tools + + , + + extensions + + and + + bundles + + in Dify Marketplace +
+
+ +
+ ) +} + +export default Marketplace From 1e0877dcbf2b6c77f2ebd301eaa67c3697d13dc0 Mon Sep 17 00:00:00 2001 From: StyleZhang Date: Tue, 29 Oct 2024 11:33:52 +0800 Subject: [PATCH 281/346] feat: marketplace list --- .../components/plugins/marketplace/list/index.tsx | 6 +++--- .../plugins/marketplace/list/list-wrapper.tsx | 12 +++++++----- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/web/app/components/plugins/marketplace/list/index.tsx b/web/app/components/plugins/marketplace/list/index.tsx index 604211fb5b..8db131f42a 100644 --- a/web/app/components/plugins/marketplace/list/index.tsx +++ b/web/app/components/plugins/marketplace/list/index.tsx @@ -5,7 +5,7 @@ import ListWithCollection from './list-with-collection' import Card from '@/app/components/plugins/card' import CardMoreInfo from '@/app/components/plugins/card/card-more-info' -interface ListProps { +type ListProps = { marketplaceCollections: MarketplaceCollection[] marketplaceCollectionPluginsMap: Record plugins?: Plugin[] @@ -16,7 +16,7 @@ const List = ({ plugins, }: ListProps) => { return ( -
+ <> { !plugins && ( ) } -
+ ) } diff --git a/web/app/components/plugins/marketplace/list/list-wrapper.tsx b/web/app/components/plugins/marketplace/list/list-wrapper.tsx index 8272edf480..68713ceb81 100644 --- a/web/app/components/plugins/marketplace/list/list-wrapper.tsx +++ b/web/app/components/plugins/marketplace/list/list-wrapper.tsx @@ -15,11 +15,13 @@ const ListWrapper = ({ const plugins = useMarketplaceContext(s => s.plugins) return ( - +
+ +
) } From f2765b9d31c320534ce520119facdc835ae0585f Mon Sep 17 00:00:00 2001 From: Joel Date: Tue, 29 Oct 2024 11:47:14 +0800 Subject: [PATCH 282/346] feat: fetch plugin icon --- .../install-plugin/base/use-get-icon.ts | 24 +++++++++++++++++++ .../install-from-local-package/index.tsx | 20 ++++++++++++---- web/service/plugins.ts | 4 ++++ 3 files changed, 44 insertions(+), 4 deletions(-) create mode 100644 web/app/components/plugins/install-plugin/base/use-get-icon.ts diff --git a/web/app/components/plugins/install-plugin/base/use-get-icon.ts b/web/app/components/plugins/install-plugin/base/use-get-icon.ts new file mode 100644 index 0000000000..210634b4a7 --- /dev/null +++ b/web/app/components/plugins/install-plugin/base/use-get-icon.ts @@ -0,0 +1,24 @@ +import { fetchIcon } from '@/service/plugins' +import { fetchWorkspaces } from '@/service/common' + +let tenantId: string | null | undefined = null + +const useGetIcon = () => { + const getIcon = async (fileName: string) => { + if (!tenantId) { + const { workspaces } = await fetchWorkspaces({ + url: '/workspaces', + params: {}, + }) + tenantId = workspaces.find(v => v.current)?.id + } + const res = await fetchIcon(tenantId!, fileName) + return res + } + + return { + getIcon, + } +} + +export default useGetIcon diff --git a/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx b/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx index 7d89ede48b..d9dd879fa4 100644 --- a/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx +++ b/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx @@ -8,10 +8,11 @@ import Uploading from './steps/uploading' import Install from './steps/install' import Installed from '../base/installed' import { useTranslation } from 'react-i18next' +import useGetIcon from '@/app/components/plugins/install-plugin/base/use-get-icon' const i18nPrefix = 'plugin.installModal' -interface InstallFromLocalPackageProps { +type InstallFromLocalPackageProps = { file: File onSuccess: () => void onClose: () => void @@ -38,12 +39,23 @@ const InstallFromLocalPackage: React.FC = ({ return t(`${i18nPrefix}.installPlugin`) }, [step]) - const handleUploaded = useCallback((result: { + const { getIcon } = useGetIcon() + + const handleUploaded = useCallback(async (result: { uniqueIdentifier: string manifest: PluginDeclaration }) => { - setUniqueIdentifier(result.uniqueIdentifier) - setManifest(result.manifest) + const { + manifest, + uniqueIdentifier, + } = result + // TODO: wait for api to fix result + const icon: any = await getIcon(manifest!.icon) + setUniqueIdentifier(uniqueIdentifier) + setManifest({ + ...manifest, + icon, + }) setStep(InstallStep.readyToInstall) }, []) diff --git a/web/service/plugins.ts b/web/service/plugins.ts index 77664cb8a2..c2e542f48c 100644 --- a/web/service/plugins.ts +++ b/web/service/plugins.ts @@ -71,6 +71,10 @@ export const installPackageFromLocal = async (uniqueIdentifier: string) => { }) } +export const fetchIcon = (tenantId: string, fileName: string) => { + return get(`workspaces/current/plugin/icon?tenant_id=${tenantId}&filename=${fileName}`) +} + export const fetchManifest = async (uniqueIdentifier: string) => { return get(`/workspaces/current/plugin/fetch-manifest?plugin_unique_identifier=${uniqueIdentifier}`) } From e135707f88f047ee82ad4a4777fc05106da3bb78 Mon Sep 17 00:00:00 2001 From: Joel Date: Tue, 29 Oct 2024 11:57:21 +0800 Subject: [PATCH 283/346] chore: plugin icon not show --- .../plugins/install-plugin/base/use-get-icon.ts | 9 ++++----- .../install-plugin/install-from-local-package/index.tsx | 5 ++--- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/web/app/components/plugins/install-plugin/base/use-get-icon.ts b/web/app/components/plugins/install-plugin/base/use-get-icon.ts index 210634b4a7..ea7f8e36b9 100644 --- a/web/app/components/plugins/install-plugin/base/use-get-icon.ts +++ b/web/app/components/plugins/install-plugin/base/use-get-icon.ts @@ -1,10 +1,10 @@ -import { fetchIcon } from '@/service/plugins' +import { apiPrefix } from '@/config' import { fetchWorkspaces } from '@/service/common' let tenantId: string | null | undefined = null const useGetIcon = () => { - const getIcon = async (fileName: string) => { + const getIconUrl = async (fileName: string) => { if (!tenantId) { const { workspaces } = await fetchWorkspaces({ url: '/workspaces', @@ -12,12 +12,11 @@ const useGetIcon = () => { }) tenantId = workspaces.find(v => v.current)?.id } - const res = await fetchIcon(tenantId!, fileName) - return res + return `${apiPrefix}/workspaces/current/plugin/icon?tenant_id=${tenantId}&filename=${fileName}` } return { - getIcon, + getIconUrl, } } diff --git a/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx b/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx index d9dd879fa4..c93cc81291 100644 --- a/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx +++ b/web/app/components/plugins/install-plugin/install-from-local-package/index.tsx @@ -39,7 +39,7 @@ const InstallFromLocalPackage: React.FC = ({ return t(`${i18nPrefix}.installPlugin`) }, [step]) - const { getIcon } = useGetIcon() + const { getIconUrl } = useGetIcon() const handleUploaded = useCallback(async (result: { uniqueIdentifier: string @@ -49,8 +49,7 @@ const InstallFromLocalPackage: React.FC = ({ manifest, uniqueIdentifier, } = result - // TODO: wait for api to fix result - const icon: any = await getIcon(manifest!.icon) + const icon = await getIconUrl(manifest!.icon) setUniqueIdentifier(uniqueIdentifier) setManifest({ ...manifest, From fc37e654fc26304bed0a1a07bedc23a4e2c68b91 Mon Sep 17 00:00:00 2001 From: crazywoola <100913391+crazywoola@users.noreply.github.com> Date: Tue, 29 Oct 2024 13:32:50 +0800 Subject: [PATCH 284/346] Feat/support form in conversation (#9980) --- .../base/markdown-blocks/button.tsx | 22 +++ .../components/base/markdown-blocks/form.tsx | 137 ++++++++++++++++++ web/app/components/base/markdown.tsx | 20 +-- 3 files changed, 162 insertions(+), 17 deletions(-) create mode 100644 web/app/components/base/markdown-blocks/button.tsx create mode 100644 web/app/components/base/markdown-blocks/form.tsx diff --git a/web/app/components/base/markdown-blocks/button.tsx b/web/app/components/base/markdown-blocks/button.tsx new file mode 100644 index 0000000000..56647b3bbe --- /dev/null +++ b/web/app/components/base/markdown-blocks/button.tsx @@ -0,0 +1,22 @@ +import { useChatContext } from '@/app/components/base/chat/chat/context' +import Button from '@/app/components/base/button' +import cn from '@/utils/classnames' + +const MarkdownButton = ({ node }: any) => { + const { onSend } = useChatContext() + const variant = node.properties.dataVariant + const message = node.properties.dataMessage + const size = node.properties.dataSize + + return +} +MarkdownButton.displayName = 'MarkdownButton' + +export default MarkdownButton diff --git a/web/app/components/base/markdown-blocks/form.tsx b/web/app/components/base/markdown-blocks/form.tsx new file mode 100644 index 0000000000..f87f2dcd91 --- /dev/null +++ b/web/app/components/base/markdown-blocks/form.tsx @@ -0,0 +1,137 @@ +import Button from '@/app/components/base/button' +import Input from '@/app/components/base/input' +import Textarea from '@/app/components/base/textarea' +import { useChatContext } from '@/app/components/base/chat/chat/context' + +enum DATA_FORMAT { + TEXT = 'text', + JSON = 'json', +} +enum SUPPORTED_TAGS { + LABEL = 'label', + INPUT = 'input', + TEXTAREA = 'textarea', + BUTTON = 'button', +} +enum SUPPORTED_TYPES { + TEXT = 'text', + PASSWORD = 'password', + EMAIL = 'email', + NUMBER = 'number', +} +const MarkdownForm = ({ node }: any) => { + // const supportedTypes = ['text', 'password', 'email', 'number'] + //
+ // + // + // + // + // + // + // + //
+ const { onSend } = useChatContext() + + const getFormValues = (children: any) => { + const formValues: { [key: string]: any } = {} + children.forEach((child: any) => { + if (child.tagName === SUPPORTED_TAGS.INPUT) + formValues[child.properties.name] = child.properties.value + if (child.tagName === SUPPORTED_TAGS.TEXTAREA) + formValues[child.properties.name] = child.properties.value + }) + return formValues + } + const onSubmit = (e: any) => { + e.preventDefault() + const format = node.properties.dataFormat || DATA_FORMAT.TEXT + const result = getFormValues(node.children) + if (format === DATA_FORMAT.JSON) { + onSend?.(JSON.stringify(result)) + } + else { + const textResult = Object.entries(result) + .map(([key, value]) => `${key}: ${value}`) + .join('\n') + onSend?.(textResult) + } + } + return ( +
{ + e.preventDefault() + e.stopPropagation() + }} + > + {node.children.filter((i: any) => i.type === 'element').map((child: any, index: number) => { + if (child.tagName === SUPPORTED_TAGS.LABEL) { + return ( + + ) + } + if (child.tagName === SUPPORTED_TAGS.INPUT) { + if (Object.values(SUPPORTED_TYPES).includes(child.properties.type)) { + return ( + { + e.preventDefault() + child.properties.value = e.target.value + }} + /> + ) + } + else { + return

Unsupported input type: {child.properties.type}

+ } + } + if (child.tagName === SUPPORTED_TAGS.TEXTAREA) { + return ( +