├── web ├── README.md ├── .eslintrc.json ├── .prettierrc ├── src │ ├── app │ │ ├── favicon.ico │ │ ├── twitter-image.png │ │ ├── opengraph-image.png │ │ ├── globals.css │ │ ├── layout.tsx │ │ ├── SpringEditor.tsx │ │ └── page.tsx │ ├── lib │ │ └── utils.ts │ └── components │ │ ├── ui │ │ ├── theme-provider.tsx │ │ ├── button.tsx │ │ └── select.tsx │ │ └── CopyButton.tsx ├── next.config.mjs ├── postcss.config.mjs ├── components.json ├── .gitignore ├── tsconfig.json ├── package.json ├── public │ └── spring.svg └── tailwind.config.ts ├── .gitignore ├── .npmignore ├── src ├── theme.js ├── index.js └── spring.js ├── tests ├── utils.js └── index.test.js ├── package.json ├── LICENSE ├── README.md └── pnpm-lock.yaml /web/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | tests/* 2 | web/* 3 | web/README.md -------------------------------------------------------------------------------- /web/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /web/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["prettier-plugin-tailwindcss"] 3 | } 4 | -------------------------------------------------------------------------------- /web/src/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinGrajeda/tailwindcss-spring/HEAD/web/src/app/favicon.ico -------------------------------------------------------------------------------- /web/next.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = {}; 3 | 4 | export default nextConfig; 5 | -------------------------------------------------------------------------------- /web/src/app/twitter-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinGrajeda/tailwindcss-spring/HEAD/web/src/app/twitter-image.png -------------------------------------------------------------------------------- /web/src/app/opengraph-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KevinGrajeda/tailwindcss-spring/HEAD/web/src/app/opengraph-image.png -------------------------------------------------------------------------------- /web/postcss.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('postcss-load-config').Config} */ 2 | const config = { 3 | plugins: { 4 | tailwindcss: {}, 5 | }, 6 | }; 7 | 8 | export default config; 9 | -------------------------------------------------------------------------------- /web/src/lib/utils.ts: -------------------------------------------------------------------------------- 1 | import { type ClassValue, clsx } from "clsx" 2 | import { twMerge } from "tailwind-merge" 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)) 6 | } 7 | -------------------------------------------------------------------------------- /web/src/components/ui/theme-provider.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import * as React from "react"; 4 | import { ThemeProvider as NextThemesProvider } from "next-themes"; 5 | import { type ThemeProviderProps } from "next-themes/dist/types"; 6 | 7 | export function ThemeProvider({ children, ...props }: ThemeProviderProps) { 8 | return {children}; 9 | } 10 | -------------------------------------------------------------------------------- /web/components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "default", 4 | "rsc": true, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "tailwind.config.ts", 8 | "css": "src/app/globals.css", 9 | "baseColor": "neutral", 10 | "cssVariables": true, 11 | "prefix": "" 12 | }, 13 | "aliases": { 14 | "components": "@/components", 15 | "utils": "@/lib/utils" 16 | } 17 | } -------------------------------------------------------------------------------- /src/theme.js: -------------------------------------------------------------------------------- 1 | export default { 2 | bounceValues: { 3 | 0: "0", 4 | 10: "10", 5 | 20: "20", 6 | 30: "30", 7 | 40: "40", 8 | 50: "50", 9 | 60: "60", 10 | 70: "70", 11 | 80: "80", 12 | }, 13 | perceptualDurationValues: { 14 | 75: "75", 15 | 100: "100", 16 | 150: "150", 17 | 200: "200", 18 | 300: "300", 19 | 500: "500", 20 | 700: "700", 21 | 1000: "1000", 22 | }, 23 | }; 24 | -------------------------------------------------------------------------------- /web/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | .yarn/install-state.gz 8 | 9 | # testing 10 | /coverage 11 | 12 | # next.js 13 | /.next/ 14 | /out/ 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | -------------------------------------------------------------------------------- /tests/utils.js: -------------------------------------------------------------------------------- 1 | import tailwindcss from "tailwindcss"; 2 | import postcss from "postcss"; 3 | import minify from "@csstools/postcss-minify"; 4 | import springPlugin from "../src/index.js"; 5 | 6 | const TAILWIND_BASE = "@tailwind utilities;"; 7 | 8 | export function generatePluginCSS(options = {}) { 9 | const { inline = "", content = "" } = options; 10 | 11 | return postcss([ 12 | minify(), 13 | tailwindcss({ 14 | plugins: [springPlugin], 15 | content: [{ raw: content }], 16 | }), 17 | ]) 18 | .process(`${TAILWIND_BASE} ${inline}`, { 19 | from: undefined, 20 | }) 21 | .then((result) => result.css); 22 | } 23 | -------------------------------------------------------------------------------- /web/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": ["dom", "dom.iterable", "esnext"], 4 | "allowJs": true, 5 | "skipLibCheck": true, 6 | "strict": true, 7 | "noEmit": true, 8 | "esModuleInterop": true, 9 | "module": "esnext", 10 | "moduleResolution": "bundler", 11 | "resolveJsonModule": true, 12 | "isolatedModules": true, 13 | "jsx": "preserve", 14 | "incremental": true, 15 | "plugins": [ 16 | { 17 | "name": "next" 18 | } 19 | ], 20 | "paths": { 21 | "@/*": ["./src/*"] 22 | } 23 | }, 24 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 25 | "exclude": ["node_modules"] 26 | } 27 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tailwindcss-spring", 3 | "version": "1.0.1", 4 | "description": "A Tailwind CSS plugin that adds spring animations to your project using CSS linear(). Define just two parameters and let the plugin generate the easing curve and the animation duration.", 5 | "license": "MIT", 6 | "main": "./src/index.js", 7 | "type": "module", 8 | "homepage": "https://tailwindcss-spring.kvin.me/", 9 | "repository": "https://github.com/KevinGrajeda/tailwindcss-spring", 10 | "scripts": { 11 | "test": "vitest" 12 | }, 13 | "keywords": [ 14 | "tailwindcss", 15 | "tailwind", 16 | "spring", 17 | "animation", 18 | "transition", 19 | "plugin", 20 | "linear()", 21 | "bounce" 22 | ], 23 | "author": "Kevin Grajeda ", 24 | "devDependencies": { 25 | "@csstools/postcss-minify": "^1.1.5", 26 | "postcss": "^8.4.40", 27 | "tailwindcss": "3.4.7", 28 | "vitest": "^2.0.5" 29 | }, 30 | "peerDependencies": { 31 | "tailwindcss": ">=3.0.0 || insiders" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "web", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "@radix-ui/react-select": "^2.1.1", 13 | "@radix-ui/react-slot": "^1.1.0", 14 | "class-variance-authority": "^0.7.0", 15 | "clsx": "^2.1.1", 16 | "lucide-react": "^0.427.0", 17 | "next": "14.2.5", 18 | "next-themes": "^0.3.0", 19 | "react": "^18", 20 | "react-dom": "^18", 21 | "tailwind-merge": "^2.5.2", 22 | "tailwindcss-animate": "^1.0.7", 23 | "tailwindcss-spring": "^1.0.0" 24 | }, 25 | "devDependencies": { 26 | "@types/node": "^20", 27 | "@types/react": "^18", 28 | "@types/react-dom": "^18", 29 | "eslint": "^8", 30 | "eslint-config-next": "14.2.5", 31 | "postcss": "^8", 32 | "prettier": "^3.3.3", 33 | "prettier-plugin-tailwindcss": "^0.6.5", 34 | "tailwindcss": "^3.4.1", 35 | "typescript": "^5" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /web/public/spring.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import createPlugin from "tailwindcss/plugin"; 2 | import theme from "./theme"; 3 | import { generateEase } from "./spring"; 4 | 5 | /** @type {import('tailwindcss/types/config').PluginCreator} */ 6 | const pluginCreator = (api) => { 7 | api.matchUtilities( 8 | { 9 | "spring-bounce": (value) => { 10 | const { durationMultiplier, ease } = generateEase(value); 11 | return { 12 | transitionTimingFunction: ease, 13 | "--tw-ease-duration-multiplier": `${durationMultiplier}`, 14 | }; 15 | }, 16 | }, 17 | { values: api.theme("bounceValues") } 18 | ); 19 | api.matchUtilities( 20 | { 21 | "spring-duration": (value) => { 22 | return { 23 | transitionDuration: `calc(var(--tw-ease-duration-multiplier) * ${value}ms)`, 24 | }; 25 | }, 26 | }, 27 | { 28 | values: api.theme("perceptualDurationValues"), 29 | } 30 | ); 31 | }; 32 | 33 | /** @type {import('tailwindcss/types/config').Config}*/ 34 | const pluginConfig = { 35 | theme, 36 | }; 37 | 38 | export default createPlugin(pluginCreator, pluginConfig); 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Kevin Grajeda 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /web/src/components/CopyButton.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { useState } from "react"; 4 | import { Button } from "./ui/button"; 5 | import { ClipboardCheckIcon, ClipboardIcon } from "lucide-react"; 6 | import { cn } from "@/lib/utils"; 7 | 8 | export default function CopyButton({ text }: { text: string }) { 9 | const [copied, setCopied] = useState(false); 10 | return ( 11 | 37 | ); 38 | } 39 | -------------------------------------------------------------------------------- /web/src/app/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | @layer base { 6 | :root { 7 | --background: 0 0% 100%; 8 | --foreground: 0 0% 3.9%; 9 | --card: 0 0% 100%; 10 | --card-foreground: 0 0% 3.9%; 11 | --popover: 0 0% 100%; 12 | --popover-foreground: 0 0% 3.9%; 13 | --primary: 0 0% 9%; 14 | --primary-foreground: 0 0% 98%; 15 | --secondary: 0 0% 96.1%; 16 | --secondary-foreground: 0 0% 9%; 17 | --muted: 0 0% 96.1%; 18 | --muted-foreground: 0 0% 45.1%; 19 | --accent: 0 0% 96.1%; 20 | --accent-foreground: 0 0% 9%; 21 | --destructive: 0 84.2% 60.2%; 22 | --destructive-foreground: 0 0% 98%; 23 | --border: 0 0% 89.8%; 24 | --input: 0 0% 89.8%; 25 | --ring: 0 0% 3.9%; 26 | --radius: 0.5rem; 27 | --chart-1: 12 76% 61%; 28 | --chart-2: 173 58% 39%; 29 | --chart-3: 197 37% 24%; 30 | --chart-4: 43 74% 66%; 31 | --chart-5: 27 87% 67%; 32 | } 33 | 34 | .dark { 35 | --background: 0 0% 3.9%; 36 | --foreground: 0 0% 98%; 37 | --card: 0 0% 3.9%; 38 | --card-foreground: 0 0% 98%; 39 | --popover: 0 0% 3.9%; 40 | --popover-foreground: 0 0% 98%; 41 | --primary: 0 0% 98%; 42 | --primary-foreground: 0 0% 9%; 43 | --secondary: 0 0% 14.9%; 44 | --secondary-foreground: 0 0% 98%; 45 | --muted: 0 0% 14.9%; 46 | --muted-foreground: 0 0% 63.9%; 47 | --accent: 0 0% 14.9%; 48 | --accent-foreground: 0 0% 98%; 49 | --destructive: 0 62.8% 30.6%; 50 | --destructive-foreground: 0 0% 98%; 51 | --border: 0 0% 14.9%; 52 | --input: 0 0% 14.9%; 53 | --ring: 0 0% 83.1%; 54 | --chart-1: 220 70% 50%; 55 | --chart-2: 160 60% 45%; 56 | --chart-3: 30 80% 55%; 57 | --chart-4: 280 65% 60%; 58 | --chart-5: 340 75% 55%; 59 | } 60 | } 61 | 62 | @layer base { 63 | * { 64 | @apply border-border; 65 | } 66 | body { 67 | @apply bg-background text-foreground; 68 | } 69 | } -------------------------------------------------------------------------------- /web/src/app/layout.tsx: -------------------------------------------------------------------------------- 1 | import type { Metadata } from "next"; 2 | import { Inter } from "next/font/google"; 3 | import "./globals.css"; 4 | import { ThemeProvider } from "@/components/ui/theme-provider"; 5 | import { cn } from "@/lib/utils"; 6 | 7 | const inter = Inter({ subsets: ["latin"] }); 8 | 9 | export const metadata: Metadata = { 10 | title: "tailwindcss-spring", 11 | description: 12 | "A Tailwind CSS plugin that adds spring animations to your project using CSS linear(). Define just two parameters and let the plugin generate the easing curve and the animation duration.", 13 | keywords: [ 14 | "tailwindcss", 15 | "tailwind", 16 | "spring", 17 | "animation", 18 | "plugin", 19 | "bounce", 20 | "linear()", 21 | "easing", 22 | "curve", 23 | "CSS", 24 | ], 25 | twitter: { 26 | title: "tailwindcss-spring", 27 | description: 28 | "A Tailwind CSS plugin that adds spring animations to your project using CSS linear(). Define just two parameters and let the plugin generate the easing curve and the animation duration.", 29 | card: "summary_large_image", 30 | }, 31 | authors: [{ name: "Kevin Grajeda", url: "https://x.com/k_grajeda" }], 32 | }; 33 | 34 | export default function RootLayout({ 35 | children, 36 | }: Readonly<{ 37 | children: React.ReactNode; 38 | }>) { 39 | return ( 40 | 41 | 47 | 53 | {children} 54 | 55 | 60 | 61 | 62 | ); 63 | } 64 | -------------------------------------------------------------------------------- /web/src/components/ui/button.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import { Slot } from "@radix-ui/react-slot" 3 | import { cva, type VariantProps } from "class-variance-authority" 4 | 5 | import { cn } from "@/lib/utils" 6 | 7 | const buttonVariants = cva( 8 | "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50", 9 | { 10 | variants: { 11 | variant: { 12 | default: "bg-primary text-primary-foreground hover:bg-primary/90", 13 | destructive: 14 | "bg-destructive text-destructive-foreground hover:bg-destructive/90", 15 | outline: 16 | "border border-input bg-background hover:bg-accent hover:text-accent-foreground", 17 | secondary: 18 | "bg-secondary text-secondary-foreground hover:bg-secondary/80", 19 | ghost: "hover:bg-accent hover:text-accent-foreground", 20 | link: "text-primary underline-offset-4 hover:underline", 21 | }, 22 | size: { 23 | default: "h-10 px-4 py-2", 24 | sm: "h-9 rounded-md px-3", 25 | lg: "h-11 rounded-md px-8", 26 | icon: "h-10 w-10", 27 | }, 28 | }, 29 | defaultVariants: { 30 | variant: "default", 31 | size: "default", 32 | }, 33 | } 34 | ) 35 | 36 | export interface ButtonProps 37 | extends React.ButtonHTMLAttributes, 38 | VariantProps { 39 | asChild?: boolean 40 | } 41 | 42 | const Button = React.forwardRef( 43 | ({ className, variant, size, asChild = false, ...props }, ref) => { 44 | const Comp = asChild ? Slot : "button" 45 | return ( 46 | 51 | ) 52 | } 53 | ) 54 | Button.displayName = "Button" 55 | 56 | export { Button, buttonVariants } 57 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tailwindcss-spring 2 | 3 | A Tailwind CSS plugin that adds spring animations to your project using CSS linear(). 4 | Define just two parameters and let the plugin generate the easing curve and the animation duration. 5 | 6 | Check out the the plugin in action on [this website](https://tailwindcss-spring.kvin.me/). 7 | 8 | ## Parameters 9 | 10 | - `spring-bounce-*` 11 | - `spring-duration-*` 12 | 13 | Example: 14 | 15 | ```html 16 |
`spring-bounce-${key}`), ...Object.keys(theme.perceptualDurationValues).map((key) => `spring-duration-${key}`),"dark"] 5 | 6 | const config = { 7 | darkMode: ["class"], 8 | content: [ 9 | './pages/**/*.{ts,tsx}', 10 | './components/**/*.{ts,tsx}', 11 | './app/**/*.{ts,tsx}', 12 | './src/**/*.{ts,tsx}', 13 | ], 14 | prefix: "", 15 | theme: { 16 | container: { 17 | center: true, 18 | padding: "2rem", 19 | screens: { 20 | "2xl": "1400px", 21 | }, 22 | }, 23 | extend: { 24 | colors: { 25 | border: "hsl(var(--border))", 26 | input: "hsl(var(--input))", 27 | ring: "hsl(var(--ring))", 28 | background: "hsl(var(--background))", 29 | foreground: "hsl(var(--foreground))", 30 | primary: { 31 | DEFAULT: "hsl(var(--primary))", 32 | foreground: "hsl(var(--primary-foreground))", 33 | }, 34 | secondary: { 35 | DEFAULT: "hsl(var(--secondary))", 36 | foreground: "hsl(var(--secondary-foreground))", 37 | }, 38 | destructive: { 39 | DEFAULT: "hsl(var(--destructive))", 40 | foreground: "hsl(var(--destructive-foreground))", 41 | }, 42 | muted: { 43 | DEFAULT: "hsl(var(--muted))", 44 | foreground: "hsl(var(--muted-foreground))", 45 | }, 46 | accent: { 47 | DEFAULT: "hsl(var(--accent))", 48 | foreground: "hsl(var(--accent-foreground))", 49 | }, 50 | popover: { 51 | DEFAULT: "hsl(var(--popover))", 52 | foreground: "hsl(var(--popover-foreground))", 53 | }, 54 | card: { 55 | DEFAULT: "hsl(var(--card))", 56 | foreground: "hsl(var(--card-foreground))", 57 | }, 58 | }, 59 | borderRadius: { 60 | lg: "var(--radius)", 61 | md: "calc(var(--radius) - 2px)", 62 | sm: "calc(var(--radius) - 4px)", 63 | }, 64 | keyframes: { 65 | "accordion-down": { 66 | from: { height: "0" }, 67 | to: { height: "var(--radix-accordion-content-height)" }, 68 | }, 69 | "accordion-up": { 70 | from: { height: "var(--radix-accordion-content-height)" }, 71 | to: { height: "0" }, 72 | }, 73 | }, 74 | animation: { 75 | "accordion-down": "accordion-down 0.2s ease-out", 76 | "accordion-up": "accordion-up 0.2s ease-out", 77 | }, 78 | }, 79 | }, 80 | plugins: [require("tailwindcss-animate"),require("tailwindcss-spring")], 81 | safelist 82 | } satisfies Config 83 | 84 | export default config -------------------------------------------------------------------------------- /tests/index.test.js: -------------------------------------------------------------------------------- 1 | import { it, describe, expect } from "vitest"; 2 | import { generatePluginCSS } from "./utils"; 3 | 4 | describe("tailwind-spring", () => { 5 | it("generates correct easing curve", async () => { 6 | const css = await generatePluginCSS({ 7 | content: '
Hello
', 8 | }); 9 | 10 | expect(css).toMatch( 11 | ".spring-bounce-0{transition-timing-function:linear(0, 0.001 0.44%, 0.0045 0.94%, 0.0195 2.03%, 0.0446 3.19%, 0.0811 4.5%, 0.1598 6.82%, 0.3685 12.34%, 0.4693 15.17%, 0.5663, 0.6498 21.27%, 0.7215 24.39%, 0.7532 25.98%, 0.7829 27.65%, 0.8105, 0.8349 31.14%, 0.8573 32.95%, 0.8776 34.84%, 0.8964 36.87%, 0.9136 39.05%, 0.929 41.37%, 0.9421 43.77%, 0.9537 46.38%, 0.9636 49.14%, 0.9789 55.31%, 0.9888 62.35%, 0.9949 71.06%, 0.9982 82.52%, 0.9997 99.94%);--tw-ease-duration-multiplier:1.66}" 12 | ); 13 | }); 14 | 15 | it("generates correct arbitrary easing curve", async () => { 16 | const css = await generatePluginCSS({ 17 | content: '
Hello
', 18 | }); 19 | expect(css).toMatch( 20 | ".spring-bounce-\\[77\\]{transition-timing-function:linear(0, 0.0032, 0.0127, 0.0288, 0.0508, 0.0793, 0.1153 1.52%, 0.2063 2.08%, 0.2995 2.56%, 0.4145 3.09%, 0.8473 4.9%, 1.0091, 1.1523 6.33%, 1.2651 6.99%, 1.3121, 1.3534, 1.3881, 1.4169, 1.44, 1.4573, 1.4689, 1.475 9.53%, 1.4758, 1.4733, 1.4673, 1.458, 1.4452, 1.4289 11.12%, 1.3848 11.71%, 1.3401 12.21%, 1.283 12.77%, 1.0708 14.64%, 0.9925, 0.9241 16.09%, 0.87 16.76%, 0.83, 0.8009 18%, 0.7905, 0.7825, 0.777, 0.774 19.23%, 0.7746, 0.7818 20.28%, 0.7955 20.83%, 0.8164 21.42%, 0.8379 21.93%, 0.8651 22.48%, 0.9665 24.37%, 1.0037, 1.0362 25.81%, 1.062 26.49%, 1.0808, 1.0945, 1.1034, 1.1075 28.94%, 1.1073 29.45%, 1.104 29.99%, 1.0974 30.55%, 1.0875 31.14%, 1.0642 32.21%, 0.9982 34.82%, 0.9827 35.54%, 0.9706 36.2%, 0.9617, 0.9552, 0.9509, 0.9489 38.62%, 0.9504 39.68%, 0.9582 40.84%, 0.9693 41.92%, 1.0009 44.55%, 1.014 45.93%, 1.0213, 1.0243 48.3%, 1.0239 49.24%, 1.0212 50.24%, 0.995 55.23%, 0.9904 56.61%, 0.9885 57.96%, 0.9899 59.95%, 1.0023 64.92%, 1.0055 67.63%, 1.0048 69.7%, 0.999 74.57%, 0.9974 77.17%, 1.0012 86.83%, 0.9996 100%);--tw-ease-duration-multiplier:5.285}" 21 | ); 22 | }); 23 | 24 | it("generates correct duration", async () => { 25 | const css = await generatePluginCSS({ 26 | content: '
Hello
', 27 | }); 28 | 29 | expect(css).toMatch( 30 | ".spring-duration-100{transition-duration:calc(var(--tw-ease-duration-multiplier) * 100ms)}" 31 | ); 32 | }); 33 | 34 | it("generates correct arbitrary duration", async () => { 35 | const css = await generatePluginCSS({ 36 | content: '
Hello
', 37 | }); 38 | 39 | expect(css).toMatch( 40 | ".spring-duration-\\[77\\]{transition-duration:calc(var(--tw-ease-duration-multiplier) * 77ms)}" 41 | ); 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /web/src/app/SpringEditor.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | import { 3 | Select, 4 | SelectContent, 5 | SelectGroup, 6 | SelectItem, 7 | SelectTrigger, 8 | SelectValue, 9 | } from "@/components/ui/select"; 10 | import { useState } from "react"; 11 | import theme from "../../../src/theme"; 12 | import { cn } from "@/lib/utils"; 13 | import CopyButton from "@/components/CopyButton"; 14 | 15 | export default function SpringEditor() { 16 | const [bounce, setBounce] = useState("60"); 17 | const [perceptualDuration, setPerceptualDuration] = useState("300"); 18 | 19 | return ( 20 | <> 21 |
22 |
23 |
24 | 25 | 26 | 48 |
49 |
50 | 51 | 78 |
79 |
80 |
81 | 90 | 105 |
106 |
107 |
108 | 109 | 112 | {`spring-bounce-${bounce} spring-duration-${perceptualDuration}`} 113 | 114 |
115 | 116 | ); 117 | } 118 | -------------------------------------------------------------------------------- /web/src/components/ui/select.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import * as React from "react"; 4 | import * as SelectPrimitive from "@radix-ui/react-select"; 5 | import { Check, ChevronDown, ChevronUp } from "lucide-react"; 6 | 7 | import { cn } from "@/lib/utils"; 8 | 9 | const Select = SelectPrimitive.Root; 10 | 11 | const SelectGroup = SelectPrimitive.Group; 12 | 13 | const SelectValue = SelectPrimitive.Value; 14 | 15 | const SelectTrigger = React.forwardRef< 16 | React.ElementRef, 17 | React.ComponentPropsWithoutRef 18 | >(({ className, children, ...props }, ref) => ( 19 | span]:line-clamp-1", 23 | className, 24 | )} 25 | {...props} 26 | > 27 | {children} 28 | 29 | 30 | 31 | 32 | )); 33 | SelectTrigger.displayName = SelectPrimitive.Trigger.displayName; 34 | 35 | const SelectScrollUpButton = React.forwardRef< 36 | React.ElementRef, 37 | React.ComponentPropsWithoutRef 38 | >(({ className, ...props }, ref) => ( 39 | 47 | 48 | 49 | )); 50 | SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName; 51 | 52 | const SelectScrollDownButton = React.forwardRef< 53 | React.ElementRef, 54 | React.ComponentPropsWithoutRef 55 | >(({ className, ...props }, ref) => ( 56 | 64 | 65 | 66 | )); 67 | SelectScrollDownButton.displayName = 68 | SelectPrimitive.ScrollDownButton.displayName; 69 | 70 | const SelectContent = React.forwardRef< 71 | React.ElementRef, 72 | React.ComponentPropsWithoutRef 73 | >(({ className, children, position = "popper", ...props }, ref) => ( 74 | 75 | 86 | 87 | 94 | {children} 95 | 96 | 97 | 98 | 99 | )); 100 | SelectContent.displayName = SelectPrimitive.Content.displayName; 101 | 102 | const SelectLabel = React.forwardRef< 103 | React.ElementRef, 104 | React.ComponentPropsWithoutRef 105 | >(({ className, ...props }, ref) => ( 106 | 111 | )); 112 | SelectLabel.displayName = SelectPrimitive.Label.displayName; 113 | 114 | const SelectItem = React.forwardRef< 115 | React.ElementRef, 116 | React.ComponentPropsWithoutRef 117 | >(({ className, children, ...props }, ref) => ( 118 | 126 | {children} 127 | 128 | )); 129 | SelectItem.displayName = SelectPrimitive.Item.displayName; 130 | 131 | const SelectSeparator = React.forwardRef< 132 | React.ElementRef, 133 | React.ComponentPropsWithoutRef 134 | >(({ className, ...props }, ref) => ( 135 | 140 | )); 141 | SelectSeparator.displayName = SelectPrimitive.Separator.displayName; 142 | 143 | export { 144 | Select, 145 | SelectGroup, 146 | SelectValue, 147 | SelectTrigger, 148 | SelectContent, 149 | SelectLabel, 150 | SelectItem, 151 | SelectSeparator, 152 | SelectScrollUpButton, 153 | SelectScrollDownButton, 154 | }; 155 | -------------------------------------------------------------------------------- /web/src/app/page.tsx: -------------------------------------------------------------------------------- 1 | import CopyButton from "@/components/CopyButton"; 2 | import SpringEditor from "./SpringEditor"; 3 | 4 | export default function Home() { 5 | return ( 6 |
7 |
8 |

9 | tailwindcss-spring 10 |

11 |
12 | 61 |
62 |
63 |

64 | A Tailwind CSS plugin that adds spring easings using CSS linear() making 65 | it easy to incorporate spring animations into your project. 66 |

67 |

68 | Define just two parameters and let the plugin do the rest. 69 |

70 | 71 |

Installation

72 |

Install the plugin

73 |
 74 |         
 75 |         npm install tailwindcss-spring
 76 |       
77 |

78 | Then add the plugin to your tailwind.config.js file: 79 |

80 |
 81 |         
 82 |           {`// tailwind.config.js
 83 | module.exports = {
 84 |   theme: {
 85 |     // ...
 86 |   },
 87 |   plugins: [
 88 |     require('tailwindcss-spring'),
 89 |     // ...
 90 |   ],
 91 | }`}
 92 |         
 93 |       
94 |

Usage

95 |

spring-bounce-*

96 |

97 | This class defines the bounce (as a percentage), generates the easing 98 | curve, and applies it to the transition-timing-function. 99 |

100 |

101 | I recommend using low bounce values for most animations unless you want 102 | a springy effect. 103 |

104 |

spring-duration-*

105 |

106 | This class defines the perceptual duration of the animation in 107 | milliseconds. 108 |

109 |

110 | The perceptual duration allows you to intuitively configure the 111 | animation, focusing on the most significant part of the motion. 112 |

113 |

114 | Since spring easings often have long settling periods, the perceptual 115 | duration isn{"'"}t used as the actual animation duration. Instead, the 116 | real duration is calculated based on the spring-bounce-* value. 117 |

118 |

More info

119 |

120 | This plugin was created by{" "} 121 | 122 | Kevin Grajeda 123 | 124 | . It{"'"}s open source, available on{" "} 125 | 129 | GitHub 130 | 131 | . 132 |

133 |

134 | You can also check out my{" "} 135 | 136 | CSS spring easing generator 137 | 138 | . 139 |

140 |

141 | A special thanks to{" "} 142 | 143 | Jake Archibald{" "} 144 | 145 | for his work on the{" "} 146 | 150 | linear easing generator 151 | 152 | . I used some of{" "} 153 | 157 | his code 158 | {" "} 159 | for spring calculations. 160 |

161 |
162 | ); 163 | } 164 | -------------------------------------------------------------------------------- /src/spring.js: -------------------------------------------------------------------------------- 1 | export function generateEase(bounce) { 2 | const perceptualDuration = 1000; 3 | 4 | const stiffness = ((2 * Math.PI) / (perceptualDuration / 1000)) ** 2; 5 | 6 | const damping = 7 | ((1 - bounce / 100) * 4 * Math.PI) / (perceptualDuration / 1000); 8 | 9 | const springSolver = createSpringSolver({ 10 | mass: 1, 11 | stiffness, 12 | damping, 13 | velocity: 0, 14 | }); 15 | const settlingDuration = calculateSettlingDuration( 16 | springSolver, 17 | perceptualDuration 18 | ); 19 | 20 | const springValues = generateSpringValues(springSolver, settlingDuration); 21 | return { 22 | ease: generateLinearSyntax( 23 | normalizeTime(springValues, settlingDuration), 24 | 4 25 | ), 26 | durationMultiplier: (settlingDuration / perceptualDuration) * 1000, 27 | }; 28 | } 29 | 30 | /** 31 | * This code uses components from the linear-easing-generator by Jake Archibald. 32 | * Original source: https://github.com/jakearchibald/linear-easing-generator 33 | * Licensed under the Apache License, Version 2.0 34 | * http://www.apache.org/licenses/LICENSE-2.0 35 | */ 36 | export function calculateSettlingDuration(solver, perceptualDuration) { 37 | const step = 1 / 8; 38 | let time = (perceptualDuration * 1.66) / 1000; 39 | 40 | while (true) { 41 | if (Math.abs(1 - solver(time)) < 0.001) { 42 | const restStart = time; 43 | let restSteps = 1; 44 | while (true) { 45 | time += step; 46 | if (Math.abs(1 - solver(time)) >= 0.0005) break; 47 | restSteps++; 48 | if (restSteps === 20) return restStart; 49 | } 50 | } 51 | time += step; 52 | if (time > 30) return 30; 53 | } 54 | } 55 | 56 | export function createSpringSolver({ mass, stiffness, damping, velocity }) { 57 | const w0 = Math.sqrt(stiffness / mass); 58 | const zeta = damping / (2 * Math.sqrt(stiffness * mass)); 59 | const wd = zeta < 1 ? w0 * Math.sqrt(1 - zeta * zeta) : 0; 60 | const b = zeta < 1 ? (zeta * w0 - velocity) / wd : -velocity + w0; 61 | 62 | function solver(t) { 63 | let displacement; 64 | 65 | if (zeta < 1) { 66 | displacement = 67 | Math.exp(-t * zeta * w0) * (Math.cos(wd * t) + b * Math.sin(wd * t)); 68 | } else { 69 | displacement = (1 + b * t) * Math.exp(-t * w0); 70 | } 71 | 72 | return 1 - displacement; 73 | } 74 | 75 | return solver; 76 | } 77 | 78 | export function generateSpringValues(springSolver, settlingDuration) { 79 | const samples = settlingDuration * 500; 80 | let values = []; 81 | 82 | for (let i = 0; i <= settlingDuration; i += 1 / samples) { 83 | values.push([i, springSolver(i)]); 84 | } 85 | values = simplifyDouglasPeucker(values, 0.001); 86 | 87 | return values; 88 | } 89 | 90 | export function normalizeTime(points, settlingDuration) { 91 | // Normalize time to 0-1 92 | return points.map(([time, value]) => [time / settlingDuration, value]); 93 | } 94 | 95 | export function generateLinearSyntax(points, round) { 96 | const xFormat = new Intl.NumberFormat("en-US", { 97 | maximumFractionDigits: Math.max(round - 2, 0), 98 | }); 99 | const yFormat = new Intl.NumberFormat("en-US", { 100 | maximumFractionDigits: round, 101 | }); 102 | 103 | const valuesWithRedundantX = new Set(); 104 | const maxDelta = 1 / 10 ** round; 105 | 106 | // Figure out entries that don't need an explicit position value 107 | for (let i = 0; i < points.length; i++) { 108 | const [x] = points[i]; 109 | // If the first item's position is 0, then we don't need to state the position 110 | if (i === 0) { 111 | if (x === 0) valuesWithRedundantX.add(points[i]); 112 | continue; 113 | } 114 | // If the last entry's position is 1, and the item before it is less than 1, then we don't need to state the position 115 | if (i === points.length - 1) { 116 | const previous = points[i - 1][0]; 117 | if (x === 1 && previous <= 1) valuesWithRedundantX.add(points[i]); 118 | continue; 119 | } 120 | 121 | // If the position is the average of the previous and next positions, then we don't need to state the position 122 | const previous = points[i - 1][0]; 123 | const next = points[i + 1][0]; 124 | 125 | const averagePos = (next - previous) / 2 + previous; 126 | const delta = Math.abs(x - averagePos); 127 | 128 | if (delta < maxDelta) valuesWithRedundantX.add(points[i]); 129 | } 130 | 131 | // Group into sections with same y 132 | const groupedValues = [[points[0]]]; 133 | 134 | for (const value of points.slice(1)) { 135 | if (value[1] === groupedValues.at(-1)[0][1]) { 136 | groupedValues.at(-1).push(value); 137 | } else { 138 | groupedValues.push([value]); 139 | } 140 | } 141 | 142 | const outputValues = groupedValues.map((group) => { 143 | const yValue = yFormat.format(group[0][1]); 144 | 145 | const regularValue = group 146 | .map((value) => { 147 | const [x] = value; 148 | let output = yValue; 149 | 150 | if (!valuesWithRedundantX.has(value)) { 151 | output += " " + xFormat.format(x * 100) + "%"; 152 | } 153 | 154 | return output; 155 | }) 156 | .join(", "); 157 | 158 | if (group.length === 1) return regularValue; 159 | 160 | // Maybe it's shorter to provide a value that skips steps? 161 | const xVals = [group[0][0], group.at(-1)[0]]; 162 | const positionalValues = xVals 163 | .map((x) => xFormat.format(x * 100) + "%") 164 | .join(" "); 165 | 166 | const skipValue = `${yValue} ${positionalValues}`; 167 | 168 | return skipValue.length > regularValue.length ? regularValue : skipValue; 169 | }); 170 | return `linear(${outputValues.join(", ")})`; 171 | } 172 | 173 | // square distance from a point to a segment 174 | function getSqSegDist(p, p1, p2) { 175 | let x = p1[0]; 176 | let y = p1[1]; 177 | let dx = p2[0] - x; 178 | let dy = p2[1] - y; 179 | 180 | if (dx !== 0 || dy !== 0) { 181 | var t = ((p[0] - x) * dx + (p[1] - y) * dy) / (dx * dx + dy * dy); 182 | 183 | if (t > 1) { 184 | x = p2[0]; 185 | y = p2[1]; 186 | } else if (t > 0) { 187 | x += dx * t; 188 | y += dy * t; 189 | } 190 | } 191 | 192 | dx = p[0] - x; 193 | dy = p[1] - y; 194 | 195 | return dx * dx + dy * dy; 196 | } 197 | 198 | function simplifyDPStep(points, first, last, sqTolerance, simplified) { 199 | let maxSqDist = sqTolerance; 200 | let index; 201 | 202 | for (let i = first + 1; i < last; i++) { 203 | const sqDist = getSqSegDist(points[i], points[first], points[last]); 204 | 205 | if (sqDist > maxSqDist) { 206 | index = i; 207 | maxSqDist = sqDist; 208 | } 209 | } 210 | 211 | if (maxSqDist > sqTolerance) { 212 | if (index - first > 1) { 213 | simplifyDPStep(points, first, index, sqTolerance, simplified); 214 | } 215 | 216 | simplified.push(points[index]); 217 | 218 | if (last - index > 1) { 219 | simplifyDPStep(points, index, last, sqTolerance, simplified); 220 | } 221 | } 222 | } 223 | 224 | // simplification using Ramer-Douglas-Peucker algorithm 225 | function simplifyDouglasPeucker(points, tolerance) { 226 | if (points.length <= 1) return points; 227 | const sqTolerance = tolerance * tolerance; 228 | const last = points.length - 1; 229 | const simplified = [points[0]]; 230 | simplifyDPStep(points, 0, last, sqTolerance, simplified); 231 | simplified.push(points[last]); 232 | 233 | return simplified; 234 | } 235 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '9.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | importers: 8 | 9 | .: 10 | devDependencies: 11 | '@csstools/postcss-minify': 12 | specifier: ^1.1.5 13 | version: 1.1.5(postcss@8.4.40) 14 | postcss: 15 | specifier: ^8.4.40 16 | version: 8.4.40 17 | tailwindcss: 18 | specifier: 3.4.7 19 | version: 3.4.7 20 | vitest: 21 | specifier: ^2.0.5 22 | version: 2.0.5 23 | 24 | packages: 25 | 26 | '@alloc/quick-lru@5.2.0': 27 | resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} 28 | engines: {node: '>=10'} 29 | 30 | '@ampproject/remapping@2.3.0': 31 | resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} 32 | engines: {node: '>=6.0.0'} 33 | 34 | '@csstools/css-tokenizer@2.4.1': 35 | resolution: {integrity: sha512-eQ9DIktFJBhGjioABJRtUucoWR2mwllurfnM8LuNGAqX3ViZXaUchqk+1s7jjtkFiT9ySdACsFEA3etErkALUg==} 36 | engines: {node: ^14 || ^16 || >=18} 37 | 38 | '@csstools/postcss-minify@1.1.5': 39 | resolution: {integrity: sha512-wWMO5pzWe5DDnUgT3VvrDXJ35jP50g8JX8uQ3A19E2KHHiZt7A2ZMODcR5+6XhVVfYGq/+adIgfNLCc9rNszQg==} 40 | engines: {node: ^14 || ^16 || >=18} 41 | peerDependencies: 42 | postcss: ^8.4 43 | 44 | '@esbuild/aix-ppc64@0.21.5': 45 | resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} 46 | engines: {node: '>=12'} 47 | cpu: [ppc64] 48 | os: [aix] 49 | 50 | '@esbuild/android-arm64@0.21.5': 51 | resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} 52 | engines: {node: '>=12'} 53 | cpu: [arm64] 54 | os: [android] 55 | 56 | '@esbuild/android-arm@0.21.5': 57 | resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} 58 | engines: {node: '>=12'} 59 | cpu: [arm] 60 | os: [android] 61 | 62 | '@esbuild/android-x64@0.21.5': 63 | resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} 64 | engines: {node: '>=12'} 65 | cpu: [x64] 66 | os: [android] 67 | 68 | '@esbuild/darwin-arm64@0.21.5': 69 | resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} 70 | engines: {node: '>=12'} 71 | cpu: [arm64] 72 | os: [darwin] 73 | 74 | '@esbuild/darwin-x64@0.21.5': 75 | resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} 76 | engines: {node: '>=12'} 77 | cpu: [x64] 78 | os: [darwin] 79 | 80 | '@esbuild/freebsd-arm64@0.21.5': 81 | resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} 82 | engines: {node: '>=12'} 83 | cpu: [arm64] 84 | os: [freebsd] 85 | 86 | '@esbuild/freebsd-x64@0.21.5': 87 | resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} 88 | engines: {node: '>=12'} 89 | cpu: [x64] 90 | os: [freebsd] 91 | 92 | '@esbuild/linux-arm64@0.21.5': 93 | resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} 94 | engines: {node: '>=12'} 95 | cpu: [arm64] 96 | os: [linux] 97 | 98 | '@esbuild/linux-arm@0.21.5': 99 | resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} 100 | engines: {node: '>=12'} 101 | cpu: [arm] 102 | os: [linux] 103 | 104 | '@esbuild/linux-ia32@0.21.5': 105 | resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} 106 | engines: {node: '>=12'} 107 | cpu: [ia32] 108 | os: [linux] 109 | 110 | '@esbuild/linux-loong64@0.21.5': 111 | resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} 112 | engines: {node: '>=12'} 113 | cpu: [loong64] 114 | os: [linux] 115 | 116 | '@esbuild/linux-mips64el@0.21.5': 117 | resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} 118 | engines: {node: '>=12'} 119 | cpu: [mips64el] 120 | os: [linux] 121 | 122 | '@esbuild/linux-ppc64@0.21.5': 123 | resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} 124 | engines: {node: '>=12'} 125 | cpu: [ppc64] 126 | os: [linux] 127 | 128 | '@esbuild/linux-riscv64@0.21.5': 129 | resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} 130 | engines: {node: '>=12'} 131 | cpu: [riscv64] 132 | os: [linux] 133 | 134 | '@esbuild/linux-s390x@0.21.5': 135 | resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} 136 | engines: {node: '>=12'} 137 | cpu: [s390x] 138 | os: [linux] 139 | 140 | '@esbuild/linux-x64@0.21.5': 141 | resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} 142 | engines: {node: '>=12'} 143 | cpu: [x64] 144 | os: [linux] 145 | 146 | '@esbuild/netbsd-x64@0.21.5': 147 | resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} 148 | engines: {node: '>=12'} 149 | cpu: [x64] 150 | os: [netbsd] 151 | 152 | '@esbuild/openbsd-x64@0.21.5': 153 | resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} 154 | engines: {node: '>=12'} 155 | cpu: [x64] 156 | os: [openbsd] 157 | 158 | '@esbuild/sunos-x64@0.21.5': 159 | resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} 160 | engines: {node: '>=12'} 161 | cpu: [x64] 162 | os: [sunos] 163 | 164 | '@esbuild/win32-arm64@0.21.5': 165 | resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} 166 | engines: {node: '>=12'} 167 | cpu: [arm64] 168 | os: [win32] 169 | 170 | '@esbuild/win32-ia32@0.21.5': 171 | resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} 172 | engines: {node: '>=12'} 173 | cpu: [ia32] 174 | os: [win32] 175 | 176 | '@esbuild/win32-x64@0.21.5': 177 | resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} 178 | engines: {node: '>=12'} 179 | cpu: [x64] 180 | os: [win32] 181 | 182 | '@isaacs/cliui@8.0.2': 183 | resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} 184 | engines: {node: '>=12'} 185 | 186 | '@jridgewell/gen-mapping@0.3.5': 187 | resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} 188 | engines: {node: '>=6.0.0'} 189 | 190 | '@jridgewell/resolve-uri@3.1.2': 191 | resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} 192 | engines: {node: '>=6.0.0'} 193 | 194 | '@jridgewell/set-array@1.2.1': 195 | resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} 196 | engines: {node: '>=6.0.0'} 197 | 198 | '@jridgewell/sourcemap-codec@1.5.0': 199 | resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} 200 | 201 | '@jridgewell/trace-mapping@0.3.25': 202 | resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} 203 | 204 | '@nodelib/fs.scandir@2.1.5': 205 | resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} 206 | engines: {node: '>= 8'} 207 | 208 | '@nodelib/fs.stat@2.0.5': 209 | resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} 210 | engines: {node: '>= 8'} 211 | 212 | '@nodelib/fs.walk@1.2.8': 213 | resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} 214 | engines: {node: '>= 8'} 215 | 216 | '@pkgjs/parseargs@0.11.0': 217 | resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} 218 | engines: {node: '>=14'} 219 | 220 | '@rollup/rollup-android-arm-eabi@4.19.1': 221 | resolution: {integrity: sha512-XzqSg714++M+FXhHfXpS1tDnNZNpgxxuGZWlRG/jSj+VEPmZ0yg6jV4E0AL3uyBKxO8mO3xtOsP5mQ+XLfrlww==} 222 | cpu: [arm] 223 | os: [android] 224 | 225 | '@rollup/rollup-android-arm64@4.19.1': 226 | resolution: {integrity: sha512-thFUbkHteM20BGShD6P08aungq4irbIZKUNbG70LN8RkO7YztcGPiKTTGZS7Kw+x5h8hOXs0i4OaHwFxlpQN6A==} 227 | cpu: [arm64] 228 | os: [android] 229 | 230 | '@rollup/rollup-darwin-arm64@4.19.1': 231 | resolution: {integrity: sha512-8o6eqeFZzVLia2hKPUZk4jdE3zW7LCcZr+MD18tXkgBBid3lssGVAYuox8x6YHoEPDdDa9ixTaStcmx88lio5Q==} 232 | cpu: [arm64] 233 | os: [darwin] 234 | 235 | '@rollup/rollup-darwin-x64@4.19.1': 236 | resolution: {integrity: sha512-4T42heKsnbjkn7ovYiAdDVRRWZLU9Kmhdt6HafZxFcUdpjlBlxj4wDrt1yFWLk7G4+E+8p2C9tcmSu0KA6auGA==} 237 | cpu: [x64] 238 | os: [darwin] 239 | 240 | '@rollup/rollup-linux-arm-gnueabihf@4.19.1': 241 | resolution: {integrity: sha512-MXg1xp+e5GhZ3Vit1gGEyoC+dyQUBy2JgVQ+3hUrD9wZMkUw/ywgkpK7oZgnB6kPpGrxJ41clkPPnsknuD6M2Q==} 242 | cpu: [arm] 243 | os: [linux] 244 | 245 | '@rollup/rollup-linux-arm-musleabihf@4.19.1': 246 | resolution: {integrity: sha512-DZNLwIY4ftPSRVkJEaxYkq7u2zel7aah57HESuNkUnz+3bZHxwkCUkrfS2IWC1sxK6F2QNIR0Qr/YXw7nkF3Pw==} 247 | cpu: [arm] 248 | os: [linux] 249 | 250 | '@rollup/rollup-linux-arm64-gnu@4.19.1': 251 | resolution: {integrity: sha512-C7evongnjyxdngSDRRSQv5GvyfISizgtk9RM+z2biV5kY6S/NF/wta7K+DanmktC5DkuaJQgoKGf7KUDmA7RUw==} 252 | cpu: [arm64] 253 | os: [linux] 254 | 255 | '@rollup/rollup-linux-arm64-musl@4.19.1': 256 | resolution: {integrity: sha512-89tFWqxfxLLHkAthAcrTs9etAoBFRduNfWdl2xUs/yLV+7XDrJ5yuXMHptNqf1Zw0UCA3cAutkAiAokYCkaPtw==} 257 | cpu: [arm64] 258 | os: [linux] 259 | 260 | '@rollup/rollup-linux-powerpc64le-gnu@4.19.1': 261 | resolution: {integrity: sha512-PromGeV50sq+YfaisG8W3fd+Cl6mnOOiNv2qKKqKCpiiEke2KiKVyDqG/Mb9GWKbYMHj5a01fq/qlUR28PFhCQ==} 262 | cpu: [ppc64] 263 | os: [linux] 264 | 265 | '@rollup/rollup-linux-riscv64-gnu@4.19.1': 266 | resolution: {integrity: sha512-/1BmHYh+iz0cNCP0oHCuF8CSiNj0JOGf0jRlSo3L/FAyZyG2rGBuKpkZVH9YF+x58r1jgWxvm1aRg3DHrLDt6A==} 267 | cpu: [riscv64] 268 | os: [linux] 269 | 270 | '@rollup/rollup-linux-s390x-gnu@4.19.1': 271 | resolution: {integrity: sha512-0cYP5rGkQWRZKy9/HtsWVStLXzCF3cCBTRI+qRL8Z+wkYlqN7zrSYm6FuY5Kd5ysS5aH0q5lVgb/WbG4jqXN1Q==} 272 | cpu: [s390x] 273 | os: [linux] 274 | 275 | '@rollup/rollup-linux-x64-gnu@4.19.1': 276 | resolution: {integrity: sha512-XUXeI9eM8rMP8aGvii/aOOiMvTs7xlCosq9xCjcqI9+5hBxtjDpD+7Abm1ZhVIFE1J2h2VIg0t2DX/gjespC2Q==} 277 | cpu: [x64] 278 | os: [linux] 279 | 280 | '@rollup/rollup-linux-x64-musl@4.19.1': 281 | resolution: {integrity: sha512-V7cBw/cKXMfEVhpSvVZhC+iGifD6U1zJ4tbibjjN+Xi3blSXaj/rJynAkCFFQfoG6VZrAiP7uGVzL440Q6Me2Q==} 282 | cpu: [x64] 283 | os: [linux] 284 | 285 | '@rollup/rollup-win32-arm64-msvc@4.19.1': 286 | resolution: {integrity: sha512-88brja2vldW/76jWATlBqHEoGjJLRnP0WOEKAUbMcXaAZnemNhlAHSyj4jIwMoP2T750LE9lblvD4e2jXleZsA==} 287 | cpu: [arm64] 288 | os: [win32] 289 | 290 | '@rollup/rollup-win32-ia32-msvc@4.19.1': 291 | resolution: {integrity: sha512-LdxxcqRVSXi6k6JUrTah1rHuaupoeuiv38du8Mt4r4IPer3kwlTo+RuvfE8KzZ/tL6BhaPlzJ3835i6CxrFIRQ==} 292 | cpu: [ia32] 293 | os: [win32] 294 | 295 | '@rollup/rollup-win32-x64-msvc@4.19.1': 296 | resolution: {integrity: sha512-2bIrL28PcK3YCqD9anGxDxamxdiJAxA+l7fWIwM5o8UqNy1t3d1NdAweO2XhA0KTDJ5aH1FsuiT5+7VhtHliXg==} 297 | cpu: [x64] 298 | os: [win32] 299 | 300 | '@types/estree@1.0.5': 301 | resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} 302 | 303 | '@vitest/expect@2.0.5': 304 | resolution: {integrity: sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA==} 305 | 306 | '@vitest/pretty-format@2.0.5': 307 | resolution: {integrity: sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ==} 308 | 309 | '@vitest/runner@2.0.5': 310 | resolution: {integrity: sha512-TfRfZa6Bkk9ky4tW0z20WKXFEwwvWhRY+84CnSEtq4+3ZvDlJyY32oNTJtM7AW9ihW90tX/1Q78cb6FjoAs+ig==} 311 | 312 | '@vitest/snapshot@2.0.5': 313 | resolution: {integrity: sha512-SgCPUeDFLaM0mIUHfaArq8fD2WbaXG/zVXjRupthYfYGzc8ztbFbu6dUNOblBG7XLMR1kEhS/DNnfCZ2IhdDew==} 314 | 315 | '@vitest/spy@2.0.5': 316 | resolution: {integrity: sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA==} 317 | 318 | '@vitest/utils@2.0.5': 319 | resolution: {integrity: sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ==} 320 | 321 | ansi-regex@5.0.1: 322 | resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} 323 | engines: {node: '>=8'} 324 | 325 | ansi-regex@6.0.1: 326 | resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} 327 | engines: {node: '>=12'} 328 | 329 | ansi-styles@4.3.0: 330 | resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} 331 | engines: {node: '>=8'} 332 | 333 | ansi-styles@6.2.1: 334 | resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} 335 | engines: {node: '>=12'} 336 | 337 | any-promise@1.3.0: 338 | resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} 339 | 340 | anymatch@3.1.3: 341 | resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} 342 | engines: {node: '>= 8'} 343 | 344 | arg@5.0.2: 345 | resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} 346 | 347 | assertion-error@2.0.1: 348 | resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} 349 | engines: {node: '>=12'} 350 | 351 | balanced-match@1.0.2: 352 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} 353 | 354 | binary-extensions@2.3.0: 355 | resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} 356 | engines: {node: '>=8'} 357 | 358 | brace-expansion@2.0.1: 359 | resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} 360 | 361 | braces@3.0.3: 362 | resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} 363 | engines: {node: '>=8'} 364 | 365 | cac@6.7.14: 366 | resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} 367 | engines: {node: '>=8'} 368 | 369 | camelcase-css@2.0.1: 370 | resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} 371 | engines: {node: '>= 6'} 372 | 373 | chai@5.1.1: 374 | resolution: {integrity: sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==} 375 | engines: {node: '>=12'} 376 | 377 | check-error@2.1.1: 378 | resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} 379 | engines: {node: '>= 16'} 380 | 381 | chokidar@3.6.0: 382 | resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} 383 | engines: {node: '>= 8.10.0'} 384 | 385 | color-convert@2.0.1: 386 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} 387 | engines: {node: '>=7.0.0'} 388 | 389 | color-name@1.1.4: 390 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} 391 | 392 | commander@4.1.1: 393 | resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} 394 | engines: {node: '>= 6'} 395 | 396 | cross-spawn@7.0.3: 397 | resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} 398 | engines: {node: '>= 8'} 399 | 400 | cssesc@3.0.0: 401 | resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} 402 | engines: {node: '>=4'} 403 | hasBin: true 404 | 405 | debug@4.3.6: 406 | resolution: {integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==} 407 | engines: {node: '>=6.0'} 408 | peerDependencies: 409 | supports-color: '*' 410 | peerDependenciesMeta: 411 | supports-color: 412 | optional: true 413 | 414 | deep-eql@5.0.2: 415 | resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} 416 | engines: {node: '>=6'} 417 | 418 | didyoumean@1.2.2: 419 | resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} 420 | 421 | dlv@1.1.3: 422 | resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} 423 | 424 | eastasianwidth@0.2.0: 425 | resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} 426 | 427 | emoji-regex@8.0.0: 428 | resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} 429 | 430 | emoji-regex@9.2.2: 431 | resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} 432 | 433 | esbuild@0.21.5: 434 | resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} 435 | engines: {node: '>=12'} 436 | hasBin: true 437 | 438 | estree-walker@3.0.3: 439 | resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} 440 | 441 | execa@8.0.1: 442 | resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} 443 | engines: {node: '>=16.17'} 444 | 445 | fast-glob@3.3.2: 446 | resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} 447 | engines: {node: '>=8.6.0'} 448 | 449 | fastq@1.17.1: 450 | resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} 451 | 452 | fill-range@7.1.1: 453 | resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} 454 | engines: {node: '>=8'} 455 | 456 | foreground-child@3.2.1: 457 | resolution: {integrity: sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==} 458 | engines: {node: '>=14'} 459 | 460 | fsevents@2.3.3: 461 | resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} 462 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 463 | os: [darwin] 464 | 465 | function-bind@1.1.2: 466 | resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} 467 | 468 | get-func-name@2.0.2: 469 | resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} 470 | 471 | get-stream@8.0.1: 472 | resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} 473 | engines: {node: '>=16'} 474 | 475 | glob-parent@5.1.2: 476 | resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} 477 | engines: {node: '>= 6'} 478 | 479 | glob-parent@6.0.2: 480 | resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} 481 | engines: {node: '>=10.13.0'} 482 | 483 | glob@10.4.5: 484 | resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} 485 | hasBin: true 486 | 487 | hasown@2.0.2: 488 | resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} 489 | engines: {node: '>= 0.4'} 490 | 491 | human-signals@5.0.0: 492 | resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} 493 | engines: {node: '>=16.17.0'} 494 | 495 | is-binary-path@2.1.0: 496 | resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} 497 | engines: {node: '>=8'} 498 | 499 | is-core-module@2.15.0: 500 | resolution: {integrity: sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==} 501 | engines: {node: '>= 0.4'} 502 | 503 | is-extglob@2.1.1: 504 | resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} 505 | engines: {node: '>=0.10.0'} 506 | 507 | is-fullwidth-code-point@3.0.0: 508 | resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} 509 | engines: {node: '>=8'} 510 | 511 | is-glob@4.0.3: 512 | resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} 513 | engines: {node: '>=0.10.0'} 514 | 515 | is-number@7.0.0: 516 | resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} 517 | engines: {node: '>=0.12.0'} 518 | 519 | is-stream@3.0.0: 520 | resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} 521 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 522 | 523 | isexe@2.0.0: 524 | resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} 525 | 526 | jackspeak@3.4.3: 527 | resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} 528 | 529 | jiti@1.21.6: 530 | resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==} 531 | hasBin: true 532 | 533 | lilconfig@2.1.0: 534 | resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} 535 | engines: {node: '>=10'} 536 | 537 | lilconfig@3.1.2: 538 | resolution: {integrity: sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==} 539 | engines: {node: '>=14'} 540 | 541 | lines-and-columns@1.2.4: 542 | resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} 543 | 544 | loupe@3.1.1: 545 | resolution: {integrity: sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==} 546 | 547 | lru-cache@10.4.3: 548 | resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} 549 | 550 | magic-string@0.30.11: 551 | resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==} 552 | 553 | merge-stream@2.0.0: 554 | resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} 555 | 556 | merge2@1.4.1: 557 | resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} 558 | engines: {node: '>= 8'} 559 | 560 | micromatch@4.0.7: 561 | resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==} 562 | engines: {node: '>=8.6'} 563 | 564 | mimic-fn@4.0.0: 565 | resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} 566 | engines: {node: '>=12'} 567 | 568 | minimatch@9.0.5: 569 | resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} 570 | engines: {node: '>=16 || 14 >=14.17'} 571 | 572 | minipass@7.1.2: 573 | resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} 574 | engines: {node: '>=16 || 14 >=14.17'} 575 | 576 | ms@2.1.2: 577 | resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} 578 | 579 | mz@2.7.0: 580 | resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} 581 | 582 | nanoid@3.3.7: 583 | resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} 584 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} 585 | hasBin: true 586 | 587 | normalize-path@3.0.0: 588 | resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} 589 | engines: {node: '>=0.10.0'} 590 | 591 | npm-run-path@5.3.0: 592 | resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} 593 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 594 | 595 | object-assign@4.1.1: 596 | resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} 597 | engines: {node: '>=0.10.0'} 598 | 599 | object-hash@3.0.0: 600 | resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} 601 | engines: {node: '>= 6'} 602 | 603 | onetime@6.0.0: 604 | resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} 605 | engines: {node: '>=12'} 606 | 607 | package-json-from-dist@1.0.0: 608 | resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} 609 | 610 | path-key@3.1.1: 611 | resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} 612 | engines: {node: '>=8'} 613 | 614 | path-key@4.0.0: 615 | resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} 616 | engines: {node: '>=12'} 617 | 618 | path-parse@1.0.7: 619 | resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} 620 | 621 | path-scurry@1.11.1: 622 | resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} 623 | engines: {node: '>=16 || 14 >=14.18'} 624 | 625 | pathe@1.1.2: 626 | resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} 627 | 628 | pathval@2.0.0: 629 | resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} 630 | engines: {node: '>= 14.16'} 631 | 632 | picocolors@1.0.1: 633 | resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} 634 | 635 | picomatch@2.3.1: 636 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} 637 | engines: {node: '>=8.6'} 638 | 639 | pify@2.3.0: 640 | resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} 641 | engines: {node: '>=0.10.0'} 642 | 643 | pirates@4.0.6: 644 | resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} 645 | engines: {node: '>= 6'} 646 | 647 | postcss-import@15.1.0: 648 | resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} 649 | engines: {node: '>=14.0.0'} 650 | peerDependencies: 651 | postcss: ^8.0.0 652 | 653 | postcss-js@4.0.1: 654 | resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} 655 | engines: {node: ^12 || ^14 || >= 16} 656 | peerDependencies: 657 | postcss: ^8.4.21 658 | 659 | postcss-load-config@4.0.2: 660 | resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} 661 | engines: {node: '>= 14'} 662 | peerDependencies: 663 | postcss: '>=8.0.9' 664 | ts-node: '>=9.0.0' 665 | peerDependenciesMeta: 666 | postcss: 667 | optional: true 668 | ts-node: 669 | optional: true 670 | 671 | postcss-nested@6.2.0: 672 | resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} 673 | engines: {node: '>=12.0'} 674 | peerDependencies: 675 | postcss: ^8.2.14 676 | 677 | postcss-selector-parser@6.1.1: 678 | resolution: {integrity: sha512-b4dlw/9V8A71rLIDsSwVmak9z2DuBUB7CA1/wSdelNEzqsjoSPeADTWNO09lpH49Diy3/JIZ2bSPB1dI3LJCHg==} 679 | engines: {node: '>=4'} 680 | 681 | postcss-value-parser@4.2.0: 682 | resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} 683 | 684 | postcss@8.4.40: 685 | resolution: {integrity: sha512-YF2kKIUzAofPMpfH6hOi2cGnv/HrUlfucspc7pDyvv7kGdqXrfj8SCl/t8owkEgKEuu8ZcRjSOxFxVLqwChZ2Q==} 686 | engines: {node: ^10 || ^12 || >=14} 687 | 688 | queue-microtask@1.2.3: 689 | resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} 690 | 691 | read-cache@1.0.0: 692 | resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} 693 | 694 | readdirp@3.6.0: 695 | resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} 696 | engines: {node: '>=8.10.0'} 697 | 698 | resolve@1.22.8: 699 | resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} 700 | hasBin: true 701 | 702 | reusify@1.0.4: 703 | resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} 704 | engines: {iojs: '>=1.0.0', node: '>=0.10.0'} 705 | 706 | rollup@4.19.1: 707 | resolution: {integrity: sha512-K5vziVlg7hTpYfFBI+91zHBEMo6jafYXpkMlqZjg7/zhIG9iHqazBf4xz9AVdjS9BruRn280ROqLI7G3OFRIlw==} 708 | engines: {node: '>=18.0.0', npm: '>=8.0.0'} 709 | hasBin: true 710 | 711 | run-parallel@1.2.0: 712 | resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} 713 | 714 | shebang-command@2.0.0: 715 | resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} 716 | engines: {node: '>=8'} 717 | 718 | shebang-regex@3.0.0: 719 | resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} 720 | engines: {node: '>=8'} 721 | 722 | siginfo@2.0.0: 723 | resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} 724 | 725 | signal-exit@4.1.0: 726 | resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} 727 | engines: {node: '>=14'} 728 | 729 | source-map-js@1.2.0: 730 | resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} 731 | engines: {node: '>=0.10.0'} 732 | 733 | stackback@0.0.2: 734 | resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} 735 | 736 | std-env@3.7.0: 737 | resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} 738 | 739 | string-width@4.2.3: 740 | resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} 741 | engines: {node: '>=8'} 742 | 743 | string-width@5.1.2: 744 | resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} 745 | engines: {node: '>=12'} 746 | 747 | strip-ansi@6.0.1: 748 | resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} 749 | engines: {node: '>=8'} 750 | 751 | strip-ansi@7.1.0: 752 | resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} 753 | engines: {node: '>=12'} 754 | 755 | strip-final-newline@3.0.0: 756 | resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} 757 | engines: {node: '>=12'} 758 | 759 | sucrase@3.35.0: 760 | resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} 761 | engines: {node: '>=16 || 14 >=14.17'} 762 | hasBin: true 763 | 764 | supports-preserve-symlinks-flag@1.0.0: 765 | resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} 766 | engines: {node: '>= 0.4'} 767 | 768 | tailwindcss@3.4.7: 769 | resolution: {integrity: sha512-rxWZbe87YJb4OcSopb7up2Ba4U82BoiSGUdoDr3Ydrg9ckxFS/YWsvhN323GMcddgU65QRy7JndC7ahhInhvlQ==} 770 | engines: {node: '>=14.0.0'} 771 | hasBin: true 772 | 773 | thenify-all@1.6.0: 774 | resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} 775 | engines: {node: '>=0.8'} 776 | 777 | thenify@3.3.1: 778 | resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} 779 | 780 | tinybench@2.8.0: 781 | resolution: {integrity: sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==} 782 | 783 | tinypool@1.0.0: 784 | resolution: {integrity: sha512-KIKExllK7jp3uvrNtvRBYBWBOAXSX8ZvoaD8T+7KB/QHIuoJW3Pmr60zucywjAlMb5TeXUkcs/MWeWLu0qvuAQ==} 785 | engines: {node: ^18.0.0 || >=20.0.0} 786 | 787 | tinyrainbow@1.2.0: 788 | resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} 789 | engines: {node: '>=14.0.0'} 790 | 791 | tinyspy@3.0.0: 792 | resolution: {integrity: sha512-q5nmENpTHgiPVd1cJDDc9cVoYN5x4vCvwT3FMilvKPKneCBZAxn2YWQjDF0UMcE9k0Cay1gBiDfTMU0g+mPMQA==} 793 | engines: {node: '>=14.0.0'} 794 | 795 | to-regex-range@5.0.1: 796 | resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} 797 | engines: {node: '>=8.0'} 798 | 799 | ts-interface-checker@0.1.13: 800 | resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} 801 | 802 | util-deprecate@1.0.2: 803 | resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} 804 | 805 | vite-node@2.0.5: 806 | resolution: {integrity: sha512-LdsW4pxj0Ot69FAoXZ1yTnA9bjGohr2yNBU7QKRxpz8ITSkhuDl6h3zS/tvgz4qrNjeRnvrWeXQ8ZF7Um4W00Q==} 807 | engines: {node: ^18.0.0 || >=20.0.0} 808 | hasBin: true 809 | 810 | vite@5.3.5: 811 | resolution: {integrity: sha512-MdjglKR6AQXQb9JGiS7Rc2wC6uMjcm7Go/NHNO63EwiJXfuk9PgqiP/n5IDJCziMkfw9n4Ubp7lttNwz+8ZVKA==} 812 | engines: {node: ^18.0.0 || >=20.0.0} 813 | hasBin: true 814 | peerDependencies: 815 | '@types/node': ^18.0.0 || >=20.0.0 816 | less: '*' 817 | lightningcss: ^1.21.0 818 | sass: '*' 819 | stylus: '*' 820 | sugarss: '*' 821 | terser: ^5.4.0 822 | peerDependenciesMeta: 823 | '@types/node': 824 | optional: true 825 | less: 826 | optional: true 827 | lightningcss: 828 | optional: true 829 | sass: 830 | optional: true 831 | stylus: 832 | optional: true 833 | sugarss: 834 | optional: true 835 | terser: 836 | optional: true 837 | 838 | vitest@2.0.5: 839 | resolution: {integrity: sha512-8GUxONfauuIdeSl5f9GTgVEpg5BTOlplET4WEDaeY2QBiN8wSm68vxN/tb5z405OwppfoCavnwXafiaYBC/xOA==} 840 | engines: {node: ^18.0.0 || >=20.0.0} 841 | hasBin: true 842 | peerDependencies: 843 | '@edge-runtime/vm': '*' 844 | '@types/node': ^18.0.0 || >=20.0.0 845 | '@vitest/browser': 2.0.5 846 | '@vitest/ui': 2.0.5 847 | happy-dom: '*' 848 | jsdom: '*' 849 | peerDependenciesMeta: 850 | '@edge-runtime/vm': 851 | optional: true 852 | '@types/node': 853 | optional: true 854 | '@vitest/browser': 855 | optional: true 856 | '@vitest/ui': 857 | optional: true 858 | happy-dom: 859 | optional: true 860 | jsdom: 861 | optional: true 862 | 863 | which@2.0.2: 864 | resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} 865 | engines: {node: '>= 8'} 866 | hasBin: true 867 | 868 | why-is-node-running@2.3.0: 869 | resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} 870 | engines: {node: '>=8'} 871 | hasBin: true 872 | 873 | wrap-ansi@7.0.0: 874 | resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} 875 | engines: {node: '>=10'} 876 | 877 | wrap-ansi@8.1.0: 878 | resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} 879 | engines: {node: '>=12'} 880 | 881 | yaml@2.5.0: 882 | resolution: {integrity: sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==} 883 | engines: {node: '>= 14'} 884 | hasBin: true 885 | 886 | snapshots: 887 | 888 | '@alloc/quick-lru@5.2.0': {} 889 | 890 | '@ampproject/remapping@2.3.0': 891 | dependencies: 892 | '@jridgewell/gen-mapping': 0.3.5 893 | '@jridgewell/trace-mapping': 0.3.25 894 | 895 | '@csstools/css-tokenizer@2.4.1': {} 896 | 897 | '@csstools/postcss-minify@1.1.5(postcss@8.4.40)': 898 | dependencies: 899 | '@csstools/css-tokenizer': 2.4.1 900 | postcss: 8.4.40 901 | 902 | '@esbuild/aix-ppc64@0.21.5': 903 | optional: true 904 | 905 | '@esbuild/android-arm64@0.21.5': 906 | optional: true 907 | 908 | '@esbuild/android-arm@0.21.5': 909 | optional: true 910 | 911 | '@esbuild/android-x64@0.21.5': 912 | optional: true 913 | 914 | '@esbuild/darwin-arm64@0.21.5': 915 | optional: true 916 | 917 | '@esbuild/darwin-x64@0.21.5': 918 | optional: true 919 | 920 | '@esbuild/freebsd-arm64@0.21.5': 921 | optional: true 922 | 923 | '@esbuild/freebsd-x64@0.21.5': 924 | optional: true 925 | 926 | '@esbuild/linux-arm64@0.21.5': 927 | optional: true 928 | 929 | '@esbuild/linux-arm@0.21.5': 930 | optional: true 931 | 932 | '@esbuild/linux-ia32@0.21.5': 933 | optional: true 934 | 935 | '@esbuild/linux-loong64@0.21.5': 936 | optional: true 937 | 938 | '@esbuild/linux-mips64el@0.21.5': 939 | optional: true 940 | 941 | '@esbuild/linux-ppc64@0.21.5': 942 | optional: true 943 | 944 | '@esbuild/linux-riscv64@0.21.5': 945 | optional: true 946 | 947 | '@esbuild/linux-s390x@0.21.5': 948 | optional: true 949 | 950 | '@esbuild/linux-x64@0.21.5': 951 | optional: true 952 | 953 | '@esbuild/netbsd-x64@0.21.5': 954 | optional: true 955 | 956 | '@esbuild/openbsd-x64@0.21.5': 957 | optional: true 958 | 959 | '@esbuild/sunos-x64@0.21.5': 960 | optional: true 961 | 962 | '@esbuild/win32-arm64@0.21.5': 963 | optional: true 964 | 965 | '@esbuild/win32-ia32@0.21.5': 966 | optional: true 967 | 968 | '@esbuild/win32-x64@0.21.5': 969 | optional: true 970 | 971 | '@isaacs/cliui@8.0.2': 972 | dependencies: 973 | string-width: 5.1.2 974 | string-width-cjs: string-width@4.2.3 975 | strip-ansi: 7.1.0 976 | strip-ansi-cjs: strip-ansi@6.0.1 977 | wrap-ansi: 8.1.0 978 | wrap-ansi-cjs: wrap-ansi@7.0.0 979 | 980 | '@jridgewell/gen-mapping@0.3.5': 981 | dependencies: 982 | '@jridgewell/set-array': 1.2.1 983 | '@jridgewell/sourcemap-codec': 1.5.0 984 | '@jridgewell/trace-mapping': 0.3.25 985 | 986 | '@jridgewell/resolve-uri@3.1.2': {} 987 | 988 | '@jridgewell/set-array@1.2.1': {} 989 | 990 | '@jridgewell/sourcemap-codec@1.5.0': {} 991 | 992 | '@jridgewell/trace-mapping@0.3.25': 993 | dependencies: 994 | '@jridgewell/resolve-uri': 3.1.2 995 | '@jridgewell/sourcemap-codec': 1.5.0 996 | 997 | '@nodelib/fs.scandir@2.1.5': 998 | dependencies: 999 | '@nodelib/fs.stat': 2.0.5 1000 | run-parallel: 1.2.0 1001 | 1002 | '@nodelib/fs.stat@2.0.5': {} 1003 | 1004 | '@nodelib/fs.walk@1.2.8': 1005 | dependencies: 1006 | '@nodelib/fs.scandir': 2.1.5 1007 | fastq: 1.17.1 1008 | 1009 | '@pkgjs/parseargs@0.11.0': 1010 | optional: true 1011 | 1012 | '@rollup/rollup-android-arm-eabi@4.19.1': 1013 | optional: true 1014 | 1015 | '@rollup/rollup-android-arm64@4.19.1': 1016 | optional: true 1017 | 1018 | '@rollup/rollup-darwin-arm64@4.19.1': 1019 | optional: true 1020 | 1021 | '@rollup/rollup-darwin-x64@4.19.1': 1022 | optional: true 1023 | 1024 | '@rollup/rollup-linux-arm-gnueabihf@4.19.1': 1025 | optional: true 1026 | 1027 | '@rollup/rollup-linux-arm-musleabihf@4.19.1': 1028 | optional: true 1029 | 1030 | '@rollup/rollup-linux-arm64-gnu@4.19.1': 1031 | optional: true 1032 | 1033 | '@rollup/rollup-linux-arm64-musl@4.19.1': 1034 | optional: true 1035 | 1036 | '@rollup/rollup-linux-powerpc64le-gnu@4.19.1': 1037 | optional: true 1038 | 1039 | '@rollup/rollup-linux-riscv64-gnu@4.19.1': 1040 | optional: true 1041 | 1042 | '@rollup/rollup-linux-s390x-gnu@4.19.1': 1043 | optional: true 1044 | 1045 | '@rollup/rollup-linux-x64-gnu@4.19.1': 1046 | optional: true 1047 | 1048 | '@rollup/rollup-linux-x64-musl@4.19.1': 1049 | optional: true 1050 | 1051 | '@rollup/rollup-win32-arm64-msvc@4.19.1': 1052 | optional: true 1053 | 1054 | '@rollup/rollup-win32-ia32-msvc@4.19.1': 1055 | optional: true 1056 | 1057 | '@rollup/rollup-win32-x64-msvc@4.19.1': 1058 | optional: true 1059 | 1060 | '@types/estree@1.0.5': {} 1061 | 1062 | '@vitest/expect@2.0.5': 1063 | dependencies: 1064 | '@vitest/spy': 2.0.5 1065 | '@vitest/utils': 2.0.5 1066 | chai: 5.1.1 1067 | tinyrainbow: 1.2.0 1068 | 1069 | '@vitest/pretty-format@2.0.5': 1070 | dependencies: 1071 | tinyrainbow: 1.2.0 1072 | 1073 | '@vitest/runner@2.0.5': 1074 | dependencies: 1075 | '@vitest/utils': 2.0.5 1076 | pathe: 1.1.2 1077 | 1078 | '@vitest/snapshot@2.0.5': 1079 | dependencies: 1080 | '@vitest/pretty-format': 2.0.5 1081 | magic-string: 0.30.11 1082 | pathe: 1.1.2 1083 | 1084 | '@vitest/spy@2.0.5': 1085 | dependencies: 1086 | tinyspy: 3.0.0 1087 | 1088 | '@vitest/utils@2.0.5': 1089 | dependencies: 1090 | '@vitest/pretty-format': 2.0.5 1091 | estree-walker: 3.0.3 1092 | loupe: 3.1.1 1093 | tinyrainbow: 1.2.0 1094 | 1095 | ansi-regex@5.0.1: {} 1096 | 1097 | ansi-regex@6.0.1: {} 1098 | 1099 | ansi-styles@4.3.0: 1100 | dependencies: 1101 | color-convert: 2.0.1 1102 | 1103 | ansi-styles@6.2.1: {} 1104 | 1105 | any-promise@1.3.0: {} 1106 | 1107 | anymatch@3.1.3: 1108 | dependencies: 1109 | normalize-path: 3.0.0 1110 | picomatch: 2.3.1 1111 | 1112 | arg@5.0.2: {} 1113 | 1114 | assertion-error@2.0.1: {} 1115 | 1116 | balanced-match@1.0.2: {} 1117 | 1118 | binary-extensions@2.3.0: {} 1119 | 1120 | brace-expansion@2.0.1: 1121 | dependencies: 1122 | balanced-match: 1.0.2 1123 | 1124 | braces@3.0.3: 1125 | dependencies: 1126 | fill-range: 7.1.1 1127 | 1128 | cac@6.7.14: {} 1129 | 1130 | camelcase-css@2.0.1: {} 1131 | 1132 | chai@5.1.1: 1133 | dependencies: 1134 | assertion-error: 2.0.1 1135 | check-error: 2.1.1 1136 | deep-eql: 5.0.2 1137 | loupe: 3.1.1 1138 | pathval: 2.0.0 1139 | 1140 | check-error@2.1.1: {} 1141 | 1142 | chokidar@3.6.0: 1143 | dependencies: 1144 | anymatch: 3.1.3 1145 | braces: 3.0.3 1146 | glob-parent: 5.1.2 1147 | is-binary-path: 2.1.0 1148 | is-glob: 4.0.3 1149 | normalize-path: 3.0.0 1150 | readdirp: 3.6.0 1151 | optionalDependencies: 1152 | fsevents: 2.3.3 1153 | 1154 | color-convert@2.0.1: 1155 | dependencies: 1156 | color-name: 1.1.4 1157 | 1158 | color-name@1.1.4: {} 1159 | 1160 | commander@4.1.1: {} 1161 | 1162 | cross-spawn@7.0.3: 1163 | dependencies: 1164 | path-key: 3.1.1 1165 | shebang-command: 2.0.0 1166 | which: 2.0.2 1167 | 1168 | cssesc@3.0.0: {} 1169 | 1170 | debug@4.3.6: 1171 | dependencies: 1172 | ms: 2.1.2 1173 | 1174 | deep-eql@5.0.2: {} 1175 | 1176 | didyoumean@1.2.2: {} 1177 | 1178 | dlv@1.1.3: {} 1179 | 1180 | eastasianwidth@0.2.0: {} 1181 | 1182 | emoji-regex@8.0.0: {} 1183 | 1184 | emoji-regex@9.2.2: {} 1185 | 1186 | esbuild@0.21.5: 1187 | optionalDependencies: 1188 | '@esbuild/aix-ppc64': 0.21.5 1189 | '@esbuild/android-arm': 0.21.5 1190 | '@esbuild/android-arm64': 0.21.5 1191 | '@esbuild/android-x64': 0.21.5 1192 | '@esbuild/darwin-arm64': 0.21.5 1193 | '@esbuild/darwin-x64': 0.21.5 1194 | '@esbuild/freebsd-arm64': 0.21.5 1195 | '@esbuild/freebsd-x64': 0.21.5 1196 | '@esbuild/linux-arm': 0.21.5 1197 | '@esbuild/linux-arm64': 0.21.5 1198 | '@esbuild/linux-ia32': 0.21.5 1199 | '@esbuild/linux-loong64': 0.21.5 1200 | '@esbuild/linux-mips64el': 0.21.5 1201 | '@esbuild/linux-ppc64': 0.21.5 1202 | '@esbuild/linux-riscv64': 0.21.5 1203 | '@esbuild/linux-s390x': 0.21.5 1204 | '@esbuild/linux-x64': 0.21.5 1205 | '@esbuild/netbsd-x64': 0.21.5 1206 | '@esbuild/openbsd-x64': 0.21.5 1207 | '@esbuild/sunos-x64': 0.21.5 1208 | '@esbuild/win32-arm64': 0.21.5 1209 | '@esbuild/win32-ia32': 0.21.5 1210 | '@esbuild/win32-x64': 0.21.5 1211 | 1212 | estree-walker@3.0.3: 1213 | dependencies: 1214 | '@types/estree': 1.0.5 1215 | 1216 | execa@8.0.1: 1217 | dependencies: 1218 | cross-spawn: 7.0.3 1219 | get-stream: 8.0.1 1220 | human-signals: 5.0.0 1221 | is-stream: 3.0.0 1222 | merge-stream: 2.0.0 1223 | npm-run-path: 5.3.0 1224 | onetime: 6.0.0 1225 | signal-exit: 4.1.0 1226 | strip-final-newline: 3.0.0 1227 | 1228 | fast-glob@3.3.2: 1229 | dependencies: 1230 | '@nodelib/fs.stat': 2.0.5 1231 | '@nodelib/fs.walk': 1.2.8 1232 | glob-parent: 5.1.2 1233 | merge2: 1.4.1 1234 | micromatch: 4.0.7 1235 | 1236 | fastq@1.17.1: 1237 | dependencies: 1238 | reusify: 1.0.4 1239 | 1240 | fill-range@7.1.1: 1241 | dependencies: 1242 | to-regex-range: 5.0.1 1243 | 1244 | foreground-child@3.2.1: 1245 | dependencies: 1246 | cross-spawn: 7.0.3 1247 | signal-exit: 4.1.0 1248 | 1249 | fsevents@2.3.3: 1250 | optional: true 1251 | 1252 | function-bind@1.1.2: {} 1253 | 1254 | get-func-name@2.0.2: {} 1255 | 1256 | get-stream@8.0.1: {} 1257 | 1258 | glob-parent@5.1.2: 1259 | dependencies: 1260 | is-glob: 4.0.3 1261 | 1262 | glob-parent@6.0.2: 1263 | dependencies: 1264 | is-glob: 4.0.3 1265 | 1266 | glob@10.4.5: 1267 | dependencies: 1268 | foreground-child: 3.2.1 1269 | jackspeak: 3.4.3 1270 | minimatch: 9.0.5 1271 | minipass: 7.1.2 1272 | package-json-from-dist: 1.0.0 1273 | path-scurry: 1.11.1 1274 | 1275 | hasown@2.0.2: 1276 | dependencies: 1277 | function-bind: 1.1.2 1278 | 1279 | human-signals@5.0.0: {} 1280 | 1281 | is-binary-path@2.1.0: 1282 | dependencies: 1283 | binary-extensions: 2.3.0 1284 | 1285 | is-core-module@2.15.0: 1286 | dependencies: 1287 | hasown: 2.0.2 1288 | 1289 | is-extglob@2.1.1: {} 1290 | 1291 | is-fullwidth-code-point@3.0.0: {} 1292 | 1293 | is-glob@4.0.3: 1294 | dependencies: 1295 | is-extglob: 2.1.1 1296 | 1297 | is-number@7.0.0: {} 1298 | 1299 | is-stream@3.0.0: {} 1300 | 1301 | isexe@2.0.0: {} 1302 | 1303 | jackspeak@3.4.3: 1304 | dependencies: 1305 | '@isaacs/cliui': 8.0.2 1306 | optionalDependencies: 1307 | '@pkgjs/parseargs': 0.11.0 1308 | 1309 | jiti@1.21.6: {} 1310 | 1311 | lilconfig@2.1.0: {} 1312 | 1313 | lilconfig@3.1.2: {} 1314 | 1315 | lines-and-columns@1.2.4: {} 1316 | 1317 | loupe@3.1.1: 1318 | dependencies: 1319 | get-func-name: 2.0.2 1320 | 1321 | lru-cache@10.4.3: {} 1322 | 1323 | magic-string@0.30.11: 1324 | dependencies: 1325 | '@jridgewell/sourcemap-codec': 1.5.0 1326 | 1327 | merge-stream@2.0.0: {} 1328 | 1329 | merge2@1.4.1: {} 1330 | 1331 | micromatch@4.0.7: 1332 | dependencies: 1333 | braces: 3.0.3 1334 | picomatch: 2.3.1 1335 | 1336 | mimic-fn@4.0.0: {} 1337 | 1338 | minimatch@9.0.5: 1339 | dependencies: 1340 | brace-expansion: 2.0.1 1341 | 1342 | minipass@7.1.2: {} 1343 | 1344 | ms@2.1.2: {} 1345 | 1346 | mz@2.7.0: 1347 | dependencies: 1348 | any-promise: 1.3.0 1349 | object-assign: 4.1.1 1350 | thenify-all: 1.6.0 1351 | 1352 | nanoid@3.3.7: {} 1353 | 1354 | normalize-path@3.0.0: {} 1355 | 1356 | npm-run-path@5.3.0: 1357 | dependencies: 1358 | path-key: 4.0.0 1359 | 1360 | object-assign@4.1.1: {} 1361 | 1362 | object-hash@3.0.0: {} 1363 | 1364 | onetime@6.0.0: 1365 | dependencies: 1366 | mimic-fn: 4.0.0 1367 | 1368 | package-json-from-dist@1.0.0: {} 1369 | 1370 | path-key@3.1.1: {} 1371 | 1372 | path-key@4.0.0: {} 1373 | 1374 | path-parse@1.0.7: {} 1375 | 1376 | path-scurry@1.11.1: 1377 | dependencies: 1378 | lru-cache: 10.4.3 1379 | minipass: 7.1.2 1380 | 1381 | pathe@1.1.2: {} 1382 | 1383 | pathval@2.0.0: {} 1384 | 1385 | picocolors@1.0.1: {} 1386 | 1387 | picomatch@2.3.1: {} 1388 | 1389 | pify@2.3.0: {} 1390 | 1391 | pirates@4.0.6: {} 1392 | 1393 | postcss-import@15.1.0(postcss@8.4.40): 1394 | dependencies: 1395 | postcss: 8.4.40 1396 | postcss-value-parser: 4.2.0 1397 | read-cache: 1.0.0 1398 | resolve: 1.22.8 1399 | 1400 | postcss-js@4.0.1(postcss@8.4.40): 1401 | dependencies: 1402 | camelcase-css: 2.0.1 1403 | postcss: 8.4.40 1404 | 1405 | postcss-load-config@4.0.2(postcss@8.4.40): 1406 | dependencies: 1407 | lilconfig: 3.1.2 1408 | yaml: 2.5.0 1409 | optionalDependencies: 1410 | postcss: 8.4.40 1411 | 1412 | postcss-nested@6.2.0(postcss@8.4.40): 1413 | dependencies: 1414 | postcss: 8.4.40 1415 | postcss-selector-parser: 6.1.1 1416 | 1417 | postcss-selector-parser@6.1.1: 1418 | dependencies: 1419 | cssesc: 3.0.0 1420 | util-deprecate: 1.0.2 1421 | 1422 | postcss-value-parser@4.2.0: {} 1423 | 1424 | postcss@8.4.40: 1425 | dependencies: 1426 | nanoid: 3.3.7 1427 | picocolors: 1.0.1 1428 | source-map-js: 1.2.0 1429 | 1430 | queue-microtask@1.2.3: {} 1431 | 1432 | read-cache@1.0.0: 1433 | dependencies: 1434 | pify: 2.3.0 1435 | 1436 | readdirp@3.6.0: 1437 | dependencies: 1438 | picomatch: 2.3.1 1439 | 1440 | resolve@1.22.8: 1441 | dependencies: 1442 | is-core-module: 2.15.0 1443 | path-parse: 1.0.7 1444 | supports-preserve-symlinks-flag: 1.0.0 1445 | 1446 | reusify@1.0.4: {} 1447 | 1448 | rollup@4.19.1: 1449 | dependencies: 1450 | '@types/estree': 1.0.5 1451 | optionalDependencies: 1452 | '@rollup/rollup-android-arm-eabi': 4.19.1 1453 | '@rollup/rollup-android-arm64': 4.19.1 1454 | '@rollup/rollup-darwin-arm64': 4.19.1 1455 | '@rollup/rollup-darwin-x64': 4.19.1 1456 | '@rollup/rollup-linux-arm-gnueabihf': 4.19.1 1457 | '@rollup/rollup-linux-arm-musleabihf': 4.19.1 1458 | '@rollup/rollup-linux-arm64-gnu': 4.19.1 1459 | '@rollup/rollup-linux-arm64-musl': 4.19.1 1460 | '@rollup/rollup-linux-powerpc64le-gnu': 4.19.1 1461 | '@rollup/rollup-linux-riscv64-gnu': 4.19.1 1462 | '@rollup/rollup-linux-s390x-gnu': 4.19.1 1463 | '@rollup/rollup-linux-x64-gnu': 4.19.1 1464 | '@rollup/rollup-linux-x64-musl': 4.19.1 1465 | '@rollup/rollup-win32-arm64-msvc': 4.19.1 1466 | '@rollup/rollup-win32-ia32-msvc': 4.19.1 1467 | '@rollup/rollup-win32-x64-msvc': 4.19.1 1468 | fsevents: 2.3.3 1469 | 1470 | run-parallel@1.2.0: 1471 | dependencies: 1472 | queue-microtask: 1.2.3 1473 | 1474 | shebang-command@2.0.0: 1475 | dependencies: 1476 | shebang-regex: 3.0.0 1477 | 1478 | shebang-regex@3.0.0: {} 1479 | 1480 | siginfo@2.0.0: {} 1481 | 1482 | signal-exit@4.1.0: {} 1483 | 1484 | source-map-js@1.2.0: {} 1485 | 1486 | stackback@0.0.2: {} 1487 | 1488 | std-env@3.7.0: {} 1489 | 1490 | string-width@4.2.3: 1491 | dependencies: 1492 | emoji-regex: 8.0.0 1493 | is-fullwidth-code-point: 3.0.0 1494 | strip-ansi: 6.0.1 1495 | 1496 | string-width@5.1.2: 1497 | dependencies: 1498 | eastasianwidth: 0.2.0 1499 | emoji-regex: 9.2.2 1500 | strip-ansi: 7.1.0 1501 | 1502 | strip-ansi@6.0.1: 1503 | dependencies: 1504 | ansi-regex: 5.0.1 1505 | 1506 | strip-ansi@7.1.0: 1507 | dependencies: 1508 | ansi-regex: 6.0.1 1509 | 1510 | strip-final-newline@3.0.0: {} 1511 | 1512 | sucrase@3.35.0: 1513 | dependencies: 1514 | '@jridgewell/gen-mapping': 0.3.5 1515 | commander: 4.1.1 1516 | glob: 10.4.5 1517 | lines-and-columns: 1.2.4 1518 | mz: 2.7.0 1519 | pirates: 4.0.6 1520 | ts-interface-checker: 0.1.13 1521 | 1522 | supports-preserve-symlinks-flag@1.0.0: {} 1523 | 1524 | tailwindcss@3.4.7: 1525 | dependencies: 1526 | '@alloc/quick-lru': 5.2.0 1527 | arg: 5.0.2 1528 | chokidar: 3.6.0 1529 | didyoumean: 1.2.2 1530 | dlv: 1.1.3 1531 | fast-glob: 3.3.2 1532 | glob-parent: 6.0.2 1533 | is-glob: 4.0.3 1534 | jiti: 1.21.6 1535 | lilconfig: 2.1.0 1536 | micromatch: 4.0.7 1537 | normalize-path: 3.0.0 1538 | object-hash: 3.0.0 1539 | picocolors: 1.0.1 1540 | postcss: 8.4.40 1541 | postcss-import: 15.1.0(postcss@8.4.40) 1542 | postcss-js: 4.0.1(postcss@8.4.40) 1543 | postcss-load-config: 4.0.2(postcss@8.4.40) 1544 | postcss-nested: 6.2.0(postcss@8.4.40) 1545 | postcss-selector-parser: 6.1.1 1546 | resolve: 1.22.8 1547 | sucrase: 3.35.0 1548 | transitivePeerDependencies: 1549 | - ts-node 1550 | 1551 | thenify-all@1.6.0: 1552 | dependencies: 1553 | thenify: 3.3.1 1554 | 1555 | thenify@3.3.1: 1556 | dependencies: 1557 | any-promise: 1.3.0 1558 | 1559 | tinybench@2.8.0: {} 1560 | 1561 | tinypool@1.0.0: {} 1562 | 1563 | tinyrainbow@1.2.0: {} 1564 | 1565 | tinyspy@3.0.0: {} 1566 | 1567 | to-regex-range@5.0.1: 1568 | dependencies: 1569 | is-number: 7.0.0 1570 | 1571 | ts-interface-checker@0.1.13: {} 1572 | 1573 | util-deprecate@1.0.2: {} 1574 | 1575 | vite-node@2.0.5: 1576 | dependencies: 1577 | cac: 6.7.14 1578 | debug: 4.3.6 1579 | pathe: 1.1.2 1580 | tinyrainbow: 1.2.0 1581 | vite: 5.3.5 1582 | transitivePeerDependencies: 1583 | - '@types/node' 1584 | - less 1585 | - lightningcss 1586 | - sass 1587 | - stylus 1588 | - sugarss 1589 | - supports-color 1590 | - terser 1591 | 1592 | vite@5.3.5: 1593 | dependencies: 1594 | esbuild: 0.21.5 1595 | postcss: 8.4.40 1596 | rollup: 4.19.1 1597 | optionalDependencies: 1598 | fsevents: 2.3.3 1599 | 1600 | vitest@2.0.5: 1601 | dependencies: 1602 | '@ampproject/remapping': 2.3.0 1603 | '@vitest/expect': 2.0.5 1604 | '@vitest/pretty-format': 2.0.5 1605 | '@vitest/runner': 2.0.5 1606 | '@vitest/snapshot': 2.0.5 1607 | '@vitest/spy': 2.0.5 1608 | '@vitest/utils': 2.0.5 1609 | chai: 5.1.1 1610 | debug: 4.3.6 1611 | execa: 8.0.1 1612 | magic-string: 0.30.11 1613 | pathe: 1.1.2 1614 | std-env: 3.7.0 1615 | tinybench: 2.8.0 1616 | tinypool: 1.0.0 1617 | tinyrainbow: 1.2.0 1618 | vite: 5.3.5 1619 | vite-node: 2.0.5 1620 | why-is-node-running: 2.3.0 1621 | transitivePeerDependencies: 1622 | - less 1623 | - lightningcss 1624 | - sass 1625 | - stylus 1626 | - sugarss 1627 | - supports-color 1628 | - terser 1629 | 1630 | which@2.0.2: 1631 | dependencies: 1632 | isexe: 2.0.0 1633 | 1634 | why-is-node-running@2.3.0: 1635 | dependencies: 1636 | siginfo: 2.0.0 1637 | stackback: 0.0.2 1638 | 1639 | wrap-ansi@7.0.0: 1640 | dependencies: 1641 | ansi-styles: 4.3.0 1642 | string-width: 4.2.3 1643 | strip-ansi: 6.0.1 1644 | 1645 | wrap-ansi@8.1.0: 1646 | dependencies: 1647 | ansi-styles: 6.2.1 1648 | string-width: 5.1.2 1649 | strip-ansi: 7.1.0 1650 | 1651 | yaml@2.5.0: {} 1652 | --------------------------------------------------------------------------------