diff --git a/README.md b/README.md index 4ce23356..6f3b4a7c 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,6 @@ TODO Release - feat: nesting inside non root/container components (e.g. image) - fix: scrollbar border radius to high (happens with very long panels) - feat: drag/click threshold -- feat: cli for kits - feat: add apfel components - feat: input - fix: decrease clipping rect when scrollbar present diff --git a/examples/card/.prettierrc b/examples/card/.prettierrc deleted file mode 100644 index fd97e8f1..00000000 --- a/examples/card/.prettierrc +++ /dev/null @@ -1,11 +0,0 @@ -{ - "printWidth": 160, - "tabWidth": 2, - "useTabs": false, - "semi": false, - "singleQuote": false, - "trailingComma": "all", - "bracketSpacing": true, - "jsxBracketSameLine": true, - "fluid": false - } \ No newline at end of file diff --git a/examples/card/src/App.jsx b/examples/card/src/App.jsx index f21c0958..51a3cb38 100644 --- a/examples/card/src/App.jsx +++ b/examples/card/src/App.jsx @@ -1,24 +1,28 @@ -import { Environment, MeshPortalMaterial, PerspectiveCamera } from "@react-three/drei" -import { Canvas, extend, useFrame } from "@react-three/fiber" -import { Root, Container, Text, setPreferredColorScheme, Content } from "@react-three/uikit" -import { BellRing, Check } from "@react-three/uikit-lucide" -import { DefaultColors, colors } from "@/theme" -import { Avatar } from "@/avatar" -import { Button } from "@/button" -import { CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/card" -import { Switch } from "@/switch" -import { useMemo, useRef } from "react" -import { signal } from "@preact/signals-core" -import { geometry, easing } from "maath" -import { Floating, Physical } from "./components/Simulation" +import { Environment, MeshPortalMaterial, PerspectiveCamera } from '@react-three/drei' +import { Canvas, extend, useFrame } from '@react-three/fiber' +import { Root, Container, Text, setPreferredColorScheme, Content } from '@react-three/uikit' +import { BellRing, Check } from '@react-three/uikit-lucide' +import { DefaultColors, colors } from '@/theme' +import { Avatar } from '@/avatar' +import { Button } from '@/button' +import { CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/card' +import { Switch } from '@/switch' +import { useMemo, useRef } from 'react' +import { signal } from '@preact/signals-core' +import { geometry, easing } from 'maath' +import { Floating, Physical } from './components/Simulation' extend(geometry) -setPreferredColorScheme("light") -const notifications = [{ title: "Your call has been confirmed.", description: "1 hour ago" }] +setPreferredColorScheme('light') +const notifications = [{ title: 'Your call has been confirmed.', description: '1 hour ago' }] export default function App() { return ( - + @@ -45,8 +49,8 @@ export function CardPage() { const translateY = useMemo(() => signal(-460), []) const translateZ = useMemo(() => signal(0), []) useFrame((_, delta) => { - easing.damp(translateY, "value", openRef.current ? 0 : -460, 0.2, delta) - easing.damp(translateZ, "value", openRef.current ? 200 : 0, 0.2, delta) + easing.damp(translateY, 'value', openRef.current ? 0 : -460, 0.2, delta) + easing.damp(translateZ, 'value', openRef.current ? 200 : 0, 0.2, delta) }) return ( @@ -58,12 +62,13 @@ export function CardPage() { onClick={(e) => (e.stopPropagation(), (openRef.current = !openRef.current))} cursor="pointer" zIndexOffset={10} - transformTranslateZ={translateZ}> + transformTranslateZ={translateZ} + > - + @@ -80,7 +85,8 @@ export function CardPage() { alignItems="center" justifyContent="space-between" borderRadiusBottom={20} - castShadow> + castShadow + > VanArsdel Marketing @@ -97,7 +103,12 @@ export function CardPage() { - + Notifications @@ -128,8 +139,15 @@ export function CardPage() { paddingBottom={index === notifications.length - 1 ? 0 : 16} alignItems="flex-start" flexDirection="row" - gap={17}> - + gap={17} + > + {notification.title} @@ -143,7 +161,11 @@ export function CardPage() { - diff --git a/examples/card/src/components/Simulation.jsx b/examples/card/src/components/Simulation.jsx index 95289c20..9aa06acc 100644 --- a/examples/card/src/components/Simulation.jsx +++ b/examples/card/src/components/Simulation.jsx @@ -1,35 +1,60 @@ -import * as THREE from "three" -import { useGLTF, Float } from "@react-three/drei" -import { useFrame } from "@react-three/fiber" -import { Physics, RigidBody, BallCollider } from "@react-three/rapier" -import { useMemo, useRef } from "react" +import * as THREE from 'three' +import { useGLTF, Float } from '@react-three/drei' +import { useFrame } from '@react-three/fiber' +import { Physics, RigidBody, BallCollider } from '@react-three/rapier' +import { useMemo, useRef } from 'react' // Shapes by https://app.spline.design/library/a4eeaee4-be03-4df8-ab05-5a073eda2eb4 export function Floating(props) { - const { nodes, materials } = useGLTF("/smileys-transformed.glb") - return ( - - - - - - - - - - - - - - - - - - ) - } + const { nodes, materials } = useGLTF('/smileys-transformed.glb') + return ( + + + + + + + + + + + + + + + + + + ) +} export function Physical() { - const { nodes, materials } = useGLTF("/smileys-transformed.glb") + const { nodes, materials } = useGLTF('/smileys-transformed.glb') const meshes = useMemo(() => Object.values(nodes).filter((node) => node.isMesh), [nodes]) return ( @@ -45,17 +70,24 @@ function RigidShape({ mesh, vec = new THREE.Vector3() }) { const api = useRef() useFrame((state, delta) => { delta = Math.min(0.1, delta) - api.current?.applyImpulse(vec.copy(api.current.translation()).negate().add({ x: 0, y: 2, z: 0 }).multiplyScalar(0.2)) + api.current?.applyImpulse( + vec.copy(api.current.translation()).negate().add({ x: 0, y: 2, z: 0 }).multiplyScalar(0.2), + ) }) return ( + colliders="ball" + > ) @@ -64,11 +96,13 @@ function RigidShape({ mesh, vec = new THREE.Vector3() }) { function Pointer({ vec = new THREE.Vector3() }) { const ref = useRef() useFrame(({ mouse, viewport }) => { - ref.current?.setNextKinematicTranslation(vec.set((mouse.x * viewport.width) / 2, (mouse.y * viewport.height) / 2, 0)) + ref.current?.setNextKinematicTranslation( + vec.set((mouse.x * viewport.width) / 2, (mouse.y * viewport.height) / 2, 0), + ) }) return ( ) -} \ No newline at end of file +} diff --git a/examples/uikit/src/App.tsx b/examples/uikit/src/App.tsx index 34374be8..3503fc75 100644 --- a/examples/uikit/src/App.tsx +++ b/examples/uikit/src/App.tsx @@ -40,6 +40,14 @@ export default function App() { borderRight={0} borderColor="red" > + + + Escribe algo... + + + Escribe algo... + + ', 'components from kit to add') + .option('-p, --path ', 'the path to add the component to.') + .option('-o, --overwrite', 'overwrite existing files.', false) + .option('-c, --cwd ', 'the working directory. defaults to the current directory.', cwd()) + .action(async (c, opts) => { + try { + let [kit, ...components] = kitAndComponentsSchema + .parse(c, { + errorMap: (issue) => { + if (issue.code === 'too_small') { + return { + message: 'Command requires and ', + } + } + return { message: issue.message ?? '' } + }, + }) + .map((s) => s.toLowerCase()) + let { overwrite, path, cwd } = commandOptionsSchema.parse(opts) + + let registry: Awaited> + try { + registry = await getRegistry(kit) + } catch (e) { + throw `Unable to fetch registry for ${kit} kit: ${getErrorString(e)}` + } + + if (path == null) { + path = ( + await prompts({ + type: 'text', + name: 'path', + message: `Configure the path for the ${chalk.cyan('components')}:`, + initial: 'src/components', + }) + ).path as string + } + + const absPath = resolve(cwd, path) + + if (!existsSync(path)) { + await mkdir(absPath, { recursive: true }) + } + + const absThemePath = resolve(path, 'theme.tsx') + if (!existsSync(absThemePath)) { + await download(kit, 'theme.tsx', absThemePath) + } + + const componentsToInstall = new Set() + + for (const component of components) { + componentsToInstall.add(component) + const registryEntry = registry[component] + if (registryEntry == null) { + throw `component ${kit} ${component} is not in the registry` + } + if (registryEntry.registryDependencies == null) { + continue + } + for (const dependency of registryEntry.registryDependencies) { + componentsToInstall.add(dependency) + } + } + + const spinner = ora(`Installing ${kit} components...`).start() + component: for (const component of componentsToInstall) { + try { + spinner.text = `Installing ${kit} ${component}...` + const registryEntry = registry[component] + if (registryEntry == null) { + throw `component not in registry` + } + const files = registryEntry.files + + if (!overwrite) { + for (const file of files) { + const absFilePath = resolve(absPath, file) + if (existsSync(absFilePath)) { + spinner.stop() + const { overwrite } = await prompts({ + type: 'confirm', + name: 'overwrite', + message: `Component ${component} already exists. Would you like to overwrite?`, + initial: false, + }) + + if (overwrite === false) { + console.log(chalk.cyan(`Installing ${kit} ${component} was skipped to prevent overwriting ${file}.`)) + continue component + } + + spinner.start(`Installing ${kit} ${component}...`) + } + } + } + for (const file of files) { + const absFilePath = resolve(absPath, file) + download(kit, file, absFilePath) + } + } catch (e) { + throw `Unable to install ${kit} ${component}: ${getErrorString(e)}` + } + } + spinner.succeed(`Done.`) + } catch (e) { + console.log(chalk.red(getErrorString(e))) + process.exit(1) + } + }) + +async function download(kit: string, file: string, targetAbsolutePath: string) { + const response = await fetch(`${BASE_URL}${kit}/${file}`) + if (response.body == null) { + throw new Error(`Invalid response when downloading ${file} from registry: ${response.statusText}`) + } + const stream = createWriteStream(targetAbsolutePath) + await finished(Readable.fromWeb(response.body as any).pipe(stream)) +} + +function getErrorString(error: any): string { + if (typeof error === 'string') { + return error + } else if (error instanceof ZodError) { + return error.format()._errors.join('\n') + } else if (error instanceof Error) { + return error.message + } + return 'Something went wrong. Please try again.' +} + +const registrySchema = z.record( + z.string(), + z.object({ + files: z.array(z.string()), + registryDependencies: z.array(z.string()).optional(), + }), +) + +async function getRegistry(kit: string) { + const data = await (await fetch(`${BASE_URL}${kit}/registry.json`)).json() + return registrySchema.parse(data) +} diff --git a/packages/uikit/src/cli/component/index.ts b/packages/uikit/src/cli/component/index.ts new file mode 100644 index 00000000..a9b845f9 --- /dev/null +++ b/packages/uikit/src/cli/component/index.ts @@ -0,0 +1,4 @@ +import { Command } from 'commander' +import { add } from './add.js' + +export const component = new Command('component').description(`add components to your project`).addCommand(add) diff --git a/packages/uikit/src/cli/index.ts b/packages/uikit/src/cli/index.ts new file mode 100644 index 00000000..c7521e50 --- /dev/null +++ b/packages/uikit/src/cli/index.ts @@ -0,0 +1,14 @@ +#!/usr/bin/env node +import { Command } from 'commander' +import { component } from './component/index.js' + +process.on('SIGINT', () => process.exit(0)) +process.on('SIGTERM', () => process.exit(0)) + +async function main() { + const program = new Command().name('uikit').description('cli for uikit') + program.addCommand(component) + program.parse() +} + +main() diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 35a64e7e..78d7b51f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -350,9 +350,24 @@ importers: base64-js: specifier: ^1.5.1 version: 1.5.1 + chalk: + specifier: ^5.3.0 + version: 5.3.0 + commander: + specifier: ^12.0.0 + version: 12.0.0 + ora: + specifier: ^8.0.1 + version: 8.0.1 + prompts: + specifier: ^2.4.2 + version: 2.4.2 yoga-wasm-web: specifier: ^0.3.3 version: 0.3.3 + zod: + specifier: ^3.22.4 + version: 3.22.4 devDependencies: '@react-three/drei': specifier: ^9.96.1 @@ -363,6 +378,9 @@ importers: '@types/node': specifier: ^20.11.0 version: 20.11.0 + '@types/prompts': + specifier: ^2.4.9 + version: 2.4.9 '@types/react': specifier: ^18.2.47 version: 18.2.47 @@ -2400,6 +2418,13 @@ packages: /@types/offscreencanvas@2019.7.3: resolution: {integrity: sha512-ieXiYmgSRXUDeOntE1InxjWyvEelZGP63M+cGuquuRLuIKKT1osnkXjxev9B7d1nXSug5vpunx+gNlbVxMlC9A==} + /@types/prompts@2.4.9: + resolution: {integrity: sha512-qTxFi6Buiu8+50/+3DGIWLHM6QuWsEKugJnnP6iv2Mc4ncxE4A/OJkjuVOA+5X0X1S/nq5VJRa8Lu+nwcvbrKA==} + dependencies: + '@types/node': 20.11.0 + kleur: 3.0.3 + dev: true + /@types/prop-types@15.7.11: resolution: {integrity: sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==} @@ -2742,6 +2767,11 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} + /ansi-regex@6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + dev: false + /ansi-styles@3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} engines: {node: '>=4'} @@ -3144,6 +3174,11 @@ packages: ansi-styles: 4.3.0 supports-color: 7.2.0 + /chalk@5.3.0: + resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + dev: false + /check-error@1.0.3: resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} dependencies: @@ -3189,12 +3224,24 @@ packages: engines: {node: '>=6'} dev: false + /cli-cursor@4.0.0: + resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + restore-cursor: 4.0.0 + dev: false + /cli-progress@3.12.0: resolution: {integrity: sha512-tRkV3HJ1ASwm19THiiLIXLO7Im7wlTuKnvkYaTkyoAPefqjNg7W7DHKUlGRxy9vxDvbyCYQkQozvptuMkGCg8A==} engines: {node: '>=4'} dependencies: string-width: 4.2.3 + /cli-spinners@2.9.2: + resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} + engines: {node: '>=6'} + dev: false + /cliui@6.0.0: resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} dependencies: @@ -3267,6 +3314,11 @@ packages: delayed-stream: 1.0.0 dev: false + /commander@12.0.0: + resolution: {integrity: sha512-MwVNWlYjDTtOjX5PiD7o5pK0UrFU/OYgcJfjjK4RaHZETNtjJqrZa9Y9ds88+A+f+d5lv+561eZ+yCKoS3gbAA==} + engines: {node: '>=18'} + dev: false + /commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} dev: false @@ -3500,6 +3552,10 @@ packages: resolution: {integrity: sha512-4nToZ5jlPO14W82NkF32wyjhYqQByVaDmLy4J2/tYcAbJfgO2TKJC780Az1V13gzq4l73CJ0yuyalpXvxXXD9A==} dev: true + /emoji-regex@10.3.0: + resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==} + dev: false + /emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -4132,6 +4188,11 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} + /get-east-asian-width@1.2.0: + resolution: {integrity: sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==} + engines: {node: '>=18'} + dev: false + /get-func-name@2.0.2: resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} dev: true @@ -4568,6 +4629,11 @@ packages: is-path-inside: 3.0.3 dev: false + /is-interactive@2.0.0: + resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==} + engines: {node: '>=12'} + dev: false + /is-invalid-path@1.0.2: resolution: {integrity: sha512-6KLcFrPCEP3AFXMfnWrIFkZpYNBVzZAoBJJDEZKtI3LXkaDjM3uFMJQjxiizUuZTZ9Oh9FNv/soXbx5TcpaDmA==} engines: {node: '>=6.0'} @@ -4665,6 +4731,16 @@ packages: engines: {node: '>=10'} dev: true + /is-unicode-supported@1.3.0: + resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} + engines: {node: '>=12'} + dev: false + + /is-unicode-supported@2.0.0: + resolution: {integrity: sha512-FRdAyx5lusK1iHG0TWpVtk9+1i+GjrzRffhDg4ovQ7mcidMQ6mj+MhKPmvh7Xwyv5gIS06ns49CA7Sqg7lC22Q==} + engines: {node: '>=18'} + dev: false + /is-weakmap@2.0.1: resolution: {integrity: sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==} dev: true @@ -4827,6 +4903,10 @@ packages: engines: {node: '>=0.10.0'} dev: true + /kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + /ktx-parse@0.4.5: resolution: {integrity: sha512-MK3FOody4TXbFf8Yqv7EBbySw7aPvEcPX++Ipt6Sox+/YMFvR5xaTyhfNSk1AEmMy+RYIw81ctN4IMxCB8OAlg==} dev: false @@ -4901,6 +4981,14 @@ packages: is-unicode-supported: 0.1.0 dev: true + /log-symbols@6.0.0: + resolution: {integrity: sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==} + engines: {node: '>=18'} + dependencies: + chalk: 5.3.0 + is-unicode-supported: 1.3.0 + dev: false + /loose-envify@1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true @@ -5055,6 +5143,11 @@ packages: engines: {node: '>=4'} hasBin: true + /mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + dev: false + /mimic-response@1.0.1: resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} engines: {node: '>=4'} @@ -5357,6 +5450,13 @@ packages: dependencies: wrappy: 1.0.2 + /onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + dependencies: + mimic-fn: 2.1.0 + dev: false + /opentype.js@0.11.0: resolution: {integrity: sha512-Z9NkAyQi/iEKQYzCSa7/VJSqVIs33wknw8Z8po+DzuRUAqivJ+hJZ94mveg3xIeKwLreJdWTMyEO7x1K13l41Q==} hasBin: true @@ -5386,6 +5486,21 @@ packages: type-check: 0.4.0 dev: true + /ora@8.0.1: + resolution: {integrity: sha512-ANIvzobt1rls2BDny5fWZ3ZVKyD6nscLvfFRpQgfWsythlcsVUC9kL0zq6j2Z5z9wwp1kd7wpsD/T9qNPVLCaQ==} + engines: {node: '>=18'} + dependencies: + chalk: 5.3.0 + cli-cursor: 4.0.0 + cli-spinners: 2.9.2 + is-interactive: 2.0.0 + is-unicode-supported: 2.0.0 + log-symbols: 6.0.0 + stdin-discarder: 0.2.2 + string-width: 7.1.0 + strip-ansi: 7.1.0 + dev: false + /oslllo-potrace@2.0.1: resolution: {integrity: sha512-XDsVIUfwXnylngcbecF/6gBHdtFgEnqDt0a9WKqXIo/jPe2AkZkmi6bNaNb9OwlAgoIjy0b1Hi6odPEqztPszg==} dependencies: @@ -5637,6 +5752,14 @@ packages: 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'} + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + dev: false + /prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} dependencies: @@ -5931,6 +6054,14 @@ packages: lowercase-keys: 1.0.1 dev: false + /restore-cursor@4.0.0: + resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + dev: false + /reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -6129,6 +6260,10 @@ packages: is-arrayish: 0.3.2 dev: false + /sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + dev: false + /slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} @@ -6180,6 +6315,11 @@ packages: /stats.js@0.17.0: resolution: {integrity: sha512-hNKz8phvYLPEcRkeG1rsGmV5ChMjKDAWU7/OJJdDErPBNChQXxCo3WZurGpnWc6gZhAzEPFad1aVgyOANH1sMw==} + /stdin-discarder@0.2.2: + resolution: {integrity: sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==} + engines: {node: '>=18'} + dev: false + /streamx@2.16.1: resolution: {integrity: sha512-m9QYj6WygWyWa3H1YY69amr4nVgy61xfjys7xO7kviL5rfIEc2naf+ewFiOA+aEJD7y0JO3h2GoiUv4TDwEGzQ==} dependencies: @@ -6197,6 +6337,15 @@ packages: is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 + /string-width@7.1.0: + resolution: {integrity: sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==} + engines: {node: '>=18'} + dependencies: + emoji-regex: 10.3.0 + get-east-asian-width: 1.2.0 + strip-ansi: 7.1.0 + dev: false + /string.prototype.codepointat@0.2.1: resolution: {integrity: sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==} dev: false @@ -6251,6 +6400,13 @@ packages: dependencies: ansi-regex: 5.0.1 + /strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + dependencies: + ansi-regex: 6.0.1 + dev: false + /strip-bom@3.0.0: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} @@ -7056,6 +7212,10 @@ packages: resolution: {integrity: sha512-N+d4UJSJbt/R3wqY7Coqs5pcV0aUj2j9IaQ3rNj9bVCLld8tTGKRa2USARjnvZJWVx1NDmQev8EknoczaOQDOA==} dev: false + /zod@3.22.4: + resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} + dev: false + /zstddec@0.0.2: resolution: {integrity: sha512-DCo0oxvcvOTGP/f5FA6tz2Z6wF+FIcEApSTu0zV5sQgn9hoT5lZ9YRAKUraxt9oP7l4e8TnNdi8IZTCX6WCkwA==} dev: false