diff --git a/.gitignore b/.gitignore index 249a3f1..82deade 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,17 @@ node_modules/ dist/ packages/*/dist/ .turbo/ +.next/ +.vercel/ + +# Generated Fumadocs files +apps/docs/.source/ + +# Copied package docs (generated at build time) +apps/docs/content/docs/zod/ +apps/docs/content/docs/react/ +apps/docs/content/docs/supabase/ +apps/docs/content/docs/type-docs/ + +# TypeDoc-generated API docs in packages +packages/cent/docs/api/ diff --git a/README.md b/README.md index dd3dfeb..4ac456c 100644 --- a/README.md +++ b/README.md @@ -2,995 +2,74 @@ **Arbitrary-precision currency library for TypeScript/JavaScript** -`cent` is a next-generation monetary math library designed to handle currencies with **fixed precision**, no matter how large the values or how many decimal places are required. +`cent` is a monetary math library designed for applications that need **exact precision** — accounting, trading, and cryptocurrency. -This makes `cent` a good choice for accounting, F/X, trading, and cryptocurrency applications. +## Why cent? -## Why `cent`? - -### The problem - -Popular libraries like [dinero.js](https://dinerojs.com/) are built on JavaScript's `Number` type, which has fundamental limitations: - -- **Precision Loss**: JavaScript's `Number` can only safely represent integers up to `Number.MAX_SAFE_INTEGER` (2⁵³ - 1) -- **Floating Point Errors**: Floating point arithmetic can introduce rounding errors -- **Limited Scale**: Struggles with high-precision assets like cryptocurrencies. Neither assets on Bitcoin (8 decimals), Solana (9 decimals), or Ethereum (18 decimals) fit into a JS `Number`. - -### The solution - -`cent` solves these problems with: - -- **🔢 Arbitrary Precision**: Uses `BigInt` for unlimited precision arithmetic -- **💰 Multi-Asset Support**: Handles traditional currencies, cryptocurrencies, and custom assets -- **🧮 Exact Mathematics**: Fxied point math that guarantees exacy results, with options for non-fixed calculations. -- **🌍 Comprehensive Currency Database**: Built-in support for 180+ world currencies -- **🎯 Type Safety**: Full TypeScript support with strict type checking -- **🔄 Immutable**: All operations return new instances, preventing accidental mutations -- **✨ Ergonomic API**: Clean factory functions for creating numbers from strings - -## Quick start 💰 - -```typescript -import { Money, Price } from '@thesis/cent' - -// Creation -const usd = Money("$100.50") -const btc = Money("0.5 BTC") - -// Arithmetic -const total = usd.add(Money("$25.25")) // $125.75 - -// Division with rounding -import { Round } from '@thesis/cent' -const split = total.divide(3, Round.HALF_UP) // $41.92 - -// Conversion with precision preservation -const price = new Price(Money("$50,000"), Money("1 BTC")) -const converted = usd.convert(price) // Exact BTC amount - -// Allocation and distribution -const [first, second, third] = usd.allocate([1, 2, 1]) // [$25.13, $50.25, $25.12] -const [a, b, c] = usd.distribute(3) // [$33.50, $33.50, $33.50] - -// Bounds and clamping -const tip = total.multiply("20%").atLeast(5).atMost(50) // $8.38 (min $5, max $50) -const safe = Money("-$50").clamp("$0", "$100") // $0.00 - -// Formatting -usd.toString({ locale: "en-US", compact: true }) // "$100.50" -btc.toString({ preferredUnit: "satoshi" }) // "50,000,000 sat" -``` - -## Configuration - -Configure library-wide defaults at application startup: - -```typescript -import { configure, Round } from '@thesis/cent' - -// Environment-based configuration -configure({ - numberInputMode: process.env.NODE_ENV === 'production' ? 'error' : 'warn', - strictPrecision: process.env.NODE_ENV === 'production', - defaultRoundingMode: Round.HALF_UP, - defaultCurrency: 'USD', -}) -``` - -**Configuration options:** -- `numberInputMode` - How to handle JS number inputs: `'warn'`, `'error'`, or `'silent'` -- `strictPrecision` - When `true`, throw on any operation that would lose precision -- `defaultRoundingMode` - Default rounding mode, or `'none'` to require explicit rounding -- `defaultCurrency` - Default currency code (default: `'USD'`) -- `defaultLocale` - Default locale for formatting (default: `'en-US'`) - -**Scoped configuration for testing:** - -```typescript -import { withConfig } from '@thesis/cent' - -// Temporarily override configuration -withConfig({ strictPrecision: true }, () => { - // This block uses strict precision mode - const result = Money("$100").divide(2) -}) -// Configuration is restored after the block -``` - -## Safe Parsing - -For user input or external data, use `Money.parse()` which returns a `Result` type instead of throwing exceptions. This enables clean, chainable error handling without try/catch blocks: - -```typescript -import { Money } from '@thesis/cent' - -// Parse user input safely -const result = Money.parse(userInput) - .map(money => money.add("8.25%")) // Add tax if valid - .map(money => money.roundTo(2, Round.HALF_UP)) // Round to cents - -// Handle success or failure -const total = result.match({ - ok: (money) => money.toString(), - err: (error) => `Invalid amount: ${error.suggestion}`, -}) - -// Or provide a default for invalid input -const amount = Money.parse(untrustedInput).unwrapOr(Money.zero("USD")) -``` - -## Type Guards - -When working with values from external sources or loosely-typed APIs, use `Money.isMoney()` for runtime type checking with full TypeScript type narrowing: - -```typescript -import { Money } from '@thesis/cent' - -function processPayment(amount: unknown) { - if (Money.isMoney(amount)) { - // TypeScript knows amount is Money here - return amount.multiply(2n).toString() - } - return "Invalid amount" -} - -// Filter for specific currencies -const amounts = [Money("$100"), Money("€50"), Money("$25")] -const usdOnly = amounts.filter(m => Money.isMoney(m, "USD")) -// usdOnly: [Money("$100"), Money("$25")] - -// Use assertions for validation with helpful errors -Money.assertMoney(value) // Throws if not Money -Money.assertPositive(money) // Throws if not > 0 -Money.assertNonNegative(money) // Throws if < 0 -Money.assertNonZero(money) // Throws if === 0 - -// Or use validate() for Result-based validation -const result = Money("$50").validate({ min: "$10", max: "$100", positive: true }) -result.match({ - ok: (money) => processPayment(money), - err: (error) => console.log(error.suggestion), -}) -``` - -## Core utils - -### `Money()` and the `Money` class - -The `Money()` factory function makes working with currencies simple: - -```typescript -import { Money } from '@thesis/cent' - -// Parse currency symbols with auto-detection -const usd = Money('$1,234.56') // US Dollar: $1,234.56 -const eur = Money('€1.234,56') // Euro (EU format): €1,234.56 -const gbp = Money('£999.99') // British Pound: £999.99 -const jpy = Money('¥50,000') // Japanese Yen: ¥50,000 - -// Parse currency codes (case insensitive) -const dollars = Money('USD 100.50') -const euros = Money('100.50 EUR') - -// Parse cryptocurrency main units -const bitcoin = Money('₿2.5') // Bitcoin: 2.5 BTC -const ethereum = Money('ETH 10.123456') // Ethereum: 10.123456 ETH - -// Parse cryptocurrency sub-units -const satoshis = Money('1000 sat') // 1000 satoshis = 0.00001000 BTC -const wei = Money('1000000 wei') // 1000000 wei = 0.000000000001 ETH -const gwei = Money('50 gwei') // 50 gwei = 0.00000005 ETH - -// Parse with fractional unit symbols -const sats = Money('§10000') // 10000 satoshis = 0.0001 BTC -const cents = Money('¢50') // 50 cents = $0.50 -const pence = Money('p75') // 75 pence = £0.75 - -// Supports negative amounts -const debt = Money('-$500.25') -const refund = Money('€-123.45') - -// Financial precision - allows sub-cent amounts -const precise = Money('$100.12345') // 5 decimal places preserved -const microYen = Money('¥1000.001') // Sub-yen precision -``` - -**A note on symbol priority**: When symbols are shared (like $ for multiple currencies), the most traded currency takes priority based on global trading volume: `$` → USD, `£` → GBP, `¥` → JPY. Use explicit currency codes for other currencies: `AUD 100`, `CAD 50`. - -The `Money` class provides safe monetary operations with automatic precision handling: +JavaScript's `Number` type fails for financial calculations: ```typescript -import { Money, EUR, USD, Round } from '@thesis/cent' - -// Create money instances -const euros = new Money({ - asset: EUR, - amount: { amount: 50025n, decimals: 2n } // €500.25 -}) - -const dollars = new Money({ - asset: USD, - amount: { amount: 100000n, decimals: 2n } // $1,000.00 -}) - -// Basic arithmetic (same currency only) -const sum = euros.add("€250.50") -console.log(sum.toString()) // "€750.75" - -// Multiplication and division -const doubled = euros.multiply("2") -const half = euros.divide("2") // Exact: factors of 2 and 5 only -const third = euros.divide(3, Round.HALF_UP) // Rounded: other factors need rounding mode - -// Comparisons -console.log(euros.greaterThan(dollars)) // Error: Different currencies -console.log(euros.isPositive()) // true -console.log(euros.equals(euros)) // true - -// Sorting arrays using compare method -const amounts = [Money("$100"), Money("$50"), Money("$200")] -const sorted = amounts.sort((a, b) => a.compare(b)) -console.log(sorted.map(m => m.toString())) // ["$50.00", "$100.00", "$200.00"] - -// Formatting options -console.log(euros.toString({ locale: 'de-DE' })) // "500,25 €" -console.log(euros.toString({ compact: true })) // "€500" - -// Fractional unit symbol formatting -const btc = Money("0.01 BTC") -console.log(btc.toString({ preferredUnit: "sat" })) // "1,000,000 sats" -console.log(btc.toString({ preferredUnit: "sat", preferFractionalSymbol: true })) // "§1,000,000" -console.log(btc.toString({ preferredUnit: "sat", preferFractionalSymbol: true, compact: true })) // "§1M" - -// Allocation and distribution -const budget = Money("$1000") - -// Allocate proportionally by ratios -const [marketing, development, operations] = budget.allocate([2, 5, 3]) -// Results: [$200, $500, $300] (2:5:3 ratio) - -// Distribute evenly -const [alice, bob, charlie] = budget.distribute(3) -// Results: [$333.34, $333.33, $333.33] (remainder to first) - -// Handle fractional units separately -const precise = Money("$100.00015") -const parts = precise.distribute(3, { distributeFractionalUnits: false }) -// Results: [$33.33, $33.33, $33.34, $0.00015] (change separated) -``` - -## Math utilities 🧮 - -`cent` comes with two flavors of arbitrary-precision math utilities. - -`FixedPointNumber` is appropriate for financial applications that require -keeping track of "cents" or other fractional units of a currency. By -disallowing arbitrary division, fixed-point numbers make it difficult to -lose track of a fractional unit. - -`RationalNumber` is appropriate for wider arbitrary-precision math -applications. - -### Examples - -```typescript -import { FixedPoint, Rational } from '@thesis/cent' - -// FixedPoint - Perfect for decimal numbers -const price = FixedPoint('1255.50') // Auto-detects 2 decimals -const rate = FixedPoint('0.875') // Auto-detects 3 decimals - -// Percentage strings are automatically converted to decimals -const percentage = FixedPoint('51.5%') // Becomes 0.515 (auto-detects 3 decimals) -const tax = FixedPoint('8.25%') // Becomes 0.0825 (auto-detects 4 decimals) - -// Arithmetic operations with automatic precision handling -const product = price.multiply("0.875") -console.log(product.toString()) // "1098.5625" - -// Use percentage parsing in calculations -const totalWithTax = price.multiply(FixedPoint('8.25%')) -console.log(totalWithTax.toString()) // "103.5788" (8.25% of $1255.50) - -// Precise division (only multiples of 2 and 5) -const half = price.divide("2") -const fifth = price.divide("5") -const tenth = price.divide("10") - -// Comparison operations -console.log(price.greaterThan("0.875")) // true -console.log(price.lessThanOrEqual("0.875")) // false - -// Also supports original constructor for explicit control -const explicit = new FixedPointNumber(125550n, 2n) // Same as FixedPoint('1255.50') - -// Rational - fractions and exact arithmetic - -// Create from fraction strings -const oneThird = Rational('1/3') -const twoFifths = Rational('2/5') - -// Create from decimal strings (auto-converted to fractions) -const quarter = Rational('0.25') // Becomes 1/4 -const decimal = Rational('0.125') // Becomes 1/8 - -// Create directly from bigint numerator and denominator -const pi = Rational(22n, 7n) // 22/7 approximation of π -const oneThird = Rational(1n, 3n) // 1/3 - -// Exact arithmetic -const sum = oneThird.add("2/5") // (1/3) + (2/5) = 11/15 -console.log(sum.toString()) // "11/15" - -const product = oneThird.multiply("2/5") // (1/3) * (2/5) = 2/15 -console.log(product.toString()) // "2/15" - -// Automatic simplification -const simplified = Rational('6/9') -console.log(simplified.toString()) // "2/3" - -// Also supports original constructor -const explicit = new RationalNumber({ p: 1n, q: 10n }) // Same as Rational('1/10') - -// Seamless conversion between types -const rational = Rational('3/8') -const decimalStr = rational.toDecimalString() // "0.375" -const fixedPoint = FixedPoint(decimalStr) // Auto-detects 3 decimals -console.log(fixedPoint.toString()) // "0.375" +0.1 + 0.2 // 0.30000000000000004 +19.99 * 100 // 1998.9999999999998 +Number.MAX_SAFE_INTEGER // Only 9 quadrillion — too small for wei ``` -## Prices and Exchange Rates - -`cent` includes `Price` and `ExchangeRate` classes for representing price ratios between assets with mathematical operations. - -`ExchangeRate` has base/quote currency semantics, time-based operations, and everything you'd expect in a fintech app. It's appropriate rates retrieved from outside services like exchanges. - -```typescript -import { ExchangeRate, Money, USD, EUR, BTC, JPY } from '@thesis/cent' - -// 1. Individual arguments with auto-timestamping -const usdEur = new ExchangeRate(USD, EUR, "1.08") // 1.08 EUR per USD -console.log(usdEur.toString()) // "1.08 €/$" - -// 2. Individual arguments with custom timestamp and source -const btcUsd = new ExchangeRate( - BTC, USD, "50000", "1640995200", // 2022-01-01 timestamp - { name: "Coinbase", priority: 1, reliability: 0.95 } -) - -const eurJpy = new ExchangeRate({ - baseCurrency: EUR, - quoteCurrency: JPY, - rate: "162.50", - timestamp: "1640995200", - source: { name: "ECB", priority: 1, reliability: 0.99 } -}) - -console.log(usdEur.baseCurrency.code) // "USD" (1 USD costs...) -console.log(usdEur.quoteCurrency.code) // "EUR" (...1.08 EUR) - -// Rate inversion - swap base and quote -const eurUsd = usdEur.invert() // 1 EUR = 0.925925... USD -console.log(eurUsd.toString()) // "0.925925925925925926 $/@" - -// Cross-currency calculations via multiplication -// EUR/USD × USD/JPY = EUR/JPY (USD cancels out) -const eurUsdRate = new ExchangeRate(EUR, USD, "1.0842") -const usdJpyRate = new ExchangeRate(USD, JPY, "149.85") -const eurJpyCalculated = eurUsdRate.multiply(usdJpyRate) - -console.log(eurJpyCalculated.baseCurrency.code) // "EUR" -console.log(eurJpyCalculated.quoteCurrency.code) // "JPY" -console.log(eurJpyCalculated.rate.toString()) // "162.4673" (1.0842 × 149.85) - -// Currency conversion with exchange rates -const dollars = Money("$100.00") -const euros = usdEur.convert(dollars) -console.log(euros.toString()) // "€108.00" +`cent` solves this with: -// Reverse conversion (automatic direction detection) -const backConverted = usdEur.convert(euros) -console.log(backConverted.toString()) // "$100.00" +- **Arbitrary precision** — `BigInt` under the hood, no floating point errors +- **Multi-asset support** — USD, EUR, BTC, ETH, SOL, and 180+ currencies +- **Type safety** — Can't accidentally add USD to EUR +- **Immutable** — All operations return new instances +- **Zero dependencies** — 8KB gzipped -// Automatic direction detection - same rate works both ways -const rate = new ExchangeRate(USD, EUR, "1.08") // 1 USD = 1.08 EUR +## Installation -const usd100 = Money("$100") -const eur108 = rate.convert(usd100) // USD → EUR: $100 → €108 -console.log(eur108.toString()) // "€108.00" - -const convertBack = rate.convert(eur108) // EUR → USD: €108 → $100 -console.log(convertBack.toString()) // "$100.00" - -// Works with any amount and either currency in the rate -const moreEuros = Money("€540") // €540 -const convertedDollars = rate.convert(moreEuros) // €540 ÷ 1.08 = $500 -console.log(convertedDollars.toString()) // "$500.00" - -// Exchange rate averaging for multiple sources -const rate1 = new ExchangeRate(USD, EUR, "1.07") -const rate2 = new ExchangeRate(USD, EUR, "1.09") -const averaged = new ExchangeRate( - ExchangeRate.average([rate1, rate2]) -) -console.log(averaged.rate.toString()) // "1.080" (average of 1.07 and 1.09) - -// Time-based operations -const currentRate = new ExchangeRate(USD, EUR, "1.08") -console.log(currentRate.isStale(300000)) // false (less than 5 minutes old) - -// Formatting options -console.log(usdEur.toString()) // "1.08 €/$" (symbol format) -console.log(usdEur.toString({ format: "code" })) // "1.08 EUR/USD" (code format) -console.log(usdEur.toString({ format: "ratio" })) // "1 USD = 1.08 EUR" (ratio format) - -// JSON serialization with BigInt support -const serialized = usdEur.toJSON() -const restored = ExchangeRate.fromJSON(serialized) -console.log(restored.equals(usdEur)) // true - -// create bid/ask spreads for trading -const rate = new ExchangeRate(USD, EUR, "1.2000") - -// apply spread using decimal string (2% spread) -const { bid, ask, mid } = rate.spread("0.02") // "2%" also works -console.log(bid.rate.toString()) // "1.1880" (1.2000 - 1% of 1.2000) -console.log(ask.rate.toString()) // "1.2120" (1.2000 + 1% of 1.2000) -console.log(mid.rate.toString()) // "1.2000" (original rate) +```bash +npm install @thesis-co/cent ``` -`Price` is appropriate for arbitrary price pairs, covering the edge cases where `ExchangeRate` might not be appropriate. It's easier to construct a new `Price` and do math with it. +## Quick Start ```typescript -import { Price, USD, EUR, BTC, JPY } from '@thesis/cent' - -// Define custom assets (for demonstration purposes) -const APPLE = { - name: 'Apple', - code: 'APPLE', - decimals: 0n, - symbol: '🍎' -} - -const ORANGE = { - name: 'Orange', - code: 'ORANGE', - decimals: 0n, - symbol: '🍊' -} - -// Create price ratios -const usdPerApple = new Price( - Money("$5.00"), // $5.00 - { asset: APPLE, amount: { amount: 1n, decimals: 0n } } // 1 apple (custom asset) -) - -const applesPerBtc = new Price( - { asset: APPLE, amount: { amount: 10000n, decimals: 0n } }, // 10,000 apples - Money("1 BTC") // 1.00000000 BTC -) - -// Price-to-Price multiplication (assets must share a common unit) -// $5/apple × 10,000 apples/BTC = $50,000/BTC -// while this is fun, remember that there might not be apple-to-BTC liquidity 😉 -const usdPerBtc = usdPerApple.multiply(applesPerBtc) -console.log(usdPerBtc.amounts[0].amount.amount) // 5000000n ($50,000.00) - -// Price-to-Price division -// $50,000/BTC ÷ $5/apple = 10,000 apples/BTC -const calculatedApplesPerBtc = usdPerBtc.divide(usdPerApple) - -// Scalar operations (multiply/divide by numbers) -const doubledPrice = usdPerApple.multiply("2") // $10.00/apple -const halfPrice = usdPerApple.divide("2") // $2.50/apple - -// Convert to mathematical ratio -const ratio = usdPerApple.asRatio() // RationalNumber: 500/1 +import { Money, Round } from '@thesis-co/cent' -// Price operations validate shared assets -try { - const orangesPerBtc = new Price( - { asset: ORANGE, amount: { amount: 5000n, decimals: 0n } }, - Money("1 BTC") - ) - usdPerApple.multiply(orangesPerBtc) // Error: no shared asset! -} catch (error) { - console.log(error.message) - // "Cannot multiply prices: no shared asset found between US Dollar/Apple and Orange/Bitcoin" -} -``` - -## Price Ranges - -`cent` includes a `PriceRange` class for representing and manipulating price ranges with precision. Perfect for e-commerce filters, pricing strategies, and financial analysis. - -```typescript -import { PriceRange, Money, USD, EUR } from '@thesis/cent' - -// Create ranges from strings -const range1 = PriceRange("$50 - $100") -const range2 = PriceRange("$50-100") // Compact format -const range3 = PriceRange("€25 - €75") - -// Create from Money instances -const range4 = PriceRange(Money("$50"), Money("$100")) - -// Mixed creation -const range5 = PriceRange("$50", Money("$100")) - -console.log(range1.min.toString()) // "$50.00" -console.log(range1.max.toString()) // "$100.00" -console.log(range1.span.toString()) // "$50.00" (difference) -console.log(range1.midpoint.toString()) // "$75.00" (precise midpoint) - -// Range operations and queries -console.log(range1.contains(Money("$75"))) // true -console.log(range1.contains("$25")) // false -console.log(range1.isAbove(Money("$40"))) // true (entire range above $40) -console.log(range1.isBelow(Money("$120"))) // true (entire range below $120) - -// Range mathematics -const range6 = PriceRange("$80 - $150") -console.log(range1.overlaps(range6)) // true - -const intersection = range1.intersect(range6) -console.log(intersection?.toString()) // "$80.00 - $100.00" - -const union = range1.union(range6) -console.log(union.toString()) // "$50.00 - $150.00" - -// Split ranges into equal parts -const parts = range1.split(3) -console.log(parts[0].toString()) // "$50.00 - $66.67" -console.log(parts[1].toString()) // "$66.67 - $83.33" -console.log(parts[2].toString()) // "$83.33 - $100.00" - -// Static factory methods for common patterns -const underRange = PriceRange.under(Money("$100")) // "$0.00 - $100.00" -const overRange = PriceRange.over(Money("$50"), Money("$500")) // "$50.00 - $500.00" -const aroundRange = PriceRange.around(Money("$100"), "10%") // "$90.00 - $110.00" - -// Create price buckets for filters -const buckets = PriceRange.createBuckets(Money("$0"), Money("$500"), 5) -buckets.forEach((bucket, i) => { - console.log(`Bucket ${i + 1}: ${bucket.toString()}`) -}) -// Bucket 1: $0.00 - $100.00 -// Bucket 2: $100.00 - $200.00 -// Bucket 3: $200.00 - $300.00 -// Bucket 4: $300.00 - $400.00 -// Bucket 5: $400.00 - $500.00 - -// Display formatting options -console.log(range1.toString()) // "$50.00 - $100.00" (default) -console.log(range1.toString({ format: "compact" })) // "$50-100" -console.log(range1.toString({ format: "from" })) // "From $50.00" -console.log(range1.toString({ format: "upTo" })) // "Up to $100.00" -console.log(range1.toString({ format: "range" })) // "$50.00 to $100.00" -console.log(range1.toString({ format: "between" })) // "Between $50.00 and $100.00" - -// Localized formatting -const eurRange = PriceRange("€50 - €100") -console.log(eurRange.toString({ locale: "de-DE" })) // "50,00 € - 100,00 €" - -// Large ranges with compact notation -const largeRange = PriceRange("$1000000 - $5000000") -console.log(largeRange.toString({ compact: true })) // "$1M - $5M" - -// Currency conversion -const exchangeRate = new ExchangeRate(USD, EUR, "0.85") -const convertedRange = range1.convert(exchangeRate) -console.log(convertedRange.toString()) // "€42.50 - €85.00" - -// E-commerce product filtering -const products = [ - { name: "Budget Widget", price: Money("$45") }, - { name: "Standard Widget", price: Money("$75") }, - { name: "Premium Widget", price: Money("$125") }, - { name: "Deluxe Widget", price: Money("$95") } -] - -const priceFilter = PriceRange("$50 - $100") -const affordableProducts = products.filter(product => - priceFilter.contains(product.price) -) - -console.log(affordableProducts.map(p => p.name)) -// ["Standard Widget", "Deluxe Widget"] - -// JSON serialization for APIs and storage -const serialized = range1.toJSON() -console.log(JSON.stringify(serialized)) - -const restored = PriceRange.fromJSON(serialized) -console.log(restored.equals(range1)) // true - -// Cryptocurrency ranges with full precision -const btcRange = PriceRange("₿0.001 - ₿0.01") -console.log(btcRange.contains(Money("₿0.005"))) // true -console.log(btcRange.toString({ preferredUnit: "sat" })) // "100,000 sats - 1,000,000 sats" -``` - -## Other features - -### Supabase Integration - -For Supabase/PostgREST applications, see [`@thesis-co/cent-supabase`](./packages/cent-supabase) which automatically handles `DECIMAL`/`NUMERIC` columns, preventing JavaScript precision loss. - -### Zod Integration - -For input validation and parsing, see [`@thesis-co/cent-zod`](./packages/cent-zod) which provides Zod schemas for all `cent` types. - -### Currency support - -`cent` includes comprehensive currency metadata for accurate formatting: - -```typescript -import { USD, EUR, BTC, ETH, JPY } from '@thesis/cent' - -// Traditional currencies -console.log(USD.decimals) // 2n -console.log(USD.symbol) // "$" -console.log(USD.fractionalUnit) // "cent" - -// Cryptocurrencies with high precision -console.log(BTC.decimals) // 8n -console.log(BTC.fractionalUnit) // Complex object with multiple units - -// Currencies with no decimals -console.log(JPY.decimals) // 0n -``` - -### JSON Serialization - -Safe serialization for APIs and storage: - -```typescript -const money = Money("$1,234,567,890,123.45") - -// serialize (BigInt becomes string) -const json = money.toJSON() -console.log(JSON.stringify(json)) -// {"asset":{"name":"United States dollar","code":"USD","decimals":"2","symbol":"$"},"amount":"1234567890123.45"} - -// Deserialize -const restored = Money.fromJSON(json) -console.log(restored.equals(money)) // true - -// FixedPointNumber also serializes as decimal strings preserving trailing zeros -const fp = FixedPoint("12.34500") -console.log(JSON.stringify(fp)) // "12.34500" -const restoredFp = FixedPointNumber.fromJSON("12.34500") -console.log(restoredFp.equals(fp)) // true -``` - -### Precision handling - -`cent` automatically handles different precisions: - -```typescript -// different decimal places are automatically normalized -const fp1 = FixedPoint("10.0") // 1 decimal -const fp2 = FixedPoint("5.00") // 2 decimals - -const sum = fp1.add("5.00") // Normalized to 2 decimals -console.log(sum.toString()) // "15.00" -``` - -### Rounding modes - -`cent` provides rounding modes for operations that may produce values that cannot be represented exactly: - -```typescript -import { Money, Round } from '@thesis/cent' - -const price = Money("$100.00") - -// Division with rounding -price.divide(3, Round.HALF_UP) // $33.33 -price.divide(3, Round.HALF_EVEN) // $33.33 (banker's rounding) -price.divide(3, Round.CEILING) // $33.34 -price.divide(3, Round.FLOOR) // $33.33 - -// Available rounding modes: -// - Round.UP - Round away from zero -// - Round.DOWN - Round toward zero (truncate) -// - Round.CEILING - Round toward positive infinity -// - Round.FLOOR - Round toward negative infinity -// - Round.HALF_UP - Round to nearest, ties away from zero (common commercial rounding) -// - Round.HALF_DOWN - Round to nearest, ties toward zero -// - Round.HALF_EVEN - Round to nearest, ties to even (banker's rounding) - -// Round to currency precision -const precise = Money({ asset: USD, amount: { amount: 100125n, decimals: 3n } }) -precise.round() // $100.13 (HALF_UP by default) -precise.round(Round.HALF_EVEN) // $100.12 (banker's rounding) - -// Round to specific decimal places -precise.roundTo(2) // 2 decimal places -precise.roundTo(0, Round.HALF_UP) // Round to whole dollars - -// Multiply with rounding -price.multiply("0.333", Round.HALF_UP) // $33.30 -``` - -### Safe division - -Unlike floating-point arithmetic, `cent` ensures exact division results when possible: - -```typescript -const number = FixedPoint("100") // 100 - -// Exact division (factors of 2 and 5 only) -console.log(number.divide("2").toString()) // "50.0" -console.log(number.divide("4").toString()) // "25.00" -console.log(number.divide("5").toString()) // "20.0" -console.log(number.divide("10").toString()) // "10.0" - -// Division by other factors requires a rounding mode -try { - number.divide("3") // throws error -} catch (error) { - console.log(error.message) // "Division by 3 requires a rounding mode..." -} - -// Money.divide() with rounding mode for non-exact division -const money = Money("$100.00") -money.divide(3, Round.HALF_UP) // $33.33 -money.divide(7, Round.CEILING) // $14.29 -``` - -If you need division that would break out of what's possible to represent in -fixed point, you can mix `FixedPointNumber` and `RationalNumber`. - -```typescript -Rational("1/3").multiply(FixedPoint("100")) -``` - -## Use cases - -### FinTech -```typescript -// handle large transfers with perfect precision -const wireTransfer = Money("$9,999,999,999.99") - -const fee = wireTransfer.multiply("0.005") // 0.5% fee -const afterFee = wireTransfer.subtract(fee) -``` - -### Cryptocurrencies -```typescript -// handle Bitcoin with satoshi and sub-satoshi precision -const satoshiAmount = Money("1 BTC") - -console.log(satoshiAmount.toString({ preferredUnit: 'satoshi' })) -// "100,000,000 satoshis" - -satoshiAmount.equals(Money("100000000 sat")) // true - -// ethereum with wei precision (18 decimals) -const weiAmount = Money("1 ETH") - -// Also supports original constructor for explicit control -const explicit = new Money({ - asset: ETH, - amount: { amount: 1000000000000000000n, decimals: 18n } // Same as Money("1 ETH") -}) - -weiAmount.equals(Money("Ξ1.0")) // true -``` - -### Accounting & bookkeeping - -```typescript -// Allocate amounts without losing precision -const revenue = Money("$12,345.67") - -// Proportional allocation by department budgets -const [marketing, engineering, sales, operations] = revenue.allocate([2, 5, 2, 1]) -// Results: [$2,469.13, $6,172.84, $2,469.13, $1,234.57] (2:5:2:1 ratio) +// Create money from strings +const price = Money("$100.50") +const btc = Money("0.5 BTC") -// Even distribution among team members -const bonus = Money("$10,000") -const [alice, bob, charlie] = bonus.distribute(3) -// Results: [$3,333.34, $3,333.33, $3,333.33] (remainder to first recipient) +// Arithmetic +const total = price.add("$25.25") // $125.75 +const tax = price.multiply("8.25%") // $8.29 +const split = total.divide(3, Round.HALF_UP) // $41.92 -// Handle fractional units for precision accounting -const preciseAmount = Money("$1,000.00123") // High-precision amount -const parts = preciseAmount.allocate([1, 1, 1], { distributeFractionalUnits: false }) -// Results: [$333.33, $333.33, $333.34, $0.00123] -// Main allocations clean, fractional $0.00123 can go to a separate ledger +// Distribution +const [a, b, c] = price.allocate([1, 2, 1]) // [$25.13, $50.25, $25.12] -// Traditional concretization for currency sub-units -const [main, change] = preciseAmount.concretize() -console.log(main.toString()) // "$1,000.00" (standard currency precision) -console.log(change.toString()) // "$0.00123" (sub-unit precision) +// Formatting +console.log(price.toString()) // "$100.50" +console.log(btc.toString({ preferredUnit: "sat" })) // "50,000,000 sats" ``` -## API reference - -### Factory Functions - -**`Money()`** - Parse currency strings with intelligent format detection -- `Money(str)` - Parse currency strings with symbols, codes, and crypto units - - Currency symbols: `Money('$100.50')`, `Money('€1.234,56')`, `Money('£999')` - - Currency codes: `Money('USD 100')`, `Money('100.50 EUR')` (case insensitive) - - Crypto main units: `Money('₿2.5')`, `Money('ETH 10.123456')` - - Crypto sub-units: `Money('1000 sat')`, `Money('50 gwei')`, `Money('1000000 wei')` - - Negative amounts: `Money('-$500')`, `Money('$-123.45')` - - Sub-unit precision: `Money('$100.12345')` (preserves exact precision) -- `Money(balance)` - Create from AssetAmount object (original constructor) - -**`FixedPoint()`** - Create fixed-point numbers with ease -- `FixedPoint(str)` - Parse decimal string, auto-detect precision (e.g., `FixedPoint('123.45')`) -- `FixedPoint(percentage)` - Parse percentage string, auto-convert to decimal (e.g., `FixedPoint('51.5%')` → `0.515`) -- `FixedPoint(fixedPoint)` - Copy/clone existing FixedPoint object (e.g., `FixedPoint(existing)`) -- `FixedPoint(amount, decimals)` - Create from bigint values (e.g., `FixedPoint(12345n, 2n)`) - -**`Rational()`** - Create rational numbers from strings, bigints, or objects -- `Rational(str)` - Parse fraction (e.g., `Rational('22/7')`) or decimal (e.g., `Rational('0.125')`) -- `Rational(p, q)` - Create from bigint numerator and denominator (e.g., `Rational(22n, 7n)`) -- `Rational(ratio)` - Create from Ratio object (e.g., `Rational({ p: 1n, q: 3n })`) - -**`PriceRange()`** - Create price ranges with intelligent parsing -- `PriceRange(str)` - Parse range strings (e.g., `PriceRange('$50 - $100')`, `PriceRange('$50-100')`) -- `PriceRange(min, max)` - Create from Money instances or strings (e.g., `PriceRange(Money('$50'), '$100')`) - -### `Round` - -Constants for rounding mode selection in arithmetic operations: - -- `Round.UP` - Round away from zero -- `Round.DOWN` - Round toward zero (truncate) -- `Round.CEILING` - Round toward positive infinity -- `Round.FLOOR` - Round toward negative infinity -- `Round.HALF_UP` - Round to nearest, ties away from zero -- `Round.HALF_DOWN` - Round to nearest, ties toward zero -- `Round.HALF_EVEN` - Round to nearest, ties to even (banker's rounding) - -### `Money` - -**Arithmetic Operations (add/subtract accept Money objects or currency strings):** -- `add(other)` - Add money amounts (same currency) -- `subtract(other)` - Subtract money amounts (same currency) -- `multiply(scalar, round?)` - Multiply by number, FixedPoint, or string; optional rounding mode -- `divide(divisor, round?)` - Divide by number, bigint, or string; rounding mode required for non-2/5 factors -- `absolute()` - Get absolute value -- `negate()` - Flip sign (multiply by -1) - -**Rounding Operations:** -- `round(mode?)` - Round to currency precision (default: `Round.HALF_UP`) -- `roundTo(decimals, mode?)` - Round to specific decimal places - -**Allocation & Distribution:** -- `allocate(ratios, options?)` - Split proportionally by ratios with optional fractional unit separation -- `distribute(parts, options?)` - Split evenly into N parts with optional fractional unit separation -- `concretize()` - Split into concrete amount and change - -**Comparison Methods (accept Money objects or currency strings):** -- `compare(other)` - Compare values: returns -1 if less, 0 if equal, 1 if greater -- `equals(other)` - Check equality -- `lessThan(other)` - Less than comparison -- `greaterThan(other)` - Greater than comparison -- `lessThanOrEqual(other)` - Less than or equal comparison -- `greaterThanOrEqual(other)` - Greater than or equal comparison -- `max(other | others[])` - Return maximum value -- `min(other | others[])` - Return minimum value - -**State Checks:** -- `isZero()` - Check if amount is zero -- `isPositive()` - Check if amount is positive -- `isNegative()` - Check if amount is negative -- `hasChange()` - Check if has fractional part -- `hasSubUnits()` - Check if has sub-units beyond currency precision - -**Conversion & Formatting:** -- `convert(price)` - Convert to another currency using price/exchange rate -- `toString(options)` - Format for display with locale, precision, and unit options -- `toJSON()` - Serialize to JSON -- `fromJSON(json)` - Deserialize from JSON +## Documentation -### `FixedPointNumber` +- [Getting Started](./apps/docs/content/docs/getting-started.mdx) — Installation and configuration +- [Core Concepts](./apps/docs/content/docs/core-concepts.mdx) — Precision, immutability, rounding modes +- **API Reference** + - [Money](./apps/docs/content/docs/api/money.mdx) — Primary currency type + - [FixedPoint & Rational](./apps/docs/content/docs/api/fixed-point.mdx) — Numeric types + - [ExchangeRate](./apps/docs/content/docs/api/exchange-rate.mdx) — Currency conversion + - [Price](./apps/docs/content/docs/api/price.mdx) — Arbitrary price ratios + - [PriceRange](./apps/docs/content/docs/api/price-range.mdx) — Price range operations +- **Guides** + - [Tax Calculations](./apps/docs/content/docs/guides/tax-calculations.mdx) — Percentages and discounts + - [Splitting Bills](./apps/docs/content/docs/guides/splitting-bills.mdx) — Fair distribution + - [Crypto Precision](./apps/docs/content/docs/guides/crypto-precision.mdx) — BTC, ETH, SOL -**Arithmetic Operations (accepts FixedPoint objects or string arguments):** -- `add(other)` - Addition -- `subtract(other)` - Subtraction -- `multiply(other)` - Multiplication -- `divide(other)` - Safe division -- `normalize(target)` - Change decimal precision +## Integrations -**Comparison Methods (accepts FixedPoint objects or string arguments):** -- `equals(other)` - Equality check -- `greaterThan(other)` - Greater than comparison -- `lessThan(other)` - Less than comparison -- `max(other | others[])` - Return maximum value -- `min(other | others[])` - Return minimum value - -**Utility Methods:** -- `toString()` - DecimalString representation -- `parseString(str, decimals)` - Parse from string with explicit decimals -- `fromDecimalString(str)` - Parse from DecimalString with auto-detected decimals - -### `RationalNumber` - -**Arithmetic Operations (accepts Ratio objects, fraction strings, or decimal strings):** -- `add(other)` - Exact addition -- `subtract(other)` - Exact subtraction -- `multiply(other)` - Exact multiplication -- `divide(other)` - Exact division - -**Comparison Methods (accepts Ratio objects, fraction strings, or decimal strings):** -- `equals(other)` - Equality check -- `greaterThan(other)` - Greater than comparison -- `lessThan(other)` - Less than comparison -- `max(other | others[])` - Return maximum value -- `min(other | others[])` - Return minimum value - -**Utility Methods:** -- `simplify()` - Reduce to lowest terms -- `toString()` - Convert to simplified "p/q" string format -- `toDecimalString(precision?)` - Convert to DecimalString (default 50 digits) -- `toFixedPoint()` - Convert to decimal (when possible) - -### `Price` - -- `multiply(scalar | Price)` - Scalar multiplication or Price-to-Price multiplication -- `divide(scalar | Price)` - Scalar division or Price-to-Price division -- `asRatio()` - Convert to RationalNumber ratio -- `invert()` - Swap numerator and denominator -- `equals(other)` - Check equality (including time for timed prices) -- `toExchangeRate(options?)` - Convert to ExchangeRate with configurable precision and base currency selection - -### `ExchangeRate` - -**Constructor Overloads:** -- `new ExchangeRate(data)` - Create from ExchangeRateData object -- `new ExchangeRate(baseCurrency, quoteCurrency, rate, timestamp?, source?)` - Create from individual arguments -- -**Exchange Rate Specific:** -- `multiply(scalar | ExchangeRate)` - Scalar multiplication or cross-currency rate calculation -- `divide(scalar | ExchangeRate)` - Scalar division or rate division -- `invert()` - Swap base and quote currencies (1/rate) -- `convert(money)` - Convert Money between currencies (automatic direction detection) -- `isStale(thresholdMs)` - Check if rate is older than threshold -- `toString(options?)` - Format as "rate quote/base" with symbol, code, or ratio formats -- `toJSON()` - Serialize to JSON with BigInt string conversion -- `fromJSON(json)` - Deserialize from JSON -- `average(rates[])` - Static method to average multiple rates -- `fromPrice(price, options)` - Static method to create ExchangeRate from Price with configurable precision - -### `PriceRange` - -**Properties:** -- `min` - Minimum price (Money instance) -- `max` - Maximum price (Money instance) -- `span` - Difference between max and min (Money instance) -- `midpoint` - Precise midpoint of the range (Money instance) -- `isEmpty` - True if min equals max -- `currency` - Currency of the range - -**Range Operations:** -- `contains(price)` - Check if price is within range (inclusive) -- `isAbove(price)` - Check if entire range is above a price -- `isBelow(price)` - Check if entire range is below a price -- `overlaps(other)` - Check if ranges overlap -- `intersect(other)` - Get intersection range (or null) -- `union(other)` - Get union range -- `split(parts)` - Split into N equal parts - -**Conversion & Formatting:** -- `convert(exchangeRate)` - Convert to different currency -- `toString(options?)` - Format for display with multiple format styles -- `toJSON(options?)` - Serialize to JSON -- `fromJSON(json)` - Deserialize from JSON (static) -- `equals(other)` - Check equality - -**Static Factory Methods:** -- `under(max)` - Create range from zero to max -- `over(min, max)` - Create range from min to max -- `between(min, max)` - Alias for constructor -- `around(basePrice, percentage)` - Create range around price with margin -- `createBuckets(min, max, count)` - Create N equal price buckets +- [`@thesis-co/cent-zod`](./packages/cent-zod) — Zod schemas for validation +- [`@thesis-co/cent-react`](./packages/cent-react) — React input and display components +- [`@thesis-co/cent-supabase`](./packages/cent-supabase) — Automatic DECIMAL/NUMERIC handling for Supabase ## Comparison with dinero.js @@ -999,10 +78,10 @@ Constants for rounding mode selection in arithmetic operations: | **Precision** | Arbitrary (BigInt) | Limited (Number) | | **Max Value** | Unlimited | ~9 quadrillion | | **Crypto Support** | Native (8-18 decimals) | Limited | -| **Allocation/Distribution** | Advanced with fractional unit separation | Basic | +| **Allocation** | Advanced with fractional separation | Basic | | **Exact Division** | Guaranteed* | No | | **Type Safety** | Full TypeScript | Partial | -| **Immutability** | Yes | Yes | -| **Performance** | Excellent | Good | -*For divisors composed of factors 2 and 5 only +## License + +MIT diff --git a/apps/docs/README.md b/apps/docs/README.md new file mode 100644 index 0000000..2dab22a --- /dev/null +++ b/apps/docs/README.md @@ -0,0 +1,105 @@ +# cent Documentation Site + +Documentation site for the cent financial math library, built with [Fumadocs](https://fumadocs.dev) and Next.js. + +## Development + +```bash +pnpm dev +``` + +This starts the dev server at http://localhost:3000. + +## Content Structure + +Documentation lives in two places: + +1. **Site-level docs** in `content/docs/` - Core documentation like getting started, core concepts, guides +2. **Package docs** in each package's `docs/` folder - Integration-specific documentation + +The build process automatically copies package documentation from: + +- `packages/cent-zod/docs/` → `content/docs/zod/` +- `packages/cent-react/docs/` → `content/docs/react/` +- `packages/cent-supabase/docs/` → `content/docs/supabase/` + +These copied directories are gitignored. The `copy-docs` script runs automatically before `dev` and `build`. + +## TypeDocs (Auto-generated API Reference) + +The TypeDocs section at `/docs/type-docs` contains API documentation auto-generated from JSDoc comments in the source code using [TypeDoc](https://typedoc.org/). + +### How it works + +1. **TypeDoc generates markdown** from JSDoc comments in `packages/cent/src/` +2. **Output goes to** `packages/cent/docs/api/` (gitignored) +3. **copy-docs processes these files** by: + - Adding frontmatter (title, description) + - Organizing into grouped sections (Core Types, Math, Errors, etc.) + - Copying to `content/docs/type-docs/` (gitignored) + +### Regenerating TypeDocs + +To update the API documentation after changing JSDoc comments: + +```bash +# From the monorepo root +pnpm --filter @thesis-co/cent docs:api + +# Then restart dev server or rebuild +pnpm dev +``` + +The `copy-docs` script runs automatically on `dev` and `build`, so you only need to manually run `docs:api` when JSDoc comments change. + +### TypeDoc configuration + +Configuration is in `packages/cent/typedoc.json`. Key settings: + +- `outputFileStrategy: "members"` - Separate file per class/function/type +- `fileExtension: ".md"` - Use .md to avoid MDX JSX parsing issues +- `hidePageHeader: true` - Frontmatter is added by copy-docs instead + +### Sidebar organization + +The `copy-docs` script creates custom `meta.json` files to organize the sidebar: + +- **Classes**: Core Types → Math → Results → Errors +- **Functions**: Factories → Configuration → Result Helpers → Type Guards → Utilities +- **Interfaces**: Configuration → Exchange Rates → Currency +- **Type Aliases**: Core Types → Math → Results & Errors → Exchange Rates → Currency Symbols → Time + +To modify the organization, edit `TYPEDOC_META_CONFIGS` in `scripts/copy-package-docs.ts`. + +## Building + +```bash +pnpm build +``` + +This runs the doc copy script and builds the Next.js site. + +## Deployment + +The site deploys to Cloudflare Pages. + +### Manual deployment + +```bash +pnpm build # Build Next.js +pnpm pages:build # Convert to Cloudflare Pages format +pnpm pages:deploy # Deploy to Cloudflare +``` + +### CI deployment + +Connect the repo to Cloudflare Pages with: + +- Build command: `cd apps/docs && pnpm build && pnpm pages:build` +- Build output directory: `apps/docs/.vercel/output/static` + +Note: The `.vercel/output/static` path is required by `@cloudflare/next-on-pages` which uses Vercel's Build Output API format internally. + +## Interactive Playground + +The `/playground` page provides an interactive TypeScript editor with the cent library available globally. Code is executed client-side using [Sucrase](https://github.com/alangpierce/sucrase) for TypeScript compilation. diff --git a/apps/docs/app/(home)/page.tsx b/apps/docs/app/(home)/page.tsx new file mode 100644 index 0000000..5a7655b --- /dev/null +++ b/apps/docs/app/(home)/page.tsx @@ -0,0 +1,34 @@ +import Link from "next/link" +import { CopyCodeBlock } from "@/components/ui/CopyCodeBlock" + +export default function HomePage() { + return ( +
+
+

cent

+

+ Bulletproof financial math for TypeScript. +

+ +
+ +
+ +
+ + Get Started + + + Playground + +
+
+
+ ) +} diff --git a/apps/docs/app/api/search/route.ts b/apps/docs/app/api/search/route.ts new file mode 100644 index 0000000..d44f0a5 --- /dev/null +++ b/apps/docs/app/api/search/route.ts @@ -0,0 +1,14 @@ +import { createSearchAPI } from "fumadocs-core/search/server" +import { source } from "@/lib/source" + +export const runtime = "edge" + +export const { GET } = createSearchAPI("advanced", { + indexes: source.getPages().map((page) => ({ + title: page.data.title, + description: page.data.description, + url: page.url, + id: page.url, + structuredData: page.data.structuredData, + })), +}) diff --git a/apps/docs/app/docs/[[...slug]]/page.tsx b/apps/docs/app/docs/[[...slug]]/page.tsx new file mode 100644 index 0000000..7bfb345 --- /dev/null +++ b/apps/docs/app/docs/[[...slug]]/page.tsx @@ -0,0 +1,47 @@ +import defaultMdxComponents from "fumadocs-ui/mdx" +import { Tab, Tabs } from "fumadocs-ui/components/tabs" +import { + DocsBody, + DocsDescription, + DocsPage, + DocsTitle, +} from "fumadocs-ui/page" +import { notFound } from "next/navigation" +import { source } from "@/lib/source" + +export default async function Page(props: { + params: Promise<{ slug?: string[] }> +}) { + const params = await props.params + const page = source.getPage(params.slug) + if (!page) notFound() + + const MDX = page.data.body + + return ( + + {page.data.title} + {page.data.description} + + + + + ) +} + +export async function generateStaticParams() { + return source.generateParams() +} + +export async function generateMetadata(props: { + params: Promise<{ slug?: string[] }> +}) { + const params = await props.params + const page = source.getPage(params.slug) + if (!page) notFound() + + return { + title: page.data.title, + description: page.data.description, + } +} diff --git a/apps/docs/app/docs/layout.tsx b/apps/docs/app/docs/layout.tsx new file mode 100644 index 0000000..1354594 --- /dev/null +++ b/apps/docs/app/docs/layout.tsx @@ -0,0 +1,19 @@ +import { DocsLayout } from "fumadocs-ui/layouts/docs" +import type { ReactNode } from "react" +import { source } from "@/lib/source" + +export default function Layout({ children }: { children: ReactNode }) { + return ( + + {children} + + ) +} diff --git a/apps/docs/app/globals.css b/apps/docs/app/globals.css new file mode 100644 index 0000000..ccd071d --- /dev/null +++ b/apps/docs/app/globals.css @@ -0,0 +1,55 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +:root { + /* Black on white color scheme */ + --fd-background: 0 0% 100%; + --fd-foreground: 0 0% 5%; + --fd-primary: 0 0% 0%; + --fd-primary-foreground: 0 0% 100%; + --fd-muted: 0 0% 96%; + --fd-muted-foreground: 0 0% 30%; + --fd-border: 0 0% 85%; + --fd-card: 0 0% 98%; + --fd-card-foreground: 0 0% 5%; + --fd-accent: 0 0% 95%; + --fd-accent-foreground: 0 0% 10%; + --fd-popover: 0 0% 100%; + --fd-popover-foreground: 0 0% 5%; + --fd-secondary: 0 0% 96%; + --fd-secondary-foreground: 0 0% 10%; +} + +.dark { + /* Inverted for dark mode */ + --fd-background: 0 0% 5%; + --fd-foreground: 0 0% 95%; + --fd-primary: 0 0% 100%; + --fd-primary-foreground: 0 0% 0%; + --fd-muted: 0 0% 12%; + --fd-muted-foreground: 0 0% 70%; + --fd-border: 0 0% 20%; + --fd-card: 0 0% 8%; + --fd-card-foreground: 0 0% 95%; + --fd-accent: 0 0% 15%; + --fd-accent-foreground: 0 0% 90%; + --fd-popover: 0 0% 8%; + --fd-popover-foreground: 0 0% 95%; + --fd-secondary: 0 0% 15%; + --fd-secondary-foreground: 0 0% 90%; +} + +/* Ensure monospace throughout */ +body { + font-family: var(--font-mono), ui-monospace, monospace; +} + +/* Code blocks styling */ +pre { + font-family: var(--font-mono), ui-monospace, monospace !important; +} + +code { + font-family: var(--font-mono), ui-monospace, monospace !important; +} diff --git a/apps/docs/app/layout.tsx b/apps/docs/app/layout.tsx new file mode 100644 index 0000000..a1d5535 --- /dev/null +++ b/apps/docs/app/layout.tsx @@ -0,0 +1,57 @@ +import "./globals.css" +import { RootProvider } from "fumadocs-ui/provider" +import type { Metadata } from "next" +import { JetBrains_Mono } from "next/font/google" +import type { ReactNode } from "react" + +const mono = JetBrains_Mono({ + subsets: ["latin"], + variable: "--font-mono", +}) + +export const metadata: Metadata = { + title: { + default: "Cent - Arbitrary-precision currency library for TypeScript", + template: "%s | Cent", + }, + description: + "Bulletproof financial math for TypeScript. Built for humans. Optimized for AI.", + keywords: [ + "typescript", + "money", + "currency", + "financial", + "precision", + "bigint", + "library", + ], + authors: [{ name: "Thesis", url: "https://thesis.co" }], + openGraph: { + title: "Cent - Arbitrary-precision currency library for TypeScript", + description: + "Bulletproof financial math for TypeScript. Built for humans. Optimized for AI.", + url: "https://cent.thesis.co", + siteName: "Cent", + type: "website", + }, + twitter: { + card: "summary_large_image", + title: "Cent - Arbitrary-precision currency library for TypeScript", + description: + "Bulletproof financial math for TypeScript. Built for humans. Optimized for AI.", + }, + robots: { + index: true, + follow: true, + }, +} + +export default function RootLayout({ children }: { children: ReactNode }) { + return ( + + + {children} + + + ) +} diff --git a/apps/docs/app/playground/page.tsx b/apps/docs/app/playground/page.tsx new file mode 100644 index 0000000..8ee80a2 --- /dev/null +++ b/apps/docs/app/playground/page.tsx @@ -0,0 +1,23 @@ +import type { Metadata } from "next" +import { Playground } from "@/components/playground/Playground" + +export const metadata: Metadata = { + title: "Playground | Cent", + description: + "Interactive TypeScript playground for the cent financial math library", +} + +export default function PlaygroundPage() { + return ( +
+
+

Playground

+

+ Experiment with the cent library in this interactive TypeScript + editor. Changes run automatically as you type. +

+
+ +
+ ) +} diff --git a/apps/docs/components/playground/Playground.tsx b/apps/docs/components/playground/Playground.tsx new file mode 100644 index 0000000..45e667e --- /dev/null +++ b/apps/docs/components/playground/Playground.tsx @@ -0,0 +1,161 @@ +"use client" + +import dynamic from "next/dynamic" +import { useCallback, useEffect, useRef, useState } from "react" +import { + EXAMPLE_LABELS, + EXAMPLES, + type ExampleKey, +} from "@/lib/playground/examples" +import { executeCode } from "@/lib/playground/execution" +import { getCodeFromUrl, getShareableUrl } from "@/lib/playground/url-state" + +// Dynamically import Monaco to avoid SSR issues +const Editor = dynamic(() => import("@monaco-editor/react"), { + ssr: false, + loading: () => ( +
+ Loading editor... +
+ ), +}) + +export function Playground() { + const [code, setCode] = useState(EXAMPLES.basic) + const [output, setOutput] = useState("") + const [error, setError] = useState(null) + const [copied, setCopied] = useState(false) + const debounceRef = useRef>() + + // Load code from URL on mount + useEffect(() => { + const urlCode = getCodeFromUrl() + if (urlCode) { + setCode(urlCode) + } + }, []) + + // Debounced execution + const runCode = useCallback((newCode: string) => { + if (debounceRef.current) { + clearTimeout(debounceRef.current) + } + debounceRef.current = setTimeout(() => { + const result = executeCode(newCode) + setOutput(result.output) + setError(result.error) + }, 300) + }, []) + + // Run on code change + useEffect(() => { + runCode(code) + return () => { + if (debounceRef.current) { + clearTimeout(debounceRef.current) + } + } + }, [code, runCode]) + + const handleExampleChange = (e: React.ChangeEvent) => { + const key = e.target.value as ExampleKey + setCode(EXAMPLES[key]) + } + + const handleShare = async () => { + const url = getShareableUrl(code) + await navigator.clipboard.writeText(url) + setCopied(true) + setTimeout(() => setCopied(false), 2000) + } + + const handleReset = () => { + setCode(EXAMPLES.basic) + window.history.replaceState(null, "", "/playground") + } + + return ( +
+ {/* Toolbar */} +
+
+ + +
+
+ + +
+
+ + {/* Editor and Output */} +
+ {/* Code Editor */} +
+ setCode(value || "")} + options={{ + minimap: { enabled: false }, + fontSize: 14, + lineNumbers: "on", + scrollBeyondLastLine: false, + automaticLayout: true, + tabSize: 2, + wordWrap: "on", + fontFamily: "var(--font-mono), ui-monospace, monospace", + }} + /> +
+ + {/* Output Panel */} +
+
+ Output +
+
+ {error ? ( + {error} + ) : output ? ( + output + ) : ( + + Run some code to see output here... + + )} +
+
+
+
+ ) +} diff --git a/apps/docs/components/ui/CopyCodeBlock.tsx b/apps/docs/components/ui/CopyCodeBlock.tsx new file mode 100644 index 0000000..f60565f --- /dev/null +++ b/apps/docs/components/ui/CopyCodeBlock.tsx @@ -0,0 +1,33 @@ +"use client" + +import { useState } from "react" + +interface CopyCodeBlockProps { + code: string + language?: string +} + +export function CopyCodeBlock({ code, language = "bash" }: CopyCodeBlockProps) { + const [copied, setCopied] = useState(false) + + const handleCopy = async () => { + await navigator.clipboard.writeText(code) + setCopied(true) + setTimeout(() => setCopied(false), 2000) + } + + return ( +
+
+        {code}
+      
+ +
+ ) +} diff --git a/apps/docs/content/docs/ai-guide.mdx b/apps/docs/content/docs/ai-guide.mdx new file mode 100644 index 0000000..29496e9 --- /dev/null +++ b/apps/docs/content/docs/ai-guide.mdx @@ -0,0 +1,170 @@ +--- +title: AI Reference +description: Compact reference for AI code generation +--- + +**NOTE:** This page is optimized for AI assistants. For detailed documentation, see [Getting Started](/docs/getting-started). + +## Installation + +```bash +npm install @thesis-co/cent +``` + +## Core Rule + +**Always use string inputs for precision:** + +```typescript +Money("$100.50") // Correct +Money(100.5) // Works but warns about precision loss +``` + +## Common Operations + +| Task | Code | +|------|------| +| Create USD | `Money("$100.50")` | +| Create EUR | `Money("100.50 EUR")` | +| Create BTC | `Money("0.5 BTC")` or `Money("50000000 sat")` | +| Add | `a.add(b)` or `a.add("$25.00")` | +| Subtract | `a.subtract(b)` | +| Multiply | `a.multiply(2)` or `a.multiply("1.5")` | +| Divide | `a.divide(2)` or `a.divide(3, Round.HALF_UP)` | +| Add percentage | `price.multiply("1.08")` or `price.add(price.multiply("8%"))` | +| Compare | `a.equals(b)`, `a.greaterThan(b)`, `a.compare(b)` | +| Split evenly | `amount.distribute(3)` | +| Split by ratio | `amount.allocate([1, 2, 1])` | +| Sum array | `Money.sum(amounts)` | + +## Formatting + +`toString()` accepts formatting options: + +```typescript +const price = Money("$1234.56") + +price.toString() // "$1,234.56" +price.toString({ excludeCurrency: true }) // "1,234.56" +price.toString({ compact: true }) // "$1K" +price.toString({ maxDecimals: 0 }) // "$1,235" +price.toString({ locale: "de-DE" }) // "1.234,56 $" +``` + +## Imports + +```typescript +import { + Money, // Factory function + FixedPoint, // Fixed-point numbers + Rational, // Rational numbers + Round, // Rounding modes + ExchangeRate, // Currency conversion + Price, // Price ratios + PriceRange, // Price ranges + USD, + EUR, + BTC, + ETH, // Currency constants +} from "@thesis-co/cent" +``` + +## Rounding Modes + +Always specify rounding for division by non-2/5 numbers: + +```typescript +amount.divide(3, Round.HALF_UP) // Common choice +amount.divide(3, Round.HALF_EVEN) // Banker's rounding +amount.divide(3, Round.FLOOR) // Round down +amount.divide(3, Round.CEILING) // Round up +``` + +## Exchange Rates + +```typescript +const rate = new ExchangeRate(USD, EUR, "0.92") +const euros = rate.convert(Money("$100")) // 92.00 EUR + +// Reverse conversion works automatically +const dollars = rate.convert(Money("92 EUR")) // $100.00 +``` + +## Price Ranges + +```typescript +const range = PriceRange("$50 - $100") +range.contains(Money("$75")) // true +range.midpoint.toString() // "$75.00" +``` + +## Anti-Patterns + +```typescript +// Division without rounding (throws if not exact) +amount.divide(3) // Error! Always specify rounding mode + +// Comparing different currencies (throws) +usd.equals(eur) // Error! Convert first with ExchangeRate + +// Manual number parsing - use Money methods instead +Number.parseFloat(price.toString()) // Bad! +price.toNumber() // Use this if you need a number + +// Manual formatting - use toString options +`$${amount.toFixed(2)}` // Bad! +amount.toString() // Built-in formatting + +// Manual reduce for sums +amounts.reduce((a, b) => a.add(b), Money.zero("USD")) // Verbose +Money.sum(amounts) // Use this instead +``` + +## Safe Parsing + +For user input, use `Money.parse()`: + +```typescript +const result = Money.parse(userInput) +if (result.isOk()) { + const money = result.unwrap() +} else { + const error = result.unwrapErr() +} + +// Or with default +const amount = Money.parse(input).unwrapOr(Money.zero("USD")) +``` + +## Complete Example + +```typescript +import { Money } from "@thesis-co/cent" + +function calculateInvoice(items: Array<{ price: string; qty: number }>) { + // Sum line items + const lineItems = items.map((item) => Money(item.price).multiply(item.qty)) + const subtotal = Money.sum(lineItems) + + // Apply 10% discount + const discount = subtotal.multiply("10%") + const discounted = subtotal.subtract(discount) + + // Add 8.25% tax + const tax = discounted.multiply("8.25%") + const total = discounted.add(tax) + + return { + subtotal: subtotal.toString(), + discount: discount.toString(), + tax: tax.toString(), + total: total.toString(), + } +} +``` + +## Links + +- [Full API Reference](/docs/api/money) +- [Guides & Examples](/docs/guides/tax-calculations) +- [GitHub](https://github.com/thesis/cent) diff --git a/apps/docs/content/docs/api/exchange-rate.mdx b/apps/docs/content/docs/api/exchange-rate.mdx new file mode 100644 index 0000000..2742c5c --- /dev/null +++ b/apps/docs/content/docs/api/exchange-rate.mdx @@ -0,0 +1,241 @@ +--- +title: ExchangeRate +description: Currency conversion with base/quote semantics +--- + +`ExchangeRate` represents the conversion rate between two currencies with base/quote semantics, timestamps, and source tracking. Use it for rates from external services like exchanges and APIs. + +## Creating Exchange Rates + +### Basic Construction + +```typescript +import { ExchangeRate, USD, EUR, BTC, JPY } from "@thesis-co/cent" + +// 1 USD = 1.08 EUR +const usdEur = new ExchangeRate(USD, EUR, "1.08") +console.log(usdEur.toString()) // "1.08 €/$" +``` + +### With Timestamp and Source + +```typescript +const btcUsd = new ExchangeRate( + BTC, + USD, + "50000", + "1640995200", // Unix timestamp + { name: "Coinbase", priority: 1, reliability: 0.95 } +) + +// Or using an object +const eurJpy = new ExchangeRate({ + baseCurrency: EUR, + quoteCurrency: JPY, + rate: "162.50", + timestamp: "1640995200", + source: { name: "ECB", priority: 1, reliability: 0.99 }, +}) +``` + +### Understanding Base and Quote + +```typescript +const rate = new ExchangeRate(USD, EUR, "1.08") + +console.log(rate.baseCurrency.code) // "USD" (1 USD costs...) +console.log(rate.quoteCurrency.code) // "EUR" (...1.08 EUR) +``` + +## Currency Conversion + +### Basic Conversion + +```typescript +import { Money, ExchangeRate, USD, EUR } from "@thesis-co/cent" + +const rate = new ExchangeRate(USD, EUR, "1.08") + +const dollars = Money("$100.00") +const euros = rate.convert(dollars) +console.log(euros.toString()) // "€108.00" +``` + +### Automatic Direction Detection + +The same rate works for both directions: + +```typescript +const rate = new ExchangeRate(USD, EUR, "1.08") // 1 USD = 1.08 EUR + +// USD → EUR +const usd100 = Money("$100") +const eur108 = rate.convert(usd100) +console.log(eur108.toString()) // "€108.00" + +// EUR → USD (automatic) +const convertBack = rate.convert(eur108) +console.log(convertBack.toString()) // "$100.00" + +// Works with any amount +const moreEuros = Money("€540") +const convertedDollars = rate.convert(moreEuros) // €540 ÷ 1.08 = $500 +console.log(convertedDollars.toString()) // "$500.00" +``` + +## Rate Operations + +### Inversion + +Swap base and quote currencies: + +```typescript +const usdEur = new ExchangeRate(USD, EUR, "1.08") // 1 USD = 1.08 EUR +const eurUsd = usdEur.invert() // 1 EUR = 0.925925... USD + +console.log(eurUsd.toString()) // "0.925925925925925926 $/€" +``` + +### Cross-Currency Calculation + +Multiply rates to derive cross-rates: + +```typescript +// EUR/USD × USD/JPY = EUR/JPY (USD cancels out) +const eurUsdRate = new ExchangeRate(EUR, USD, "1.0842") +const usdJpyRate = new ExchangeRate(USD, JPY, "149.85") +const eurJpyCalculated = eurUsdRate.multiply(usdJpyRate) + +console.log(eurJpyCalculated.baseCurrency.code) // "EUR" +console.log(eurJpyCalculated.quoteCurrency.code) // "JPY" +console.log(eurJpyCalculated.rate.toString()) // "162.4673" (1.0842 × 149.85) +``` + +### Averaging Multiple Rates + +Combine rates from multiple sources: + +```typescript +const rate1 = new ExchangeRate(USD, EUR, "1.07") +const rate2 = new ExchangeRate(USD, EUR, "1.09") + +const averaged = new ExchangeRate(ExchangeRate.average([rate1, rate2])) +console.log(averaged.rate.toString()) // "1.080" +``` + +### Bid/Ask Spreads + +Create bid and ask rates for trading: + +```typescript +const rate = new ExchangeRate(USD, EUR, "1.2000") + +// Apply 2% spread +const { bid, ask, mid } = rate.spread("0.02") // "2%" also works + +console.log(bid.rate.toString()) // "1.1880" (mid - 1%) +console.log(ask.rate.toString()) // "1.2120" (mid + 1%) +console.log(mid.rate.toString()) // "1.2000" +``` + +## Time-Based Operations + +### Staleness Check + +```typescript +const currentRate = new ExchangeRate(USD, EUR, "1.08") + +// Check if rate is older than 5 minutes (300000ms) +console.log(currentRate.isStale(300000)) // false (just created) + +// Useful for caching and refresh logic +if (cachedRate.isStale(60000)) { + // Refresh rate if older than 1 minute +} +``` + +## Formatting + +### Format Options + +```typescript +const rate = new ExchangeRate(USD, EUR, "1.08") + +// Symbol format (default) +console.log(rate.toString()) // "1.08 €/$" + +// Code format +console.log(rate.toString({ format: "code" })) // "1.08 EUR/USD" + +// Ratio format +console.log(rate.toString({ format: "ratio" })) // "1 USD = 1.08 EUR" +``` + +## Serialization + +### JSON Support + +```typescript +const rate = new ExchangeRate(USD, EUR, "1.08") + +// Serialize (BigInt becomes string) +const json = rate.toJSON() +console.log(JSON.stringify(json)) + +// Deserialize +const restored = ExchangeRate.fromJSON(json) +console.log(restored.equals(rate)) // true +``` + +## API Reference + +### Constructor + +```typescript +new ExchangeRate(data: ExchangeRateData) +new ExchangeRate( + baseCurrency: Currency, + quoteCurrency: Currency, + rate: string, + timestamp?: string, + source?: { name: string; priority: number; reliability: number } +) +``` + +### Methods + +| Method | Description | +|--------|-------------| +| `convert(money)` | Convert Money between currencies (auto direction) | +| `multiply(scalar \| ExchangeRate)` | Scalar or cross-rate multiplication | +| `divide(scalar \| ExchangeRate)` | Scalar or rate division | +| `invert()` | Swap base and quote (1/rate) | +| `spread(percent)` | Create bid/ask/mid rates | +| `isStale(thresholdMs)` | Check if rate is older than threshold | +| `equals(other)` | Check equality | +| `toString(options?)` | Format as string | +| `toJSON()` | Serialize to JSON | + +### Static Methods + +| Method | Description | +|--------|-------------| +| `ExchangeRate.fromJSON(json)` | Deserialize from JSON | +| `ExchangeRate.average(rates[])` | Average multiple rates | +| `ExchangeRate.fromPrice(price, options)` | Create from Price object | + +### Properties + +| Property | Description | +|----------|-------------| +| `baseCurrency` | The base currency (1 unit of this...) | +| `quoteCurrency` | The quote currency (...equals N units of this) | +| `rate` | The rate as a FixedPointNumber | +| `timestamp` | When the rate was recorded | +| `source` | Optional source metadata | + +## Next Steps + +- [Price](/docs/api/price) — Arbitrary price ratios +- [Money API Reference](/docs/api/money) — Currency values +- [Crypto Precision](/docs/guides/crypto-precision) — BTC/ETH conversion examples diff --git a/apps/docs/content/docs/api/fixed-point.mdx b/apps/docs/content/docs/api/fixed-point.mdx new file mode 100644 index 0000000..364fd0c --- /dev/null +++ b/apps/docs/content/docs/api/fixed-point.mdx @@ -0,0 +1,224 @@ +--- +title: FixedPoint & Rational +description: Arbitrary-precision numeric types for financial calculations +--- + +**Note:** Most users won't need these types directly. The `Money` class handles precision automatically. These are useful for advanced calculations or when you need raw numeric operations without currency semantics. + +cent provides two numeric types beyond `Money` for precise mathematical operations. + +## FixedPoint + +`FixedPointNumber` is appropriate for financial applications that require tracking decimal precision. By disallowing arbitrary division, fixed-point numbers prevent accidental precision loss. + +### Creating FixedPoint Numbers + +```typescript +import { FixedPoint } from "@thesis-co/cent" + +// From decimal string (auto-detects precision) +const price = FixedPoint("1255.50") // 2 decimals +const rate = FixedPoint("0.875") // 3 decimals + +// From percentage string (converted to decimal) +const percentage = FixedPoint("51.5%") // Becomes 0.515 +const tax = FixedPoint("8.25%") // Becomes 0.0825 + +// From bigint values (explicit control) +const explicit = FixedPoint(125550n, 2n) // Same as FixedPoint("1255.50") +``` + +### Arithmetic Operations + +```typescript +const price = FixedPoint("1255.50") + +// Addition and subtraction +const sum = price.add("100.25") // 1355.75 +const diff = price.subtract("55.50") // 1200.00 + +// Multiplication (precision is preserved) +const product = price.multiply("0.875") +console.log(product.toString()) // "1098.5625" + +// Percentage calculations +const withTax = price.multiply(FixedPoint("8.25%")) +console.log(withTax.toString()) // "103.578..." (8.25% of 1255.50) +``` + +### Safe Division + +Division is only allowed for factors of 2 and 5 (which can be represented exactly in decimal): + +```typescript +const number = FixedPoint("100") + +// Exact division (factors of 2 and 5) +number.divide("2").toString() // "50.0" +number.divide("4").toString() // "25.00" +number.divide("5").toString() // "20.0" +number.divide("10").toString() // "10.0" + +// Division by other factors throws an error +number.divide("3") // Error: "Division by 3 requires a rounding mode..." +``` + +For non-exact division, use `Rational` numbers or specify a rounding mode on `Money`. + +### Comparison Methods + +```typescript +const a = FixedPoint("100.50") +const b = FixedPoint("99.99") + +a.equals(b) // false +a.greaterThan(b) // true +a.lessThan(b) // false +a.max(b).toString() // "100.50" +a.min(b).toString() // "99.99" +``` + +## Rational + +`RationalNumber` stores values as exact fractions (numerator/denominator), enabling arbitrary division without precision loss. + +### Creating Rational Numbers + +```typescript +import { Rational } from "@thesis-co/cent" + +// From fraction string +const oneThird = Rational("1/3") +const twoFifths = Rational("2/5") + +// From decimal string (auto-converted to fraction) +const quarter = Rational("0.25") // Becomes 1/4 +const decimal = Rational("0.125") // Becomes 1/8 + +// From bigint numerator and denominator +const pi = Rational(22n, 7n) // 22/7 approximation +const third = Rational(1n, 3n) // 1/3 + +// From Ratio object +const ratio = Rational({ p: 1n, q: 10n }) // 1/10 +``` + +### Exact Arithmetic + +```typescript +const oneThird = Rational("1/3") + +// Addition +const sum = oneThird.add("2/5") // (1/3) + (2/5) = 11/15 +console.log(sum.toString()) // "11/15" + +// Multiplication +const product = oneThird.multiply("2/5") // (1/3) * (2/5) = 2/15 +console.log(product.toString()) // "2/15" + +// Division (exact, no precision loss) +const divided = oneThird.divide("2/3") // (1/3) / (2/3) = 1/2 +console.log(divided.toString()) // "1/2" +``` + +### Automatic Simplification + +Fractions are automatically reduced to lowest terms: + +```typescript +const simplified = Rational("6/9") +console.log(simplified.toString()) // "2/3" + +const large = Rational("100/250") +console.log(large.toString()) // "2/5" +``` + +### Converting to Decimal + +```typescript +const rational = Rational("3/8") + +// To decimal string (specify precision for repeating decimals) +rational.toDecimalString() // "0.375" + +// To FixedPoint +const fixedPoint = FixedPoint(rational.toDecimalString()) +console.log(fixedPoint.toString()) // "0.375" + +// Some fractions can't be represented exactly +const third = Rational("1/3") +third.toDecimalString(10) // "0.3333333333" (10 digits) +``` + +## Mixing Types + +You can mix `FixedPoint` and `Rational` for complex calculations: + +```typescript +// Use Rational for division, then convert back +const result = Rational("1/3").multiply(FixedPoint("100")) +console.log(result.toDecimalString()) // "33.333..." + +// For Money operations, convert at the end +const money = Money("$100.00") +const portion = Rational("1/3") +const amount = money.multiply(portion.toDecimalString(10), Round.HALF_UP) +``` + +## API Reference + +### FixedPoint Factory + +```typescript +FixedPoint(str: string): FixedPointNumber // Parse decimal or percentage +FixedPoint(amount: bigint, decimals: bigint): FixedPointNumber // From bigints +FixedPoint(existing: FixedPointNumber): FixedPointNumber // Clone +``` + +### FixedPointNumber Methods + +| Method | Description | +|--------|-------------| +| `add(other)` | Addition | +| `subtract(other)` | Subtraction | +| `multiply(other)` | Multiplication | +| `divide(other)` | Safe division (factors of 2 and 5 only) | +| `normalize(decimals)` | Change decimal precision | +| `equals(other)` | Equality check | +| `greaterThan(other)` | Greater than comparison | +| `lessThan(other)` | Less than comparison | +| `max(other)` | Return maximum | +| `min(other)` | Return minimum | +| `toString()` | Decimal string representation | + +### Rational Factory + +```typescript +Rational(str: string): RationalNumber // Parse "p/q" or decimal +Rational(p: bigint, q: bigint): RationalNumber // From bigints +Rational(ratio: { p: bigint, q: bigint }): RationalNumber // From object +``` + +### RationalNumber Methods + +| Method | Description | +|--------|-------------| +| `add(other)` | Exact addition | +| `subtract(other)` | Exact subtraction | +| `multiply(other)` | Exact multiplication | +| `divide(other)` | Exact division | +| `simplify()` | Reduce to lowest terms | +| `equals(other)` | Equality check | +| `greaterThan(other)` | Greater than comparison | +| `lessThan(other)` | Less than comparison | +| `max(other)` | Return maximum | +| `min(other)` | Return minimum | +| `toString()` | Fraction string "p/q" | +| `toDecimalString(precision?)` | Convert to decimal (default 50 digits) | +| `toFixedPoint()` | Convert to FixedPoint (when possible) | + +## Next Steps + +- [Money API Reference](/docs/api/money) — Primary currency type +- [Exchange Rates](/docs/api/exchange-rate) — Currency conversion +- [Core Concepts](/docs/core-concepts) — Precision and rounding diff --git a/apps/docs/content/docs/api/money.mdx b/apps/docs/content/docs/api/money.mdx new file mode 100644 index 0000000..b6a43d7 --- /dev/null +++ b/apps/docs/content/docs/api/money.mdx @@ -0,0 +1,387 @@ +--- +title: Money +description: Complete API reference for the Money class +--- + +The `Money` class is the primary way to work with currency values in cent. + +## Creating Money + +### Money(input) + +Factory function to create Money from various input types. + +```typescript +// From string with currency symbol +const usd = Money("$100.50") +const eur = Money("100.50 EUR") + +// From string with currency code +const btc = Money("0.5 BTC") +const eth = Money("1.5 ETH") + +// With explicit currency +const amount = Money("100.50", "USD") +``` + +**Parameters:** +- `input` - String, number, or existing Money value +- `currency` (optional) - Currency code to use + +**Returns:** `Money` instance + +### Money.zero(currency) + +Create a zero-value Money for a given currency. + +```typescript +const zero = Money.zero("USD") // $0.00 +const zeroSats = Money.zero("BTC") // 0.00000000 BTC +``` + +### Money.parse(input) + +Safely parse untrusted input, returning a `Result` type. + +```typescript +const result = Money.parse(userInput) + +if (result.isOk()) { + const money = result.unwrap() +} else { + const error = result.unwrapErr() + console.log(error.message, error.suggestion) +} + +// Or with default value +const amount = Money.parse(input).unwrapOr(Money.zero("USD")) +``` + +## Arithmetic Operations + +All operations return new `Money` instances (immutable). + +### add(other) + +Add another Money value or string. + +```typescript +const total = price.add(tax) +const also = price.add("$10.00") +const withPercent = price.add(price.multiply("8%")) +``` + +### subtract(other) + +Subtract another Money value or string. + +```typescript +const remaining = balance.subtract(payment) +const discount = price.subtract("$5.00") +``` + +### multiply(factor) + +Multiply by a number, string, or percentage. + +```typescript +const doubled = price.multiply(2) +const tax = subtotal.multiply("8.25%") +const scaled = price.multiply("1.5") +``` + +### divide(divisor, roundingMode?) + +Divide by a number. Rounding mode is required for non-exact divisions. + +```typescript +// Exact divisions (factors of 2 and 5) +const half = price.divide(2) +const fifth = price.divide(5) + +// Non-exact divisions require rounding +const third = price.divide(3, Round.HALF_UP) +const seventh = price.divide(7, Round.CEILING) +``` + +### negate() + +Return the negation of this Money. + +```typescript +const positive = Money("$100") +const negative = positive.negate() // -$100 +``` + +### abs() + +Return the absolute value. + +```typescript +const neg = Money("-$100") +const pos = neg.abs() // $100 +``` + +## Comparison Operations + +### equals(other) + +Check if two Money values are equal. + +```typescript +const a = Money("$100") +const b = Money("$100.00") +a.equals(b) // true +``` + +### greaterThan(other) + +Check if this is greater than another value. + +```typescript +price.greaterThan(minimum) // boolean +``` + +### lessThan(other) + +Check if this is less than another value. + +```typescript +balance.lessThan(overdraftLimit) // boolean +``` + +### greaterThanOrEqual(other) + +```typescript +total.greaterThanOrEqual(minimum) // boolean +``` + +### lessThanOrEqual(other) + +```typescript +expense.lessThanOrEqual(budget) // boolean +``` + +### compare(other) + +Returns -1, 0, or 1 for sorting. + +```typescript +amounts.sort((a, b) => a.compare(b)) +``` + +### isPositive() / isNegative() / isZero() + +```typescript +balance.isPositive() // true if > 0 +balance.isNegative() // true if < 0 +balance.isZero() // true if exactly 0 +``` + +## Distribution Methods + +### distribute(count, options?) + +Split evenly among N recipients. + +```typescript +const [a, b, c] = price.distribute(3) +// Remainder goes to first recipient +``` + +**Options:** +- `distributeFractionalUnits` - Whether to include sub-unit precision (default: true) + +### allocate(ratios) + +Split by ratios for proportional distribution. + +```typescript +const [marketing, dev, ops] = budget.allocate([2, 5, 3]) +// $1000 becomes [$200, $500, $300] +``` + +### concretize() + +Separate into whole units and fractional remainder. + +```typescript +const [main, fractional] = Money("$100.00123").concretize() +// main: $100.00, fractional: $0.00123 +``` + +## Rounding Methods + +### round(mode) + +Round to currency's default precision. + +```typescript +const rounded = precise.round(Round.HALF_UP) +``` + +### roundTo(decimals, mode) + +Round to a specific number of decimal places. + +```typescript +const cents = amount.roundTo(2, Round.HALF_EVEN) +const whole = amount.roundTo(0, Round.FLOOR) +``` + +## Clamping Methods + +### clamp(min, max) + +Constrain a value within a range. + +```typescript +Money("$50").clamp("$0", "$100") // $50.00 (within bounds) +Money("-$50").clamp("$0", "$100") // $0.00 (below min, clamped up) +Money("$150").clamp("$0", "$100") // $100.00 (above max, clamped down) + +// With Money instances +const min = Money("$10") +const max = Money("$1000") +price.clamp(min, max) + +// With numbers (interpreted in same currency) +price.clamp(0, 100) +``` + +### atLeast(min) + +Ensure a minimum value. + +```typescript +Money("$50").atLeast("$0") // $50.00 (already above min) +Money("-$50").atLeast("$0") // $0.00 (raised to min) + +// Ensure non-negative amounts +const safeAmount = amount.atLeast(0) + +// With Money instance +Money("$25").atLeast(Money("$50")) // $50.00 +``` + +### atMost(max) + +Ensure a maximum value. + +```typescript +Money("$50").atMost("$100") // $50.00 (already below max) +Money("$150").atMost("$100") // $100.00 (reduced to max) + +// Cap at maximum allowed amount +const cappedAmount = amount.atMost("$10000") + +// With Money instance +Money("$75").atMost(Money("$50")) // $50.00 +``` + +## Formatting Methods + +### toString(options?) + +Format as a string with currency symbol. + +```typescript +Money("$100.50").toString() // "$100.50" +Money("0.5 BTC").toString() // "0.50000000 BTC" +``` + +**Options:** + +```typescript +const price = Money("$1234.567") + +// Locale formatting +price.toString({ locale: "de-DE" }) // "1.234,57 $" + +// Compact notation +Money("$1500000").toString({ compact: true }) // "$1.5M" + +// Control decimal places +price.toString({ maxDecimals: 2 }) // "$1,234.57" +price.toString({ minDecimals: 4 }) // "$1,234.5670" + +// Exclude currency symbol +price.toString({ excludeCurrency: true }) // "1,234.567" + +// Rounding mode for formatting +price.toString({ maxDecimals: 2, roundingMode: Round.FLOOR }) // "$1,234.56" +``` + +| Option | Type | Description | +|--------|------|-------------| +| `locale` | `string` | Display locale (default "en-US") | +| `compact` | `boolean` | Use compact notation (e.g., $1M) | +| `maxDecimals` | `number` | Maximum decimal places to display | +| `minDecimals` | `number` | Minimum decimal places (forces trailing zeros) | +| `excludeCurrency` | `boolean` | Exclude currency symbol/code | +| `preferSymbol` | `boolean` | Prefer symbol over code for non-ISO currencies | +| `preferredUnit` | `string` | Preferred fractional unit (e.g., "sat" for BTC) | +| `roundingMode` | `RoundingMode` | Rounding mode for formatting | + +### toJSON() + +Return JSON-serializable representation. + +```typescript +JSON.stringify({ price: Money("$100") }) +// {"price": {"amount": "10000", "currency": "USD"}} +``` + +## Properties + +### currency + +The Currency object for this Money. + +```typescript +const m = Money("$100") +m.currency.code // "USD" +m.currency.symbol // "$" +m.currency.decimals // 2n +``` + +### amount + +The raw BigInt amount in smallest units. + +```typescript +Money("$1.50").amount // 150n (cents) +Money("1 BTC").amount // 100000000n (satoshis) +``` + +## Static Methods + +### Money.min(...values) + +Return the minimum of multiple Money values. + +```typescript +const lowest = Money.min(a, b, c) +``` + +### Money.max(...values) + +Return the maximum of multiple Money values. + +```typescript +const highest = Money.max(a, b, c) +``` + +### Money.sum(values) + +Sum an array of Money values. + +```typescript +const total = Money.sum(lineItems) +``` + +## Next Steps + +- [Core Concepts](/docs/core-concepts) — Understanding precision and immutability +- [Tax Calculations](/docs/guides/tax-calculations) — Practical percentage examples +- [Crypto Precision](/docs/guides/crypto-precision) — Working with BTC and ETH diff --git a/apps/docs/content/docs/api/price-range.mdx b/apps/docs/content/docs/api/price-range.mdx new file mode 100644 index 0000000..09fcd56 --- /dev/null +++ b/apps/docs/content/docs/api/price-range.mdx @@ -0,0 +1,325 @@ +--- +title: PriceRange +description: Represent and manipulate price ranges with precision +--- + +`PriceRange` represents a min-max price range for e-commerce filters, pricing strategies, and financial analysis. + +## Creating Price Ranges + +### From Strings + +```typescript +import { PriceRange, Money } from "@thesis-co/cent" + +const range1 = PriceRange("$50 - $100") +const range2 = PriceRange("$50-100") // Compact format +const range3 = PriceRange("€25 - €75") +``` + +### From Money Instances + +```typescript +const range = PriceRange(Money("$50"), Money("$100")) + +// Mixed creation +const mixed = PriceRange("$50", Money("$100")) +``` + +## Properties + +```typescript +const range = PriceRange("$50 - $100") + +range.min.toString() // "$50.00" +range.max.toString() // "$100.00" +range.span.toString() // "$50.00" (max - min) +range.midpoint.toString() // "$75.00" +range.isEmpty // false (true if min === max) +range.currency // Currency object +``` + +## Range Queries + +### Contains + +```typescript +const range = PriceRange("$50 - $100") + +range.contains(Money("$75")) // true +range.contains("$25") // false +range.contains("$50") // true (inclusive) +range.contains("$100") // true (inclusive) +``` + +### Position Checks + +```typescript +const range = PriceRange("$50 - $100") + +range.isAbove(Money("$40")) // true (entire range above $40) +range.isAbove(Money("$60")) // false + +range.isBelow(Money("$120")) // true (entire range below $120) +range.isBelow(Money("$80")) // false +``` + +## Range Operations + +### Overlap Detection + +```typescript +const range1 = PriceRange("$50 - $100") +const range2 = PriceRange("$80 - $150") + +range1.overlaps(range2) // true +``` + +### Intersection + +```typescript +const range1 = PriceRange("$50 - $100") +const range2 = PriceRange("$80 - $150") + +const intersection = range1.intersect(range2) +console.log(intersection?.toString()) // "$80.00 - $100.00" + +// Returns null if no overlap +const noOverlap = range1.intersect(PriceRange("$200 - $300")) +console.log(noOverlap) // null +``` + +### Union + +```typescript +const range1 = PriceRange("$50 - $100") +const range2 = PriceRange("$80 - $150") + +const union = range1.union(range2) +console.log(union.toString()) // "$50.00 - $150.00" +``` + +### Split + +Divide a range into equal parts: + +```typescript +const range = PriceRange("$50 - $100") +const parts = range.split(3) + +console.log(parts[0].toString()) // "$50.00 - $66.67" +console.log(parts[1].toString()) // "$66.67 - $83.33" +console.log(parts[2].toString()) // "$83.33 - $100.00" +``` + +## Static Factory Methods + +### Under + +Create a range from zero to max: + +```typescript +const under100 = PriceRange.under(Money("$100")) +console.log(under100.toString()) // "$0.00 - $100.00" +``` + +### Over + +Create a range from min to max: + +```typescript +const range = PriceRange.over(Money("$50"), Money("$500")) +console.log(range.toString()) // "$50.00 - $500.00" +``` + +### Around + +Create a range around a center point: + +```typescript +const range = PriceRange.around(Money("$100"), "10%") +console.log(range.toString()) // "$90.00 - $110.00" +``` + +### Create Buckets + +Generate N equal price buckets: + +```typescript +const buckets = PriceRange.createBuckets(Money("$0"), Money("$500"), 5) + +buckets.forEach((bucket, i) => { + console.log(`Bucket ${i + 1}: ${bucket.toString()}`) +}) +// Bucket 1: $0.00 - $100.00 +// Bucket 2: $100.00 - $200.00 +// Bucket 3: $200.00 - $300.00 +// Bucket 4: $300.00 - $400.00 +// Bucket 5: $400.00 - $500.00 +``` + +## Formatting + +### Format Styles + +```typescript +const range = PriceRange("$50 - $100") + +range.toString() // "$50.00 - $100.00" (default) +range.toString({ format: "compact" }) // "$50-100" +range.toString({ format: "from" }) // "From $50.00" +range.toString({ format: "upTo" }) // "Up to $100.00" +range.toString({ format: "range" }) // "$50.00 to $100.00" +range.toString({ format: "between" }) // "Between $50.00 and $100.00" +``` + +### Localization + +```typescript +const eurRange = PriceRange("€50 - €100") +console.log(eurRange.toString({ locale: "de-DE" })) // "50,00 € - 100,00 €" +``` + +### Compact Notation + +```typescript +const largeRange = PriceRange("$1000000 - $5000000") +console.log(largeRange.toString({ compact: true })) // "$1M - $5M" +``` + +### Crypto Units + +```typescript +const btcRange = PriceRange("₿0.001 - ₿0.01") + +console.log(btcRange.contains(Money("₿0.005"))) // true +console.log(btcRange.toString({ preferredUnit: "sat" })) // "100,000 sats - 1,000,000 sats" +``` + +## Currency Conversion + +```typescript +import { ExchangeRate, USD, EUR } from "@thesis-co/cent" + +const range = PriceRange("$50 - $100") +const exchangeRate = new ExchangeRate(USD, EUR, "0.85") + +const convertedRange = range.convert(exchangeRate) +console.log(convertedRange.toString()) // "€42.50 - €85.00" +``` + +## Serialization + +```typescript +const range = PriceRange("$50 - $100") + +// Serialize +const json = range.toJSON() +console.log(JSON.stringify(json)) + +// Deserialize +const restored = PriceRange.fromJSON(json) +console.log(restored.equals(range)) // true +``` + +## Use Cases + +### E-Commerce Filtering + +```typescript +const products = [ + { name: "Budget Widget", price: Money("$45") }, + { name: "Standard Widget", price: Money("$75") }, + { name: "Premium Widget", price: Money("$125") }, + { name: "Deluxe Widget", price: Money("$95") }, +] + +const priceFilter = PriceRange("$50 - $100") +const affordableProducts = products.filter((product) => + priceFilter.contains(product.price) +) + +console.log(affordableProducts.map((p) => p.name)) +// ["Standard Widget", "Deluxe Widget"] +``` + +### Price Tier Display + +```typescript +const tiers = PriceRange.createBuckets(Money("$0"), Money("$200"), 4) + +const tierLabels = tiers.map((tier, i) => ({ + label: ["Budget", "Value", "Standard", "Premium"][i], + range: tier.toString({ format: "range" }), +})) + +// [ +// { label: "Budget", range: "$0.00 to $50.00" }, +// { label: "Value", range: "$50.00 to $100.00" }, +// { label: "Standard", range: "$100.00 to $150.00" }, +// { label: "Premium", range: "$150.00 to $200.00" }, +// ] +``` + +### Discount Range Display + +```typescript +const originalPrice = Money("$100") +const discountRange = PriceRange.around(originalPrice, "20%") + +console.log(`Prices may vary: ${discountRange.toString()}`) +// "Prices may vary: $80.00 - $120.00" +``` + +## API Reference + +### Constructor + +```typescript +PriceRange(str: string): PriceRange // Parse "$50 - $100" +PriceRange(min: Money | string, max: Money | string): PriceRange +``` + +### Properties + +| Property | Type | Description | +|----------|------|-------------| +| `min` | `Money` | Minimum price | +| `max` | `Money` | Maximum price | +| `span` | `Money` | Difference (max - min) | +| `midpoint` | `Money` | Center point | +| `isEmpty` | `boolean` | True if min === max | +| `currency` | `Currency` | Currency of the range | + +### Methods + +| Method | Description | +|--------|-------------| +| `contains(price)` | Check if price is within range | +| `isAbove(price)` | Check if entire range is above price | +| `isBelow(price)` | Check if entire range is below price | +| `overlaps(other)` | Check if ranges overlap | +| `intersect(other)` | Get intersection (or null) | +| `union(other)` | Get union range | +| `split(parts)` | Split into N equal parts | +| `convert(exchangeRate)` | Convert to different currency | +| `equals(other)` | Check equality | +| `toString(options?)` | Format for display | +| `toJSON()` | Serialize to JSON | + +### Static Methods + +| Method | Description | +|--------|-------------| +| `PriceRange.under(max)` | Range from zero to max | +| `PriceRange.over(min, max)` | Range from min to max | +| `PriceRange.between(min, max)` | Alias for constructor | +| `PriceRange.around(base, percent)` | Range around base ± percent | +| `PriceRange.createBuckets(min, max, count)` | Create N equal buckets | +| `PriceRange.fromJSON(json)` | Deserialize from JSON | + +## Next Steps + +- [Money API Reference](/docs/api/money) — Currency values +- [ExchangeRate](/docs/api/exchange-rate) — Currency conversion +- [Splitting Bills](/docs/guides/splitting-bills) — Distribution examples diff --git a/apps/docs/content/docs/api/price.mdx b/apps/docs/content/docs/api/price.mdx new file mode 100644 index 0000000..f04a551 --- /dev/null +++ b/apps/docs/content/docs/api/price.mdx @@ -0,0 +1,227 @@ +--- +title: Price +description: Arbitrary price ratios between any two assets +--- + +`Price` represents a ratio between any two assets. Unlike `ExchangeRate`, which is designed for currency pairs from external services, `Price` handles arbitrary price relationships including non-currency assets. + +## When to Use Price vs ExchangeRate + +| Use Case | Type | +|----------|------| +| Rates from exchanges/APIs | `ExchangeRate` | +| Arbitrary asset ratios | `Price` | +| Time-stamped rates | `ExchangeRate` | +| Custom/non-currency assets | `Price` | +| Bid/ask spreads | `ExchangeRate` | + +## Creating Prices + +### From Money Values + +```typescript +import { Price, Money } from "@thesis-co/cent" + +// $50,000 per BTC +const btcPrice = new Price(Money("$50,000"), Money("1 BTC")) + +// €5.00 per apple (custom asset) +const APPLE = { + name: "Apple", + code: "APPLE", + decimals: 0n, + symbol: "🍎", +} + +const usdPerApple = new Price(Money("$5.00"), { + asset: APPLE, + amount: { amount: 1n, decimals: 0n }, +}) +``` + +### With Custom Assets + +```typescript +const APPLE = { + name: "Apple", + code: "APPLE", + decimals: 0n, + symbol: "🍎", +} + +const ORANGE = { + name: "Orange", + code: "ORANGE", + decimals: 0n, + symbol: "🍊", +} + +// 10,000 apples per BTC +const applesPerBtc = new Price( + { asset: APPLE, amount: { amount: 10000n, decimals: 0n } }, + Money("1 BTC") +) +``` + +## Price Operations + +### Scalar Multiplication and Division + +```typescript +const usdPerApple = new Price(Money("$5.00"), { + asset: APPLE, + amount: { amount: 1n, decimals: 0n }, +}) + +// Double the price +const doubled = usdPerApple.multiply("2") // $10.00/apple + +// Half the price +const halved = usdPerApple.divide("2") // $2.50/apple +``` + +### Price-to-Price Multiplication + +When two prices share a common asset, you can multiply them to derive a new price: + +```typescript +// $5/apple × 10,000 apples/BTC = $50,000/BTC +const usdPerBtc = usdPerApple.multiply(applesPerBtc) + +console.log(usdPerBtc.amounts[0].amount.amount) // 5000000n ($50,000.00) +``` + +The shared asset (apples) cancels out, leaving you with USD/BTC. + +### Price-to-Price Division + +```typescript +// $50,000/BTC ÷ $5/apple = 10,000 apples/BTC +const calculatedApplesPerBtc = usdPerBtc.divide(usdPerApple) +``` + +### Validation + +Price operations validate that assets can be combined: + +```typescript +try { + const orangesPerBtc = new Price( + { asset: ORANGE, amount: { amount: 5000n, decimals: 0n } }, + Money("1 BTC") + ) + + // Error: no shared asset between USD/Apple and Orange/BTC + usdPerApple.multiply(orangesPerBtc) +} catch (error) { + console.log(error.message) + // "Cannot multiply prices: no shared asset found between US Dollar/Apple and Orange/Bitcoin" +} +``` + +## Converting to Mathematical Ratio + +```typescript +const price = new Price(Money("$5.00"), { + asset: APPLE, + amount: { amount: 1n, decimals: 0n }, +}) + +// Get as RationalNumber for further math +const ratio = price.asRatio() // 500/1 (in cents/apple) +``` + +## Converting to ExchangeRate + +When both sides of a Price are currencies, convert to ExchangeRate for additional features: + +```typescript +const btcUsdPrice = new Price(Money("$50,000"), Money("1 BTC")) + +const exchangeRate = btcUsdPrice.toExchangeRate({ + precision: 2, // Decimal places + baseAsSelection: "denominator", // BTC as base +}) + +// Now you can use ExchangeRate features +console.log(exchangeRate.toString({ format: "ratio" })) // "1 BTC = $50,000.00" +``` + +## API Reference + +### Constructor + +```typescript +new Price(numerator: Money | AssetAmount, denominator: Money | AssetAmount) +``` + +### Methods + +| Method | Description | +|--------|-------------| +| `multiply(scalar \| Price)` | Scalar or Price-to-Price multiplication | +| `divide(scalar \| Price)` | Scalar or Price-to-Price division | +| `invert()` | Swap numerator and denominator | +| `asRatio()` | Convert to RationalNumber | +| `equals(other)` | Check equality | +| `toExchangeRate(options?)` | Convert to ExchangeRate (currency pairs only) | + +### Properties + +| Property | Description | +|----------|-------------| +| `amounts` | Tuple of [numerator, denominator] AssetAmounts | + +## Use Cases + +### Commodity Pricing + +```typescript +const BARREL = { name: "Barrel of Oil", code: "BBL", decimals: 0n, symbol: "🛢️" } + +const oilPrice = new Price(Money("$75.50"), { + asset: BARREL, + amount: { amount: 1n, decimals: 0n }, +}) + +// Calculate cost of 100 barrels +const cost = oilPrice.multiply("100") +``` + +### Unit Conversions with Value + +```typescript +// Price per kilogram +const pricePerKg = new Price(Money("$12.99"), { + asset: { name: "Kilogram", code: "KG", decimals: 3n, symbol: "kg" }, + amount: { amount: 1000n, decimals: 3n }, // 1.000 kg +}) + +// Derive price per gram +const pricePerGram = pricePerKg.divide("1000") +``` + +### Derived Rates + +```typescript +// If you have: +// - Gold price in USD +// - USD/EUR exchange rate +// You can derive gold price in EUR + +const goldUsd = new Price(Money("$2000"), { + asset: { name: "Troy Ounce Gold", code: "XAU", decimals: 0n, symbol: "Au" }, + amount: { amount: 1n, decimals: 0n }, +}) + +const usdPerEur = new Price(Money("$1.08"), Money("€1")) + +// goldUsd × (EUR/USD) = gold in EUR +const goldEur = goldUsd.divide(usdPerEur) +``` + +## Next Steps + +- [ExchangeRate](/docs/api/exchange-rate) — Currency-specific rate handling +- [PriceRange](/docs/api/price-range) — Price range operations +- [Money API Reference](/docs/api/money) — Currency values diff --git a/apps/docs/content/docs/core-concepts.mdx b/apps/docs/content/docs/core-concepts.mdx new file mode 100644 index 0000000..6033a65 --- /dev/null +++ b/apps/docs/content/docs/core-concepts.mdx @@ -0,0 +1,154 @@ +--- +title: Core Concepts +description: Understanding Money, precision, and immutability in cent +--- + +cent is built on a few key principles that make financial calculations safe and predictable. + +## Arbitrary Precision + +cent uses `BigInt` under the hood, which means: + +- **No precision loss** — Values are stored exactly as specified +- **No limits** — Handle amounts from satoshis to quadrillions +- **No floating point errors** — `0.1 + 0.2` actually equals `0.3` + +```typescript +// JavaScript Number fails at large values +Number.MAX_SAFE_INTEGER // 9,007,199,254,740,991 + +// cent handles any size +const huge = Money("$9,999,999,999,999,999.99") +const precise = Money("0.123456789012345678 ETH") // Full 18 decimals +``` + +## Immutability + +All operations return new instances. The original value is never modified: + +```typescript +const price = Money("$100.00") +const withTax = price.add("$8.25") + +console.log(price.toString()) // "$100.00" (unchanged) +console.log(withTax.toString()) // "$108.25" (new instance) +``` + +This prevents accidental mutations and makes code easier to reason about. + +## Type Safety + +cent prevents common mistakes at compile time: + +```typescript +const usd = Money("$100") +const eur = Money("100 EUR") + +// TypeScript error: Can't compare different currencies +usd.equals(eur) // Error! + +// Convert first using an exchange rate +const rate = new ExchangeRate(USD, EUR, "0.92") +usd.equals(eur.convert(rate)) // OK +``` + +## Safe Parsing + +For user input or external data, use `Money.parse()` which returns a `Result` type: + +```typescript +const result = Money.parse(userInput) + .map((money) => money.add("8.25%")) + .map((money) => money.roundTo(2, Round.HALF_UP)) + +const total = result.match({ + ok: (money) => money.toString(), + err: (error) => `Invalid amount: ${error.suggestion}`, +}) + +// Or provide a default +const amount = Money.parse(untrustedInput).unwrapOr(Money.zero("USD")) +``` + +## Rounding Modes + +Division and some multiplications may produce values that can't be represented exactly. cent requires you to specify how to handle this: + +```typescript +const price = Money("$100.00") + +// Division by factors of 2 and 5 is exact +price.divide(2) // $50.00 (exact) +price.divide(5) // $20.00 (exact) + +// Other divisors require a rounding mode +price.divide(3, Round.HALF_UP) // $33.33 +price.divide(3, Round.HALF_EVEN) // $33.33 (banker's rounding) +price.divide(3, Round.CEILING) // $33.34 +price.divide(3, Round.FLOOR) // $33.33 +``` + +**Available rounding modes:** + +| Mode | Description | +|------|-------------| +| `Round.UP` | Round away from zero | +| `Round.DOWN` | Round toward zero (truncate) | +| `Round.CEILING` | Round toward positive infinity | +| `Round.FLOOR` | Round toward negative infinity | +| `Round.HALF_UP` | Round to nearest, ties away from zero | +| `Round.HALF_DOWN` | Round to nearest, ties toward zero | +| `Round.HALF_EVEN` | Round to nearest, ties to even (banker's rounding) | + +## Numeric Types + +cent provides three numeric types for different use cases: + +### Money + +The primary type for working with currency values: + +```typescript +const usd = Money("$100.50") +const btc = Money("0.5 BTC") +``` + +### FixedPoint + +For decimal numbers where you need to track precision: + +```typescript +const rate = FixedPoint("0.875") +const percentage = FixedPoint("8.25%") // Becomes 0.0825 +``` + +### Rational + +For exact fractional arithmetic without precision loss: + +```typescript +const oneThird = Rational("1/3") +const result = oneThird.multiply("3") // Exactly 1 +``` + +## Currency Support + +cent includes 180+ currencies with proper metadata: + +```typescript +import { USD, EUR, BTC, ETH, JPY } from "@thesis-co/cent" + +console.log(USD.decimals) // 2n +console.log(BTC.decimals) // 8n +console.log(ETH.decimals) // 18n +console.log(JPY.decimals) // 0n + +console.log(USD.symbol) // "$" +console.log(USD.fractionalUnit) // "cent" +``` + +## Next Steps + +- [Money API Reference](/docs/api/money) — Complete method documentation +- [Tax Calculations Guide](/docs/guides/tax-calculations) — Practical examples +- [Crypto Precision Guide](/docs/guides/crypto-precision) — Working with BTC and ETH diff --git a/apps/docs/content/docs/getting-started.mdx b/apps/docs/content/docs/getting-started.mdx new file mode 100644 index 0000000..09475ed --- /dev/null +++ b/apps/docs/content/docs/getting-started.mdx @@ -0,0 +1,77 @@ +--- +title: Getting Started +description: Install cent and start using precise financial calculations in minutes +--- + +## Installation + + + +```bash +npm install @thesis-co/cent +``` + + +```bash +pnpm add @thesis-co/cent +``` + + +```bash +yarn add @thesis-co/cent +``` + + + +## Quick Start + +```typescript +import { Money, Round } from "@thesis-co/cent" + +// Create money values from strings +const price = Money("$100.50") +const btc = Money("0.5 BTC") + +// Arithmetic operations +const total = price.add("$25.25") // $125.75 + +// Division with rounding +const split = total.divide(3, Round.HALF_UP) // $41.92 + +// Allocation and distribution +const [a, b, c] = price.distribute(3) // [$33.50, $33.50, $33.50] + +// Formatting +console.log(price.toString()) // "$100.50" +``` + +## Configuration + +Configure library-wide defaults at application startup: + +```typescript +import { configure, Round } from "@thesis-co/cent" + +configure({ + numberInputMode: process.env.NODE_ENV === "production" ? "error" : "warn", + strictPrecision: process.env.NODE_ENV === "production", + defaultRoundingMode: Round.HALF_UP, + defaultCurrency: "USD", +}) +``` + +**Options:** + +| Option | Description | Default | +|--------|-------------|---------| +| `numberInputMode` | How to handle JS number inputs: `'warn'`, `'error'`, or `'silent'` | `'warn'` | +| `strictPrecision` | Throw on any operation that would lose precision | `false` | +| `defaultRoundingMode` | Default rounding mode, or `'none'` to require explicit rounding | `Round.HALF_UP` | +| `defaultCurrency` | Default currency code | `'USD'` | +| `defaultLocale` | Default locale for formatting | `'en-US'` | + +## Next Steps + +- [Core Concepts](/docs/core-concepts) — Understand Money, precision, and immutability +- [API Reference](/docs/api/money) — Complete Money class documentation +- [Guides](/docs/guides/tax-calculations) — Practical examples and patterns diff --git a/apps/docs/content/docs/guides/crypto-precision.mdx b/apps/docs/content/docs/guides/crypto-precision.mdx new file mode 100644 index 0000000..e33076a --- /dev/null +++ b/apps/docs/content/docs/guides/crypto-precision.mdx @@ -0,0 +1,209 @@ +--- +title: Crypto Precision +description: Working with Bitcoin, Ethereum, and other cryptocurrencies +--- + +cent handles cryptocurrency with full precision — 8 decimal places for Bitcoin (satoshi precision by default, sub-satoshi precision supported), 18 for Ethereum (wei precision by default), and 9 for Solana (lamport precision by default). + +## Bitcoin (BTC) + +### Working with Bitcoin + +```typescript +import { Money, BTC } from "@thesis-co/cent" + +// From BTC amount +const btc = Money("0.5 BTC") +const precise = Money("0.00012345 BTC") + +// From satoshis (1 BTC = 100,000,000 sats) +const sats = Money("50000000 sats") +const alsoHalfBtc = Money("0.5 BTC") +sats.equals(alsoHalfBtc) // true + +// Access the raw satoshi amount +const oneBtc = Money("1 BTC") +console.log(oneBtc.amount) // 100000000n (satoshis) + +// Work at satoshi precision +const fee = Money("1000 sats") +const total = btc.add(fee) +``` + +### Bitcoin Use Cases + +```typescript +// Mining rewards with precise split +const blockReward = Money("6.25 BTC") +const [pool, miner] = blockReward.allocate([2, 98]) + +// Transaction fee calculation +const txSize = 250 // vbytes +const feeRate = Money("50 sats") // per vbyte +const txFee = feeRate.multiply(txSize) +``` + +### Lightning + +The Lightning Network supports millisatoshis (1/1000th of a satoshi) for streaming payments and sub-satoshi precision: + +```typescript +// Millisatoshi precision +const oneMilliSat = Money("1 msats") +const streamPayment = Money("500 msats") + +// Streaming payment rate +const ratePerSecond = Money("10 msats") // per second +const duration = 3600 // 1 hour +const totalStreamed = ratePerSecond.multiply(duration) +console.log(totalStreamed.toString()) // "36000 msats" +``` + +## Ethereum (ETH) + +### Working with Ethereum + +Wei is the smallest natural unit of Ethereum — there are 10^18 wei in 1 ETH. Most ERC-20 tokens also use 18 decimals. + +```typescript +import { Money, ETH } from "@thesis-co/cent" + +// From ETH amount +const eth = Money("1.5 ETH") +const precise = Money("1.234567890123456789 ETH") // Full 18 decimals + +// Access the raw wei amount +const oneEth = Money("1 ETH") +console.log(oneEth.amount) // 1000000000000000000n (wei) +console.log(ETH.decimals) // 18n + +// Gas calculations in gwei (1 gwei = 10^9 wei) +const gasPrice = Money("0.000000020 ETH") // 20 gwei +const gasLimit = 21000 +const gasCost = gasPrice.multiply(gasLimit) +console.log(gasCost.toString()) // "0.00042 ETH" +``` + +### Ethereum Use Cases + +```typescript +// DeFi precision +const stakeAmount = Money("100.123456789012345678 ETH") + +// Token-like calculations +const price = Money("0.000001 ETH") // Price per token +const quantity = 1000000 +const total = price.multiply(quantity) + +// Percentage yield calculation +const principal = Money("10 ETH") +const apy = "5.25%" +const yearlyYield = principal.multiply(apy) +``` + +## Solana (SOL) + +Lamports are the smallest unit of Solana — there are 10^9 lamports in 1 SOL (9 decimal places). + +```typescript +import { Money, SOL } from "@thesis-co/cent" + +// From SOL amount +const sol = Money("10.5 SOL") +const precise = Money("1.123456789 SOL") // Full 9 decimals + +// Access the raw lamport amount +const oneSol = Money("1 SOL") +console.log(oneSol.amount) // 1000000000n (lamports) +console.log(SOL.decimals) // 9n + +// Transaction fees +const txFee = Money("0.000005 SOL") // 5000 lamports +const totalCost = sol.add(txFee) +``` + +## Currency Conversion + +### BTC to ETH + +```typescript +import { Money, ExchangeRate, BTC, ETH } from "@thesis-co/cent" + +// Define exchange rate: 1 BTC = 15.5 ETH +const rate = new ExchangeRate(BTC, ETH, "15.5") + +const btcAmount = Money("0.5 BTC") +const ethAmount = rate.convert(btcAmount) + +console.log(ethAmount.toString()) // "7.75 ETH" +``` + +### Crypto to Fiat + +```typescript +import { Money, ExchangeRate, BTC, USD } from "@thesis-co/cent" + +// 1 BTC = $45,000 +const btcUsd = new ExchangeRate(BTC, USD, "45000") + +const holdings = Money("0.25 BTC") +const usdValue = btcUsd.convert(holdings) + +console.log(usdValue.toString()) // "$11,250.00" +``` + +## Handling Large Numbers + +cent handles extremely large values without precision loss: + +```typescript +// Total Bitcoin supply in satoshis +const maxSupply = Money("21000000 BTC") +console.log(maxSupply.amount) // 2100000000000000n sats + +// Very small amounts +const dust = Money("1 sats") +const halfDust = dust.divide(2, Round.FLOOR) // Still works! + +// Ethereum with full precision +const weiAmount = Money("0.000000000000000001 ETH") // 1 wei +``` + +## Best Practices + +### Always Use Strings + +```typescript +// Correct - preserves precision +const btc = Money("0.12345678 BTC") + +// Avoid - may lose precision for very precise values +const btc = Money(0.12345678, "BTC") +``` + +### Specify Rounding for Division + +```typescript +// For crypto calculations, be explicit about rounding +const split = btcAmount.divide(3, Round.FLOOR) // Round down for safety +const fee = amount.multiply("0.1%").round(Round.CEILING) // Round up for fees +``` + +### Keep Full Precision Until Display + +```typescript +// Calculate with full precision +const result = amount + .multiply(rate) + .add(fee) + .subtract(discount) + +// Round only when displaying +console.log(result.roundTo(8, Round.HALF_UP).toString()) +``` + +## Next Steps + +- [Money API Reference](/docs/api/money) — Complete method documentation +- [Currency Conversion Guide](/docs/guides/currency-conversion) — Multi-currency support +- [Tax Calculations](/docs/guides/tax-calculations) — Percentage operations diff --git a/apps/docs/content/docs/guides/splitting-bills.mdx b/apps/docs/content/docs/guides/splitting-bills.mdx new file mode 100644 index 0000000..10fe5fe --- /dev/null +++ b/apps/docs/content/docs/guides/splitting-bills.mdx @@ -0,0 +1,157 @@ +--- +title: Splitting Bills +description: Divide amounts fairly using allocate and distribute +--- + +cent provides two methods for dividing money: `distribute` for equal splits and `allocate` for proportional splits. + +## Equal Splits with distribute + +Split an amount evenly among N recipients: + +```typescript +import { Money } from "@thesis-co/cent" + +const bill = Money("$100.00") +const [alice, bob, charlie] = bill.distribute(3) + +console.log(alice.toString()) // "$33.34" +console.log(bob.toString()) // "$33.33" +console.log(charlie.toString()) // "$33.33" +``` + +The remainder always goes to the first recipient, ensuring the total equals the original amount. + +## Proportional Splits with allocate + +Split by ratios for proportional distribution: + +```typescript +const budget = Money("$1000.00") + +// Split 2:5:3 ratio +const [marketing, development, operations] = budget.allocate([2, 5, 3]) + +console.log(marketing.toString()) // "$200.00" +console.log(development.toString()) // "$500.00" +console.log(operations.toString()) // "$300.00" +``` + +## Restaurant Bill Example + +```typescript +interface Diner { + name: string + items: string[] + subtotal: string +} + +function splitBill(diners: Diner[], tip: string, taxRate: string) { + // Calculate each person's portion before tip/tax + const subtotals = diners.map((d) => Money(d.subtotal)) + const totalFood = subtotals.reduce((sum, s) => sum.add(s), Money.zero("USD")) + + // Calculate shared costs + const taxAmount = totalFood.multiply(taxRate) + const tipAmount = totalFood.multiply(tip) + const sharedCosts = taxAmount.add(tipAmount) + + // Allocate shared costs proportionally + const ratios = subtotals.map((s) => + Number(s.toString().replace(/[$,]/g, "")) + ) + const sharedSplits = sharedCosts.allocate(ratios) + + // Final amounts + return diners.map((diner, i) => ({ + name: diner.name, + food: subtotals[i].toString(), + share: sharedSplits[i].toString(), + total: subtotals[i].add(sharedSplits[i]).toString(), + })) +} + +const result = splitBill( + [ + { name: "Alice", items: ["Pasta"], subtotal: "$18.00" }, + { name: "Bob", items: ["Steak", "Wine"], subtotal: "$45.00" }, + { name: "Charlie", items: ["Salad"], subtotal: "$12.00" }, + ], + "20%", + "8%" +) + +console.log(result) +// [ +// { name: "Alice", food: "$18.00", share: "$5.04", total: "$23.04" }, +// { name: "Bob", food: "$45.00", share: "$12.60", total: "$57.60" }, +// { name: "Charlie", food: "$12.00", share: "$3.36", total: "$15.36" }, +// ] +``` + +## Handling Remainders + +When splitting doesn't divide evenly, cent ensures no money is lost: + +```typescript +const amount = Money("$100.01") +const parts = amount.distribute(3) + +console.log(parts.map((p) => p.toString())) +// ["$33.34", "$33.34", "$33.33"] + +// Verify nothing is lost +const sum = parts.reduce((a, b) => a.add(b)) +console.log(sum.equals(amount)) // true +``` + +## Fractional Units + +For high-precision amounts, you can separate sub-unit remainders: + +```typescript +const precise = Money("$100.00015") + +// With fractional unit separation +const parts = precise.distribute(3, { distributeFractionalUnits: false }) + +console.log(parts.map((p) => p.toString())) +// ["$33.33", "$33.33", "$33.34", "$0.00015"] +// Main splits clean, fractional amount separated +``` + +## Investment Allocation + +```typescript +const portfolio = Money("$10000.00") + +// 60/40 stocks/bonds split +const [stocks, bonds] = portfolio.allocate([60, 40]) +console.log(`Stocks: ${stocks.toString()}`) // "$6,000.00" +console.log(`Bonds: ${bonds.toString()}`) // "$4,000.00" + +// Further split stocks by sector +const [tech, healthcare, finance] = stocks.allocate([40, 35, 25]) +console.log(`Tech: ${tech.toString()}`) // "$2,400.00" +console.log(`Healthcare: ${healthcare.toString()}`) // "$2,100.00" +console.log(`Finance: ${finance.toString()}`) // "$1,500.00" +``` + +## Concretize for Accounting + +Separate "change" from whole currency units: + +```typescript +const amount = Money("$100.00123") +const [main, change] = amount.concretize() + +console.log(main.toString()) // "$100.00" +console.log(change.toString()) // "$0.00123" +``` + +This is useful for ledger entries where sub-cent precision needs separate tracking. + +## Next Steps + +- [Tax Calculations Guide](/docs/guides/tax-calculations) — Calculate taxes and discounts +- [Currency Conversion Guide](/docs/guides/currency-conversion) — Multi-currency support diff --git a/apps/docs/content/docs/guides/tax-calculations.mdx b/apps/docs/content/docs/guides/tax-calculations.mdx new file mode 100644 index 0000000..440c4e0 --- /dev/null +++ b/apps/docs/content/docs/guides/tax-calculations.mdx @@ -0,0 +1,213 @@ +--- +title: Tax Calculations +description: Calculate taxes, discounts, and percentages with precision +--- + +cent makes percentage-based calculations straightforward and precise. + +## Basic Tax Calculation + +```typescript +import { Money, Round } from "@thesis-co/cent" + +const subtotal = Money("$156.78") +const taxRate = "7.5%" + +// Calculate tax +const tax = subtotal.multiply(taxRate) +const total = subtotal.add(tax) + +console.log(tax.toString()) // "$11.76" +console.log(total.toString()) // "$168.54" +``` + +## Percentage Operations + +The `multiply` method accepts percentage strings: + +```typescript +const price = Money("$100.00") + +// Add percentage +const withTax = price.multiply("1.08") // $108.00 +const alsoWithTax = price.add(price.multiply("8%")) // $108.00 + +// Subtract percentage (discount) +const discounted = price.multiply("0.90") // $90.00 (10% off) +``` + +## Complex Tax Scenarios + +### Multiple Tax Rates + +```typescript +const subtotal = Money("$500.00") +const stateTax = "6%" +const localTax = "2.5%" + +// Calculate each tax +const stateAmount = subtotal.multiply(stateTax) +const localAmount = subtotal.multiply(localTax) + +// Total +const total = subtotal.add(stateAmount).add(localAmount) + +console.log(`Subtotal: ${subtotal.toString()}`) // $500.00 +console.log(`State Tax: ${stateAmount.toString()}`) // $30.00 +console.log(`Local Tax: ${localAmount.toString()}`) // $12.50 +console.log(`Total: ${total.toString()}`) // $542.50 +``` + +### Tax-Inclusive Pricing + +Calculate the tax amount from a tax-inclusive price: + +```typescript +const taxInclusivePrice = Money("$108.00") +const taxRate = "8%" + +// Price = Subtotal x (1 + taxRate) +// Subtotal = Price / (1 + taxRate) +const subtotal = taxInclusivePrice.divide("1.08", Round.HALF_UP) +const taxAmount = taxInclusivePrice.subtract(subtotal) + +console.log(`Subtotal: ${subtotal.toString()}`) // $100.00 +console.log(`Tax: ${taxAmount.toString()}`) // $8.00 +``` + +## Discounts + +### Percentage Discount + +```typescript +const originalPrice = Money("$200.00") +const discountPercent = "20%" + +const discountAmount = originalPrice.multiply(discountPercent) +const salePrice = originalPrice.subtract(discountAmount) + +console.log(`Discount: ${discountAmount.toString()}`) // $40.00 +console.log(`Sale Price: ${salePrice.toString()}`) // $160.00 +``` + +### Combined Discount and Tax + +```typescript +const subtotal = Money("$200.00") + +// Apply 20% discount first +const discounted = subtotal.multiply("0.80") // $160.00 + +// Then calculate 8% tax +const tax = discounted.multiply("8%") // $12.80 +const total = discounted.add(tax) // $172.80 + +console.log(`After Discount: ${discounted.toString()}`) +console.log(`Tax: ${tax.toString()}`) +console.log(`Total: ${total.toString()}`) +``` + +## Rounding Considerations + +Tax calculations often need explicit rounding: + +```typescript +const price = Money("$33.33") +const taxRate = "7.5%" + +// Without rounding specification +const tax = price.multiply(taxRate) // $2.49975 + +// Round to currency precision +const roundedTax = tax.roundTo(2, Round.HALF_UP) // $2.50 + +// Or use round() which uses currency's default precision +const alsoRounded = tax.round(Round.HALF_UP) // $2.50 +``` + +### Banker's Rounding + +For financial applications that require unbiased rounding: + +```typescript +const amounts = [ + Money("$10.005"), + Money("$10.015"), + Money("$10.025"), + Money("$10.035"), +] + +// HALF_EVEN rounds ties to the nearest even number +const bankersRounded = amounts.map((a) => a.round(Round.HALF_EVEN)) +// [$10.00, $10.02, $10.02, $10.04] + +// Compare with HALF_UP +const standardRounded = amounts.map((a) => a.round(Round.HALF_UP)) +// [$10.01, $10.02, $10.03, $10.04] +``` + +## Invoice Example + +```typescript +interface LineItem { + description: string + price: string + quantity: number +} + +function calculateInvoice( + items: LineItem[], + discountPercent: number, + taxPercent: number +) { + // Calculate line totals + const lineAmounts = items.map((item) => + Money(item.price).multiply(item.quantity) + ) + + // Sum to subtotal + const subtotal = lineAmounts.reduce( + (sum, amount) => sum.add(amount), + Money.zero("USD") + ) + + // Apply discount + const discountAmount = subtotal.multiply(`${discountPercent}%`) + const afterDiscount = subtotal.subtract(discountAmount) + + // Calculate tax + const taxAmount = afterDiscount.multiply(`${taxPercent}%`) + const total = afterDiscount.add(taxAmount) + + return { + subtotal: subtotal.toString(), + discount: discountAmount.toString(), + afterDiscount: afterDiscount.toString(), + tax: taxAmount.toString(), + total: total.toString(), + } +} + +const invoice = calculateInvoice( + [ + { description: "Widget", price: "$29.99", quantity: 2 }, + { description: "Gadget", price: "$49.99", quantity: 1 }, + ], + 10, // 10% discount + 8.25 // 8.25% tax +) + +console.log(invoice) +// { +// subtotal: "$109.97", +// discount: "$11.00", +// afterDiscount: "$98.97", +// tax: "$8.17", +// total: "$107.14" +// } +``` + +## Next Steps + +- [Bill Splitting Guide](/docs/guides/splitting-bills) — Divide amounts fairly +- [Currency Conversion Guide](/docs/guides/currency-conversion) — Multi-currency support diff --git a/apps/docs/content/docs/index.mdx b/apps/docs/content/docs/index.mdx new file mode 100644 index 0000000..383e3ca --- /dev/null +++ b/apps/docs/content/docs/index.mdx @@ -0,0 +1,50 @@ +--- +title: Introduction +description: Precise financial calculations for TypeScript +--- + +Cent is an arbitrary-precision financial calculation library for TypeScript. It provides: + +- **Arbitrary precision** — BigInt under the hood, no floating point errors +- **Multi-asset support** — USD, EUR, BTC, ETH, and 180+ currencies +- **Type safety** — Can't accidentally add USD to EUR +- **Zero dependencies** — 8KB gzipped, tree-shakable + +## Quick Start + +```bash +npm install @thesis-co/cent +``` + +```typescript +import { Money } from "@thesis-co/cent" + +// Create money values +const price = Money("$100.00") +const tax = price.multiply("0.08") +const total = price.add(tax) + +console.log(total.toString()) // $108.00 +``` + +## Why Cent? + +JavaScript's floating point math is famously broken for financial calculations: + +```typescript +0.1 + 0.2 // 0.30000000000000004 +19.99 * 3 // 59.96999999999999 +``` + +Cent solves this with arbitrary-precision arithmetic: + +```typescript +Money("$0.10").add("$0.20").toString() // $0.30 +Money("$19.99").multiply(3).toString() // $59.97 +``` + +## Next Steps + +- [Getting Started](/docs/getting-started) — Installation and basic usage +- [Core Concepts](/docs/core-concepts) — Understanding Money, precision, and immutability +- [API Reference](/docs/api/money) — Complete API documentation diff --git a/apps/docs/content/docs/meta.json b/apps/docs/content/docs/meta.json new file mode 100644 index 0000000..be16866 --- /dev/null +++ b/apps/docs/content/docs/meta.json @@ -0,0 +1,26 @@ +{ + "title": "Cent", + "pages": [ + "index", + "getting-started", + "core-concepts", + "---Guides---", + "guides/tax-calculations", + "guides/splitting-bills", + "guides/crypto-precision", + "---API---", + "api/money", + "api/exchange-rate", + "api/price", + "api/price-range", + "api/fixed-point", + "---Integrations---", + "zod", + "react", + "supabase", + "---TypeDocs---", + "type-docs", + "---Reference---", + "ai-guide" + ] +} diff --git a/apps/docs/lib/playground/examples.ts b/apps/docs/lib/playground/examples.ts new file mode 100644 index 0000000..c0fdbf6 --- /dev/null +++ b/apps/docs/lib/playground/examples.ts @@ -0,0 +1,108 @@ +export const EXAMPLES = { + basic: `// Basic Money Operations +const price = Money("$99.99") +const tax = price.multiply("8%") +const total = price.add(tax) + +console.log("Price:", price.toString()) +console.log("Tax:", tax.toString()) +console.log("Total:", total.toString()) +`, + + taxCalculation: `// Tax Calculation with Rounding +const subtotal = Money("$156.78") +const taxRate = "7.5%" + +const tax = subtotal.multiply(taxRate) +const total = subtotal.add(tax) + +// Round to cents +const roundedTotal = total.roundTo(2, Round.HALF_UP) + +console.log("Subtotal:", subtotal.toString()) +console.log("Tax (7.5%):", tax.toString()) +console.log("Total:", roundedTotal.toString()) +`, + + billSplitting: `// Bill Splitting with Distribute and Allocate +const bill = Money("$127.43") + +// Split equally among 4 people +const splits = bill.distribute(4) +console.log("Equal split:") +splits.forEach((s, i) => console.log(\` Person \${i + 1}: \${s.toString()}\`)) + +// Split by ratio (2:1:1) +const ratioSplits = bill.allocate([2, 1, 1]) +console.log("\\nRatio split (2:1:1):") +ratioSplits.forEach((s, i) => console.log(\` Share \${i + 1}: \${s.toString()}\`)) +`, + + currencyConversion: `// Currency Conversion +// Define exchange rate: 1 USD = 0.92 EUR +const rate = new ExchangeRate(USD, EUR, "0.92") + +const dollars = Money("$250.00") +const euros = rate.convert(dollars) + +console.log("Original:", dollars.toString()) +console.log("Converted:", euros.toString()) + +// Reverse conversion works automatically +const backToDollars = rate.convert(euros) +console.log("Back to USD:", backToDollars.toString()) +`, + + cryptocurrency: `// Cryptocurrency Precision +// Bitcoin with satoshi precision (8 decimals) +const btc = Money("0.00012345 BTC") +console.log("BTC:", btc.toString()) + +// Ethereum with wei precision (18 decimals) +const eth = Money("1.234567890123456789 ETH") +console.log("ETH:", eth.toString()) + +// Convert between units +const sats = Money("100000000 sat") +console.log("100M sats =", Money("1 BTC").equals(sats) ? "1 BTC" : "not 1 BTC") +`, + + invoice: `// Invoice Calculation +const items = [ + { name: "Widget", price: "$29.99", qty: 2 }, + { name: "Gadget", price: "$49.99", qty: 1 }, + { name: "Gizmo", price: "$15.00", qty: 3 } +] + +// Calculate subtotal +const subtotal = items.reduce( + (sum, item) => sum.add(Money(item.price).multiply(item.qty)), + Money.zero("USD") +) + +// Apply 10% discount +const discount = subtotal.multiply("10%") +const afterDiscount = subtotal.subtract(discount) + +// Add 8.25% tax +const tax = afterDiscount.multiply("8.25%").roundTo(2, Round.HALF_UP) +const total = afterDiscount.add(tax) + +console.log("Subtotal:", subtotal.toString()) +console.log("Discount (10%):", discount.toString()) +console.log("After Discount:", afterDiscount.toString()) +console.log("Tax (8.25%):", tax.toString()) +console.log("Total:", total.toString()) +`, +} as const + +export type ExampleKey = keyof typeof EXAMPLES + +export const EXAMPLE_LABELS: Record = { + basic: "Basic Operations", + taxCalculation: "Tax Calculation", + billSplitting: "Bill Splitting", + currencyConversion: "Currency Conversion", + cryptocurrency: "Cryptocurrency", + invoice: "Invoice Builder", +} diff --git a/apps/docs/lib/playground/execution.ts b/apps/docs/lib/playground/execution.ts new file mode 100644 index 0000000..10ca7f4 --- /dev/null +++ b/apps/docs/lib/playground/execution.ts @@ -0,0 +1,123 @@ +import * as Cent from "@thesis-co/cent" +import { transform } from "sucrase" + +interface ExecutionResult { + output: string + error: string | null +} + +function formatValue(value: unknown): string { + if (value === null) return "null" + if (value === undefined) return "undefined" + if (typeof value === "bigint") return `${value}n` + if (Array.isArray(value)) { + return `[${value.map(formatValue).join(", ")}]` + } + if (typeof value === "object" && value !== null) { + // Check if it has a toString method that's not the default Object.toString + if ( + "toString" in value && + typeof (value as { toString: () => string }).toString === "function" + ) { + const str = (value as { toString: () => string }).toString() + // If toString returns something meaningful (not [object Object]) + if (!str.startsWith("[object ")) { + return str + } + } + try { + return JSON.stringify( + value, + (_, v) => (typeof v === "bigint" ? `${v}n` : v), + 2, + ) + } catch { + return String(value) + } + } + return String(value) +} + +// Strip import statements since cent is provided globally +function stripImports(code: string): string { + // Remove import statements for @thesis-co/cent + return code.replace( + /^import\s+.*from\s+['"]@thesis-co\/cent['"];?\s*$/gm, + "// import removed - cent is available globally", + ) +} + +export function executeCode(code: string): ExecutionResult { + const logs: string[] = [] + let error: string | null = null + + try { + // Strip imports before transformation + const strippedCode = stripImports(code) + + // Transform TypeScript to JavaScript (without import transform since we stripped them) + const compiled = transform(strippedCode, { + transforms: ["typescript"], + production: true, + }).code + + // Create mock console + const mockConsole = { + log: (...args: unknown[]) => { + logs.push(args.map(formatValue).join(" ")) + }, + error: (...args: unknown[]) => { + logs.push(`Error: ${args.map(formatValue).join(" ")}`) + }, + warn: (...args: unknown[]) => { + logs.push(`Warning: ${args.map(formatValue).join(" ")}`) + }, + info: (...args: unknown[]) => { + logs.push(args.map(formatValue).join(" ")) + }, + } + + // Execute in sandboxed context with cent available + const fn = new Function( + "console", + "Money", + "FixedPoint", + "Rational", + "Round", + "Price", + "PriceRange", + "ExchangeRate", + "USD", + "EUR", + "GBP", + "JPY", + "BTC", + "ETH", + compiled, + ) + + fn( + mockConsole, + Cent.Money, + Cent.FixedPoint, + Cent.Rational, + Cent.Round, + Cent.Price, + Cent.PriceRange, + Cent.ExchangeRate, + Cent.USD, + Cent.EUR, + Cent.GBP, + Cent.JPY, + Cent.BTC, + Cent.ETH, + ) + } catch (e) { + error = e instanceof Error ? e.message : String(e) + } + + return { + output: logs.join("\n"), + error, + } +} diff --git a/apps/docs/lib/playground/url-state.ts b/apps/docs/lib/playground/url-state.ts new file mode 100644 index 0000000..9841b74 --- /dev/null +++ b/apps/docs/lib/playground/url-state.ts @@ -0,0 +1,35 @@ +import LZString from "lz-string" + +interface PlaygroundState { + code: string + example?: string +} + +export function encodePlaygroundState(state: PlaygroundState): string { + const json = JSON.stringify(state) + return LZString.compressToEncodedURIComponent(json) +} + +export function decodePlaygroundState(hash: string): PlaygroundState | null { + try { + const json = LZString.decompressFromEncodedURIComponent(hash) + return json ? JSON.parse(json) : null + } catch { + return null + } +} + +export function getShareableUrl(code: string): string { + const encoded = encodePlaygroundState({ code }) + return `${typeof window !== "undefined" ? window.location.origin : ""}/playground#code=${encoded}` +} + +export function getCodeFromUrl(): string | null { + if (typeof window === "undefined") return null + + const hash = window.location.hash.slice(1) + if (!hash.startsWith("code=")) return null + + const state = decodePlaygroundState(hash.slice(5)) + return state?.code ?? null +} diff --git a/apps/docs/lib/source.ts b/apps/docs/lib/source.ts new file mode 100644 index 0000000..4cf9c0d --- /dev/null +++ b/apps/docs/lib/source.ts @@ -0,0 +1,8 @@ +import { loader } from "fumadocs-core/source" +import { createMDXSource } from "fumadocs-mdx" +import { docs, meta } from "@/.source" + +export const source = loader({ + baseUrl: "/docs", + source: createMDXSource(docs, meta), +}) diff --git a/apps/docs/next-env.d.ts b/apps/docs/next-env.d.ts new file mode 100644 index 0000000..40c3d68 --- /dev/null +++ b/apps/docs/next-env.d.ts @@ -0,0 +1,5 @@ +/// +/// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information. diff --git a/apps/docs/next.config.mjs b/apps/docs/next.config.mjs new file mode 100644 index 0000000..b84bfc4 --- /dev/null +++ b/apps/docs/next.config.mjs @@ -0,0 +1,14 @@ +import { createMDX } from "fumadocs-mdx/next" + +const withMDX = createMDX() + +/** @type {import('next').NextConfig} */ +const config = { + reactStrictMode: true, + // Required for Cloudflare Pages + images: { + unoptimized: true, + }, +} + +export default withMDX(config) diff --git a/apps/docs/package.json b/apps/docs/package.json new file mode 100644 index 0000000..df4f64b --- /dev/null +++ b/apps/docs/package.json @@ -0,0 +1,40 @@ +{ + "name": "@thesis-co/cent-docs", + "version": "0.0.1", + "private": true, + "scripts": { + "copy-docs": "tsx scripts/copy-package-docs.ts", + "dev": "pnpm run copy-docs && next dev", + "build": "pnpm run copy-docs && next build", + "start": "next start", + "lint": "next lint", + "pages:build": "npx @cloudflare/next-on-pages", + "pages:dev": "npx wrangler pages dev .vercel/output/static --compatibility-date=2024-01-01", + "pages:deploy": "npx wrangler pages deploy .vercel/output/static" + }, + "dependencies": { + "fumadocs-core": "^14.0.0", + "fumadocs-mdx": "^10.0.0", + "fumadocs-ui": "^14.0.0", + "next": "^14.2.0", + "react": "^18.3.0", + "react-dom": "^18.3.0", + "@thesis-co/cent": "workspace:*", + "@monaco-editor/react": "^4.6.0", + "sucrase": "^3.35.0", + "lz-string": "^1.5.0" + }, + "devDependencies": { + "tsx": "^4.0.0", + "@cloudflare/next-on-pages": "^1.13.0", + "@types/node": "^20.11.24", + "@types/react": "^18.3.0", + "@types/react-dom": "^18.3.0", + "@types/lz-string": "^1.5.0", + "autoprefixer": "^10.4.20", + "postcss": "^8.4.49", + "tailwindcss": "^3.4.0", + "typescript": "^5.5.4", + "wrangler": "^3.0.0" + } +} diff --git a/apps/docs/postcss.config.mjs b/apps/docs/postcss.config.mjs new file mode 100644 index 0000000..2ef30fc --- /dev/null +++ b/apps/docs/postcss.config.mjs @@ -0,0 +1,9 @@ +/** @type {import('postcss-load-config').Config} */ +const config = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +}; + +export default config; diff --git a/apps/docs/public/llms.txt b/apps/docs/public/llms.txt new file mode 100644 index 0000000..a7e4684 --- /dev/null +++ b/apps/docs/public/llms.txt @@ -0,0 +1,24 @@ +# cent.thesis.co llms.txt + +> Cent is an arbitrary-precision currency library for TypeScript. + +## Quick Start +npm install @thesis-co/cent + +## Core Usage +- Use string inputs: Money("$100.50") +- Specify rounding for division: amount.divide(3, Round.HALF_UP) +- All operations are immutable + +## Key Types +- Money: Currency values with arbitrary precision +- FixedPoint: Fixed-point decimal numbers +- Rational: Exact fractional arithmetic +- ExchangeRate: Currency conversion +- PriceRange: Price range operations + +## Links +- AI Guide: https://cent.thesis.co/docs/ai-guide +- API Reference: https://cent.thesis.co/docs/api/money +- Playground: https://cent.thesis.co/playground +- GitHub: https://github.com/thesis/cent diff --git a/apps/docs/scripts/copy-package-docs.ts b/apps/docs/scripts/copy-package-docs.ts new file mode 100644 index 0000000..a8b5167 --- /dev/null +++ b/apps/docs/scripts/copy-package-docs.ts @@ -0,0 +1,457 @@ +import * as fs from "node:fs" +import * as path from "node:path" + +interface PackageConfig { + name: string + sourceDir: string + destDir: string +} + +const PACKAGES: PackageConfig[] = [ + { + name: "Zod Integration", + sourceDir: "packages/cent-zod/docs", + destDir: "zod", + }, + { + name: "React Hooks", + sourceDir: "packages/cent-react/docs", + destDir: "react", + }, + { + name: "Supabase Integration", + sourceDir: "packages/cent-supabase/docs", + destDir: "supabase", + }, +] + +// TypeDoc-generated API docs configuration +const GENERATED_API_CONFIG = { + sourceDir: "packages/cent/docs/api", + destDir: "type-docs", +} + +const MONOREPO_ROOT = path.resolve(__dirname, "../../..") +const DOCS_CONTENT_DIR = path.resolve(__dirname, "../content/docs") + +// Extract title from filename or content +function extractTitle(filename: string, content: string): string { + // Try to extract from first heading in content + // TypeDoc adds prefixes like "Class:", "Function:", etc. - strip those + const headingMatch = content.match(/^#\s+(?:Class:\s*|Function:\s*|Interface:\s*|Enum:\s*|Type Alias:\s*)?(.+)$/m) + if (headingMatch) { + // Remove trailing () from function names, trim, and unescape markdown escapes + return headingMatch[1] + .trim() + .replace(/\(\)$/, "") + .replace(/\\([<>])/g, "$1") // Remove backslash escapes from < and > + } + + // Fall back to filename + const baseName = path.basename(filename, ".mdx") + if (baseName === "README") return "API Reference" + return baseName +} + +// Get description based on the type of API item +function getDescription(filename: string, folderName: string): string { + const baseName = path.basename(filename).replace(/\.(mdx|md)$/, "") + if (baseName === "README") return "Complete API reference for @thesis-co/cent" + + switch (folderName) { + case "classes": + return `API reference for the ${baseName} class` + case "functions": + return `API reference for the ${baseName} function` + case "interfaces": + return `API reference for the ${baseName} interface` + case "enumerations": + return `API reference for the ${baseName} enum` + case "type-aliases": + return `API reference for the ${baseName} type` + default: + return `API reference for ${baseName}` + } +} + +// Escape title for YAML frontmatter (quote if contains special chars) +function escapeYamlValue(value: string): string { + // YAML special chars that require quoting + const needsQuoting = /[:#'"@\[\]{}&*!|>%]/.test(value) || value.startsWith("-") || value.startsWith("?") + if (needsQuoting) { + // Use double quotes and escape any internal double quotes + return `"${value.replace(/"/g, '\\"')}"` + } + return value +} + +// Add frontmatter and remove the first heading (which becomes redundant) +function addFrontmatter(content: string, title: string, description: string): string { + // Check if file already has frontmatter + if (content.startsWith("---")) { + return content + } + + // Remove the first heading line since Fumadocs renders the title from frontmatter + const contentWithoutFirstHeading = content.replace( + /^#\s+(?:Class:|Function:|Interface:|Enum:|Type Alias:)?\s*.+\n+/m, + "" + ) + + const frontmatter = `--- +title: ${escapeYamlValue(title)} +description: ${escapeYamlValue(description)} +--- + +` + return frontmatter + contentWithoutFirstHeading +} + +// Escape < and > in text (outside of code blocks) to prevent MDX JSX parsing +function escapeJsxInMarkdown(content: string): string { + // Split by code blocks to only process non-code sections + const parts: string[] = [] + let lastIndex = 0 + // Match fenced code blocks (``` ... ```) and inline code (` ... `) + const codeBlockRegex = /(```[\s\S]*?```|`[^`]+`)/g + let match + + while ((match = codeBlockRegex.exec(content)) !== null) { + // Process text before this code block + const textBefore = content.slice(lastIndex, match.index) + // Escape < and > that look like operators (<=, >=, <, >) not JSX + const escaped = textBefore + .replace(/<=(?!\s*[A-Za-z_$])/g, "\\<=") // Escape <= not followed by component name + .replace(/>=(?!\s*[A-Za-z_$])/g, "\\>=") // Escape >= not followed by component name + .replace(/<(?=[^A-Za-z/!]|$)/g, "\\<") // Escape < not followed by letter or / + .replace(/(?<=[^\\])>(?=[^A-Za-z]|$)/g, "\\>") // Escape > carefully + parts.push(escaped) + parts.push(match[0]) // Keep code blocks unchanged + lastIndex = match.index + match[0].length + } + + // Process remaining text after last code block + if (lastIndex < content.length) { + const remaining = content.slice(lastIndex) + const escaped = remaining + .replace(/<=(?!\s*[A-Za-z_$])/g, "\\<=") + .replace(/>=(?!\s*[A-Za-z_$])/g, "\\>=") + .replace(/<(?=[^A-Za-z/!]|$)/g, "\\<") + .replace(/(?<=[^\\])>(?=[^A-Za-z]|$)/g, "\\>") + parts.push(escaped) + } + + return parts.join("") +} + +// Copy TypeDoc-generated API docs with frontmatter processing +function copyGeneratedApiDocs(sourceDir: string, destDir: string): number { + if (!fs.existsSync(sourceDir)) { + console.log(` Source not found: ${sourceDir}`) + return 0 + } + + const entries = fs.readdirSync(sourceDir, { withFileTypes: true }) + if (entries.length === 0) { + return 0 + } + + fs.mkdirSync(destDir, { recursive: true }) + let count = 0 + + for (const entry of entries) { + const srcPath = path.join(sourceDir, entry.name) + const destPath = path.join(destDir, entry.name) + + if (entry.isDirectory()) { + count += copyGeneratedApiDocs(srcPath, destPath) + } else if (entry.name.endsWith(".mdx") || entry.name.endsWith(".md")) { + let content = fs.readFileSync(srcPath, "utf-8") + const folderName = path.basename(sourceDir) + const title = extractTitle(entry.name, content) + const description = getDescription(entry.name, folderName) + content = addFrontmatter(content, title, description) + // Write as .md file (Fumadocs handles .md files, and they avoid MDX JSX parsing issues) + // Rename README to index for Fumadocs + let outputPath = destPath.replace(/\.mdx$/, ".md") + if (entry.name === "README.md" || entry.name === "README.mdx") { + outputPath = path.join(path.dirname(outputPath), "index.md") + } + fs.writeFileSync(outputPath, content) + count++ + } + } + + return count +} + +function cleanDirectory(dir: string): void { + if (fs.existsSync(dir)) { + fs.rmSync(dir, { recursive: true, force: true }) + console.log(` Cleaned: ${dir}`) + } +} + +function copyDirectoryRecursive(src: string, dest: string): number { + if (!fs.existsSync(src)) { + return 0 + } + + const entries = fs.readdirSync(src, { withFileTypes: true }) + + if (entries.length === 0) { + return 0 + } + + fs.mkdirSync(dest, { recursive: true }) + let count = 0 + + for (const entry of entries) { + const srcPath = path.join(src, entry.name) + const destPath = path.join(dest, entry.name) + + if (entry.isDirectory()) { + count += copyDirectoryRecursive(srcPath, destPath) + } else { + fs.copyFileSync(srcPath, destPath) + count++ + } + } + + return count +} + +function generateMetaJsonIfMissing(destDir: string, title: string): void { + const metaPath = path.join(destDir, "meta.json") + + if (fs.existsSync(metaPath)) { + console.log(` Found existing meta.json`) + return + } + + if (!fs.existsSync(destDir)) { + return + } + + const entries = fs.readdirSync(destDir, { withFileTypes: true }) + // Support both .md and .mdx files + const mdFiles = entries + .filter((e) => e.isFile() && (e.name.endsWith(".mdx") || e.name.endsWith(".md"))) + .map((e) => e.name.replace(/\.(mdx|md)$/, "")) + + const subdirs = entries + .filter((e) => e.isDirectory()) + .map((e) => `...${e.name}`) + + if (mdFiles.length === 0 && subdirs.length === 0) { + return + } + + const sortedPages = [ + ...mdFiles.filter((p) => p === "index"), + ...mdFiles.filter((p) => p !== "index").sort(), + ...subdirs.sort(), + ] + + const meta = { title, pages: sortedPages } + fs.writeFileSync(metaPath, JSON.stringify(meta, null, 2) + "\n") + console.log(` Generated meta.json with ${sortedPages.length} entries`) +} + +// Custom meta.json configurations for TypeDoc-generated API sections +const TYPEDOC_META_CONFIGS: Record = { + "type-docs": { + title: "@thesis-co/cent", + pages: [ + "classes", + "functions", + "interfaces", + "type-aliases", + "enumerations", + ], + }, + "type-docs/classes": { + title: "Classes", + pages: [ + "---Core Types---", + "MoneyClass", + "Price", + "PriceRangeClass", + "ExchangeRate", + "---Math---", + "FixedPointNumber", + "RationalNumber", + "---Results---", + "Ok", + "Err", + "---Errors---", + "CentError", + "CurrencyMismatchError", + "DivisionError", + "EmptyArrayError", + "ExchangeRateError", + "InvalidInputError", + "ParseError", + "PrecisionLossError", + "ValidationError", + ], + }, + "type-docs/functions": { + title: "Functions", + pages: [ + "---Factories---", + "Money", + "FixedPoint", + "Rational", + "PriceRangeFactory", + "---Configuration---", + "configure", + "getConfig", + "getDefaultConfig", + "resetConfig", + "withConfig", + "---Result Helpers---", + "ok", + "err", + "---Type Guards---", + "isDecimalString", + "isFixedPointNumber", + "isFractionalUnitSymbol", + "isFractionString", + "isMoneyAmountNegative", + "isMoneyAmountPositive", + "isMoneyAmountZero", + "isPrimarySymbol", + "isRateStale", + "isRationalNumber", + "isRationalString", + "---Utilities---", + "compareSources", + "filterByReliability", + "getComparableValue", + "getCurrencyFromCode", + "getFractionalUnitInfo", + "getPrimaryCurrency", + "getRationalStringType", + "parseFraction", + "sortSources", + "toDecimalString", + "toFixedPointNumber", + "toRationalString", + ], + }, + "type-docs/interfaces": { + title: "Interfaces", + pages: [ + "---Configuration---", + "CentConfig", + "CentErrorOptions", + "RateStalenessConfig", + "---Exchange Rates---", + "ExchangeRateProvider", + "ExchangeRateSource", + "---Currency---", + "FractionalUnitSymbol", + ], + }, + "type-docs/type-aliases": { + title: "Type Aliases", + pages: [ + "---Core Types---", + "Currency", + "MoneyAmount", + "AssetAmount", + "Asset", + "AnyAsset", + "FungibleAsset", + "---Math---", + "DecimalString", + "RationalString", + "FixedPointType", + "Ratio", + "---Results & Errors---", + "Result", + "Round", + "ErrorCode", + "---Exchange Rates---", + "ExchangeRateData", + "PricePoint", + "---Currency Symbols---", + "PrimarySymbol", + "FractionalUnitSymbolKey", + "---Time---", + "UNIXTime", + "UTCTime", + ], + }, + "type-docs/enumerations": { + title: "Enumerations", + pages: ["RoundingMode"], + }, +} + +function generateTypeDocMetaFiles(baseDir: string): void { + for (const [relativePath, config] of Object.entries(TYPEDOC_META_CONFIGS)) { + const metaPath = path.join(baseDir, relativePath, "meta.json") + const dirPath = path.dirname(metaPath) + + if (!fs.existsSync(dirPath)) { + continue + } + + fs.writeFileSync(metaPath, JSON.stringify(config, null, 2) + "\n") + } + console.log(` Created ${Object.keys(TYPEDOC_META_CONFIGS).length} custom meta.json files`) +} + +function main(): void { + console.log("Copying package documentation...\n") + + let totalCopied = 0 + + for (const pkg of PACKAGES) { + console.log(`Processing: ${pkg.name}`) + + const sourceDir = path.join(MONOREPO_ROOT, pkg.sourceDir) + const destDir = path.join(DOCS_CONTENT_DIR, pkg.destDir) + + cleanDirectory(destDir) + + if (!fs.existsSync(sourceDir)) { + console.log(` Source not found: ${sourceDir}`) + continue + } + + const copied = copyDirectoryRecursive(sourceDir, destDir) + + if (copied === 0) { + console.log(` No files to copy (empty source)`) + continue + } + + console.log(` Copied ${copied} files`) + totalCopied += copied + + generateMetaJsonIfMissing(destDir, pkg.name) + } + + // Copy TypeDoc-generated API docs + console.log(`\nProcessing: TypeDocs`) + const apiSourceDir = path.join(MONOREPO_ROOT, GENERATED_API_CONFIG.sourceDir) + const apiDestDir = path.join(DOCS_CONTENT_DIR, GENERATED_API_CONFIG.destDir) + + cleanDirectory(apiDestDir) + + const apiCopied = copyGeneratedApiDocs(apiSourceDir, apiDestDir) + if (apiCopied > 0) { + console.log(` Copied and processed ${apiCopied} files`) + totalCopied += apiCopied + generateTypeDocMetaFiles(DOCS_CONTENT_DIR) + } else { + console.log(` No API docs found (run 'pnpm docs:api' in packages/cent first)`) + } + + console.log(`\nTotal: ${totalCopied} files copied`) +} + +main() diff --git a/apps/docs/source.config.ts b/apps/docs/source.config.ts new file mode 100644 index 0000000..8dc2107 --- /dev/null +++ b/apps/docs/source.config.ts @@ -0,0 +1,7 @@ +import { defineDocs, defineConfig } from 'fumadocs-mdx/config'; + +export const { docs, meta } = defineDocs({ + dir: 'content/docs', +}); + +export default defineConfig(); diff --git a/apps/docs/tailwind.config.ts b/apps/docs/tailwind.config.ts new file mode 100644 index 0000000..ad3fdae --- /dev/null +++ b/apps/docs/tailwind.config.ts @@ -0,0 +1,22 @@ +import { createPreset } from 'fumadocs-ui/tailwind-plugin'; +import type { Config } from 'tailwindcss'; + +const config: Config = { + content: [ + './components/**/*.{ts,tsx}', + './app/**/*.{ts,tsx}', + './content/**/*.{md,mdx}', + './node_modules/fumadocs-ui/dist/**/*.js', + ], + presets: [createPreset()], + theme: { + extend: { + fontFamily: { + sans: ['var(--font-mono)'], + mono: ['var(--font-mono)'], + }, + }, + }, +}; + +export default config; diff --git a/apps/docs/tsconfig.json b/apps/docs/tsconfig.json new file mode 100644 index 0000000..ab68925 --- /dev/null +++ b/apps/docs/tsconfig.json @@ -0,0 +1,33 @@ +{ + "compilerOptions": { + "target": "ES2017", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": ["./*"] + } + }, + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + ".next/types/**/*.ts", + ".source/**/*.ts" + ], + "exclude": ["node_modules"] +} diff --git a/apps/docs/wrangler.toml b/apps/docs/wrangler.toml new file mode 100644 index 0000000..44274f3 --- /dev/null +++ b/apps/docs/wrangler.toml @@ -0,0 +1,7 @@ +name = "cent-docs" +compatibility_date = "2024-01-01" +compatibility_flags = ["nodejs_compat"] + +# Note: @cloudflare/next-on-pages uses Vercel's Build Output API format internally, +# so the output directory is .vercel/output/static by design +pages_build_output_dir = ".vercel/output/static" diff --git a/biome.json b/biome.json index 75c95a7..c04bb8a 100644 --- a/biome.json +++ b/biome.json @@ -1,4 +1,13 @@ { "extends": ["@thesis-co/biome-config/biome"], - "files": { "includes": ["packages/*/src/**/*.ts", "packages/*/test/**/*.ts"] } + "files": { + "includes": [ + "packages/*/src/**/*.ts", + "packages/*/test/**/*.ts", + "apps/*/app/**/*.tsx", + "apps/*/app/**/*.ts", + "apps/*/components/**/*.tsx", + "apps/*/lib/**/*.ts" + ] + } } diff --git a/packages/cent-react/README.md b/packages/cent-react/README.md index 7db3362..80bac74 100644 --- a/packages/cent-react/README.md +++ b/packages/cent-react/README.md @@ -1,6 +1,6 @@ # @thesis-co/cent-react -React bindings for [@thesis-co/cent](https://www.npmjs.com/package/@thesis-co/cent) - display, input, and manage money values with ease. +React components and hooks for [`@thesis-co/cent`](https://www.npmjs.com/package/@thesis-co/cent) - display, input, and manage money values. ## Installation @@ -8,234 +8,28 @@ React bindings for [@thesis-co/cent](https://www.npmjs.com/package/@thesis-co/ce npm install @thesis-co/cent @thesis-co/cent-react ``` -## Quick Start - -### Display Money - -```tsx -import { MoneyDisplay } from '@thesis-co/cent-react'; -import { Money } from '@thesis-co/cent'; - -// Basic usage - -// → "$1,234.56" - -// Compact notation - -// → "$1.5M" - -// Crypto with satoshis - -// → "100,000 sats" - -// Locale formatting - -// → "1.234,56 €" - -// Null handling with placeholder - -// → "—" -``` - -### Custom Parts Rendering - -```tsx - - {({ parts, isNegative }) => ( - - {parts.map((part, i) => ( - - {part.value} - - ))} - - )} - -``` - -### Money Input +## Quick Example ```tsx -import { MoneyInput } from '@thesis-co/cent-react'; +import { MoneyDisplay, MoneyInput, MoneyProvider } from '@thesis-co/cent-react'; import { Money } from '@thesis-co/cent'; -function PaymentForm() { +function App() { const [amount, setAmount] = useState(null); return ( - setAmount(e.target.value)} - currency="USD" - min="$1" - max="$10000" - placeholder="Enter amount" - /> - ); -} -``` - -### With react-hook-form - -```tsx -import { Controller, useForm } from 'react-hook-form'; -import { MoneyInput } from '@thesis-co/cent-react'; - -function CheckoutForm() { - const { control, handleSubmit } = useForm(); - - return ( -
- ( - - )} + + setAmount(e.target.value)} + currency="USD" /> - - ); -} -``` - -### useMoney Hook - -```tsx -import { useMoney, MoneyDisplay } from '@thesis-co/cent-react'; - -function TipCalculator() { - const bill = useMoney({ currency: 'USD' }); - const tip = bill.money?.multiply(0.18) ?? null; - - return ( -
- - {bill.error && {bill.error.message}} - -

Tip (18%):

-

Total:

-
- ); -} -``` - -### MoneyProvider - -Set default configuration for all descendant components: - -```tsx -import { MoneyProvider } from '@thesis-co/cent-react'; - -function App() { - return ( - - + ); } ``` -### useExchangeRate Hook - -```tsx -import { useExchangeRate, MoneyDisplay } from '@thesis-co/cent-react'; -import { Money } from '@thesis-co/cent'; - -function CurrencyConverter() { - const [usd, setUsd] = useState(Money.zero('USD')); - - const { convert, isLoading, isStale, refetch } = useExchangeRate({ - from: 'USD', - to: 'EUR', - pollInterval: 60000, // Refresh every minute - staleThreshold: 300000, // Stale after 5 minutes - }); - - const eur = convert(usd); - - return ( -
- setUsd(e.target.value)} currency="USD" /> - - {isLoading ? ( - Loading... - ) : ( - - )} - - {isStale && ( - - )} -
- ); -} -``` - -**Note:** `useExchangeRate` requires an `exchangeRateResolver` to be provided via `MoneyProvider`: - -```tsx - { - const response = await fetch(`/api/rates/${from}/${to}`); - const data = await response.json(); - return new ExchangeRate(from, to, data.rate); - }} -> - - -``` - -### MoneyDiff - -Display the difference between two money values: - -```tsx -import { MoneyDiff } from '@thesis-co/cent-react'; -import { Money } from '@thesis-co/cent'; - -// Basic difference - -// → "+$20.00" - -// With percentage change - -// → "+$20.00 (+20.00%)" - -// Custom rendering - - {({ direction, formatted }) => ( - - {formatted.difference} - - )} - -``` - -## API Reference - -### Components - -| Component | Description | -|-----------|-------------| -| `MoneyDisplay` | Display formatted money values | -| `MoneyInput` | Controlled input for money values | -| `MoneyDiff` | Display difference between two values | -| `MoneyProvider` | Context provider for default configuration | - -### Hooks - -| Hook | Description | -|------|-------------| -| `useMoney` | Manage money state with validation | -| `useExchangeRate` | Fetch and manage exchange rates | -| `useMoneyConfig` | Access MoneyProvider context | - -## Requirements +## Documentation -- React 17.0.0 or later -- @thesis-co/cent 0.0.5 or later +See the [full documentation](./docs/) for all components (`MoneyDisplay`, `MoneyInput`, `MoneyDiff`) and hooks (`useMoney`, `useExchangeRate`). diff --git a/packages/cent-react/docs/components.mdx b/packages/cent-react/docs/components.mdx new file mode 100644 index 0000000..08e5d3c --- /dev/null +++ b/packages/cent-react/docs/components.mdx @@ -0,0 +1,162 @@ +--- +title: Components +description: React components for displaying and inputting money values +--- + +# Components + +## MoneyDisplay + +Display formatted money values with locale-aware formatting. + +```tsx +import { MoneyDisplay } from '@thesis-co/cent-react'; +import { Money } from '@thesis-co/cent'; + +// Basic usage + +// "$1,234.56" + +// Compact notation + +// "$1.5M" + +// Crypto with preferred unit + +// "100,000 sats" + +// Locale formatting + +// "1.234,56 €" + +// Null handling + +// "—" +``` + +### Props + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `value` | `Money \| null` | required | Money value to display | +| `compact` | `boolean` | `false` | Use compact notation (1.5M) | +| `locale` | `string` | from provider | Locale for formatting | +| `preferredUnit` | `string` | - | Preferred unit (e.g., "sat") | +| `placeholder` | `ReactNode` | - | Shown when value is null | +| `children` | `(parts) => ReactNode` | - | Custom parts renderer | + +### Custom Rendering + +```tsx + + {({ parts, isNegative }) => ( + + {parts.map((part, i) => ( + {part.value} + ))} + + )} + +``` + +## MoneyInput + +Controlled input component for money values. + +```tsx +import { MoneyInput } from '@thesis-co/cent-react'; + +function PaymentForm() { + const [amount, setAmount] = useState(null); + + return ( + setAmount(e.target.value)} + currency="USD" + min="$1" + max="$10000" + placeholder="Enter amount" + /> + ); +} +``` + +### Props + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `value` | `Money \| null` | required | Current value | +| `onChange` | `(e) => void` | required | Change handler | +| `currency` | `string` | from provider | Currency code | +| `min` | `string \| Money` | - | Minimum value | +| `max` | `string \| Money` | - | Maximum value | +| `placeholder` | `string` | - | Input placeholder | +| `name` | `string` | - | Form field name | +| `disabled` | `boolean` | `false` | Disable input | + +### With react-hook-form + +```tsx +import { Controller, useForm } from 'react-hook-form'; +import { MoneyInput } from '@thesis-co/cent-react'; + +function CheckoutForm() { + const { control, handleSubmit } = useForm(); + + return ( +
+ ( + + )} + /> + + ); +} +``` + +## MoneyDiff + +Display the difference between two money values. + +```tsx +import { MoneyDiff } from '@thesis-co/cent-react'; +import { Money } from '@thesis-co/cent'; + +// Basic difference + +// "+$20.00" + +// With percentage change + +// "+$20.00 (+20.00%)" +``` + +### Props + +| Prop | Type | Default | Description | +|------|------|---------|-------------| +| `value` | `Money` | required | Current value | +| `compareTo` | `Money` | required | Value to compare against | +| `showPercentage` | `boolean` | `false` | Show percentage change | +| `children` | `(data) => ReactNode` | - | Custom renderer | + +### Custom Rendering + +```tsx + + {({ direction, formatted }) => ( + + {formatted.difference} + + )} + +``` diff --git a/packages/cent-react/docs/hooks.mdx b/packages/cent-react/docs/hooks.mdx new file mode 100644 index 0000000..e433966 --- /dev/null +++ b/packages/cent-react/docs/hooks.mdx @@ -0,0 +1,135 @@ +--- +title: Hooks +description: React hooks for managing money state and exchange rates +--- + +# Hooks + +## useMoney + +Manage money state with built-in validation. + +```tsx +import { useMoney, MoneyDisplay } from '@thesis-co/cent-react'; + +function TipCalculator() { + const bill = useMoney({ currency: 'USD' }); + const tip = bill.money?.multiply(0.18) ?? null; + + return ( +
+ + {bill.error && {bill.error.message}} + +

Tip (18%):

+

Total:

+
+ ); +} +``` + +### Options + +| Option | Type | Description | +|--------|------|-------------| +| `currency` | `string` | Currency code for the money value | +| `initialValue` | `Money` | Initial value | +| `min` | `string \| Money` | Minimum allowed value | +| `max` | `string \| Money` | Maximum allowed value | + +### Return Value + +| Property | Type | Description | +|----------|------|-------------| +| `money` | `Money \| null` | Current money value | +| `inputProps` | `object` | Props to spread on an input element | +| `error` | `{ message: string } \| null` | Validation error | +| `setMoney` | `(money: Money \| null) => void` | Set the value programmatically | +| `reset` | `() => void` | Reset to initial value | + +## useExchangeRate + +Fetch and manage exchange rates with polling and staleness tracking. + +```tsx +import { useExchangeRate, MoneyDisplay } from '@thesis-co/cent-react'; +import { Money } from '@thesis-co/cent'; + +function CurrencyConverter() { + const [usd, setUsd] = useState(Money.zero('USD')); + + const { convert, isLoading, isStale, refetch } = useExchangeRate({ + from: 'USD', + to: 'EUR', + pollInterval: 60000, // Refresh every minute + staleThreshold: 300000, // Stale after 5 minutes + }); + + const eur = convert(usd); + + return ( +
+ setUsd(e.target.value)} currency="USD" /> + + {isLoading ? ( + Loading... + ) : ( + + )} + + {isStale && ( + + )} +
+ ); +} +``` + +**Note:** Requires `exchangeRateResolver` to be provided via `MoneyProvider`. + +### Options + +| Option | Type | Description | +|--------|------|-------------| +| `from` | `string` | Base currency code | +| `to` | `string` | Quote currency code | +| `pollInterval` | `number` | Auto-refresh interval in ms | +| `staleThreshold` | `number` | Time in ms before rate is considered stale | + +### Return Value + +| Property | Type | Description | +|----------|------|-------------| +| `rate` | `ExchangeRate \| null` | Current exchange rate | +| `convert` | `(money: Money) => Money \| null` | Convert money to target currency | +| `isLoading` | `boolean` | Initial loading state | +| `isStale` | `boolean` | Rate exceeds stale threshold | +| `error` | `Error \| null` | Fetch error | +| `refetch` | `() => void` | Manually refresh the rate | + +## useMoneyConfig + +Access `MoneyProvider` context values. + +```tsx +import { useMoneyConfig } from '@thesis-co/cent-react'; + +function CurrencySelector() { + const { locale, defaultCurrency } = useMoneyConfig(); + + return ( +
+ Current locale: {locale} + Default currency: {defaultCurrency} +
+ ); +} +``` + +### Return Value + +| Property | Type | Description | +|----------|------|-------------| +| `locale` | `string` | Current locale | +| `defaultCurrency` | `string` | Default currency code | +| `exchangeRateResolver` | `function \| undefined` | Exchange rate resolver function | diff --git a/packages/cent-react/docs/index.mdx b/packages/cent-react/docs/index.mdx new file mode 100644 index 0000000..2c1997e --- /dev/null +++ b/packages/cent-react/docs/index.mdx @@ -0,0 +1,85 @@ +--- +title: Overview +description: React components and hooks for displaying and managing money values +--- + +# React + +Display, input, and manage money values with React components and hooks for `@thesis-co/cent`. + +## Installation + + + +```bash +npm install @thesis-co/cent @thesis-co/cent-react +``` + + +```bash +pnpm add @thesis-co/cent @thesis-co/cent-react +``` + + +```bash +yarn add @thesis-co/cent @thesis-co/cent-react +``` + + + +## Quick Start + +```tsx +import { MoneyDisplay, MoneyInput, MoneyProvider } from '@thesis-co/cent-react'; +import { Money } from '@thesis-co/cent'; + +function App() { + const [amount, setAmount] = useState(null); + + return ( + + setAmount(e.target.value)} + currency="USD" + /> + + + ); +} +``` + +## MoneyProvider + +Set default configuration for all descendant components: + +```tsx +import { MoneyProvider } from '@thesis-co/cent-react'; + +function App() { + return ( + { + const response = await fetch(`/api/rates/${from}/${to}`); + const data = await response.json(); + return new ExchangeRate(from, to, data.rate); + }} + > + + + ); +} +``` + +| Prop | Type | Description | +|------|------|-------------| +| `locale` | `string` | Default locale for formatting | +| `defaultCurrency` | `string` | Default currency code | +| `exchangeRateResolver` | `(from, to) => Promise` | Required for `useExchangeRate` | + +## Next Steps + +- [Components](/docs/react/components) - MoneyDisplay, MoneyInput, MoneyDiff +- [Hooks](/docs/react/hooks) - useMoney, useExchangeRate, useMoneyConfig diff --git a/packages/cent-react/docs/meta.json b/packages/cent-react/docs/meta.json new file mode 100644 index 0000000..d881e5e --- /dev/null +++ b/packages/cent-react/docs/meta.json @@ -0,0 +1,4 @@ +{ + "title": "React", + "pages": ["index", "components", "hooks"] +} diff --git a/packages/cent-supabase/README.md b/packages/cent-supabase/README.md index 25cdb71..a9945b8 100644 --- a/packages/cent-supabase/README.md +++ b/packages/cent-supabase/README.md @@ -1,20 +1,6 @@ # @thesis-co/cent-supabase -Integration for `@thesis-co/cent` for easy storage and querying in -Supabase. - -## The problem - -The Supabase client returns `DECIMAL` columns as JSON numbers, losing -precision: - -```typescript -// Database stores: 19.99 -const { data } = await supabase.from('products').select('price').single() -console.log(data.price) // 19.990000000000002 -``` - -This package wraps the Supabase client to cast money columns to text on the wire, then converts them to `Money` objects in your app. +Supabase integration for [`@thesis-co/cent`](https://www.npmjs.com/package/@thesis-co/cent) - store and query money values without precision loss. ## Installation @@ -22,11 +8,10 @@ This package wraps the Supabase client to cast money columns to text on the wire npm install @thesis-co/cent-supabase @thesis-co/cent @supabase/supabase-js ``` -## Quick start +## Quick Example ```typescript import { createCentSupabaseClient } from '@thesis-co/cent-supabase' -import { Money } from '@thesis-co/cent' const supabase = createCentSupabaseClient( process.env.SUPABASE_URL!, @@ -34,135 +19,17 @@ const supabase = createCentSupabaseClient( { tables: { products: { - money: { - // statically defined currencies (every price is in USD) - price: { currencyCode: 'USD' }, - cost: { currencyCode: 'USD' } - } - }, - orders: { - money: { - // for dynamic currencies (each row has a - // total and total_currency) - total: { currencyColumn: 'total_currency' }, - tax: { currencyColumn: 'tax_currency' } - } + money: { price: { currencyCode: 'USD' } } } } } ) -// SELECT — returns Money objects +// SELECT returns Money objects const { data } = await supabase.from('products').select('*') console.log(data[0].price.toString()) // "$29.99" - -// INSERT — accepts Money objects -await supabase.from('orders').insert({ - total: Money('€150.00'), - tax: Money('€15.00') - // 'currency' column auto-populated as 'EUR' -}) - -// Aggregates work too -const { data: stats } = await supabase.from('orders').select('sum(total)').single() -console.log(stats.sum.toString()) // "$1,234.56" -``` - -## Configuration - -### Static currency - -When all rows use the same currency: - -```typescript -products: { - money: { - price: { currencyCode: 'USD' } - } -} -``` - -### Dynamic currency - -When currency varies per row (stored in another column): - -```typescript -orders: { - money: { - total: { currencyColumn: 'currency' } - } -} ``` -On insert, the currency column is auto-populated from the Money object. - -### Minor units - -When storing cents, satoshis, or wei as integers: - -```typescript -transactions: { - money: { - amount_sats: { currencyCode: 'BTC', minorUnits: true } - } -} -// Database: 150000000 → Money("1.5 BTC") -``` - -## Realtime - -Subscriptions automatically transform payloads: - -```typescript -supabase - .channel('orders') - .on('postgres_changes', { event: 'INSERT', schema: 'public', table: 'orders' }, (payload) => { - console.log(payload.new.total.toString()) // Money object - }) - .subscribe() -``` - -## Helper functions - -For RPC results or manual transformations: - -```typescript -import { parseMoneyResult, serializeMoney, moneySelect } from '@thesis-co/cent-supabase' - -// Transform RPC results -const { data } = await supabase.rpc('calculate_total', { order_id: '...' }) -const result = parseMoneyResult(data, { total: { currencyCode: 'USD' } }) - -// Serialize Money for custom mutations -const serialized = serializeMoney({ price: Money('$99.99') }, { price: { currencyCode: 'USD' } }) -// { price: '99.99' } - -// Build select string with casts -moneySelect('id, name, price', ['price']) // "id, name, price::text" -``` - -## Limitations - -- **Nested relations**: Money columns in nested selects (e.g., `orders(items(price))`) aren't auto-transformed. Use `parseMoneyResult` on nested data. -- **Computed expressions**: Use explicit `::text` cast: `.select('(price * qty)::text as subtotal')` -- **RPC functions**: Transform results with `parseMoneyResult` - -## Database Schema - -Use `DECIMAL`/`NUMERIC`, not PostgreSQL's `MONEY` type: - -```sql -CREATE TABLE orders ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - total DECIMAL(19,4) NOT NULL, - currency TEXT NOT NULL, - created_at TIMESTAMPTZ DEFAULT now() -) -``` +## Documentation -| Use Case | PostgreSQL Type | -|----------|-----------------| -| USD, EUR | `DECIMAL(19,4)` | -| BTC (8 decimals) | `DECIMAL(28,8)` | -| ETH (18 decimals) | `DECIMAL(38,18)` | -| Minor units | `BIGINT` | +See the [full documentation](./docs/) for static/dynamic currencies, minor units, realtime subscriptions, and helper functions. diff --git a/packages/cent-supabase/docs/configuration.mdx b/packages/cent-supabase/docs/configuration.mdx new file mode 100644 index 0000000..bd4eb90 --- /dev/null +++ b/packages/cent-supabase/docs/configuration.mdx @@ -0,0 +1,139 @@ +--- +title: Configuration +description: Configure money columns, currencies, and helper functions +--- + +# Configuration + +## Static Currency + +When all rows in a table use the same currency: + +```typescript +const supabase = createCentSupabaseClient(url, key, { + tables: { + products: { + money: { + price: { currencyCode: 'USD' }, + cost: { currencyCode: 'USD' } + } + } + } +}) +``` + +## Dynamic Currency + +When currency varies per row (stored in another column): + +```typescript +const supabase = createCentSupabaseClient(url, key, { + tables: { + orders: { + money: { + total: { currencyColumn: 'currency' }, + tax: { currencyColumn: 'currency' } + } + } + } +}) + +// On insert, currency column is auto-populated +await supabase.from('orders').insert({ + total: Money('€150.00'), + tax: Money('€15.00') + // currency automatically set to 'EUR' +}) +``` + +## Minor Units + +When storing cents, satoshis, or wei as integers: + +```typescript +const supabase = createCentSupabaseClient(url, key, { + tables: { + transactions: { + money: { + amount_sats: { currencyCode: 'BTC', minorUnits: true } + } + } + } +}) + +// Database: 150000000 (integer) -> Money("1.5 BTC") +``` + +## Realtime Subscriptions + +Subscriptions automatically transform payloads: + +```typescript +supabase + .channel('orders') + .on('postgres_changes', { + event: 'INSERT', + schema: 'public', + table: 'orders' + }, (payload) => { + console.log(payload.new.total.toString()) // Money object + }) + .subscribe() +``` + +## Helper Functions + +For RPC results or manual transformations: + +```typescript +import { + parseMoneyResult, + serializeMoney, + moneySelect +} from '@thesis-co/cent-supabase' + +// Transform RPC results +const { data } = await supabase.rpc('calculate_total', { order_id: '...' }) +const result = parseMoneyResult(data, { + total: { currencyCode: 'USD' } +}) + +// Serialize Money for custom mutations +const serialized = serializeMoney( + { price: Money('$99.99') }, + { price: { currencyCode: 'USD' } } +) +// { price: '99.99' } + +// Build select string with casts +moneySelect('id, name, price', ['price']) +// "id, name, price::text" +``` + +## Limitations + +- **Nested relations**: Money columns in nested selects (e.g., `orders(items(price))`) aren't auto-transformed. Use `parseMoneyResult` on nested data. + +- **Computed expressions**: Use explicit `::text` cast: + ```typescript + .select('(price * qty)::text as subtotal') + ``` + +- **RPC functions**: Transform results with `parseMoneyResult` + +## Wrapping an Existing Client + +If you already have a Supabase client instance: + +```typescript +import { wrapSupabaseClient } from '@thesis-co/cent-supabase' + +const existingClient = createClient(url, key) +const supabase = wrapSupabaseClient(existingClient, { + tables: { + products: { + money: { price: { currencyCode: 'USD' } } + } + } +}) +``` diff --git a/packages/cent-supabase/docs/index.mdx b/packages/cent-supabase/docs/index.mdx new file mode 100644 index 0000000..f0e8ca8 --- /dev/null +++ b/packages/cent-supabase/docs/index.mdx @@ -0,0 +1,99 @@ +--- +title: Overview +description: Precision-safe money storage and querying with Supabase +--- + +# Supabase + +Store and query money values in Supabase without precision loss. + +## The Problem + +The Supabase client returns `DECIMAL` columns as JSON numbers, losing precision: + +```typescript +// Database stores: 19.99 +const { data } = await supabase.from('products').select('price').single() +console.log(data.price) // 19.990000000000002 +``` + +This package wraps the Supabase client to cast money columns to text on the wire, then converts them to `Money` objects in your app. + +## Installation + + + +```bash +npm install @thesis-co/cent-supabase @thesis-co/cent @supabase/supabase-js +``` + + +```bash +pnpm add @thesis-co/cent-supabase @thesis-co/cent @supabase/supabase-js +``` + + +```bash +yarn add @thesis-co/cent-supabase @thesis-co/cent @supabase/supabase-js +``` + + + +## Quick Start + +```typescript +import { createCentSupabaseClient } from '@thesis-co/cent-supabase' +import { Money } from '@thesis-co/cent' + +const supabase = createCentSupabaseClient( + process.env.SUPABASE_URL!, + process.env.SUPABASE_ANON_KEY!, + { + tables: { + products: { + money: { + price: { currencyCode: 'USD' }, + cost: { currencyCode: 'USD' } + } + } + } + } +) + +// SELECT returns Money objects +const { data } = await supabase.from('products').select('*') +console.log(data[0].price.toString()) // "$29.99" + +// INSERT accepts Money objects +await supabase.from('products').insert({ + name: 'Widget', + price: Money('$29.99'), + cost: Money('$15.00') +}) +``` + +## Database Schema + +Use `DECIMAL`/`NUMERIC` columns, not PostgreSQL's `MONEY` type: + +```sql +CREATE TABLE products ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + name TEXT NOT NULL, + price DECIMAL(19,4) NOT NULL, + currency TEXT NOT NULL, + created_at TIMESTAMPTZ DEFAULT now() +) +``` + +| Use Case | PostgreSQL Type | +|----------|-----------------| +| USD, EUR (2 decimals) | `DECIMAL(19,4)` | +| BTC (8 decimals) | `DECIMAL(28,8)` | +| ETH (18 decimals) | `DECIMAL(38,18)` | +| Minor units (cents, sats) | `BIGINT` | + +## Next Steps + +- [Configuration](/docs/supabase/configuration) - Static/dynamic currencies, minor units, helper functions +- [Getting Started](/docs/getting-started) - Learn the basics of Cent diff --git a/packages/cent-supabase/docs/meta.json b/packages/cent-supabase/docs/meta.json new file mode 100644 index 0000000..a247d0e --- /dev/null +++ b/packages/cent-supabase/docs/meta.json @@ -0,0 +1,4 @@ +{ + "title": "Supabase", + "pages": ["index", "configuration"] +} diff --git a/packages/cent-zod/README.md b/packages/cent-zod/README.md index b9c8457..8b2e0c2 100644 --- a/packages/cent-zod/README.md +++ b/packages/cent-zod/README.md @@ -1,22 +1,23 @@ # @thesis-co/cent-zod -Zod schemas for parsing and validating `@thesis-co/cent` types. +Zod schemas for parsing and validating [`@thesis-co/cent`](https://www.npmjs.com/package/@thesis-co/cent) types. + +## Installation ```bash -pnpm add @thesis-co/cent-zod +npm install @thesis-co/cent-zod ``` -## Schemas - -### zMoney +## Quick Example ```ts import { zMoney, zMoneyString } from "@thesis-co/cent-zod" -zMoneyString.parse("$100.50") // MoneyClass +// Parse money strings +zMoneyString.parse("$100.50") // Money -// With constraints -zMoney({ +// With validation constraints +const schema = zMoney({ currency: "USD", min: "$0.50", max: "$10000", @@ -24,61 +25,6 @@ zMoney({ }) ``` -### zPrice - -```ts -import { zPrice } from "@thesis-co/cent-zod" - -zPrice().parse({ numerator: "$50,000", denominator: "1 BTC" }) -zPrice().parse(["$50,000", "1 BTC"]) - -// Currency constraints -zPrice("USD", "BTC") -``` - -### zExchangeRate - -```ts -import { zExchangeRate } from "@thesis-co/cent-zod" - -zExchangeRate("USD", "EUR").parse({ base: "USD", quote: "EUR", rate: "0.92" }) - -// With staleness check -zExchangeRate({ base: "BTC", quote: "USD", maxAge: 60000 }) -``` - -### zPriceRange - -```ts -import { zPriceRange } from "@thesis-co/cent-zod" - -zPriceRange().parse("$50 - $100") -zPriceRange().parse({ min: "$50", max: "$100" }) - -// With constraints -zPriceRange({ - currency: "USD", - bounds: { min: "$0", max: "$10000" }, - minSpan: "$10", -}) -``` - -### zCurrency +## Documentation -```ts -import { zCurrency } from "@thesis-co/cent-zod" - -zCurrency().parse("USD") // Currency object -zCurrency({ allowed: ["USD", "EUR", "GBP"] }) -zCurrency({ type: "crypto" }) -``` - -## Type Inference - -```ts -import { z } from "zod" -import { zMoney } from "@thesis-co/cent-zod" - -const schema = zMoney("USD") -type USDMoney = z.infer // MoneyClass -``` +See the [full documentation](./docs/) for all schemas including `zPrice`, `zExchangeRate`, `zPriceRange`, and `zCurrency`. diff --git a/packages/cent-zod/docs/index.mdx b/packages/cent-zod/docs/index.mdx new file mode 100644 index 0000000..60ef3cd --- /dev/null +++ b/packages/cent-zod/docs/index.mdx @@ -0,0 +1,65 @@ +--- +title: Overview +description: Zod schemas for parsing and validating Cent types +--- + +# Zod + +Validate user input, API responses, and form data with Zod schemas for `@thesis-co/cent` types. + +## Installation + + + +```bash +npm install @thesis-co/cent-zod +``` + + +```bash +pnpm add @thesis-co/cent-zod +``` + + +```bash +yarn add @thesis-co/cent-zod +``` + + + +## Quick Start + +```typescript +import { zMoney, zMoneyString } from "@thesis-co/cent-zod" + +// Parse a money string +const money = zMoneyString.parse("$100.50") // Returns Money instance + +// With validation constraints +const schema = zMoney({ + currency: "USD", + min: "$0.50", + max: "$10000", + positive: true, +}) + +schema.parse(Money("$50")) // Valid +schema.parse(Money("-$10")) // Throws ZodError (not positive) +``` + +## Type Inference + +All schemas support Zod's type inference: + +```typescript +import { z } from "zod" +import { zMoney } from "@thesis-co/cent-zod" + +const schema = zMoney("USD") +type USDMoney = z.infer // Money +``` + +## Next Steps + +- [Schema Reference](/docs/zod/schemas) - Full API documentation for all schemas +- [Core Concepts](/docs/core-concepts) - Understanding Money, precision, and immutability diff --git a/packages/cent-zod/docs/meta.json b/packages/cent-zod/docs/meta.json new file mode 100644 index 0000000..2e8c7ca --- /dev/null +++ b/packages/cent-zod/docs/meta.json @@ -0,0 +1,4 @@ +{ + "title": "Zod", + "pages": ["index", "schemas"] +} diff --git a/packages/cent-zod/docs/schemas.mdx b/packages/cent-zod/docs/schemas.mdx new file mode 100644 index 0000000..3d65935 --- /dev/null +++ b/packages/cent-zod/docs/schemas.mdx @@ -0,0 +1,123 @@ +--- +title: Schema Reference +description: API reference for all Zod schemas in cent-zod +--- + +# Schema Reference + +Complete API reference for all schemas in `@thesis-co/cent-zod`. + +## zMoney / zMoneyString + +Parse and validate Money values. + +```typescript +import { zMoney, zMoneyString } from "@thesis-co/cent-zod" + +// Basic parsing +zMoneyString.parse("$100.50") // Money + +// With constraints +zMoney({ + currency: "USD", // Require specific currency + min: "$0.50", // Minimum value + max: "$10000", // Maximum value + positive: true, // Must be positive +}) +``` + +| Option | Type | Description | +|--------|------|-------------| +| `currency` | `string` | Required currency code | +| `min` | `string \| Money` | Minimum allowed value | +| `max` | `string \| Money` | Maximum allowed value | +| `positive` | `boolean` | Require positive values | + +## zPrice + +Parse price pairs (numerator/denominator). + +```typescript +import { zPrice } from "@thesis-co/cent-zod" + +// Object format +zPrice().parse({ numerator: "$50,000", denominator: "1 BTC" }) + +// Tuple format +zPrice().parse(["$50,000", "1 BTC"]) + +// With currency constraints +zPrice("USD", "BTC") +``` + +## zExchangeRate + +Parse and validate exchange rates. + +```typescript +import { zExchangeRate } from "@thesis-co/cent-zod" + +// Basic parsing +zExchangeRate("USD", "EUR").parse({ + base: "USD", + quote: "EUR", + rate: "0.92" +}) + +// With staleness check +zExchangeRate({ + base: "BTC", + quote: "USD", + maxAge: 60000 // Reject if older than 60 seconds +}) +``` + +| Option | Type | Description | +|--------|------|-------------| +| `base` | `string` | Base currency code | +| `quote` | `string` | Quote currency code | +| `maxAge` | `number` | Maximum age in milliseconds | + +## zPriceRange + +Parse price ranges. + +```typescript +import { zPriceRange } from "@thesis-co/cent-zod" + +// String format +zPriceRange().parse("$50 - $100") + +// Object format +zPriceRange().parse({ min: "$50", max: "$100" }) + +// With constraints +zPriceRange({ + currency: "USD", + bounds: { min: "$0", max: "$10000" }, + minSpan: "$10", // Minimum difference between min and max +}) +``` + +## zCurrency + +Parse and validate currency codes. + +```typescript +import { zCurrency } from "@thesis-co/cent-zod" + +// Basic parsing +zCurrency().parse("USD") // Returns Currency object + +// Restrict to specific currencies +zCurrency({ allowed: ["USD", "EUR", "GBP"] }) + +// Restrict by type +zCurrency({ type: "crypto" }) // Only crypto currencies +zCurrency({ type: "fiat" }) // Only fiat currencies +``` + +| Option | Type | Description | +|--------|------|-------------| +| `allowed` | `string[]` | Allowed currency codes | +| `type` | `"crypto" \| "fiat"` | Restrict to currency type | diff --git a/packages/cent/docs/core-concepts.mdx b/packages/cent/docs/core-concepts.mdx new file mode 100644 index 0000000..58b9240 --- /dev/null +++ b/packages/cent/docs/core-concepts.mdx @@ -0,0 +1,156 @@ +--- +title: Core Concepts +description: Understanding Money, precision, and immutability in cent +--- + +# Core Concepts + +cent is built on a few key principles that make financial calculations safe and predictable. + +## Arbitrary Precision + +cent uses `BigInt` under the hood, which means: + +- **No precision loss** — Values are stored exactly as specified +- **No limits** — Handle amounts from satoshis to quadrillions +- **No floating point errors** — `0.1 + 0.2` actually equals `0.3` + +```typescript +// JavaScript Number fails at large values +Number.MAX_SAFE_INTEGER; // 9,007,199,254,740,991 + +// cent handles any size +const huge = Money("$9,999,999,999,999,999.99"); +const precise = Money("0.123456789012345678 ETH"); // Full 18 decimals +``` + +## Immutability + +All operations return new instances. The original value is never modified: + +```typescript +const price = Money("$100.00"); +const withTax = price.add("$8.25"); + +console.log(price.toString()); // "$100.00" (unchanged) +console.log(withTax.toString()); // "$108.25" (new instance) +``` + +This prevents accidental mutations and makes code easier to reason about. + +## Type Safety + +cent prevents common mistakes at compile time: + +```typescript +const usd = Money("$100"); +const eur = Money("€100"); + +// TypeScript error: Can't compare different currencies +usd.equals(eur); // Error! + +// Convert first using an exchange rate +const rate = new ExchangeRate(USD, EUR, "0.92"); +usd.equals(eur.convert(rate)); // OK +``` + +## Safe Parsing + +For user input or external data, use `Money.parse()` which returns a `Result` type: + +```typescript +const result = Money.parse(userInput) + .map(money => money.add("8.25%")) + .map(money => money.roundTo(2, Round.HALF_UP)); + +const total = result.match({ + ok: (money) => money.toString(), + err: (error) => `Invalid amount: ${error.suggestion}`, +}); + +// Or provide a default +const amount = Money.parse(untrustedInput).unwrapOr(Money.zero("USD")); +``` + +## Rounding Modes + +Division and some multiplications may produce values that can't be represented exactly. cent requires you to specify how to handle this: + +```typescript +const price = Money("$100.00"); + +// Division by factors of 2 and 5 is exact +price.divide(2); // $50.00 (exact) +price.divide(5); // $20.00 (exact) + +// Other divisors require a rounding mode +price.divide(3, Round.HALF_UP); // $33.33 +price.divide(3, Round.HALF_EVEN); // $33.33 (banker's rounding) +price.divide(3, Round.CEILING); // $33.34 +price.divide(3, Round.FLOOR); // $33.33 +``` + +**Available rounding modes:** + +| Mode | Description | +|------|-------------| +| `Round.UP` | Round away from zero | +| `Round.DOWN` | Round toward zero (truncate) | +| `Round.CEILING` | Round toward positive infinity | +| `Round.FLOOR` | Round toward negative infinity | +| `Round.HALF_UP` | Round to nearest, ties away from zero | +| `Round.HALF_DOWN` | Round to nearest, ties toward zero | +| `Round.HALF_EVEN` | Round to nearest, ties to even (banker's rounding) | + +## Numeric Types + +cent provides three numeric types for different use cases: + +### Money + +The primary type for working with currency values: + +```typescript +const usd = Money("$100.50"); +const btc = Money("0.5 BTC"); +``` + +### FixedPoint + +For decimal numbers where you need to track precision: + +```typescript +const rate = FixedPoint("0.875"); +const percentage = FixedPoint("8.25%"); // Becomes 0.0825 +``` + +### Rational + +For exact fractional arithmetic without precision loss: + +```typescript +const oneThird = Rational("1/3"); +const result = oneThird.multiply("3"); // Exactly 1 +``` + +## Currency Support + +cent includes 180+ currencies with proper metadata: + +```typescript +import { USD, EUR, BTC, ETH, JPY } from '@thesis-co/cent'; + +console.log(USD.decimals); // 2n +console.log(BTC.decimals); // 8n +console.log(ETH.decimals); // 18n +console.log(JPY.decimals); // 0n + +console.log(USD.symbol); // "$" +console.log(USD.fractionalUnit); // "cent" +``` + +## Next Steps + +- [Money API Reference](/docs/api/money) — Complete method documentation +- [Tax Calculations Guide](/docs/guides/tax-calculations) — Practical examples +- [Crypto Precision Guide](/docs/guides/crypto-precision) — Working with BTC and ETH diff --git a/packages/cent/docs/getting-started.mdx b/packages/cent/docs/getting-started.mdx new file mode 100644 index 0000000..535ce2b --- /dev/null +++ b/packages/cent/docs/getting-started.mdx @@ -0,0 +1,90 @@ +--- +title: Getting Started +description: Install cent and start using precise financial calculations in minutes +--- + +# Getting Started + +Install cent and start using precise financial calculations in your TypeScript project. + +## Installation + +```bash +npm install @thesis-co/cent +``` + +Or with your preferred package manager: + +```bash +pnpm add @thesis-co/cent +yarn add @thesis-co/cent +``` + +## Quick Start + +```typescript +import { Money, Round } from '@thesis-co/cent'; + +// Create money values from strings +const price = Money("$100.50"); +const btc = Money("0.5 BTC"); + +// Arithmetic operations +const total = price.add("$25.25"); // $125.75 + +// Division with rounding +const split = total.divide(3, Round.HALF_UP); // $41.92 + +// Allocation and distribution +const [a, b, c] = price.distribute(3); // [$33.50, $33.50, $33.50] + +// Formatting +console.log(price.toString()); // "$100.50" +``` + +## Why cent? + +JavaScript's floating point math is famously broken for financial calculations: + +```typescript +0.1 + 0.2; // 0.30000000000000004 +19.99 * 3; // 59.96999999999999 +``` + +cent solves this with arbitrary-precision arithmetic: + +```typescript +Money("$0.10").add("$0.20").toString(); // "$0.30" +Money("$19.99").multiply(3).toString(); // "$59.97" +``` + +## Configuration + +Configure library-wide defaults at application startup: + +```typescript +import { configure, Round } from '@thesis-co/cent'; + +configure({ + numberInputMode: process.env.NODE_ENV === 'production' ? 'error' : 'warn', + strictPrecision: process.env.NODE_ENV === 'production', + defaultRoundingMode: Round.HALF_UP, + defaultCurrency: 'USD', +}); +``` + +**Options:** + +| Option | Description | Default | +|--------|-------------|---------| +| `numberInputMode` | How to handle JS number inputs: `'warn'`, `'error'`, or `'silent'` | `'warn'` | +| `strictPrecision` | Throw on any operation that would lose precision | `false` | +| `defaultRoundingMode` | Default rounding mode, or `'none'` to require explicit rounding | `Round.HALF_UP` | +| `defaultCurrency` | Default currency code | `'USD'` | +| `defaultLocale` | Default locale for formatting | `'en-US'` | + +## Next Steps + +- [Core Concepts](/docs/core-concepts) — Understand Money, precision, and immutability +- [API Reference](/docs/api/money) — Complete Money class documentation +- [Guides](/docs/guides/tax-calculations) — Practical examples and patterns diff --git a/packages/cent/docs/guides/splitting-bills.mdx b/packages/cent/docs/guides/splitting-bills.mdx new file mode 100644 index 0000000..2869b37 --- /dev/null +++ b/packages/cent/docs/guides/splitting-bills.mdx @@ -0,0 +1,161 @@ +--- +title: Splitting Bills +description: Divide amounts fairly using allocate and distribute +--- + +# Splitting Bills + +cent provides two methods for dividing money: `distribute` for equal splits and `allocate` for proportional splits. + +## Equal Splits with distribute + +Split an amount evenly among N recipients: + +```typescript +import { Money } from '@thesis-co/cent'; + +const bill = Money("$100.00"); +const [alice, bob, charlie] = bill.distribute(3); + +console.log(alice.toString()); // "$33.34" +console.log(bob.toString()); // "$33.33" +console.log(charlie.toString()); // "$33.33" +``` + +The remainder always goes to the first recipient, ensuring the total equals the original amount. + +## Proportional Splits with allocate + +Split by ratios for proportional distribution: + +```typescript +const budget = Money("$1000.00"); + +// Split 2:5:3 ratio +const [marketing, development, operations] = budget.allocate([2, 5, 3]); + +console.log(marketing.toString()); // "$200.00" +console.log(development.toString()); // "$500.00" +console.log(operations.toString()); // "$300.00" +``` + +## Restaurant Bill Example + +```typescript +interface Diner { + name: string; + items: string[]; + subtotal: string; +} + +function splitBill( + diners: Diner[], + tip: string, + taxRate: string +) { + // Calculate each person's portion before tip/tax + const subtotals = diners.map(d => Money(d.subtotal)); + const totalFood = subtotals.reduce((sum, s) => sum.add(s), Money.zero("USD")); + + // Calculate shared costs + const taxAmount = totalFood.multiply(taxRate); + const tipAmount = totalFood.multiply(tip); + const sharedCosts = taxAmount.add(tipAmount); + + // Allocate shared costs proportionally + const ratios = subtotals.map(s => Number(s.toString().replace(/[$,]/g, ''))); + const sharedSplits = sharedCosts.allocate(ratios); + + // Final amounts + return diners.map((diner, i) => ({ + name: diner.name, + food: subtotals[i].toString(), + share: sharedSplits[i].toString(), + total: subtotals[i].add(sharedSplits[i]).toString(), + })); +} + +const result = splitBill( + [ + { name: "Alice", items: ["Pasta"], subtotal: "$18.00" }, + { name: "Bob", items: ["Steak", "Wine"], subtotal: "$45.00" }, + { name: "Charlie", items: ["Salad"], subtotal: "$12.00" }, + ], + "20%", + "8%" +); + +console.log(result); +// [ +// { name: "Alice", food: "$18.00", share: "$5.04", total: "$23.04" }, +// { name: "Bob", food: "$45.00", share: "$12.60", total: "$57.60" }, +// { name: "Charlie", food: "$12.00", share: "$3.36", total: "$15.36" }, +// ] +``` + +## Handling Remainders + +When splitting doesn't divide evenly, cent ensures no money is lost: + +```typescript +const amount = Money("$100.01"); +const parts = amount.distribute(3); + +console.log(parts.map(p => p.toString())); +// ["$33.34", "$33.34", "$33.33"] + +// Verify nothing is lost +const sum = parts.reduce((a, b) => a.add(b)); +console.log(sum.equals(amount)); // true +``` + +## Fractional Units + +For high-precision amounts, you can separate sub-unit remainders: + +```typescript +const precise = Money("$100.00015"); + +// With fractional unit separation +const parts = precise.distribute(3, { distributeFractionalUnits: false }); + +console.log(parts.map(p => p.toString())); +// ["$33.33", "$33.33", "$33.34", "$0.00015"] +// Main splits clean, fractional amount separated +``` + +## Investment Allocation + +```typescript +const portfolio = Money("$10000.00"); + +// 60/40 stocks/bonds split +const [stocks, bonds] = portfolio.allocate([60, 40]); +console.log(`Stocks: ${stocks.toString()}`); // "$6,000.00" +console.log(`Bonds: ${bonds.toString()}`); // "$4,000.00" + +// Further split stocks by sector +const [tech, healthcare, finance] = stocks.allocate([40, 35, 25]); +console.log(`Tech: ${tech.toString()}`); // "$2,400.00" +console.log(`Healthcare: ${healthcare.toString()}`); // "$2,100.00" +console.log(`Finance: ${finance.toString()}`); // "$1,500.00" +``` + +## Concretize for Accounting + +Separate "change" from whole currency units: + +```typescript +const amount = Money("$100.00123"); +const [main, change] = amount.concretize(); + +console.log(main.toString()); // "$100.00" +console.log(change.toString()); // "$0.00123" +``` + +This is useful for ledger entries where sub-cent precision needs separate tracking. + +## Next Steps + +- [Tax Calculations Guide](/docs/guides/tax-calculations) — Calculate taxes and discounts +- [Currency Conversion Guide](/docs/guides/currency-conversion) — Multi-currency support diff --git a/packages/cent/docs/guides/tax-calculations.mdx b/packages/cent/docs/guides/tax-calculations.mdx new file mode 100644 index 0000000..2143ec8 --- /dev/null +++ b/packages/cent/docs/guides/tax-calculations.mdx @@ -0,0 +1,215 @@ +--- +title: Tax Calculations +description: Calculate taxes, discounts, and percentages with precision +--- + +# Tax Calculations + +cent makes percentage-based calculations straightforward and precise. + +## Basic Tax Calculation + +```typescript +import { Money, Round } from '@thesis-co/cent'; + +const subtotal = Money("$156.78"); +const taxRate = "7.5%"; + +// Calculate tax +const tax = subtotal.multiply(taxRate); +const total = subtotal.add(tax); + +console.log(tax.toString()); // "$11.76" +console.log(total.toString()); // "$168.54" +``` + +## Percentage Operations + +The `multiply` method accepts percentage strings: + +```typescript +const price = Money("$100.00"); + +// Add percentage +const withTax = price.multiply("1.08"); // $108.00 +const alsoWithTax = price.add(price.multiply("8%")); // $108.00 + +// Subtract percentage (discount) +const discounted = price.multiply("0.90"); // $90.00 (10% off) +``` + +## Complex Tax Scenarios + +### Multiple Tax Rates + +```typescript +const subtotal = Money("$500.00"); +const stateTax = "6%"; +const localTax = "2.5%"; + +// Calculate each tax +const stateAmount = subtotal.multiply(stateTax); +const localAmount = subtotal.multiply(localTax); + +// Total +const total = subtotal.add(stateAmount).add(localAmount); + +console.log(`Subtotal: ${subtotal.toString()}`); // $500.00 +console.log(`State Tax: ${stateAmount.toString()}`); // $30.00 +console.log(`Local Tax: ${localAmount.toString()}`); // $12.50 +console.log(`Total: ${total.toString()}`); // $542.50 +``` + +### Tax-Inclusive Pricing + +Calculate the tax amount from a tax-inclusive price: + +```typescript +const taxInclusivePrice = Money("$108.00"); +const taxRate = "8%"; + +// Price = Subtotal × (1 + taxRate) +// Subtotal = Price ÷ (1 + taxRate) +const subtotal = taxInclusivePrice.divide("1.08", Round.HALF_UP); +const taxAmount = taxInclusivePrice.subtract(subtotal); + +console.log(`Subtotal: ${subtotal.toString()}`); // $100.00 +console.log(`Tax: ${taxAmount.toString()}`); // $8.00 +``` + +## Discounts + +### Percentage Discount + +```typescript +const originalPrice = Money("$200.00"); +const discountPercent = "20%"; + +const discountAmount = originalPrice.multiply(discountPercent); +const salePrice = originalPrice.subtract(discountAmount); + +console.log(`Discount: ${discountAmount.toString()}`); // $40.00 +console.log(`Sale Price: ${salePrice.toString()}`); // $160.00 +``` + +### Combined Discount and Tax + +```typescript +const subtotal = Money("$200.00"); + +// Apply 20% discount first +const discounted = subtotal.multiply("0.80"); // $160.00 + +// Then calculate 8% tax +const tax = discounted.multiply("8%"); // $12.80 +const total = discounted.add(tax); // $172.80 + +console.log(`After Discount: ${discounted.toString()}`); +console.log(`Tax: ${tax.toString()}`); +console.log(`Total: ${total.toString()}`); +``` + +## Rounding Considerations + +Tax calculations often need explicit rounding: + +```typescript +const price = Money("$33.33"); +const taxRate = "7.5%"; + +// Without rounding specification +const tax = price.multiply(taxRate); // $2.49975 + +// Round to currency precision +const roundedTax = tax.roundTo(2, Round.HALF_UP); // $2.50 + +// Or use round() which uses currency's default precision +const alsoRounded = tax.round(Round.HALF_UP); // $2.50 +``` + +### Banker's Rounding + +For financial applications that require unbiased rounding: + +```typescript +const amounts = [ + Money("$10.005"), + Money("$10.015"), + Money("$10.025"), + Money("$10.035"), +]; + +// HALF_EVEN rounds ties to the nearest even number +const bankersRounded = amounts.map(a => a.round(Round.HALF_EVEN)); +// [$10.00, $10.02, $10.02, $10.04] + +// Compare with HALF_UP +const standardRounded = amounts.map(a => a.round(Round.HALF_UP)); +// [$10.01, $10.02, $10.03, $10.04] +``` + +## Invoice Example + +```typescript +interface LineItem { + description: string; + price: string; + quantity: number; +} + +function calculateInvoice( + items: LineItem[], + discountPercent: number, + taxPercent: number +) { + // Calculate line totals + const lineAmounts = items.map(item => + Money(item.price).multiply(item.quantity) + ); + + // Sum to subtotal + const subtotal = lineAmounts.reduce( + (sum, amount) => sum.add(amount), + Money.zero("USD") + ); + + // Apply discount + const discountAmount = subtotal.multiply(`${discountPercent}%`); + const afterDiscount = subtotal.subtract(discountAmount); + + // Calculate tax + const taxAmount = afterDiscount.multiply(`${taxPercent}%`); + const total = afterDiscount.add(taxAmount); + + return { + subtotal: subtotal.toString(), + discount: discountAmount.toString(), + afterDiscount: afterDiscount.toString(), + tax: taxAmount.toString(), + total: total.toString(), + }; +} + +const invoice = calculateInvoice( + [ + { description: "Widget", price: "$29.99", quantity: 2 }, + { description: "Gadget", price: "$49.99", quantity: 1 }, + ], + 10, // 10% discount + 8.25 // 8.25% tax +); + +console.log(invoice); +// { +// subtotal: "$109.97", +// discount: "$11.00", +// afterDiscount: "$98.97", +// tax: "$8.17", +// total: "$107.14" +// } +``` + +## Next Steps + +- [Bill Splitting Guide](/docs/guides/splitting-bills) — Divide amounts fairly +- [Currency Conversion Guide](/docs/guides/currency-conversion) — Multi-currency support diff --git a/packages/cent/package.json b/packages/cent/package.json index f408b78..34b60c0 100644 --- a/packages/cent/package.json +++ b/packages/cent/package.json @@ -29,13 +29,16 @@ "lint:fix": "pnpx @biomejs/biome check --write", "build": "tsc", "test": "jest", + "docs:api": "typedoc", "prepublishOnly": "pnpm run build && pnpm run test && pnpm run lint" }, "devDependencies": { "@types/jest": "^29.5.12", "@types/node": "^20.11.24", "jest": "^29.7.0", - "ts-jest": "^29.1.2" + "ts-jest": "^29.1.2", + "typedoc": "^0.28.16", + "typedoc-plugin-markdown": "^4.9.0" }, "dependencies": { "zod": "^4.0.0" diff --git a/packages/cent/typedoc.json b/packages/cent/typedoc.json new file mode 100644 index 0000000..cf5c95c --- /dev/null +++ b/packages/cent/typedoc.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://typedoc.org/schema.json", + "entryPoints": ["src/index.ts"], + "out": "docs/api", + "plugin": ["typedoc-plugin-markdown"], + "excludePrivate": true, + "excludeInternal": true, + "readme": "none", + "outputFileStrategy": "members", + "membersWithOwnFile": ["Class", "Interface", "Enum", "Function", "TypeAlias"], + "hidePageHeader": true, + "hideBreadcrumbs": true, + "useCodeBlocks": true, + "fileExtension": ".md" +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 137734b..b632cbb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,7 +10,7 @@ importers: devDependencies: '@thesis-co/biome-config': specifier: github:thesis/biome-config - version: https://codeload.github.com/thesis/biome-config/tar.gz/6e8586bfa74c62c9ede2ca12abbcac1dc0ad4606 + version: https://codeload.github.com/thesis/biome-config/tar.gz/c38100c9023d10a1c486bc0eca388f3cf8ca4046 turbo: specifier: ^2.0.0 version: 2.7.3 @@ -18,6 +18,73 @@ importers: specifier: 5.5.4 version: 5.5.4 + apps/docs: + dependencies: + '@monaco-editor/react': + specifier: ^4.6.0 + version: 4.7.0(monaco-editor@0.55.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@thesis-co/cent': + specifier: workspace:* + version: link:../../packages/cent + fumadocs-core: + specifier: ^14.0.0 + version: 14.7.7(@types/react@18.3.27)(next@14.2.35(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + fumadocs-mdx: + specifier: ^10.0.0 + version: 10.1.0(fumadocs-core@14.7.7(@types/react@18.3.27)(next@14.2.35(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(next@14.2.35(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + fumadocs-ui: + specifier: ^14.0.0 + version: 14.7.7(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(fumadocs-core@14.7.7(@types/react@18.3.27)(next@14.2.35(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(next@14.2.35(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.2)) + lz-string: + specifier: ^1.5.0 + version: 1.5.0 + next: + specifier: ^14.2.0 + version: 14.2.35(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: + specifier: ^18.3.0 + version: 18.3.1 + react-dom: + specifier: ^18.3.0 + version: 18.3.1(react@18.3.1) + sucrase: + specifier: ^3.35.0 + version: 3.35.1 + devDependencies: + '@cloudflare/next-on-pages': + specifier: ^1.13.0 + version: 1.13.16(next@14.2.35(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(wrangler@3.114.16) + '@types/lz-string': + specifier: ^1.5.0 + version: 1.5.0 + '@types/node': + specifier: ^20.11.24 + version: 20.19.9 + '@types/react': + specifier: ^18.3.0 + version: 18.3.27 + '@types/react-dom': + specifier: ^18.3.0 + version: 18.3.7(@types/react@18.3.27) + autoprefixer: + specifier: ^10.4.20 + version: 10.4.23(postcss@8.5.6) + postcss: + specifier: ^8.4.49 + version: 8.5.6 + tailwindcss: + specifier: ^3.4.0 + version: 3.4.19(tsx@4.21.0)(yaml@2.8.2) + tsx: + specifier: ^4.0.0 + version: 4.21.0 + typescript: + specifier: ^5.5.4 + version: 5.5.4 + wrangler: + specifier: ^3.0.0 + version: 3.114.16 + packages/cent: dependencies: zod: @@ -36,6 +103,12 @@ importers: ts-jest: specifier: ^29.1.2 version: 29.4.0(@babel/core@7.28.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.28.0))(jest-util@29.7.0)(jest@29.7.0(@types/node@20.19.9))(typescript@5.5.4) + typedoc: + specifier: ^0.28.16 + version: 0.28.16(typescript@5.5.4) + typedoc-plugin-markdown: + specifier: ^4.9.0 + version: 4.9.0(typedoc@0.28.16(typescript@5.5.4)) packages/cent-react: devDependencies: @@ -129,6 +202,10 @@ packages: '@adobe/css-tools@4.4.4': resolution: {integrity: sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==} + '@alloc/quick-lru@5.2.0': + resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} + engines: {node: '>=10'} + '@ampproject/remapping@2.3.0': resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} @@ -355,2022 +432,5390 @@ packages: cpu: [x64] os: [win32] - '@istanbuljs/load-nyc-config@1.1.0': - resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} - engines: {node: '>=8'} - - '@istanbuljs/schema@0.1.3': - resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} - engines: {node: '>=8'} - - '@jest/console@29.7.0': - resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@cloudflare/kv-asset-handler@0.3.4': + resolution: {integrity: sha512-YLPHc8yASwjNkmcDMQMY35yiWjoKAKnhUbPRszBRS0YgH+IXtsMp61j+yTcnCE3oO2DgP0U3iejLC8FTtKDC8Q==} + engines: {node: '>=16.13'} - '@jest/core@29.7.0': - resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@cloudflare/next-on-pages@1.13.16': + resolution: {integrity: sha512-52h51WNcfmx3szTdTd+n/xgz4qNxFtjOGG0zwnUAhTg8cjPwSUYmZp0OPRNw2jYG9xHwRS2ttSPAS8tcGkQGsw==} + deprecated: 'Please use the OpenNext adapter instead: https://opennext.js.org/cloudflare' + hasBin: true peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + '@cloudflare/workers-types': ^4.20240208.0 + next: '>=14.3.0 && <=15.5.2' + vercel: '>=30.0.0 && <=47.0.4' + wrangler: ^3.28.2 || ^4.0.0 peerDependenciesMeta: - node-notifier: + '@cloudflare/workers-types': optional: true - '@jest/environment@29.7.0': - resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/expect-utils@29.7.0': - resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/expect@29.7.0': - resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/fake-timers@29.7.0': - resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/globals@29.7.0': - resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/reporters@29.7.0': - resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@cloudflare/unenv-preset@2.0.2': + resolution: {integrity: sha512-nyzYnlZjjV5xT3LizahG1Iu6mnrCaxglJ04rZLpDwlDVDZ7v46lNsfxhV3A/xtfgQuSHmLnc6SVI+KwBpc3Lwg==} peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + unenv: 2.0.0-rc.14 + workerd: ^1.20250124.0 peerDependenciesMeta: - node-notifier: + workerd: optional: true - '@jest/schemas@29.6.3': - resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@cloudflare/workerd-darwin-64@1.20250718.0': + resolution: {integrity: sha512-FHf4t7zbVN8yyXgQ/r/GqLPaYZSGUVzeR7RnL28Mwj2djyw2ZergvytVc7fdGcczl6PQh+VKGfZCfUqpJlbi9g==} + engines: {node: '>=16'} + cpu: [x64] + os: [darwin] - '@jest/source-map@29.6.3': - resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@cloudflare/workerd-darwin-arm64@1.20250718.0': + resolution: {integrity: sha512-fUiyUJYyqqp4NqJ0YgGtp4WJh/II/YZsUnEb6vVy5Oeas8lUOxnN+ZOJ8N/6/5LQCVAtYCChRiIrBbfhTn5Z8Q==} + engines: {node: '>=16'} + cpu: [arm64] + os: [darwin] - '@jest/test-result@29.7.0': - resolution: {integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@cloudflare/workerd-linux-64@1.20250718.0': + resolution: {integrity: sha512-5+eb3rtJMiEwp08Kryqzzu8d1rUcK+gdE442auo5eniMpT170Dz0QxBrqkg2Z48SFUPYbj+6uknuA5tzdRSUSg==} + engines: {node: '>=16'} + cpu: [x64] + os: [linux] - '@jest/test-sequencer@29.7.0': - resolution: {integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@cloudflare/workerd-linux-arm64@1.20250718.0': + resolution: {integrity: sha512-Aa2M/DVBEBQDdATMbn217zCSFKE+ud/teS+fFS+OQqKABLn0azO2qq6ANAHYOIE6Q3Sq4CxDIQr8lGdaJHwUog==} + engines: {node: '>=16'} + cpu: [arm64] + os: [linux] - '@jest/transform@29.7.0': - resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@cloudflare/workerd-windows-64@1.20250718.0': + resolution: {integrity: sha512-dY16RXKffmugnc67LTbyjdDHZn5NoTF1yHEf2fN4+OaOnoGSp3N1x77QubTDwqZ9zECWxgQfDLjddcH8dWeFhg==} + engines: {node: '>=16'} + cpu: [x64] + os: [win32] - '@jest/types@29.6.3': - resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} - '@jridgewell/gen-mapping@0.3.12': - resolution: {integrity: sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==} + '@emnapi/runtime@1.8.1': + resolution: {integrity: sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==} - '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} + '@esbuild-plugins/node-globals-polyfill@0.2.3': + resolution: {integrity: sha512-r3MIryXDeXDOZh7ih1l/yE9ZLORCd5e8vWg02azWRGj5SPTuoh69A2AIyn0Z31V/kHBfZ4HgWJ+OK3GTTwLmnw==} + peerDependencies: + esbuild: '*' - '@jridgewell/sourcemap-codec@1.5.4': - resolution: {integrity: sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==} + '@esbuild-plugins/node-modules-polyfill@0.2.2': + resolution: {integrity: sha512-LXV7QsWJxRuMYvKbiznh+U1ilIop3g2TeKRzUxOG5X3YITc8JyyTa90BmLwqqv0YnX4v32CSlG+vsziZp9dMvA==} + peerDependencies: + esbuild: '*' - '@jridgewell/trace-mapping@0.3.29': - resolution: {integrity: sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==} + '@esbuild/aix-ppc64@0.24.2': + resolution: {integrity: sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] - '@sinclair/typebox@0.27.8': - resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + '@esbuild/aix-ppc64@0.27.2': + resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] - '@sinonjs/commons@3.0.1': - resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} + '@esbuild/android-arm64@0.17.19': + resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] - '@sinonjs/fake-timers@10.3.0': - resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} + '@esbuild/android-arm64@0.24.2': + resolution: {integrity: sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] - '@supabase/auth-js@2.90.1': - resolution: {integrity: sha512-vxb66dgo6h3yyPbR06735Ps+dK3hj0JwS8w9fdQPVZQmocSTlKUW5MfxSy99mN0XqCCuLMQ3jCEiIIUU23e9ng==} - engines: {node: '>=20.0.0'} + '@esbuild/android-arm64@0.27.2': + resolution: {integrity: sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] - '@supabase/functions-js@2.90.1': - resolution: {integrity: sha512-x9mV9dF1Lam9qL3zlpP6mSM5C9iqMPtF5B/tU1Jj/F0ufX5mjDf9ghVBaErVxmrQJRL4+iMKWKY2GnODkpS8tw==} - engines: {node: '>=20.0.0'} + '@esbuild/android-arm@0.15.18': + resolution: {integrity: sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] - '@supabase/postgrest-js@2.90.1': - resolution: {integrity: sha512-jh6vqzaYzoFn3raaC0hcFt9h+Bt+uxNRBSdc7PfToQeRGk7PDPoweHsbdiPWREtDVTGKfu+PyPW9e2jbK+BCgQ==} - engines: {node: '>=20.0.0'} + '@esbuild/android-arm@0.17.19': + resolution: {integrity: sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-arm@0.24.2': + resolution: {integrity: sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-arm@0.27.2': + resolution: {integrity: sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.17.19': + resolution: {integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] - '@supabase/realtime-js@2.90.1': - resolution: {integrity: sha512-PWbnEMkcQRuor8jhObp4+Snufkq8C6fBp+MchVp2qBPY1NXk/c3Iv3YyiFYVzo0Dzuw4nAlT4+ahuPggy4r32w==} - engines: {node: '>=20.0.0'} + '@esbuild/android-x64@0.24.2': + resolution: {integrity: sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] - '@supabase/storage-js@2.90.1': - resolution: {integrity: sha512-GHY+Ps/K/RBfRj7kwx+iVf2HIdqOS43rM2iDOIDpapyUnGA9CCBFzFV/XvfzznGykd//z2dkGZhlZZprsVFqGg==} - engines: {node: '>=20.0.0'} + '@esbuild/android-x64@0.27.2': + resolution: {integrity: sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] - '@supabase/supabase-js@2.90.1': - resolution: {integrity: sha512-U8KaKGLUgTIFHtwEW1dgw1gK7XrdpvvYo7nzzqPx721GqPe8WZbAiLh/hmyKLGBYQ/mmQNr20vU9tWSDZpii3w==} - engines: {node: '>=20.0.0'} + '@esbuild/darwin-arm64@0.17.19': + resolution: {integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] - '@testing-library/dom@9.3.4': - resolution: {integrity: sha512-FlS4ZWlp97iiNWig0Muq8p+3rVDjRiYE+YKGbAqXOu9nwJFFOdL00kFpz42M+4huzYi86vAK1sOOfyOG45muIQ==} - engines: {node: '>=14'} + '@esbuild/darwin-arm64@0.24.2': + resolution: {integrity: sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] - '@testing-library/jest-dom@6.9.1': - resolution: {integrity: sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==} - engines: {node: '>=14', npm: '>=6', yarn: '>=1'} + '@esbuild/darwin-arm64@0.27.2': + resolution: {integrity: sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] - '@testing-library/react@14.3.1': - resolution: {integrity: sha512-H99XjUhWQw0lTgyMN05W3xQG1Nh4lq574D8keFf1dDoNTJgp66VbJozRaczoF+wsiaPJNt/TcnfpLGufGxSrZQ==} - engines: {node: '>=14'} - peerDependencies: - react: ^18.0.0 - react-dom: ^18.0.0 + '@esbuild/darwin-x64@0.17.19': + resolution: {integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] - '@testing-library/user-event@14.6.1': - resolution: {integrity: sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==} - engines: {node: '>=12', npm: '>=6'} - peerDependencies: - '@testing-library/dom': '>=7.21.4' + '@esbuild/darwin-x64@0.24.2': + resolution: {integrity: sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] - '@thesis-co/biome-config@https://codeload.github.com/thesis/biome-config/tar.gz/6e8586bfa74c62c9ede2ca12abbcac1dc0ad4606': - resolution: {tarball: https://codeload.github.com/thesis/biome-config/tar.gz/6e8586bfa74c62c9ede2ca12abbcac1dc0ad4606} - version: 0.0.1 - engines: {node: '>=14.0.0'} + '@esbuild/darwin-x64@0.27.2': + resolution: {integrity: sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] - '@tootallnate/once@2.0.0': - resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} - engines: {node: '>= 10'} + '@esbuild/freebsd-arm64@0.17.19': + resolution: {integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] - '@types/aria-query@5.0.4': - resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} + '@esbuild/freebsd-arm64@0.24.2': + resolution: {integrity: sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] - '@types/babel__core@7.20.5': - resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + '@esbuild/freebsd-arm64@0.27.2': + resolution: {integrity: sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] - '@types/babel__generator@7.27.0': - resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} + '@esbuild/freebsd-x64@0.17.19': + resolution: {integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] - '@types/babel__template@7.4.4': - resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + '@esbuild/freebsd-x64@0.24.2': + resolution: {integrity: sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] - '@types/babel__traverse@7.20.7': - resolution: {integrity: sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==} + '@esbuild/freebsd-x64@0.27.2': + resolution: {integrity: sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] - '@types/graceful-fs@4.1.9': - resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} + '@esbuild/linux-arm64@0.17.19': + resolution: {integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] - '@types/istanbul-lib-coverage@2.0.6': - resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} + '@esbuild/linux-arm64@0.24.2': + resolution: {integrity: sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] - '@types/istanbul-lib-report@3.0.3': - resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} + '@esbuild/linux-arm64@0.27.2': + resolution: {integrity: sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] - '@types/istanbul-reports@3.0.4': - resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} + '@esbuild/linux-arm@0.17.19': + resolution: {integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] - '@types/jest@29.5.14': - resolution: {integrity: sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==} + '@esbuild/linux-arm@0.24.2': + resolution: {integrity: sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] - '@types/jsdom@20.0.1': - resolution: {integrity: sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==} + '@esbuild/linux-arm@0.27.2': + resolution: {integrity: sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] - '@types/node@20.19.9': - resolution: {integrity: sha512-cuVNgarYWZqxRJDQHEB58GEONhOK79QVR/qYx4S7kcUObQvUwvFnYxJuuHUKm2aieN9X3yZB4LZsuYNU1Qphsw==} + '@esbuild/linux-ia32@0.17.19': + resolution: {integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] - '@types/phoenix@1.6.7': - resolution: {integrity: sha512-oN9ive//QSBkf19rfDv45M7eZPi0eEXylht2OLEXicu5b4KoQ1OzXIw+xDSGWxSxe1JmepRR/ZH283vsu518/Q==} + '@esbuild/linux-ia32@0.24.2': + resolution: {integrity: sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] - '@types/prop-types@15.7.15': - resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} + '@esbuild/linux-ia32@0.27.2': + resolution: {integrity: sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] - '@types/react-dom@18.3.7': - resolution: {integrity: sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==} - peerDependencies: - '@types/react': ^18.0.0 + '@esbuild/linux-loong64@0.15.18': + resolution: {integrity: sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] - '@types/react@18.3.27': - resolution: {integrity: sha512-cisd7gxkzjBKU2GgdYrTdtQx1SORymWyaAFhaxQPK9bYO9ot3Y5OikQRvY0VYQtvwjeQnizCINJAenh/V7MK2w==} + '@esbuild/linux-loong64@0.17.19': + resolution: {integrity: sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] - '@types/stack-utils@2.0.3': - resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} + '@esbuild/linux-loong64@0.24.2': + resolution: {integrity: sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] - '@types/tough-cookie@4.0.5': - resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} + '@esbuild/linux-loong64@0.27.2': + resolution: {integrity: sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] - '@types/ws@8.18.1': - resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + '@esbuild/linux-mips64el@0.17.19': + resolution: {integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] - '@types/yargs-parser@21.0.3': - resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} + '@esbuild/linux-mips64el@0.24.2': + resolution: {integrity: sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] - '@types/yargs@17.0.33': - resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==} + '@esbuild/linux-mips64el@0.27.2': + resolution: {integrity: sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] - abab@2.0.6: - resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==} - deprecated: Use your platform's native atob() and btoa() methods instead + '@esbuild/linux-ppc64@0.17.19': + resolution: {integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] - acorn-globals@7.0.1: - resolution: {integrity: sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==} + '@esbuild/linux-ppc64@0.24.2': + resolution: {integrity: sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] - acorn-walk@8.3.4: - resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} - engines: {node: '>=0.4.0'} + '@esbuild/linux-ppc64@0.27.2': + resolution: {integrity: sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] - acorn@8.15.0: - resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} - engines: {node: '>=0.4.0'} - hasBin: true + '@esbuild/linux-riscv64@0.17.19': + resolution: {integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] - agent-base@6.0.2: - resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} - engines: {node: '>= 6.0.0'} + '@esbuild/linux-riscv64@0.24.2': + resolution: {integrity: sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] - ansi-escapes@4.3.2: - resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} - engines: {node: '>=8'} + '@esbuild/linux-riscv64@0.27.2': + resolution: {integrity: sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] - ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} + '@esbuild/linux-s390x@0.17.19': + resolution: {integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] - ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} + '@esbuild/linux-s390x@0.24.2': + resolution: {integrity: sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] - ansi-styles@5.2.0: - resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} - engines: {node: '>=10'} + '@esbuild/linux-s390x@0.27.2': + resolution: {integrity: sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] - anymatch@3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} - engines: {node: '>= 8'} + '@esbuild/linux-x64@0.17.19': + resolution: {integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] - argparse@1.0.10: - resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + '@esbuild/linux-x64@0.24.2': + resolution: {integrity: sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] - aria-query@5.1.3: - resolution: {integrity: sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==} + '@esbuild/linux-x64@0.27.2': + resolution: {integrity: sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] - aria-query@5.3.2: - resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} - engines: {node: '>= 0.4'} + '@esbuild/netbsd-arm64@0.24.2': + resolution: {integrity: sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] - array-buffer-byte-length@1.0.2: - resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} - engines: {node: '>= 0.4'} + '@esbuild/netbsd-arm64@0.27.2': + resolution: {integrity: sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] - async@3.2.6: - resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + '@esbuild/netbsd-x64@0.17.19': + resolution: {integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] - asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + '@esbuild/netbsd-x64@0.24.2': + resolution: {integrity: sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] - available-typed-arrays@1.0.7: - resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} - engines: {node: '>= 0.4'} + '@esbuild/netbsd-x64@0.27.2': + resolution: {integrity: sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] - babel-jest@29.7.0: - resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@babel/core': ^7.8.0 + '@esbuild/openbsd-arm64@0.24.2': + resolution: {integrity: sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] - babel-plugin-istanbul@6.1.1: - resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} - engines: {node: '>=8'} + '@esbuild/openbsd-arm64@0.27.2': + resolution: {integrity: sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] - babel-plugin-jest-hoist@29.6.3: - resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@esbuild/openbsd-x64@0.17.19': + resolution: {integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] - babel-preset-current-node-syntax@1.1.0: - resolution: {integrity: sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==} - peerDependencies: - '@babel/core': ^7.0.0 + '@esbuild/openbsd-x64@0.24.2': + resolution: {integrity: sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] - babel-preset-jest@29.6.3: - resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@babel/core': ^7.0.0 + '@esbuild/openbsd-x64@0.27.2': + resolution: {integrity: sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + '@esbuild/openharmony-arm64@0.27.2': + resolution: {integrity: sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] - brace-expansion@1.1.12: - resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + '@esbuild/sunos-x64@0.17.19': + resolution: {integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] - brace-expansion@2.0.2: - resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} + '@esbuild/sunos-x64@0.24.2': + resolution: {integrity: sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] - braces@3.0.3: - resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} - engines: {node: '>=8'} + '@esbuild/sunos-x64@0.27.2': + resolution: {integrity: sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] - browserslist@4.25.1: - resolution: {integrity: sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true + '@esbuild/win32-arm64@0.17.19': + resolution: {integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] - bs-logger@0.2.6: - resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} - engines: {node: '>= 6'} + '@esbuild/win32-arm64@0.24.2': + resolution: {integrity: sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] - bser@2.1.1: - resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} + '@esbuild/win32-arm64@0.27.2': + resolution: {integrity: sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] - buffer-from@1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + '@esbuild/win32-ia32@0.17.19': + resolution: {integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] - call-bind-apply-helpers@1.0.2: - resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} - engines: {node: '>= 0.4'} + '@esbuild/win32-ia32@0.24.2': + resolution: {integrity: sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] - call-bind@1.0.8: - resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} - engines: {node: '>= 0.4'} + '@esbuild/win32-ia32@0.27.2': + resolution: {integrity: sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] - call-bound@1.0.4: - resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} - engines: {node: '>= 0.4'} + '@esbuild/win32-x64@0.17.19': + resolution: {integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] - callsites@3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} + '@esbuild/win32-x64@0.24.2': + resolution: {integrity: sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] - camelcase@5.3.1: - resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} - engines: {node: '>=6'} + '@esbuild/win32-x64@0.27.2': + resolution: {integrity: sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] - camelcase@6.3.0: - resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} - engines: {node: '>=10'} + '@fastify/busboy@2.1.1': + resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} + engines: {node: '>=14'} - caniuse-lite@1.0.30001727: - resolution: {integrity: sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==} + '@floating-ui/core@1.7.3': + resolution: {integrity: sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==} - chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} + '@floating-ui/dom@1.7.4': + resolution: {integrity: sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==} - char-regex@1.0.2: - resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} - engines: {node: '>=10'} + '@floating-ui/react-dom@2.1.6': + resolution: {integrity: sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' - ci-info@3.9.0: - resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} - engines: {node: '>=8'} + '@floating-ui/utils@0.2.10': + resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} - cjs-module-lexer@1.4.3: - resolution: {integrity: sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==} + '@formatjs/intl-localematcher@0.5.10': + resolution: {integrity: sha512-af3qATX+m4Rnd9+wHcjJ4w2ijq+rAVP3CCinJQvFv1kgSu1W6jypUmvleJxcewdxmutM8dmIRZFxO/IQBZmP2Q==} - cliui@8.0.1: - resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} - engines: {node: '>=12'} + '@gerrit0/mini-shiki@3.21.0': + resolution: {integrity: sha512-9PrsT5DjZA+w3lur/aOIx3FlDeHdyCEFlv9U+fmsVyjPZh61G5SYURQ/1ebe2U63KbDmI2V8IhIUegWb8hjOyg==} - co@4.6.0: - resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} - engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} + '@img/sharp-darwin-arm64@0.33.5': + resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] - collect-v8-coverage@1.0.2: - resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} + '@img/sharp-darwin-x64@0.33.5': + resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] - color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} + '@img/sharp-libvips-darwin-arm64@1.0.4': + resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} + cpu: [arm64] + os: [darwin] - color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + '@img/sharp-libvips-darwin-x64@1.0.4': + resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} + cpu: [x64] + os: [darwin] - combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} + '@img/sharp-libvips-linux-arm64@1.0.4': + resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} + cpu: [arm64] + os: [linux] - concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + '@img/sharp-libvips-linux-arm@1.0.5': + resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} + cpu: [arm] + os: [linux] - convert-source-map@2.0.0: - resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + '@img/sharp-libvips-linux-s390x@1.0.4': + resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} + cpu: [s390x] + os: [linux] - create-jest@29.7.0: - resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true + '@img/sharp-libvips-linux-x64@1.0.4': + resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} + cpu: [x64] + os: [linux] - cross-spawn@7.0.6: - resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} - engines: {node: '>= 8'} + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} + cpu: [arm64] + os: [linux] - css.escape@1.5.1: - resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} + '@img/sharp-libvips-linuxmusl-x64@1.0.4': + resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} + cpu: [x64] + os: [linux] - cssom@0.3.8: - resolution: {integrity: sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==} + '@img/sharp-linux-arm64@0.33.5': + resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] - cssom@0.5.0: - resolution: {integrity: sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==} + '@img/sharp-linux-arm@0.33.5': + resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] - cssstyle@2.3.0: - resolution: {integrity: sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==} - engines: {node: '>=8'} + '@img/sharp-linux-s390x@0.33.5': + resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] - csstype@3.2.3: - resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + '@img/sharp-linux-x64@0.33.5': + resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] - data-urls@3.0.2: - resolution: {integrity: sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==} - engines: {node: '>=12'} + '@img/sharp-linuxmusl-arm64@0.33.5': + resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] - debug@4.4.1: - resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true + '@img/sharp-linuxmusl-x64@0.33.5': + resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] - decimal.js@10.6.0: - resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} + '@img/sharp-wasm32@0.33.5': + resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] - dedent@1.6.0: - resolution: {integrity: sha512-F1Z+5UCFpmQUzJa11agbyPVMbpgT/qA3/SKyJ1jyBgm7dUcUEa8v9JwDkerSQXfakBwFljIxhOJqGkjUwZ9FSA==} + '@img/sharp-win32-ia32@0.33.5': + resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.33.5': + resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + + '@istanbuljs/load-nyc-config@1.1.0': + resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} + engines: {node: '>=8'} + + '@istanbuljs/schema@0.1.3': + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + + '@jest/console@29.7.0': + resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/core@29.7.0': + resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: - babel-plugin-macros: ^3.1.0 + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 peerDependenciesMeta: - babel-plugin-macros: + node-notifier: optional: true - deep-equal@2.2.3: - resolution: {integrity: sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==} - engines: {node: '>= 0.4'} + '@jest/environment@29.7.0': + resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - deepmerge@4.3.1: - resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} - engines: {node: '>=0.10.0'} + '@jest/expect-utils@29.7.0': + resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - define-data-property@1.1.4: - resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} - engines: {node: '>= 0.4'} + '@jest/expect@29.7.0': + resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - define-properties@1.2.1: - resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} - engines: {node: '>= 0.4'} + '@jest/fake-timers@29.7.0': + resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} + '@jest/globals@29.7.0': + resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - detect-newline@3.1.0: - resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} - engines: {node: '>=8'} + '@jest/reporters@29.7.0': + resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true - diff-sequences@29.6.3: - resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} + '@jest/schemas@29.6.3': + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dom-accessibility-api@0.5.16: - resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} + '@jest/source-map@29.6.3': + resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dom-accessibility-api@0.6.3: - resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==} + '@jest/test-result@29.7.0': + resolution: {integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - domexception@4.0.0: - resolution: {integrity: sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==} - engines: {node: '>=12'} - deprecated: Use your platform's native DOMException instead + '@jest/test-sequencer@29.7.0': + resolution: {integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dunder-proto@1.0.1: - resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} - engines: {node: '>= 0.4'} + '@jest/transform@29.7.0': + resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - ejs@3.1.10: - resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} - engines: {node: '>=0.10.0'} - hasBin: true + '@jest/types@29.6.3': + resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - electron-to-chromium@1.5.190: - resolution: {integrity: sha512-k4McmnB2091YIsdCgkS0fMVMPOJgxl93ltFzaryXqwip1AaxeDqKCGLxkXODDA5Ab/D+tV5EL5+aTx76RvLRxw==} + '@jridgewell/gen-mapping@0.3.12': + resolution: {integrity: sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==} - emittery@0.13.1: - resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} - engines: {node: '>=12'} + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} - emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + '@jridgewell/sourcemap-codec@1.5.4': + resolution: {integrity: sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==} - entities@6.0.1: - resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} - engines: {node: '>=0.12'} + '@jridgewell/trace-mapping@0.3.29': + resolution: {integrity: sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==} - error-ex@1.3.2: - resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + '@jridgewell/trace-mapping@0.3.9': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} - es-define-property@1.0.1: - resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} - engines: {node: '>= 0.4'} + '@mdx-js/mdx@3.1.1': + resolution: {integrity: sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==} - es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} + '@monaco-editor/loader@1.7.0': + resolution: {integrity: sha512-gIwR1HrJrrx+vfyOhYmCZ0/JcWqG5kbfG7+d3f/C1LXk2EvzAbHSg3MQ5lO2sMlo9izoAZ04shohfKLVT6crVA==} - es-get-iterator@1.1.3: - resolution: {integrity: sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==} + '@monaco-editor/react@4.7.0': + resolution: {integrity: sha512-cyzXQCtO47ydzxpQtCGSQGOC8Gk3ZUeBXFAxD+CWXYFo5OqZyZUonFl0DwUlTyAfRHntBfw2p3w4s9R6oe1eCA==} + peerDependencies: + monaco-editor: '>= 0.25.0 < 1' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - es-object-atoms@1.1.1: - resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} - engines: {node: '>= 0.4'} + '@next/env@14.2.35': + resolution: {integrity: sha512-DuhvCtj4t9Gwrx80dmz2F4t/zKQ4ktN8WrMwOuVzkJfBilwAwGr6v16M5eI8yCuZ63H9TTuEU09Iu2HqkzFPVQ==} - es-set-tostringtag@2.1.0: - resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} - engines: {node: '>= 0.4'} + '@next/swc-darwin-arm64@14.2.33': + resolution: {integrity: sha512-HqYnb6pxlsshoSTubdXKu15g3iivcbsMXg4bYpjL2iS/V6aQot+iyF4BUc2qA/J/n55YtvE4PHMKWBKGCF/+wA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] - escalade@3.2.0: - resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} - engines: {node: '>=6'} + '@next/swc-darwin-x64@14.2.33': + resolution: {integrity: sha512-8HGBeAE5rX3jzKvF593XTTFg3gxeU4f+UWnswa6JPhzaR6+zblO5+fjltJWIZc4aUalqTclvN2QtTC37LxvZAA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] - escape-string-regexp@2.0.0: - resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} - engines: {node: '>=8'} + '@next/swc-linux-arm64-gnu@14.2.33': + resolution: {integrity: sha512-JXMBka6lNNmqbkvcTtaX8Gu5by9547bukHQvPoLe9VRBx1gHwzf5tdt4AaezW85HAB3pikcvyqBToRTDA4DeLw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] - escodegen@2.1.0: - resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} - engines: {node: '>=6.0'} - hasBin: true + '@next/swc-linux-arm64-musl@14.2.33': + resolution: {integrity: sha512-Bm+QulsAItD/x6Ih8wGIMfRJy4G73tu1HJsrccPW6AfqdZd0Sfm5Imhgkgq2+kly065rYMnCOxTBvmvFY1BKfg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] - esprima@4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} - hasBin: true + '@next/swc-linux-x64-gnu@14.2.33': + resolution: {integrity: sha512-FnFn+ZBgsVMbGDsTqo8zsnRzydvsGV8vfiWwUo1LD8FTmPTdV+otGSWKc4LJec0oSexFnCYVO4hX8P8qQKaSlg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] - estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} + '@next/swc-linux-x64-musl@14.2.33': + resolution: {integrity: sha512-345tsIWMzoXaQndUTDv1qypDRiebFxGYx9pYkhwY4hBRaOLt8UGfiWKr9FSSHs25dFIf8ZqIFaPdy5MljdoawA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] - esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} + '@next/swc-win32-arm64-msvc@14.2.33': + resolution: {integrity: sha512-nscpt0G6UCTkrT2ppnJnFsYbPDQwmum4GNXYTeoTIdsmMydSKFz9Iny2jpaRupTb+Wl298+Rh82WKzt9LCcqSQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] - execa@5.1.1: - resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} - engines: {node: '>=10'} + '@next/swc-win32-ia32-msvc@14.2.33': + resolution: {integrity: sha512-pc9LpGNKhJ0dXQhZ5QMmYxtARwwmWLpeocFmVG5Z0DzWq5Uf0izcI8tLc+qOpqxO1PWqZ5A7J1blrUIKrIFc7Q==} + engines: {node: '>= 10'} + cpu: [ia32] + os: [win32] - exit@0.1.2: - resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} - engines: {node: '>= 0.8.0'} + '@next/swc-win32-x64-msvc@14.2.33': + resolution: {integrity: sha512-nOjfZMy8B94MdisuzZo9/57xuFVLHJaDj5e/xrduJp9CV2/HrfxTRH2fbyLe+K9QT41WBLUd4iXX3R7jBp0EUg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] - expect@29.7.0: - resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} - fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} - fb-watchman@2.0.2: - resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} - filelist@1.0.4: - resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} + '@orama/orama@2.1.1': + resolution: {integrity: sha512-euTV/2kya290SNkl5m8e/H1na8iDygk74nNtl4E0YZNyYIrEMwE1JwamoroMKGZw2Uz+in/8gH3m1+2YfP0j1w==} + engines: {node: '>= 16.0.0'} - fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} - engines: {node: '>=8'} + '@radix-ui/number@1.1.1': + resolution: {integrity: sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==} - find-up@4.1.0: - resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} - engines: {node: '>=8'} + '@radix-ui/primitive@1.1.3': + resolution: {integrity: sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==} - for-each@0.3.5: - resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} - engines: {node: '>= 0.4'} + '@radix-ui/react-accordion@1.2.12': + resolution: {integrity: sha512-T4nygeh9YE9dLRPhAHSeOZi7HBXo+0kYIPJXayZfvWOWA0+n3dESrZbjfDPUABkUNym6Hd+f2IR113To8D2GPA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - form-data@4.0.5: - resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} - engines: {node: '>= 6'} + '@radix-ui/react-arrow@1.1.7': + resolution: {integrity: sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - fs.realpath@1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + '@radix-ui/react-collapsible@1.1.12': + resolution: {integrity: sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] + '@radix-ui/react-collection@1.1.7': + resolution: {integrity: sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + '@radix-ui/react-compose-refs@1.1.2': + resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - functions-have-names@1.2.3: - resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + '@radix-ui/react-context@1.1.2': + resolution: {integrity: sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - gensync@1.0.0-beta.2: - resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} - engines: {node: '>=6.9.0'} + '@radix-ui/react-dialog@1.1.15': + resolution: {integrity: sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} + '@radix-ui/react-direction@1.1.1': + resolution: {integrity: sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - get-intrinsic@1.3.0: - resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} - engines: {node: '>= 0.4'} + '@radix-ui/react-dismissable-layer@1.1.11': + resolution: {integrity: sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - get-package-type@0.1.0: - resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} - engines: {node: '>=8.0.0'} + '@radix-ui/react-focus-guards@1.1.3': + resolution: {integrity: sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - get-proto@1.0.1: - resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} - engines: {node: '>= 0.4'} + '@radix-ui/react-focus-scope@1.1.7': + resolution: {integrity: sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - get-stream@6.0.1: - resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} - engines: {node: '>=10'} + '@radix-ui/react-id@1.1.1': + resolution: {integrity: sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - glob@7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Glob versions prior to v9 are no longer supported + '@radix-ui/react-navigation-menu@1.2.14': + resolution: {integrity: sha512-YB9mTFQvCOAQMHU+C/jVl96WmuWeltyUEpRJJky51huhds5W2FQr1J8D/16sQlf0ozxkPK8uF3niQMdUwZPv5w==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - gopd@1.2.0: - resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} - engines: {node: '>= 0.4'} + '@radix-ui/react-popover@1.1.15': + resolution: {integrity: sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + '@radix-ui/react-popper@1.2.8': + resolution: {integrity: sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - has-bigints@1.1.0: - resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} - engines: {node: '>= 0.4'} + '@radix-ui/react-portal@1.1.9': + resolution: {integrity: sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} + '@radix-ui/react-presence@1.1.5': + resolution: {integrity: sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - has-property-descriptors@1.0.2: - resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + '@radix-ui/react-primitive@2.1.3': + resolution: {integrity: sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - has-symbols@1.1.0: - resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} - engines: {node: '>= 0.4'} + '@radix-ui/react-roving-focus@1.1.11': + resolution: {integrity: sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - has-tostringtag@1.0.2: - resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} - engines: {node: '>= 0.4'} + '@radix-ui/react-scroll-area@1.2.10': + resolution: {integrity: sha512-tAXIa1g3sM5CGpVT0uIbUx/U3Gs5N8T52IICuCtObaos1S8fzsrPXG5WObkQN3S6NVl6wKgPhAIiBGbWnvc97A==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} - engines: {node: '>= 0.4'} + '@radix-ui/react-slot@1.2.3': + resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - html-encoding-sniffer@3.0.0: - resolution: {integrity: sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==} - engines: {node: '>=12'} + '@radix-ui/react-slot@1.2.4': + resolution: {integrity: sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - html-escaper@2.0.2: - resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + '@radix-ui/react-tabs@1.1.13': + resolution: {integrity: sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - http-proxy-agent@5.0.0: - resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} - engines: {node: '>= 6'} + '@radix-ui/react-use-callback-ref@1.1.1': + resolution: {integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - https-proxy-agent@5.0.1: - resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} - engines: {node: '>= 6'} + '@radix-ui/react-use-controllable-state@1.2.2': + resolution: {integrity: sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - human-signals@2.1.0: - resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} - engines: {node: '>=10.17.0'} + '@radix-ui/react-use-effect-event@0.0.2': + resolution: {integrity: sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - iceberg-js@0.8.1: - resolution: {integrity: sha512-1dhVQZXhcHje7798IVM+xoo/1ZdVfzOMIc8/rgVSijRK38EDqOJoGula9N/8ZI5RD8QTxNQtK/Gozpr+qUqRRA==} - engines: {node: '>=20.0.0'} + '@radix-ui/react-use-escape-keydown@1.1.1': + resolution: {integrity: sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - iconv-lite@0.6.3: - resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} - engines: {node: '>=0.10.0'} + '@radix-ui/react-use-layout-effect@1.1.1': + resolution: {integrity: sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - import-local@3.2.0: - resolution: {integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==} - engines: {node: '>=8'} - hasBin: true + '@radix-ui/react-use-previous@1.1.1': + resolution: {integrity: sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} + '@radix-ui/react-use-rect@1.1.1': + resolution: {integrity: sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - indent-string@4.0.0: - resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} - engines: {node: '>=8'} + '@radix-ui/react-use-size@1.1.1': + resolution: {integrity: sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - inflight@1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} - deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + '@radix-ui/react-visually-hidden@1.2.3': + resolution: {integrity: sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true - inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + '@radix-ui/rect@1.1.1': + resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==} - internal-slot@1.1.0: - resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} - engines: {node: '>= 0.4'} + '@shikijs/core@2.5.0': + resolution: {integrity: sha512-uu/8RExTKtavlpH7XqnVYBrfBkUc20ngXiX9NSrBhOVZYv/7XQRKUyhtkeflY5QsxC0GbJThCerruZfsUaSldg==} - is-arguments@1.2.0: - resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==} - engines: {node: '>= 0.4'} + '@shikijs/engine-javascript@2.5.0': + resolution: {integrity: sha512-VjnOpnQf8WuCEZtNUdjjwGUbtAVKuZkVQ/5cHy/tojVVRIRtlWMYVjyWhxOmIq05AlSOv72z7hRNRGVBgQOl0w==} - is-array-buffer@3.0.5: - resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} - engines: {node: '>= 0.4'} + '@shikijs/engine-oniguruma@2.5.0': + resolution: {integrity: sha512-pGd1wRATzbo/uatrCIILlAdFVKdxImWJGQ5rFiB5VZi2ve5xj3Ax9jny8QvkaV93btQEwR/rSz5ERFpC5mKNIw==} - is-arrayish@0.2.1: - resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + '@shikijs/engine-oniguruma@3.21.0': + resolution: {integrity: sha512-OYknTCct6qiwpQDqDdf3iedRdzj6hFlOPv5hMvI+hkWfCKs5mlJ4TXziBG9nyabLwGulrUjHiCq3xCspSzErYQ==} - is-bigint@1.1.0: - resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} - engines: {node: '>= 0.4'} + '@shikijs/langs@2.5.0': + resolution: {integrity: sha512-Qfrrt5OsNH5R+5tJ/3uYBBZv3SuGmnRPejV9IlIbFH3HTGLDlkqgHymAlzklVmKBjAaVmkPkyikAV/sQ1wSL+w==} - is-boolean-object@1.2.2: - resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} - engines: {node: '>= 0.4'} + '@shikijs/langs@3.21.0': + resolution: {integrity: sha512-g6mn5m+Y6GBJ4wxmBYqalK9Sp0CFkUqfNzUy2pJglUginz6ZpWbaWjDB4fbQ/8SHzFjYbtU6Ddlp1pc+PPNDVA==} - is-callable@1.2.7: - resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} - engines: {node: '>= 0.4'} + '@shikijs/rehype@2.5.0': + resolution: {integrity: sha512-BO/QRsuQVdzQdoQLq//zcex8K6w57kD9zT8KhSs9kNBJFVDsxm6mTmi6OiRIxysZqhvVrEpY5Mh9IOv1NnjGFg==} - is-core-module@2.16.1: - resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} - engines: {node: '>= 0.4'} + '@shikijs/themes@2.5.0': + resolution: {integrity: sha512-wGrk+R8tJnO0VMzmUExHR+QdSaPUl/NKs+a4cQQRWyoc3YFbUzuLEi/KWK1hj+8BfHRKm2jNhhJck1dfstJpiw==} - is-date-object@1.1.0: - resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} - engines: {node: '>= 0.4'} + '@shikijs/themes@3.21.0': + resolution: {integrity: sha512-BAE4cr9EDiZyYzwIHEk7JTBJ9CzlPuM4PchfcA5ao1dWXb25nv6hYsoDiBq2aZK9E3dlt3WB78uI96UESD+8Mw==} - is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} + '@shikijs/transformers@2.5.0': + resolution: {integrity: sha512-SI494W5X60CaUwgi8u4q4m4s3YAFSxln3tzNjOSYqq54wlVgz0/NbbXEb3mdLbqMBztcmS7bVTaEd2w0qMmfeg==} - is-generator-fn@2.1.0: - resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} - engines: {node: '>=6'} + '@shikijs/types@2.5.0': + resolution: {integrity: sha512-ygl5yhxki9ZLNuNpPitBWvcy9fsSKKaRuO4BAlMyagszQidxcpLAr0qiW/q43DtSIDxO6hEbtYLiFZNXO/hdGw==} - is-map@2.0.3: - resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} - engines: {node: '>= 0.4'} + '@shikijs/types@3.21.0': + resolution: {integrity: sha512-zGrWOxZ0/+0ovPY7PvBU2gIS9tmhSUUt30jAcNV0Bq0gb2S98gwfjIs1vxlmH5zM7/4YxLamT6ChlqqAJmPPjA==} - is-number-object@1.1.1: - resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} - engines: {node: '>= 0.4'} + '@shikijs/vscode-textmate@10.0.2': + resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} - is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} + '@sinclair/typebox@0.27.8': + resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} - is-potential-custom-element-name@1.0.1: - resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + '@sinonjs/commons@3.0.1': + resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} - is-regex@1.2.1: - resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} - engines: {node: '>= 0.4'} + '@sinonjs/fake-timers@10.3.0': + resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} - is-set@2.0.3: - resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} - engines: {node: '>= 0.4'} + '@supabase/auth-js@2.90.1': + resolution: {integrity: sha512-vxb66dgo6h3yyPbR06735Ps+dK3hj0JwS8w9fdQPVZQmocSTlKUW5MfxSy99mN0XqCCuLMQ3jCEiIIUU23e9ng==} + engines: {node: '>=20.0.0'} - is-shared-array-buffer@1.0.4: - resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} - engines: {node: '>= 0.4'} + '@supabase/functions-js@2.90.1': + resolution: {integrity: sha512-x9mV9dF1Lam9qL3zlpP6mSM5C9iqMPtF5B/tU1Jj/F0ufX5mjDf9ghVBaErVxmrQJRL4+iMKWKY2GnODkpS8tw==} + engines: {node: '>=20.0.0'} - is-stream@2.0.1: - resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} - engines: {node: '>=8'} + '@supabase/postgrest-js@2.90.1': + resolution: {integrity: sha512-jh6vqzaYzoFn3raaC0hcFt9h+Bt+uxNRBSdc7PfToQeRGk7PDPoweHsbdiPWREtDVTGKfu+PyPW9e2jbK+BCgQ==} + engines: {node: '>=20.0.0'} - is-string@1.1.1: - resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} - engines: {node: '>= 0.4'} + '@supabase/realtime-js@2.90.1': + resolution: {integrity: sha512-PWbnEMkcQRuor8jhObp4+Snufkq8C6fBp+MchVp2qBPY1NXk/c3Iv3YyiFYVzo0Dzuw4nAlT4+ahuPggy4r32w==} + engines: {node: '>=20.0.0'} - is-symbol@1.1.1: - resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} - engines: {node: '>= 0.4'} + '@supabase/storage-js@2.90.1': + resolution: {integrity: sha512-GHY+Ps/K/RBfRj7kwx+iVf2HIdqOS43rM2iDOIDpapyUnGA9CCBFzFV/XvfzznGykd//z2dkGZhlZZprsVFqGg==} + engines: {node: '>=20.0.0'} - is-weakmap@2.0.2: - resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} - engines: {node: '>= 0.4'} + '@supabase/supabase-js@2.90.1': + resolution: {integrity: sha512-U8KaKGLUgTIFHtwEW1dgw1gK7XrdpvvYo7nzzqPx721GqPe8WZbAiLh/hmyKLGBYQ/mmQNr20vU9tWSDZpii3w==} + engines: {node: '>=20.0.0'} - is-weakset@2.0.4: - resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} - engines: {node: '>= 0.4'} + '@swc/counter@0.1.3': + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} - isarray@2.0.5: - resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + '@swc/helpers@0.5.5': + resolution: {integrity: sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==} - isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + '@testing-library/dom@9.3.4': + resolution: {integrity: sha512-FlS4ZWlp97iiNWig0Muq8p+3rVDjRiYE+YKGbAqXOu9nwJFFOdL00kFpz42M+4huzYi86vAK1sOOfyOG45muIQ==} + engines: {node: '>=14'} - istanbul-lib-coverage@3.2.2: - resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} - engines: {node: '>=8'} + '@testing-library/jest-dom@6.9.1': + resolution: {integrity: sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==} + engines: {node: '>=14', npm: '>=6', yarn: '>=1'} - istanbul-lib-instrument@5.2.1: - resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} - engines: {node: '>=8'} + '@testing-library/react@14.3.1': + resolution: {integrity: sha512-H99XjUhWQw0lTgyMN05W3xQG1Nh4lq574D8keFf1dDoNTJgp66VbJozRaczoF+wsiaPJNt/TcnfpLGufGxSrZQ==} + engines: {node: '>=14'} + peerDependencies: + react: ^18.0.0 + react-dom: ^18.0.0 - istanbul-lib-instrument@6.0.3: - resolution: {integrity: sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==} - engines: {node: '>=10'} + '@testing-library/user-event@14.6.1': + resolution: {integrity: sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==} + engines: {node: '>=12', npm: '>=6'} + peerDependencies: + '@testing-library/dom': '>=7.21.4' - istanbul-lib-report@3.0.1: - resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} - engines: {node: '>=10'} + '@thesis-co/biome-config@https://codeload.github.com/thesis/biome-config/tar.gz/c38100c9023d10a1c486bc0eca388f3cf8ca4046': + resolution: {tarball: https://codeload.github.com/thesis/biome-config/tar.gz/c38100c9023d10a1c486bc0eca388f3cf8ca4046} + version: 0.0.1 + engines: {node: '>=14.0.0'} - istanbul-lib-source-maps@4.0.1: - resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} - engines: {node: '>=10'} + '@tootallnate/once@2.0.0': + resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} + engines: {node: '>= 10'} - istanbul-reports@3.1.7: - resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} - engines: {node: '>=8'} + '@types/aria-query@5.0.4': + resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} - jake@10.9.2: - resolution: {integrity: sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==} - engines: {node: '>=10'} - hasBin: true + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} - jest-changed-files@29.7.0: - resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@types/babel__generator@7.27.0': + resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} - jest-circus@29.7.0: - resolution: {integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} - jest-cli@29.7.0: - resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true + '@types/babel__traverse@7.20.7': + resolution: {integrity: sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==} - jest-config@29.7.0: - resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@types/node': '*' - ts-node: '>=9.0.0' - peerDependenciesMeta: - '@types/node': - optional: true - ts-node: - optional: true + '@types/debug@4.1.12': + resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} - jest-diff@29.7.0: - resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@types/estree-jsx@1.0.5': + resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} - jest-docblock@29.7.0: - resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - jest-each@29.7.0: - resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@types/graceful-fs@4.1.9': + resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} - jest-environment-jsdom@29.7.0: - resolution: {integrity: sha512-k9iQbsf9OyOfdzWH8HDmrRT0gSIcX+FLNW7IQq94tFX0gynPwqDTW0Ho6iMVNjGz/nb+l/vW3dWM2bbLLpkbXA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - canvas: ^2.5.0 - peerDependenciesMeta: - canvas: - optional: true + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} - jest-environment-node@29.7.0: - resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@types/istanbul-lib-coverage@2.0.6': + resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} - jest-get-type@29.6.3: - resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@types/istanbul-lib-report@3.0.3': + resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} - jest-haste-map@29.7.0: - resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@types/istanbul-reports@3.0.4': + resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} - jest-leak-detector@29.7.0: - resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@types/jest@29.5.14': + resolution: {integrity: sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==} - jest-matcher-utils@29.7.0: - resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@types/jsdom@20.0.1': + resolution: {integrity: sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==} - jest-message-util@29.7.0: - resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@types/lz-string@1.5.0': + resolution: {integrity: sha512-s84fKOrzqqNCAPljhVyC5TjAo6BH4jKHw9NRNFNiRUY5QSgZCmVm5XILlWbisiKl+0OcS7eWihmKGS5akc2iQw==} + deprecated: This is a stub types definition. lz-string provides its own type definitions, so you do not need this installed. - jest-mock@29.7.0: - resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} - jest-pnp-resolver@1.2.3: - resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} - engines: {node: '>=6'} - peerDependencies: - jest-resolve: '*' - peerDependenciesMeta: - jest-resolve: - optional: true + '@types/mdx@2.0.13': + resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==} - jest-regex-util@29.6.3: - resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} - jest-resolve-dependencies@29.7.0: - resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@types/node@20.19.9': + resolution: {integrity: sha512-cuVNgarYWZqxRJDQHEB58GEONhOK79QVR/qYx4S7kcUObQvUwvFnYxJuuHUKm2aieN9X3yZB4LZsuYNU1Qphsw==} - jest-resolve@29.7.0: - resolution: {integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@types/phoenix@1.6.7': + resolution: {integrity: sha512-oN9ive//QSBkf19rfDv45M7eZPi0eEXylht2OLEXicu5b4KoQ1OzXIw+xDSGWxSxe1JmepRR/ZH283vsu518/Q==} - jest-runner@29.7.0: - resolution: {integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@types/prop-types@15.7.15': + resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} - jest-runtime@29.7.0: - resolution: {integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@types/react-dom@18.3.7': + resolution: {integrity: sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==} + peerDependencies: + '@types/react': ^18.0.0 - jest-snapshot@29.7.0: - resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@types/react@18.3.27': + resolution: {integrity: sha512-cisd7gxkzjBKU2GgdYrTdtQx1SORymWyaAFhaxQPK9bYO9ot3Y5OikQRvY0VYQtvwjeQnizCINJAenh/V7MK2w==} - jest-util@29.7.0: - resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@types/stack-utils@2.0.3': + resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} - jest-validate@29.7.0: - resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@types/tough-cookie@4.0.5': + resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} - jest-watcher@29.7.0: - resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@types/trusted-types@2.0.7': + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} - jest-worker@29.7.0: - resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@types/unist@2.0.11': + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} - jest@29.7.0: - resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} - js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + '@types/ws@8.18.1': + resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} - js-yaml@3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} - hasBin: true + '@types/yargs-parser@21.0.3': + resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} - jsdom@20.0.3: - resolution: {integrity: sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==} - engines: {node: '>=14'} - peerDependencies: - canvas: ^2.5.0 - peerDependenciesMeta: - canvas: - optional: true + '@types/yargs@17.0.33': + resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==} - jsesc@3.1.0: - resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} - engines: {node: '>=6'} + '@ungap/structured-clone@1.3.0': + resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + + abab@2.0.6: + resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==} + deprecated: Use your platform's native atob() and btoa() methods instead + + acorn-globals@7.0.1: + resolution: {integrity: sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn-walk@8.3.2: + resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} + engines: {node: '>=0.4.0'} + + acorn-walk@8.3.4: + resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} + engines: {node: '>=0.4.0'} + + acorn@8.14.0: + resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} + engines: {node: '>=0.4.0'} hasBin: true - json-parse-even-better-errors@2.3.1: - resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + acorn@8.15.0: + resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} + engines: {node: '>=0.4.0'} + hasBin: true - json5@2.2.3: - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} - engines: {node: '>=6'} + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + + ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + aria-hidden@1.2.6: + resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} + engines: {node: '>=10'} + + aria-query@5.1.3: + resolution: {integrity: sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==} + + aria-query@5.3.2: + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} + engines: {node: '>= 0.4'} + + array-buffer-byte-length@1.0.2: + resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} + engines: {node: '>= 0.4'} + + as-table@1.0.55: + resolution: {integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==} + + ast-types@0.14.2: + resolution: {integrity: sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA==} + engines: {node: '>=4'} + + astring@1.9.0: + resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} hasBin: true - kleur@3.0.3: - resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} - engines: {node: '>=6'} + async@3.2.6: + resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} - leven@3.1.0: - resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} - engines: {node: '>=6'} + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - lines-and-columns@1.2.4: - resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + autoprefixer@10.4.23: + resolution: {integrity: sha512-YYTXSFulfwytnjAPlw8QHncHJmlvFKtczb8InXaAx9Q0LbfDnfEYDE55omerIJKihhmU61Ft+cAOSzQVaBUmeA==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 - locate-path@5.0.0: - resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + babel-jest@29.7.0: + resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.8.0 + + babel-plugin-istanbul@6.1.1: + resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} engines: {node: '>=8'} - lodash.memoize@4.1.2: - resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} + babel-plugin-jest-hoist@29.6.3: + resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - loose-envify@1.4.0: - resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + babel-preset-current-node-syntax@1.1.0: + resolution: {integrity: sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==} + peerDependencies: + '@babel/core': ^7.0.0 + + babel-preset-jest@29.6.3: + resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.0.0 + + bail@2.0.2: + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + baseline-browser-mapping@2.9.14: + resolution: {integrity: sha512-B0xUquLkiGLgHhpPBqvl7GWegWBUNuujQ6kXd/r1U38ElPT6Ok8KZ8e+FpUGEc2ZoRQUzq/aUnaKFc/svWUGSg==} hasBin: true - lru-cache@5.1.1: - resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} - lz-string@1.5.0: - resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} + blake3-wasm@2.1.5: + resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==} + + brace-expansion@1.1.12: + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + + brace-expansion@2.0.2: + resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browserslist@4.25.1: + resolution: {integrity: sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true - make-dir@4.0.0: - resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} - engines: {node: '>=10'} + browserslist@4.28.1: + resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true - make-error@1.3.6: - resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + bs-logger@0.2.6: + resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} + engines: {node: '>= 6'} - makeerror@1.0.12: - resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + bser@2.1.1: + resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} - math-intrinsics@1.1.0: - resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + busboy@1.6.0: + resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} + engines: {node: '>=10.16.0'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} - merge-stream@2.0.0: - resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + call-bind@1.0.8: + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + engines: {node: '>= 0.4'} - micromatch@4.0.8: - resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} - engines: {node: '>=8.6'} + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} - mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} - mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} + camelcase-css@2.0.1: + resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} + engines: {node: '>= 6'} - mimic-fn@2.1.0: - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} engines: {node: '>=6'} - min-indent@1.0.1: - resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} - engines: {node: '>=4'} + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} - minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + caniuse-lite@1.0.30001727: + resolution: {integrity: sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==} - minimatch@5.1.6: - resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + caniuse-lite@1.0.30001764: + resolution: {integrity: sha512-9JGuzl2M+vPL+pz70gtMF9sHdMFbY9FJaQBi186cHKH3pSzDvzoUJUPV6fqiKIMyXbud9ZLg4F3Yza1vJ1+93g==} + + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} - ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + chalk@5.6.2: + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - natural-compare@1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + char-regex@1.0.2: + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} + engines: {node: '>=10'} - node-int64@0.4.0: - resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} + character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} - node-releases@2.0.19: - resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} - normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} - npm-run-path@4.0.1: - resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + character-reference-invalid@2.0.1: + resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + + ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} - nwsapi@2.2.23: - resolution: {integrity: sha512-7wfH4sLbt4M0gCDzGE6vzQBo0bfTKjU7Sfpqy/7gs1qBfYz2vEJH6vXcBKpO3+6Yu1telwd0t9HpyOoLEQQbIQ==} + cjs-module-lexer@1.4.3: + resolution: {integrity: sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==} - object-inspect@1.13.4: - resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} - engines: {node: '>= 0.4'} + class-variance-authority@0.7.1: + resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} - object-is@1.1.6: - resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==} - engines: {node: '>= 0.4'} + client-only@0.0.1: + resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} - object-keys@1.1.1: - resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} - engines: {node: '>= 0.4'} + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + + co@4.6.0: + resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} + engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} + + collapse-white-space@2.1.0: + resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} + + collect-v8-coverage@1.0.2: + resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + + color@4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + + commander@11.1.0: + resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} + engines: {node: '>=16'} + + commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + + compute-scroll-into-view@3.1.1: + resolution: {integrity: sha512-VRhuHOLoKYOy4UbilLbUzbYg93XLjv2PncJC50EuTWPA3gaja1UjBsUP/D/9/juV3vQFr6XBEzn9KCAHdUvOHw==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cookie@0.5.0: + resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} + engines: {node: '>= 0.6'} + + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + + create-jest@29.7.0: + resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + css.escape@1.5.1: + resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + cssom@0.3.8: + resolution: {integrity: sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==} + + cssom@0.5.0: + resolution: {integrity: sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==} + + cssstyle@2.3.0: + resolution: {integrity: sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==} + engines: {node: '>=8'} + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + data-uri-to-buffer@2.0.2: + resolution: {integrity: sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==} + + data-urls@3.0.2: + resolution: {integrity: sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==} + engines: {node: '>=12'} + + debug@4.4.1: + resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decimal.js@10.6.0: + resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} + + decode-named-character-reference@1.2.0: + resolution: {integrity: sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==} + + dedent@1.6.0: + resolution: {integrity: sha512-F1Z+5UCFpmQUzJa11agbyPVMbpgT/qA3/SKyJ1jyBgm7dUcUEa8v9JwDkerSQXfakBwFljIxhOJqGkjUwZ9FSA==} + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true + + deep-equal@2.2.3: + resolution: {integrity: sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==} + engines: {node: '>= 0.4'} + + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + defu@6.1.4: + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + detect-newline@3.1.0: + resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} + engines: {node: '>=8'} + + detect-node-es@1.1.0: + resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + + didyoumean@1.2.2: + resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} + + diff-sequences@29.6.3: + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + dlv@1.1.3: + resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + + dom-accessibility-api@0.5.16: + resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} + + dom-accessibility-api@0.6.3: + resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==} + + domexception@4.0.0: + resolution: {integrity: sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==} + engines: {node: '>=12'} + deprecated: Use your platform's native DOMException instead + + dompurify@3.2.7: + resolution: {integrity: sha512-WhL/YuveyGXJaerVlMYGWhvQswa7myDG17P7Vu65EWC05o8vfeNbvNf4d/BOvH99+ZW+LlQsc1GDKMa1vNK6dw==} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + ejs@3.1.10: + resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} + engines: {node: '>=0.10.0'} + hasBin: true + + electron-to-chromium@1.5.190: + resolution: {integrity: sha512-k4McmnB2091YIsdCgkS0fMVMPOJgxl93ltFzaryXqwip1AaxeDqKCGLxkXODDA5Ab/D+tV5EL5+aTx76RvLRxw==} + + electron-to-chromium@1.5.267: + resolution: {integrity: sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==} + + emittery@0.13.1: + resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} + engines: {node: '>=12'} + + emoji-regex-xs@1.0.0: + resolution: {integrity: sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + entities@6.0.1: + resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} + engines: {node: '>=0.12'} + + error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-get-iterator@1.1.3: + resolution: {integrity: sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + esast-util-from-estree@2.0.0: + resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==} + + esast-util-from-js@2.0.1: + resolution: {integrity: sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==} + + esbuild-android-64@0.15.18: + resolution: {integrity: sha512-wnpt3OXRhcjfIDSZu9bnzT4/TNTDsOUvip0foZOUBG7QbSt//w3QV4FInVJxNhKc/ErhUxc5z4QjHtMi7/TbgA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + esbuild-android-arm64@0.15.18: + resolution: {integrity: sha512-G4xu89B8FCzav9XU8EjsXacCKSG2FT7wW9J6hOc18soEHJdtWu03L3TQDGf0geNxfLTtxENKBzMSq9LlbjS8OQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + esbuild-darwin-64@0.15.18: + resolution: {integrity: sha512-2WAvs95uPnVJPuYKP0Eqx+Dl/jaYseZEUUT1sjg97TJa4oBtbAKnPnl3b5M9l51/nbx7+QAEtuummJZW0sBEmg==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + esbuild-darwin-arm64@0.15.18: + resolution: {integrity: sha512-tKPSxcTJ5OmNb1btVikATJ8NftlyNlc8BVNtyT/UAr62JFOhwHlnoPrhYWz09akBLHI9nElFVfWSTSRsrZiDUA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + esbuild-freebsd-64@0.15.18: + resolution: {integrity: sha512-TT3uBUxkteAjR1QbsmvSsjpKjOX6UkCstr8nMr+q7zi3NuZ1oIpa8U41Y8I8dJH2fJgdC3Dj3CXO5biLQpfdZA==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + esbuild-freebsd-arm64@0.15.18: + resolution: {integrity: sha512-R/oVr+X3Tkh+S0+tL41wRMbdWtpWB8hEAMsOXDumSSa6qJR89U0S/PpLXrGF7Wk/JykfpWNokERUpCeHDl47wA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + esbuild-linux-32@0.15.18: + resolution: {integrity: sha512-lphF3HiCSYtaa9p1DtXndiQEeQDKPl9eN/XNoBf2amEghugNuqXNZA/ZovthNE2aa4EN43WroO0B85xVSjYkbg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + esbuild-linux-64@0.15.18: + resolution: {integrity: sha512-hNSeP97IviD7oxLKFuii5sDPJ+QHeiFTFLoLm7NZQligur8poNOWGIgpQ7Qf8Balb69hptMZzyOBIPtY09GZYw==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + esbuild-linux-arm64@0.15.18: + resolution: {integrity: sha512-54qr8kg/6ilcxd+0V3h9rjT4qmjc0CccMVWrjOEM/pEcUzt8X62HfBSeZfT2ECpM7104mk4yfQXkosY8Quptug==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + esbuild-linux-arm@0.15.18: + resolution: {integrity: sha512-UH779gstRblS4aoS2qpMl3wjg7U0j+ygu3GjIeTonCcN79ZvpPee12Qun3vcdxX+37O5LFxz39XeW2I9bybMVA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + esbuild-linux-mips64le@0.15.18: + resolution: {integrity: sha512-Mk6Ppwzzz3YbMl/ZZL2P0q1tnYqh/trYZ1VfNP47C31yT0K8t9s7Z077QrDA/guU60tGNp2GOwCQnp+DYv7bxQ==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + esbuild-linux-ppc64le@0.15.18: + resolution: {integrity: sha512-b0XkN4pL9WUulPTa/VKHx2wLCgvIAbgwABGnKMY19WhKZPT+8BxhZdqz6EgkqCLld7X5qiCY2F/bfpUUlnFZ9w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + esbuild-linux-riscv64@0.15.18: + resolution: {integrity: sha512-ba2COaoF5wL6VLZWn04k+ACZjZ6NYniMSQStodFKH/Pu6RxzQqzsmjR1t9QC89VYJxBeyVPTaHuBMCejl3O/xg==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + esbuild-linux-s390x@0.15.18: + resolution: {integrity: sha512-VbpGuXEl5FCs1wDVp93O8UIzl3ZrglgnSQ+Hu79g7hZu6te6/YHgVJxCM2SqfIila0J3k0csfnf8VD2W7u2kzQ==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + esbuild-netbsd-64@0.15.18: + resolution: {integrity: sha512-98ukeCdvdX7wr1vUYQzKo4kQ0N2p27H7I11maINv73fVEXt2kyh4K4m9f35U1K43Xc2QGXlzAw0K9yoU7JUjOg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + esbuild-openbsd-64@0.15.18: + resolution: {integrity: sha512-yK5NCcH31Uae076AyQAXeJzt/vxIo9+omZRKj1pauhk3ITuADzuOx5N2fdHrAKPxN+zH3w96uFKlY7yIn490xQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + esbuild-sunos-64@0.15.18: + resolution: {integrity: sha512-On22LLFlBeLNj/YF3FT+cXcyKPEI263nflYlAhz5crxtp3yRG1Ugfr7ITyxmCmjm4vbN/dGrb/B7w7U8yJR9yw==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + esbuild-windows-32@0.15.18: + resolution: {integrity: sha512-o+eyLu2MjVny/nt+E0uPnBxYuJHBvho8vWsC2lV61A7wwTWC3jkN2w36jtA+yv1UgYkHRihPuQsL23hsCYGcOQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + esbuild-windows-64@0.15.18: + resolution: {integrity: sha512-qinug1iTTaIIrCorAUjR0fcBk24fjzEedFYhhispP8Oc7SFvs+XeW3YpAKiKp8dRpizl4YYAhxMjlftAMJiaUw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + esbuild-windows-arm64@0.15.18: + resolution: {integrity: sha512-q9bsYzegpZcLziq0zgUi5KqGVtfhjxGbnksaBFYmWLxeV/S1fK4OLdq2DFYnXcLMjlZw2L0jLsk1eGoB522WXQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + esbuild@0.15.18: + resolution: {integrity: sha512-x/R72SmW3sSFRm5zrrIjAhCeQSAWoni3CmHEqfQrZIQTM3lVCdehdwuIqaOtfC2slvpdlLa62GYoN8SxT23m6Q==} + engines: {node: '>=12'} + hasBin: true + + esbuild@0.17.19: + resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==} + engines: {node: '>=12'} + hasBin: true + + esbuild@0.24.2: + resolution: {integrity: sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==} + engines: {node: '>=18'} + hasBin: true + + esbuild@0.27.2: + resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-string-regexp@2.0.0: + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + + escodegen@2.1.0: + resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} + engines: {node: '>=6.0'} + hasBin: true + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-util-attach-comments@3.0.0: + resolution: {integrity: sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==} + + estree-util-build-jsx@3.0.1: + resolution: {integrity: sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==} + + estree-util-is-identifier-name@3.0.0: + resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} + + estree-util-scope@1.0.0: + resolution: {integrity: sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==} + + estree-util-to-js@2.0.0: + resolution: {integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==} + + estree-util-value-to-estree@3.5.0: + resolution: {integrity: sha512-aMV56R27Gv3QmfmF1MY12GWkGzzeAezAX+UplqHVASfjc9wNzI/X6hC0S9oxq61WT4aQesLGslWP9tKk6ghRZQ==} + + estree-util-visit@2.0.0: + resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==} + + estree-walker@0.6.1: + resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + + exit-hook@2.2.1: + resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==} + engines: {node: '>=6'} + + exit@0.1.2: + resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} + engines: {node: '>= 0.8.0'} + + expect@29.7.0: + resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + exsolve@1.0.8: + resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==} + + extend-shallow@2.0.1: + resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} + engines: {node: '>=0.10.0'} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + + fb-watchman@2.0.2: + resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + filelist@1.0.4: + resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} + + form-data@4.0.5: + resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} + engines: {node: '>= 6'} + + fraction.js@5.3.4: + resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + fumadocs-core@14.7.7: + resolution: {integrity: sha512-ZP2sFZki291se9R6/K959a6CDNqM+oQKejEygViSTQnkCQ8UWApRQHUZQS670sub8ysBFE8aGlgsnAs+n9HlyA==} + peerDependencies: + '@orama/tokenizers': 2.x.x + '@oramacloud/client': 1.x.x || 2.x.x + algoliasearch: 4.24.0 + next: 14.x.x || 15.x.x + react: 18.x.x || 19.x.x + react-dom: 18.x.x || 19.x.x + peerDependenciesMeta: + '@orama/tokenizers': + optional: true + '@oramacloud/client': + optional: true + algoliasearch: + optional: true + next: + optional: true + react: + optional: true + react-dom: + optional: true + + fumadocs-mdx@10.1.0: + resolution: {integrity: sha512-EKetIV7z/J/GL6n7AN8krWXADt9nmrvkRHm130eJh3aYbI3BAFOm1+smwzfYAecy4jCCrCDT02EF3mjU5nk2pQ==} + deprecated: this package has been deprecated + hasBin: true + peerDependencies: + fumadocs-core: ^13.2.1 || ^14.0.0 + next: 14.x.x || 15.x.x + + fumadocs-ui@14.7.7: + resolution: {integrity: sha512-DLx5CT1CQljMzZVJZ5wZ4R8/s1QhMIbKJHaqFpy3mnylilclFqncoyA2BI5YbuqH6g4zywgPKdgZKNTZ0KnS6A==} + peerDependencies: + fumadocs-core: 14.7.7 + next: 14.x.x || 15.x.x + react: 18.x.x || 19.x.x + react-dom: 18.x.x || 19.x.x + tailwindcss: ^3.4.14 + peerDependenciesMeta: + tailwindcss: + optional: true + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-nonce@1.0.1: + resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} + engines: {node: '>=6'} + + get-package-type@0.1.0: + resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} + engines: {node: '>=8.0.0'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-source@2.0.12: + resolution: {integrity: sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==} + + get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + + get-tsconfig@4.13.0: + resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==} + + github-slugger@2.0.0: + resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + glob-to-regexp@0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + gray-matter@4.0.3: + resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==} + engines: {node: '>=6.0'} + + has-bigints@1.1.0: + resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} + engines: {node: '>= 0.4'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + hast-util-to-estree@3.1.3: + resolution: {integrity: sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==} + + hast-util-to-html@9.0.5: + resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==} + + hast-util-to-jsx-runtime@2.3.6: + resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==} + + hast-util-to-string@3.0.1: + resolution: {integrity: sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==} + + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + + html-encoding-sniffer@3.0.0: + resolution: {integrity: sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==} + engines: {node: '>=12'} + + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + + html-void-elements@3.0.0: + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + + http-proxy-agent@5.0.0: + resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} + engines: {node: '>= 6'} + + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + + human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + + iceberg-js@0.8.1: + resolution: {integrity: sha512-1dhVQZXhcHje7798IVM+xoo/1ZdVfzOMIc8/rgVSijRK38EDqOJoGula9N/8ZI5RD8QTxNQtK/Gozpr+qUqRRA==} + engines: {node: '>=20.0.0'} + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + image-size@1.2.1: + resolution: {integrity: sha512-rH+46sQJ2dlwfjfhCyNx5thzrv+dtmBIhPHk0zgRUukHzZ/kRueTJXoYYsclBaKcSMBWuGbOFXtioLpzTb5euw==} + engines: {node: '>=16.x'} + hasBin: true + + import-local@3.2.0: + resolution: {integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==} + engines: {node: '>=8'} + hasBin: true + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + inline-style-parser@0.2.7: + resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==} + + internal-slot@1.1.0: + resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} + engines: {node: '>= 0.4'} + + is-alphabetical@2.0.1: + resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} + + is-alphanumerical@2.0.1: + resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + + is-arguments@1.2.0: + resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==} + engines: {node: '>= 0.4'} + + is-array-buffer@3.0.5: + resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} + engines: {node: '>= 0.4'} + + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + is-arrayish@0.3.4: + resolution: {integrity: sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==} + + is-bigint@1.1.0: + resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} + engines: {node: '>= 0.4'} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-boolean-object@1.2.2: + resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} + engines: {node: '>= 0.4'} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + + is-date-object@1.1.0: + resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} + engines: {node: '>= 0.4'} + + is-decimal@2.0.1: + resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} + + is-extendable@0.1.1: + resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} + engines: {node: '>=0.10.0'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-generator-fn@2.1.0: + resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} + engines: {node: '>=6'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-hexadecimal@2.0.1: + resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + + is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + + is-number-object@1.1.1: + resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} + engines: {node: '>= 0.4'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + + is-potential-custom-element-name@1.0.1: + resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.4: + resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} + engines: {node: '>= 0.4'} + + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + + is-string@1.1.1: + resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} + engines: {node: '>= 0.4'} + + is-symbol@1.1.1: + resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} + engines: {node: '>= 0.4'} + + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + + is-weakset@2.0.4: + resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} + engines: {node: '>= 0.4'} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + + istanbul-lib-instrument@5.2.1: + resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} + engines: {node: '>=8'} + + istanbul-lib-instrument@6.0.3: + resolution: {integrity: sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==} + engines: {node: '>=10'} + + istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + + istanbul-lib-source-maps@4.0.1: + resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} + engines: {node: '>=10'} + + istanbul-reports@3.1.7: + resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} + engines: {node: '>=8'} + + jake@10.9.2: + resolution: {integrity: sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==} + engines: {node: '>=10'} + hasBin: true + + jest-changed-files@29.7.0: + resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-circus@29.7.0: + resolution: {integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-cli@29.7.0: + resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + jest-config@29.7.0: + resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@types/node': '*' + ts-node: '>=9.0.0' + peerDependenciesMeta: + '@types/node': + optional: true + ts-node: + optional: true + + jest-diff@29.7.0: + resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-docblock@29.7.0: + resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-each@29.7.0: + resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-environment-jsdom@29.7.0: + resolution: {integrity: sha512-k9iQbsf9OyOfdzWH8HDmrRT0gSIcX+FLNW7IQq94tFX0gynPwqDTW0Ho6iMVNjGz/nb+l/vW3dWM2bbLLpkbXA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + canvas: ^2.5.0 + peerDependenciesMeta: + canvas: + optional: true + + jest-environment-node@29.7.0: + resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-get-type@29.6.3: + resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-haste-map@29.7.0: + resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-leak-detector@29.7.0: + resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-matcher-utils@29.7.0: + resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-message-util@29.7.0: + resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-mock@29.7.0: + resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-pnp-resolver@1.2.3: + resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} + engines: {node: '>=6'} + peerDependencies: + jest-resolve: '*' + peerDependenciesMeta: + jest-resolve: + optional: true + + jest-regex-util@29.6.3: + resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-resolve-dependencies@29.7.0: + resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-resolve@29.7.0: + resolution: {integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-runner@29.7.0: + resolution: {integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-runtime@29.7.0: + resolution: {integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-snapshot@29.7.0: + resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-util@29.7.0: + resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-validate@29.7.0: + resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-watcher@29.7.0: + resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-worker@29.7.0: + resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest@29.7.0: + resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + jiti@1.21.7: + resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} + hasBin: true + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + hasBin: true + + jsdom@20.0.3: + resolution: {integrity: sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==} + engines: {node: '>=14'} + peerDependencies: + canvas: ^2.5.0 + peerDependenciesMeta: + canvas: + optional: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + + kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + + leven@3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + engines: {node: '>=14'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + linkify-it@5.0.0: + resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} + + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + + lodash.memoize@4.1.2: + resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + lucide-react@0.473.0: + resolution: {integrity: sha512-KW6u5AKeIjkvrxXZ6WuCu9zHE/gEYSXCay+Gre2ZoInD0Je/e3RBtP4OHpJVJ40nDklSvjVKjgH7VU8/e2dzRw==} + peerDependencies: + react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + lunr@2.3.9: + resolution: {integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==} + + lz-string@1.5.0: + resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} + hasBin: true + + magic-string@0.25.9: + resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} + + make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + + make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + + makeerror@1.0.12: + resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + + markdown-extensions@2.0.0: + resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==} + engines: {node: '>=16'} + + markdown-it@14.1.0: + resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==} + hasBin: true + + markdown-table@3.0.4: + resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + + marked@14.0.0: + resolution: {integrity: sha512-uIj4+faQ+MgHgwUW1l2PsPglZLOLOT1uErt06dAPtx2kjteLAkbsd/0FiYg/MGS+i7ZKLb7w2WClxHkzOOuryQ==} + engines: {node: '>= 18'} + hasBin: true + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + mdast-util-find-and-replace@3.0.2: + resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} + + mdast-util-from-markdown@2.0.2: + resolution: {integrity: sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==} + + mdast-util-gfm-autolink-literal@2.0.1: + resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} + + mdast-util-gfm-footnote@2.1.0: + resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==} + + mdast-util-gfm-strikethrough@2.0.0: + resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} + + mdast-util-gfm-table@2.0.0: + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} + + mdast-util-gfm-task-list-item@2.0.0: + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} + + mdast-util-gfm@3.1.0: + resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} + + mdast-util-mdx-expression@2.0.1: + resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==} + + mdast-util-mdx-jsx@3.2.0: + resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==} + + mdast-util-mdx@3.0.0: + resolution: {integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==} + + mdast-util-mdxjs-esm@2.0.1: + resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==} + + mdast-util-phrasing@4.1.0: + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + + mdast-util-to-hast@13.2.1: + resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==} + + mdast-util-to-markdown@2.1.2: + resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} + + mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + + mdurl@2.0.0: + resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromark-core-commonmark@2.0.3: + resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + + micromark-extension-gfm-autolink-literal@2.1.0: + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} + + micromark-extension-gfm-footnote@2.1.0: + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} + + micromark-extension-gfm-strikethrough@2.1.0: + resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} + + micromark-extension-gfm-table@2.1.1: + resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==} + + micromark-extension-gfm-tagfilter@2.0.0: + resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} + + micromark-extension-gfm-task-list-item@2.1.0: + resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} + + micromark-extension-gfm@3.0.0: + resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + + micromark-extension-mdx-expression@3.0.1: + resolution: {integrity: sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==} + + micromark-extension-mdx-jsx@3.0.2: + resolution: {integrity: sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==} + + micromark-extension-mdx-md@2.0.0: + resolution: {integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==} + + micromark-extension-mdxjs-esm@3.0.0: + resolution: {integrity: sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==} + + micromark-extension-mdxjs@3.0.0: + resolution: {integrity: sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==} + + micromark-factory-destination@2.0.1: + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + + micromark-factory-label@2.0.1: + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + + micromark-factory-mdx-expression@2.0.3: + resolution: {integrity: sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==} + + micromark-factory-space@2.0.1: + resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} + + micromark-factory-title@2.0.1: + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + + micromark-factory-whitespace@2.0.1: + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-chunked@2.0.1: + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + + micromark-util-classify-character@2.0.1: + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + + micromark-util-combine-extensions@2.0.1: + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + + micromark-util-decode-numeric-character-reference@2.0.2: + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + + micromark-util-decode-string@2.0.1: + resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-events-to-acorn@2.0.3: + resolution: {integrity: sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==} + + micromark-util-html-tag-name@2.0.1: + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + + micromark-util-normalize-identifier@2.0.1: + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + + micromark-util-resolve-all@2.0.1: + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-subtokenize@2.1.0: + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + + micromark@4.0.2: + resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mime@3.0.0: + resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} + engines: {node: '>=10.0.0'} + hasBin: true + + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + + min-indent@1.0.1: + resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} + engines: {node: '>=4'} + + miniflare@3.20250718.3: + resolution: {integrity: sha512-JuPrDJhwLrNLEJiNLWO7ZzJrv/Vv9kZuwMYCfv0LskQDM6Eonw4OvywO3CH/wCGjgHzha/qyjUh8JQ068TjDgQ==} + engines: {node: '>=16.13'} + hasBin: true + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + engines: {node: '>=10'} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + monaco-editor@0.55.1: + resolution: {integrity: sha512-jz4x+TJNFHwHtwuV9vA9rMujcZRb0CEilTEwG2rRSpe/A7Jdkuj8xPKttCgOh+v/lkHy7HsZ64oj+q3xoAFl9A==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + mustache@4.2.0: + resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==} + hasBin: true + + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + negotiator@1.0.0: + resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} + engines: {node: '>= 0.6'} + + next-themes@0.4.6: + resolution: {integrity: sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==} + peerDependencies: + react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc + react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc + + next@14.2.35: + resolution: {integrity: sha512-KhYd2Hjt/O1/1aZVX3dCwGXM1QmOV4eNM2UTacK5gipDdPN/oHHK/4oVGy7X8GMfPMsUTUEmGlsy0EY1YGAkig==} + engines: {node: '>=18.17.0'} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.41.2 + react: ^18.2.0 + react-dom: ^18.2.0 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@playwright/test': + optional: true + sass: + optional: true + + node-int64@0.4.0: + resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} + + node-releases@2.0.19: + resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} + + node-releases@2.0.27: + resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + + nwsapi@2.2.23: + resolution: {integrity: sha512-7wfH4sLbt4M0gCDzGE6vzQBo0bfTKjU7Sfpqy/7gs1qBfYz2vEJH6vXcBKpO3+6Yu1telwd0t9HpyOoLEQQbIQ==} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-hash@3.0.0: + resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} + engines: {node: '>= 6'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + object-is@1.1.6: + resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object.assign@4.1.7: + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} + engines: {node: '>= 0.4'} + + ohash@2.0.11: + resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + + oniguruma-to-es@3.1.1: + resolution: {integrity: sha512-bUH8SDvPkH3ho3dvwJwfonjlQ4R80vjyvrU8YpxuROddv55vAEJrTuCuCVUhhsHbtlD9tGGbaNApGQckXhS8iQ==} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + package-manager-manager@0.2.0: + resolution: {integrity: sha512-V02gl0bafXJ2gcY6j+5IHM7UdnYwmF+2OsFZuqVcha6iMSStD4dpIOBOsypnUIwOi4jLcPz6RQuyifmAE3mG8g==} + + parse-entities@4.0.2: + resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} + + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + + parse5@7.3.0: + resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-to-regexp@6.3.0: + resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + pcre-to-regexp@1.1.0: + resolution: {integrity: sha512-KF9XxmUQJ2DIlMj3TqNqY1AWvyvTuIuq11CuuekxyaYMiFuMKGgQrePYMX5bXKLhLG3sDI4CsGAYHPaT7VV7+g==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} + + pify@2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + + pirates@4.0.7: + resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} + engines: {node: '>= 6'} + + pkg-dir@4.2.0: + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} + + possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} + engines: {node: '>= 0.4'} + + postcss-import@15.1.0: + resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} + engines: {node: '>=14.0.0'} + peerDependencies: + postcss: ^8.0.0 + + postcss-js@4.1.0: + resolution: {integrity: sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==} + engines: {node: ^12 || ^14 || >= 16} + peerDependencies: + postcss: ^8.4.21 + + postcss-load-config@6.0.1: + resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} + engines: {node: '>= 18'} + peerDependencies: + jiti: '>=1.21.0' + postcss: '>=8.0.9' + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + jiti: + optional: true + postcss: + optional: true + tsx: + optional: true + yaml: + optional: true + + postcss-nested@6.2.0: + resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.2.14 + + postcss-selector-parser@6.1.2: + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + engines: {node: '>=4'} + + postcss-selector-parser@7.1.1: + resolution: {integrity: sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==} + engines: {node: '>=4'} + + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + + postcss@8.4.31: + resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} + engines: {node: ^10 || ^12 || >=14} + + postcss@8.5.6: + resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} + engines: {node: ^10 || ^12 || >=14} + + pretty-format@27.5.1: + resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + pretty-format@29.7.0: + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + printable-characters@1.0.42: + resolution: {integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==} + + prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + + property-information@7.1.0: + resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} + + psl@1.15.0: + resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==} + + punycode.js@2.3.1: + resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} + engines: {node: '>=6'} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + pure-rand@6.1.0: + resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} + + querystringify@2.2.0: + resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + queue@6.0.2: + resolution: {integrity: sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==} + + react-dom@18.3.1: + resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} + peerDependencies: + react: ^18.3.1 + + react-is@17.0.2: + resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + + react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + + react-medium-image-zoom@5.4.0: + resolution: {integrity: sha512-BsE+EnFVQzFIlyuuQrZ9iTwyKpKkqdFZV1ImEQN573QPqGrIUuNni7aF+sZwDcxlsuOMayCr6oO/PZR/yJnbRg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + react-remove-scroll-bar@2.3.8: + resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + react-remove-scroll@2.7.2: + resolution: {integrity: sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + react-style-singleton@2.2.3: + resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + react@18.3.1: + resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} + engines: {node: '>=0.10.0'} + + read-cache@1.0.0: + resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + recma-build-jsx@1.0.0: + resolution: {integrity: sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==} + + recma-jsx@1.0.1: + resolution: {integrity: sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + recma-parse@1.0.0: + resolution: {integrity: sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==} + + recma-stringify@1.0.0: + resolution: {integrity: sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==} + + redent@3.0.0: + resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} + engines: {node: '>=8'} + + regex-recursion@6.0.2: + resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==} + + regex-utilities@2.3.0: + resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==} + + regex@6.1.0: + resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==} + + regexp.prototype.flags@1.5.4: + resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} + engines: {node: '>= 0.4'} + + reghex@1.0.2: + resolution: {integrity: sha512-bYtyDmFGHxn1Y4gxIs12+AUQ1WRDNvaIhn6ZuKc5KUbSVcmm6U6vx/RA66s26xGhTWBErKKDKK7lorkvvIBB5g==} + + rehype-recma@1.0.0: + resolution: {integrity: sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==} + + remark-gfm@4.0.1: + resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} + + remark-mdx@3.1.1: + resolution: {integrity: sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==} + + remark-parse@11.0.0: + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} + + remark-rehype@11.1.2: + resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==} + + remark-stringify@11.0.0: + resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + + remark@15.0.1: + resolution: {integrity: sha512-Eht5w30ruCXgFmxVUSlNWQ9iiimq07URKeFS3hNc8cUWy1llX4KDWfyEDZRycMc+znsN9Ux5/tJ/BFdgdOwA3A==} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + requires-port@1.0.0: + resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + + resolve-cwd@3.0.0: + resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} + engines: {node: '>=8'} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + resolve.exports@2.0.3: + resolution: {integrity: sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==} + engines: {node: '>=10'} + + resolve@1.22.10: + resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} + engines: {node: '>= 0.4'} + hasBin: true + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rollup-plugin-inject@3.0.2: + resolution: {integrity: sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==} + deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject. + + rollup-plugin-node-polyfills@0.2.1: + resolution: {integrity: sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA==} + + rollup-pluginutils@2.8.2: + resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safe-regex-test@1.1.0: + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} + engines: {node: '>= 0.4'} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + saxes@6.0.0: + resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} + engines: {node: '>=v12.22.7'} + + scheduler@0.23.2: + resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + + scroll-into-view-if-needed@3.1.0: + resolution: {integrity: sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==} + + section-matter@1.0.0: + resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==} + engines: {node: '>=4'} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.7.2: + resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} + engines: {node: '>=10'} + hasBin: true + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + sharp@0.33.5: + resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + shellac@0.8.0: + resolution: {integrity: sha512-M3F2vzYIM7frKOs0+kgs/ITMlXhGpgtqs9HxDPciz3bckzAqqfd4LrBn+CCmSbICyJS+Jz5UDkmkR1jE+m+g+Q==} + + shiki@2.5.0: + resolution: {integrity: sha512-mI//trrsaiCIPsja5CNfsyNOqgAZUb6VpJA+340toL42UpzQlXpwRV9nch69X6gaUxrr9kaOOa6e3y3uAkGFxQ==} + + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + simple-swizzle@0.2.4: + resolution: {integrity: sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==} + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map-support@0.5.13: + resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + source-map@0.7.6: + resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} + engines: {node: '>= 12'} + + sourcemap-codec@1.4.8: + resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} + deprecated: Please use @jridgewell/sourcemap-codec instead + + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + stack-utils@2.0.6: + resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} + engines: {node: '>=10'} + + stacktracey@2.1.8: + resolution: {integrity: sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==} + + state-local@1.0.7: + resolution: {integrity: sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==} + + stop-iteration-iterator@1.1.0: + resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} + engines: {node: '>= 0.4'} + + stoppable@1.1.0: + resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==} + engines: {node: '>=4', npm: '>=6'} + + streamsearch@1.1.0: + resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} + engines: {node: '>=10.0.0'} + + string-length@4.0.2: + resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} + engines: {node: '>=10'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-bom-string@1.0.0: + resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==} + engines: {node: '>=0.10.0'} + + strip-bom@4.0.0: + resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} + engines: {node: '>=8'} + + strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + + strip-indent@3.0.0: + resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} + engines: {node: '>=8'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + style-to-js@1.1.21: + resolution: {integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==} + + style-to-object@1.0.14: + resolution: {integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==} + + styled-jsx@5.1.1: + resolution: {integrity: sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@babel/core': '*' + babel-plugin-macros: '*' + react: '>= 16.8.0 || 17.x.x || ^18.0.0-0' + peerDependenciesMeta: + '@babel/core': + optional: true + babel-plugin-macros: + optional: true + + sucrase@3.35.1: + resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + symbol-tree@3.2.4: + resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + + tailwind-merge@2.6.0: + resolution: {integrity: sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA==} + + tailwindcss@3.4.19: + resolution: {integrity: sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==} + engines: {node: '>=14.0.0'} + hasBin: true + + test-exclude@6.0.0: + resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} + engines: {node: '>=8'} + + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} + + tmpl@1.0.5: + resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + tough-cookie@4.1.4: + resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} + engines: {node: '>=6'} + + tr46@3.0.0: + resolution: {integrity: sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==} + engines: {node: '>=12'} + + trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + + trough@2.2.0: + resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + + ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + + ts-jest@29.4.0: + resolution: {integrity: sha512-d423TJMnJGu80/eSgfQ5w/R+0zFJvdtTxwtF9KzFFunOpSeD+79lHJQIiAhluJoyGRbvj9NZJsl9WjCUo0ND7Q==} + engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@babel/core': '>=7.0.0-beta.0 <8' + '@jest/transform': ^29.0.0 || ^30.0.0 + '@jest/types': ^29.0.0 || ^30.0.0 + babel-jest: ^29.0.0 || ^30.0.0 + esbuild: '*' + jest: ^29.0.0 || ^30.0.0 + jest-util: ^29.0.0 || ^30.0.0 + typescript: '>=4.3 <6' + peerDependenciesMeta: + '@babel/core': + optional: true + '@jest/transform': + optional: true + '@jest/types': + optional: true + babel-jest: + optional: true + esbuild: + optional: true + jest-util: + optional: true + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tsx@4.21.0: + resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==} + engines: {node: '>=18.0.0'} + hasBin: true + + turbo-darwin-64@2.7.3: + resolution: {integrity: sha512-aZHhvRiRHXbJw1EcEAq4aws1hsVVUZ9DPuSFaq9VVFAKCup7niIEwc22glxb7240yYEr1vLafdQ2U294Vcwz+w==} + cpu: [x64] + os: [darwin] + + turbo-darwin-arm64@2.7.3: + resolution: {integrity: sha512-CkVrHSq+Bnhl9sX2LQgqQYVfLTWC2gvI74C4758OmU0djfrssDKU9d4YQF0AYXXhIIRZipSXfxClQziIMD+EAg==} + cpu: [arm64] + os: [darwin] + + turbo-linux-64@2.7.3: + resolution: {integrity: sha512-GqDsCNnzzr89kMaLGpRALyigUklzgxIrSy2pHZVXyifgczvYPnLglex78Aj3T2gu+T3trPPH2iJ+pWucVOCC2Q==} + cpu: [x64] + os: [linux] + + turbo-linux-arm64@2.7.3: + resolution: {integrity: sha512-NdCDTfIcIo3dWjsiaAHlxu5gW61Ed/8maah1IAF/9E3EtX0aAHNiBMbuYLZaR4vRJ7BeVkYB6xKWRtdFLZ0y3g==} + cpu: [arm64] + os: [linux] + + turbo-windows-64@2.7.3: + resolution: {integrity: sha512-7bVvO987daXGSJVYBoG8R4Q+csT1pKIgLJYZevXRQ0Hqw0Vv4mKme/TOjYXs9Qb1xMKh51Tb3bXKDbd8/4G08g==} + cpu: [x64] + os: [win32] + + turbo-windows-arm64@2.7.3: + resolution: {integrity: sha512-nTodweTbPmkvwMu/a55XvjMsPtuyUSC+sV7f/SR57K36rB2I0YG21qNETN+00LOTUW9B3omd8XkiXJkt4kx/cw==} + cpu: [arm64] + os: [win32] + + turbo@2.7.3: + resolution: {integrity: sha512-+HjKlP4OfYk+qzvWNETA3cUO5UuK6b5MSc2UJOKyvBceKucQoQGb2g7HlC2H1GHdkfKrk4YF1VPvROkhVZDDLQ==} + hasBin: true + + type-detect@4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + + type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + + type-fest@4.41.0: + resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} + engines: {node: '>=16'} + + typedoc-plugin-markdown@4.9.0: + resolution: {integrity: sha512-9Uu4WR9L7ZBgAl60N/h+jqmPxxvnC9nQAlnnO/OujtG2ubjnKTVUFY1XDhcMY+pCqlX3N2HsQM2QTYZIU9tJuw==} + engines: {node: '>= 18'} + peerDependencies: + typedoc: 0.28.x + + typedoc@0.28.16: + resolution: {integrity: sha512-x4xW77QC3i5DUFMBp0qjukOTnr/sSg+oEs86nB3LjDslvAmwe/PUGDWbe3GrIqt59oTqoXK5GRK9tAa0sYMiog==} + engines: {node: '>= 18', pnpm: '>= 10'} + hasBin: true + peerDependencies: + typescript: 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x || 5.9.x + + typescript@5.5.4: + resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} + engines: {node: '>=14.17'} + hasBin: true + + uc.micro@2.1.0: + resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} + + ufo@1.6.2: + resolution: {integrity: sha512-heMioaxBcG9+Znsda5Q8sQbWnLJSl98AFDXTO80wELWEzX3hordXsTdxrIfMQoO9IY1MEnoGoPjpoKpMj+Yx0Q==} + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + + undici@5.29.0: + resolution: {integrity: sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==} + engines: {node: '>=14.0'} + + unenv@2.0.0-rc.14: + resolution: {integrity: sha512-od496pShMen7nOy5VmVJCnq8rptd45vh6Nx/r2iPbrba6pa6p+tS2ywuIHRZ/OBvSbQZB0kWvpO9XBNVFXHD3Q==} + + unified@11.0.5: + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} + + unist-util-is@6.0.1: + resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} + + unist-util-position-from-estree@2.0.0: + resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==} + + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-parents@6.0.2: + resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} + + unist-util-visit@5.0.0: + resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} + + universalify@0.2.0: + resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} + engines: {node: '>= 4.0.0'} + + update-browserslist-db@1.1.3: + resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + url-parse@1.5.10: + resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + + use-callback-ref@1.3.3: + resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + use-sidecar@1.1.3: + resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + v8-to-istanbul@9.3.0: + resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} + engines: {node: '>=10.12.0'} + + vfile-message@4.0.3: + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + + w3c-xmlserializer@4.0.0: + resolution: {integrity: sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==} + engines: {node: '>=14'} + + walker@1.0.8: + resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} + + webidl-conversions@7.0.0: + resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} + engines: {node: '>=12'} + + whatwg-encoding@2.0.0: + resolution: {integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==} + engines: {node: '>=12'} + deprecated: Use @exodus/bytes instead for a more spec-conformant and faster implementation + + whatwg-mimetype@3.0.0: + resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} + engines: {node: '>=12'} + + whatwg-url@11.0.0: + resolution: {integrity: sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==} + engines: {node: '>=12'} + + which-boxed-primitive@1.1.1: + resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} + engines: {node: '>= 0.4'} + + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + + which-typed-array@1.1.19: + resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} + engines: {node: '>= 0.4'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + workerd@1.20250718.0: + resolution: {integrity: sha512-kqkIJP/eOfDlUyBzU7joBg+tl8aB25gEAGqDap+nFWb+WHhnooxjGHgxPBy3ipw2hnShPFNOQt5lFRxbwALirg==} + engines: {node: '>=16'} + hasBin: true + + wrangler@3.114.16: + resolution: {integrity: sha512-ve/ULRjrquu5BHNJ+1T0ipJJlJ6pD7qLmhwRkk0BsUIxatNe4HP4odX/R4Mq/RHG6LOnVAFs7SMeSHlz/1mNlQ==} + engines: {node: '>=16.17.0'} + hasBin: true + peerDependencies: + '@cloudflare/workers-types': ^4.20250408.0 + peerDependenciesMeta: + '@cloudflare/workers-types': + optional: true + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + write-file-atomic@4.0.2: + resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.19.0: + resolution: {integrity: sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + xml-name-validator@4.0.0: + resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} + engines: {node: '>=12'} + + xmlchars@2.2.0: + resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yaml@2.8.2: + resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==} + engines: {node: '>= 14.6'} + hasBin: true + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + youch@3.3.4: + resolution: {integrity: sha512-UeVBXie8cA35DS6+nBkls68xaBBXCye0CNznrhszZjTbRVnJKQuNsyLKBTTL4ln1o1rh2PKtv35twV7irj5SEg==} + + zod@3.22.3: + resolution: {integrity: sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug==} + + zod@3.25.76: + resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + + zod@4.3.5: + resolution: {integrity: sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g==} + + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + +snapshots: + + '@adobe/css-tools@4.4.4': {} + + '@alloc/quick-lru@5.2.0': {} + + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.12 + '@jridgewell/trace-mapping': 0.3.29 + + '@babel/code-frame@7.27.1': + dependencies: + '@babel/helper-validator-identifier': 7.27.1 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.28.0': {} + + '@babel/core@7.28.0': + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.0 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-module-transforms': 7.27.3(@babel/core@7.28.0) + '@babel/helpers': 7.28.2 + '@babel/parser': 7.28.0 + '@babel/template': 7.27.2 + '@babel/traverse': 7.28.0 + '@babel/types': 7.28.2 + convert-source-map: 2.0.0 + debug: 4.4.1 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.28.0': + dependencies: + '@babel/parser': 7.28.0 + '@babel/types': 7.28.2 + '@jridgewell/gen-mapping': 0.3.12 + '@jridgewell/trace-mapping': 0.3.29 + jsesc: 3.1.0 + + '@babel/helper-compilation-targets@7.27.2': + dependencies: + '@babel/compat-data': 7.28.0 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.25.1 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-module-imports@7.27.1': + dependencies: + '@babel/traverse': 7.28.0 + '@babel/types': 7.28.2 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.27.3(@babel/core@7.28.0)': + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + '@babel/traverse': 7.28.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-plugin-utils@7.27.1': {} + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.27.1': {} + + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helpers@7.28.2': + dependencies: + '@babel/template': 7.27.2 + '@babel/types': 7.28.2 + + '@babel/parser@7.28.0': + dependencies: + '@babel/types': 7.28.2 + + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.28.0)': + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.28.0)': + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.28.0)': + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.28.0)': + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.28.0)': + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.28.0)': + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.28.0)': + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.0)': + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.28.0)': + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.28.0)': + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.28.0)': + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.28.0)': + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.28.0)': + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.28.0)': + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.28.0)': + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.28.0)': + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.0)': + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/runtime@7.28.4': {} + + '@babel/template@7.27.2': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/parser': 7.28.0 + '@babel/types': 7.28.2 + + '@babel/traverse@7.28.0': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.0 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.28.0 + '@babel/template': 7.27.2 + '@babel/types': 7.28.2 + debug: 4.4.1 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.28.2': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + + '@bcoe/v8-coverage@0.2.3': {} + + '@biomejs/biome@2.1.1': + optionalDependencies: + '@biomejs/cli-darwin-arm64': 2.1.1 + '@biomejs/cli-darwin-x64': 2.1.1 + '@biomejs/cli-linux-arm64': 2.1.1 + '@biomejs/cli-linux-arm64-musl': 2.1.1 + '@biomejs/cli-linux-x64': 2.1.1 + '@biomejs/cli-linux-x64-musl': 2.1.1 + '@biomejs/cli-win32-arm64': 2.1.1 + '@biomejs/cli-win32-x64': 2.1.1 + + '@biomejs/cli-darwin-arm64@2.1.1': + optional: true + + '@biomejs/cli-darwin-x64@2.1.1': + optional: true + + '@biomejs/cli-linux-arm64-musl@2.1.1': + optional: true + + '@biomejs/cli-linux-arm64@2.1.1': + optional: true + + '@biomejs/cli-linux-x64-musl@2.1.1': + optional: true + + '@biomejs/cli-linux-x64@2.1.1': + optional: true + + '@biomejs/cli-win32-arm64@2.1.1': + optional: true + + '@biomejs/cli-win32-x64@2.1.1': + optional: true + + '@cloudflare/kv-asset-handler@0.3.4': + dependencies: + mime: 3.0.0 + + '@cloudflare/next-on-pages@1.13.16(next@14.2.35(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(wrangler@3.114.16)': + dependencies: + acorn: 8.15.0 + ast-types: 0.14.2 + chalk: 5.6.2 + chokidar: 3.6.0 + commander: 11.1.0 + cookie: 0.5.0 + esbuild: 0.15.18 + js-yaml: 4.1.1 + miniflare: 3.20250718.3 + next: 14.2.35(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + package-manager-manager: 0.2.0 + pcre-to-regexp: 1.1.0 + semver: 7.7.2 + wrangler: 3.114.16 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@cloudflare/unenv-preset@2.0.2(unenv@2.0.0-rc.14)(workerd@1.20250718.0)': + dependencies: + unenv: 2.0.0-rc.14 + optionalDependencies: + workerd: 1.20250718.0 + + '@cloudflare/workerd-darwin-64@1.20250718.0': + optional: true + + '@cloudflare/workerd-darwin-arm64@1.20250718.0': + optional: true + + '@cloudflare/workerd-linux-64@1.20250718.0': + optional: true - object.assign@4.1.7: - resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} - engines: {node: '>= 0.4'} + '@cloudflare/workerd-linux-arm64@1.20250718.0': + optional: true - once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + '@cloudflare/workerd-windows-64@1.20250718.0': + optional: true - onetime@5.1.2: - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} - engines: {node: '>=6'} + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 - p-limit@2.3.0: - resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} - engines: {node: '>=6'} + '@emnapi/runtime@1.8.1': + dependencies: + tslib: 2.8.1 + optional: true - p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} + '@esbuild-plugins/node-globals-polyfill@0.2.3(esbuild@0.17.19)': + dependencies: + esbuild: 0.17.19 - p-locate@4.1.0: - resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} - engines: {node: '>=8'} + '@esbuild-plugins/node-modules-polyfill@0.2.2(esbuild@0.17.19)': + dependencies: + esbuild: 0.17.19 + escape-string-regexp: 4.0.0 + rollup-plugin-node-polyfills: 0.2.1 - p-try@2.2.0: - resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} - engines: {node: '>=6'} + '@esbuild/aix-ppc64@0.24.2': + optional: true - parse-json@5.2.0: - resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} - engines: {node: '>=8'} + '@esbuild/aix-ppc64@0.27.2': + optional: true - parse5@7.3.0: - resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + '@esbuild/android-arm64@0.17.19': + optional: true - path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} + '@esbuild/android-arm64@0.24.2': + optional: true - path-is-absolute@1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} + '@esbuild/android-arm64@0.27.2': + optional: true - path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} + '@esbuild/android-arm@0.15.18': + optional: true - path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + '@esbuild/android-arm@0.17.19': + optional: true - picocolors@1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + '@esbuild/android-arm@0.24.2': + optional: true - picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} + '@esbuild/android-arm@0.27.2': + optional: true - pirates@4.0.7: - resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} - engines: {node: '>= 6'} + '@esbuild/android-x64@0.17.19': + optional: true - pkg-dir@4.2.0: - resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} - engines: {node: '>=8'} + '@esbuild/android-x64@0.24.2': + optional: true - possible-typed-array-names@1.1.0: - resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} - engines: {node: '>= 0.4'} + '@esbuild/android-x64@0.27.2': + optional: true - pretty-format@27.5.1: - resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} - engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + '@esbuild/darwin-arm64@0.17.19': + optional: true - pretty-format@29.7.0: - resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@esbuild/darwin-arm64@0.24.2': + optional: true - prompts@2.4.2: - resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} - engines: {node: '>= 6'} + '@esbuild/darwin-arm64@0.27.2': + optional: true - psl@1.15.0: - resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==} + '@esbuild/darwin-x64@0.17.19': + optional: true - punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} + '@esbuild/darwin-x64@0.24.2': + optional: true - pure-rand@6.1.0: - resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} + '@esbuild/darwin-x64@0.27.2': + optional: true - querystringify@2.2.0: - resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} + '@esbuild/freebsd-arm64@0.17.19': + optional: true - react-dom@18.3.1: - resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} - peerDependencies: - react: ^18.3.1 + '@esbuild/freebsd-arm64@0.24.2': + optional: true - react-is@17.0.2: - resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + '@esbuild/freebsd-arm64@0.27.2': + optional: true - react-is@18.3.1: - resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + '@esbuild/freebsd-x64@0.17.19': + optional: true - react@18.3.1: - resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} - engines: {node: '>=0.10.0'} + '@esbuild/freebsd-x64@0.24.2': + optional: true - redent@3.0.0: - resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} - engines: {node: '>=8'} + '@esbuild/freebsd-x64@0.27.2': + optional: true - regexp.prototype.flags@1.5.4: - resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} - engines: {node: '>= 0.4'} + '@esbuild/linux-arm64@0.17.19': + optional: true - require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} + '@esbuild/linux-arm64@0.24.2': + optional: true - requires-port@1.0.0: - resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + '@esbuild/linux-arm64@0.27.2': + optional: true - resolve-cwd@3.0.0: - resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} - engines: {node: '>=8'} + '@esbuild/linux-arm@0.17.19': + optional: true - resolve-from@5.0.0: - resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} - engines: {node: '>=8'} + '@esbuild/linux-arm@0.24.2': + optional: true - resolve.exports@2.0.3: - resolution: {integrity: sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==} - engines: {node: '>=10'} + '@esbuild/linux-arm@0.27.2': + optional: true - resolve@1.22.10: - resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} - engines: {node: '>= 0.4'} - hasBin: true + '@esbuild/linux-ia32@0.17.19': + optional: true - safe-regex-test@1.1.0: - resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} - engines: {node: '>= 0.4'} + '@esbuild/linux-ia32@0.24.2': + optional: true - safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + '@esbuild/linux-ia32@0.27.2': + optional: true - saxes@6.0.0: - resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} - engines: {node: '>=v12.22.7'} + '@esbuild/linux-loong64@0.15.18': + optional: true - scheduler@0.23.2: - resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + '@esbuild/linux-loong64@0.17.19': + optional: true - semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} - hasBin: true + '@esbuild/linux-loong64@0.24.2': + optional: true - semver@7.7.2: - resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} - engines: {node: '>=10'} - hasBin: true + '@esbuild/linux-loong64@0.27.2': + optional: true - set-function-length@1.2.2: - resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} - engines: {node: '>= 0.4'} + '@esbuild/linux-mips64el@0.17.19': + optional: true - set-function-name@2.0.2: - resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} - engines: {node: '>= 0.4'} + '@esbuild/linux-mips64el@0.24.2': + optional: true - shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} + '@esbuild/linux-mips64el@0.27.2': + optional: true - shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} + '@esbuild/linux-ppc64@0.17.19': + optional: true - side-channel-list@1.0.0: - resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} - engines: {node: '>= 0.4'} + '@esbuild/linux-ppc64@0.24.2': + optional: true - side-channel-map@1.0.1: - resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} - engines: {node: '>= 0.4'} + '@esbuild/linux-ppc64@0.27.2': + optional: true - side-channel-weakmap@1.0.2: - resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} - engines: {node: '>= 0.4'} + '@esbuild/linux-riscv64@0.17.19': + optional: true - side-channel@1.1.0: - resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} - engines: {node: '>= 0.4'} + '@esbuild/linux-riscv64@0.24.2': + optional: true - signal-exit@3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + '@esbuild/linux-riscv64@0.27.2': + optional: true - sisteransi@1.0.5: - resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + '@esbuild/linux-s390x@0.17.19': + optional: true - slash@3.0.0: - resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} - engines: {node: '>=8'} + '@esbuild/linux-s390x@0.24.2': + optional: true - source-map-support@0.5.13: - resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} + '@esbuild/linux-s390x@0.27.2': + optional: true - source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} + '@esbuild/linux-x64@0.17.19': + optional: true - sprintf-js@1.0.3: - resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + '@esbuild/linux-x64@0.24.2': + optional: true - stack-utils@2.0.6: - resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} - engines: {node: '>=10'} + '@esbuild/linux-x64@0.27.2': + optional: true - stop-iteration-iterator@1.1.0: - resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} - engines: {node: '>= 0.4'} + '@esbuild/netbsd-arm64@0.24.2': + optional: true - string-length@4.0.2: - resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} - engines: {node: '>=10'} + '@esbuild/netbsd-arm64@0.27.2': + optional: true - string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} + '@esbuild/netbsd-x64@0.17.19': + optional: true - strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} + '@esbuild/netbsd-x64@0.24.2': + optional: true - strip-bom@4.0.0: - resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} - engines: {node: '>=8'} + '@esbuild/netbsd-x64@0.27.2': + optional: true - strip-final-newline@2.0.0: - resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} - engines: {node: '>=6'} + '@esbuild/openbsd-arm64@0.24.2': + optional: true - strip-indent@3.0.0: - resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} - engines: {node: '>=8'} + '@esbuild/openbsd-arm64@0.27.2': + optional: true - strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} + '@esbuild/openbsd-x64@0.17.19': + optional: true - supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} + '@esbuild/openbsd-x64@0.24.2': + optional: true - supports-color@8.1.1: - resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} - engines: {node: '>=10'} + '@esbuild/openbsd-x64@0.27.2': + optional: true - supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} + '@esbuild/openharmony-arm64@0.27.2': + optional: true - symbol-tree@3.2.4: - resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + '@esbuild/sunos-x64@0.17.19': + optional: true - test-exclude@6.0.0: - resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} - engines: {node: '>=8'} + '@esbuild/sunos-x64@0.24.2': + optional: true - tmpl@1.0.5: - resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} + '@esbuild/sunos-x64@0.27.2': + optional: true - to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} + '@esbuild/win32-arm64@0.17.19': + optional: true - tough-cookie@4.1.4: - resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} - engines: {node: '>=6'} + '@esbuild/win32-arm64@0.24.2': + optional: true - tr46@3.0.0: - resolution: {integrity: sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==} - engines: {node: '>=12'} + '@esbuild/win32-arm64@0.27.2': + optional: true - ts-jest@29.4.0: - resolution: {integrity: sha512-d423TJMnJGu80/eSgfQ5w/R+0zFJvdtTxwtF9KzFFunOpSeD+79lHJQIiAhluJoyGRbvj9NZJsl9WjCUo0ND7Q==} - engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0} - hasBin: true - peerDependencies: - '@babel/core': '>=7.0.0-beta.0 <8' - '@jest/transform': ^29.0.0 || ^30.0.0 - '@jest/types': ^29.0.0 || ^30.0.0 - babel-jest: ^29.0.0 || ^30.0.0 - esbuild: '*' - jest: ^29.0.0 || ^30.0.0 - jest-util: ^29.0.0 || ^30.0.0 - typescript: '>=4.3 <6' - peerDependenciesMeta: - '@babel/core': - optional: true - '@jest/transform': - optional: true - '@jest/types': - optional: true - babel-jest: - optional: true - esbuild: - optional: true - jest-util: - optional: true + '@esbuild/win32-ia32@0.17.19': + optional: true - tslib@2.8.1: - resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + '@esbuild/win32-ia32@0.24.2': + optional: true - turbo-darwin-64@2.7.3: - resolution: {integrity: sha512-aZHhvRiRHXbJw1EcEAq4aws1hsVVUZ9DPuSFaq9VVFAKCup7niIEwc22glxb7240yYEr1vLafdQ2U294Vcwz+w==} - cpu: [x64] - os: [darwin] + '@esbuild/win32-ia32@0.27.2': + optional: true - turbo-darwin-arm64@2.7.3: - resolution: {integrity: sha512-CkVrHSq+Bnhl9sX2LQgqQYVfLTWC2gvI74C4758OmU0djfrssDKU9d4YQF0AYXXhIIRZipSXfxClQziIMD+EAg==} - cpu: [arm64] - os: [darwin] + '@esbuild/win32-x64@0.17.19': + optional: true - turbo-linux-64@2.7.3: - resolution: {integrity: sha512-GqDsCNnzzr89kMaLGpRALyigUklzgxIrSy2pHZVXyifgczvYPnLglex78Aj3T2gu+T3trPPH2iJ+pWucVOCC2Q==} - cpu: [x64] - os: [linux] + '@esbuild/win32-x64@0.24.2': + optional: true - turbo-linux-arm64@2.7.3: - resolution: {integrity: sha512-NdCDTfIcIo3dWjsiaAHlxu5gW61Ed/8maah1IAF/9E3EtX0aAHNiBMbuYLZaR4vRJ7BeVkYB6xKWRtdFLZ0y3g==} - cpu: [arm64] - os: [linux] + '@esbuild/win32-x64@0.27.2': + optional: true - turbo-windows-64@2.7.3: - resolution: {integrity: sha512-7bVvO987daXGSJVYBoG8R4Q+csT1pKIgLJYZevXRQ0Hqw0Vv4mKme/TOjYXs9Qb1xMKh51Tb3bXKDbd8/4G08g==} - cpu: [x64] - os: [win32] + '@fastify/busboy@2.1.1': {} - turbo-windows-arm64@2.7.3: - resolution: {integrity: sha512-nTodweTbPmkvwMu/a55XvjMsPtuyUSC+sV7f/SR57K36rB2I0YG21qNETN+00LOTUW9B3omd8XkiXJkt4kx/cw==} - cpu: [arm64] - os: [win32] + '@floating-ui/core@1.7.3': + dependencies: + '@floating-ui/utils': 0.2.10 - turbo@2.7.3: - resolution: {integrity: sha512-+HjKlP4OfYk+qzvWNETA3cUO5UuK6b5MSc2UJOKyvBceKucQoQGb2g7HlC2H1GHdkfKrk4YF1VPvROkhVZDDLQ==} - hasBin: true + '@floating-ui/dom@1.7.4': + dependencies: + '@floating-ui/core': 1.7.3 + '@floating-ui/utils': 0.2.10 - type-detect@4.0.8: - resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} - engines: {node: '>=4'} + '@floating-ui/react-dom@2.1.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@floating-ui/dom': 1.7.4 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - type-fest@0.21.3: - resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} - engines: {node: '>=10'} + '@floating-ui/utils@0.2.10': {} - type-fest@4.41.0: - resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} - engines: {node: '>=16'} + '@formatjs/intl-localematcher@0.5.10': + dependencies: + tslib: 2.8.1 - typescript@5.5.4: - resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} - engines: {node: '>=14.17'} - hasBin: true + '@gerrit0/mini-shiki@3.21.0': + dependencies: + '@shikijs/engine-oniguruma': 3.21.0 + '@shikijs/langs': 3.21.0 + '@shikijs/themes': 3.21.0 + '@shikijs/types': 3.21.0 + '@shikijs/vscode-textmate': 10.0.2 - undici-types@6.21.0: - resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + '@img/sharp-darwin-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.0.4 + optional: true - universalify@0.2.0: - resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} - engines: {node: '>= 4.0.0'} + '@img/sharp-darwin-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.0.4 + optional: true - update-browserslist-db@1.1.3: - resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' + '@img/sharp-libvips-darwin-arm64@1.0.4': + optional: true - url-parse@1.5.10: - resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + '@img/sharp-libvips-darwin-x64@1.0.4': + optional: true - v8-to-istanbul@9.3.0: - resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} - engines: {node: '>=10.12.0'} + '@img/sharp-libvips-linux-arm64@1.0.4': + optional: true - w3c-xmlserializer@4.0.0: - resolution: {integrity: sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==} - engines: {node: '>=14'} + '@img/sharp-libvips-linux-arm@1.0.5': + optional: true - walker@1.0.8: - resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} + '@img/sharp-libvips-linux-s390x@1.0.4': + optional: true - webidl-conversions@7.0.0: - resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} - engines: {node: '>=12'} + '@img/sharp-libvips-linux-x64@1.0.4': + optional: true - whatwg-encoding@2.0.0: - resolution: {integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==} - engines: {node: '>=12'} - deprecated: Use @exodus/bytes instead for a more spec-conformant and faster implementation + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + optional: true - whatwg-mimetype@3.0.0: - resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==} - engines: {node: '>=12'} + '@img/sharp-libvips-linuxmusl-x64@1.0.4': + optional: true - whatwg-url@11.0.0: - resolution: {integrity: sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==} - engines: {node: '>=12'} + '@img/sharp-linux-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.0.4 + optional: true - which-boxed-primitive@1.1.1: - resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} - engines: {node: '>= 0.4'} + '@img/sharp-linux-arm@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.0.5 + optional: true - which-collection@1.0.2: - resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} - engines: {node: '>= 0.4'} + '@img/sharp-linux-s390x@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.0.4 + optional: true - which-typed-array@1.1.19: - resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} - engines: {node: '>= 0.4'} + '@img/sharp-linux-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.0.4 + optional: true - which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true + '@img/sharp-linuxmusl-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + optional: true - wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} + '@img/sharp-linuxmusl-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + optional: true - wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + '@img/sharp-wasm32@0.33.5': + dependencies: + '@emnapi/runtime': 1.8.1 + optional: true - write-file-atomic@4.0.2: - resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + '@img/sharp-win32-ia32@0.33.5': + optional: true - ws@8.19.0: - resolution: {integrity: sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true + '@img/sharp-win32-x64@0.33.5': + optional: true - xml-name-validator@4.0.0: - resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} - engines: {node: '>=12'} + '@istanbuljs/load-nyc-config@1.1.0': + dependencies: + camelcase: 5.3.1 + find-up: 4.1.0 + get-package-type: 0.1.0 + js-yaml: 3.14.1 + resolve-from: 5.0.0 - xmlchars@2.2.0: - resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + '@istanbuljs/schema@0.1.3': {} - y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} + '@jest/console@29.7.0': + dependencies: + '@jest/types': 29.6.3 + '@types/node': 20.19.9 + chalk: 4.1.2 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + slash: 3.0.0 + + '@jest/core@29.7.0': + dependencies: + '@jest/console': 29.7.0 + '@jest/reporters': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.19.9 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + ci-info: 3.9.0 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-changed-files: 29.7.0 + jest-config: 29.7.0(@types/node@20.19.9) + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-resolve-dependencies: 29.7.0 + jest-runner: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + jest-watcher: 29.7.0 + micromatch: 4.0.8 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-ansi: 6.0.1 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + - ts-node - yallist@3.1.1: - resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + '@jest/environment@29.7.0': + dependencies: + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 20.19.9 + jest-mock: 29.7.0 - yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} + '@jest/expect-utils@29.7.0': + dependencies: + jest-get-type: 29.6.3 - yargs@17.7.2: - resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} - engines: {node: '>=12'} + '@jest/expect@29.7.0': + dependencies: + expect: 29.7.0 + jest-snapshot: 29.7.0 + transitivePeerDependencies: + - supports-color - yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} + '@jest/fake-timers@29.7.0': + dependencies: + '@jest/types': 29.6.3 + '@sinonjs/fake-timers': 10.3.0 + '@types/node': 20.19.9 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-util: 29.7.0 - zod@4.3.5: - resolution: {integrity: sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g==} + '@jest/globals@29.7.0': + dependencies: + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/types': 29.6.3 + jest-mock: 29.7.0 + transitivePeerDependencies: + - supports-color -snapshots: + '@jest/reporters@29.7.0': + dependencies: + '@bcoe/v8-coverage': 0.2.3 + '@jest/console': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.29 + '@types/node': 20.19.9 + chalk: 4.1.2 + collect-v8-coverage: 1.0.2 + exit: 0.1.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-instrument: 6.0.3 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.1.7 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + jest-worker: 29.7.0 + slash: 3.0.0 + string-length: 4.0.2 + strip-ansi: 6.0.1 + v8-to-istanbul: 9.3.0 + transitivePeerDependencies: + - supports-color - '@adobe/css-tools@4.4.4': {} + '@jest/schemas@29.6.3': + dependencies: + '@sinclair/typebox': 0.27.8 - '@ampproject/remapping@2.3.0': + '@jest/source-map@29.6.3': dependencies: - '@jridgewell/gen-mapping': 0.3.12 '@jridgewell/trace-mapping': 0.3.29 + callsites: 3.1.0 + graceful-fs: 4.2.11 - '@babel/code-frame@7.27.1': + '@jest/test-result@29.7.0': dependencies: - '@babel/helper-validator-identifier': 7.27.1 - js-tokens: 4.0.0 - picocolors: 1.1.1 + '@jest/console': 29.7.0 + '@jest/types': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + collect-v8-coverage: 1.0.2 - '@babel/compat-data@7.28.0': {} + '@jest/test-sequencer@29.7.0': + dependencies: + '@jest/test-result': 29.7.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + slash: 3.0.0 - '@babel/core@7.28.0': + '@jest/transform@29.7.0': dependencies: - '@ampproject/remapping': 2.3.0 - '@babel/code-frame': 7.27.1 - '@babel/generator': 7.28.0 - '@babel/helper-compilation-targets': 7.27.2 - '@babel/helper-module-transforms': 7.27.3(@babel/core@7.28.0) - '@babel/helpers': 7.28.2 - '@babel/parser': 7.28.0 - '@babel/template': 7.27.2 - '@babel/traverse': 7.28.0 - '@babel/types': 7.28.2 + '@babel/core': 7.28.0 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.29 + babel-plugin-istanbul: 6.1.1 + chalk: 4.1.2 convert-source-map: 2.0.0 - debug: 4.4.1 - gensync: 1.0.0-beta.2 - json5: 2.2.3 - semver: 6.3.1 + fast-json-stable-stringify: 2.1.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + micromatch: 4.0.8 + pirates: 4.0.7 + slash: 3.0.0 + write-file-atomic: 4.0.2 transitivePeerDependencies: - supports-color - '@babel/generator@7.28.0': + '@jest/types@29.6.3': dependencies: - '@babel/parser': 7.28.0 - '@babel/types': 7.28.2 - '@jridgewell/gen-mapping': 0.3.12 + '@jest/schemas': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 20.19.9 + '@types/yargs': 17.0.33 + chalk: 4.1.2 + + '@jridgewell/gen-mapping@0.3.12': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.4 '@jridgewell/trace-mapping': 0.3.29 - jsesc: 3.1.0 - '@babel/helper-compilation-targets@7.27.2': + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.4': {} + + '@jridgewell/trace-mapping@0.3.29': dependencies: - '@babel/compat-data': 7.28.0 - '@babel/helper-validator-option': 7.27.1 - browserslist: 4.25.1 - lru-cache: 5.1.1 - semver: 6.3.1 + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.4 - '@babel/helper-globals@7.28.0': {} + '@jridgewell/trace-mapping@0.3.9': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.4 - '@babel/helper-module-imports@7.27.1': + '@mdx-js/mdx@3.1.1': dependencies: - '@babel/traverse': 7.28.0 - '@babel/types': 7.28.2 + '@types/estree': 1.0.8 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdx': 2.0.13 + acorn: 8.15.0 + collapse-white-space: 2.1.0 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + estree-util-scope: 1.0.0 + estree-walker: 3.0.3 + hast-util-to-jsx-runtime: 2.3.6 + markdown-extensions: 2.0.0 + recma-build-jsx: 1.0.0 + recma-jsx: 1.0.1(acorn@8.15.0) + recma-stringify: 1.0.0 + rehype-recma: 1.0.0 + remark-mdx: 3.1.1 + remark-parse: 11.0.0 + remark-rehype: 11.1.2 + source-map: 0.7.6 + unified: 11.0.5 + unist-util-position-from-estree: 2.0.0 + unist-util-stringify-position: 4.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.27.3(@babel/core@7.28.0)': + '@monaco-editor/loader@1.7.0': dependencies: - '@babel/core': 7.28.0 - '@babel/helper-module-imports': 7.27.1 - '@babel/helper-validator-identifier': 7.27.1 - '@babel/traverse': 7.28.0 - transitivePeerDependencies: - - supports-color + state-local: 1.0.7 - '@babel/helper-plugin-utils@7.27.1': {} + '@monaco-editor/react@4.7.0(monaco-editor@0.55.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@monaco-editor/loader': 1.7.0 + monaco-editor: 0.55.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) - '@babel/helper-string-parser@7.27.1': {} + '@next/env@14.2.35': {} - '@babel/helper-validator-identifier@7.27.1': {} + '@next/swc-darwin-arm64@14.2.33': + optional: true - '@babel/helper-validator-option@7.27.1': {} + '@next/swc-darwin-x64@14.2.33': + optional: true - '@babel/helpers@7.28.2': - dependencies: - '@babel/template': 7.27.2 - '@babel/types': 7.28.2 + '@next/swc-linux-arm64-gnu@14.2.33': + optional: true - '@babel/parser@7.28.0': - dependencies: - '@babel/types': 7.28.2 + '@next/swc-linux-arm64-musl@14.2.33': + optional: true - '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.28.0)': - dependencies: - '@babel/core': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 + '@next/swc-linux-x64-gnu@14.2.33': + optional: true - '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.28.0)': - dependencies: - '@babel/core': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 + '@next/swc-linux-x64-musl@14.2.33': + optional: true - '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.28.0)': + '@next/swc-win32-arm64-msvc@14.2.33': + optional: true + + '@next/swc-win32-ia32-msvc@14.2.33': + optional: true + + '@next/swc-win32-x64-msvc@14.2.33': + optional: true + + '@nodelib/fs.scandir@2.1.5': dependencies: - '@babel/core': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 - '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.28.0)': + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': dependencies: - '@babel/core': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.20.1 - '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.28.0)': + '@orama/orama@2.1.1': {} + + '@radix-ui/number@1.1.1': {} + + '@radix-ui/primitive@1.1.3': {} + + '@radix-ui/react-accordion@1.2.12(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/core': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collapsible': 1.1.12(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.27)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.27 + '@types/react-dom': 18.3.7(@types/react@18.3.27) - '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.28.0)': + '@radix-ui/react-arrow@1.1.7(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/core': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.27 + '@types/react-dom': 18.3.7(@types/react@18.3.27) - '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.28.0)': + '@radix-ui/react-collapsible@1.1.12(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/core': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.27)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.27 + '@types/react-dom': 18.3.7(@types/react@18.3.27) - '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.0)': + '@radix-ui/react-collection@1.1.7(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/core': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@18.3.27)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.27 + '@types/react-dom': 18.3.7(@types/react@18.3.27) - '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.28.0)': + '@radix-ui/react-compose-refs@1.1.2(@types/react@18.3.27)(react@18.3.1)': dependencies: - '@babel/core': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.27 - '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.28.0)': + '@radix-ui/react-context@1.1.2(@types/react@18.3.27)(react@18.3.1)': dependencies: - '@babel/core': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.27 - '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.28.0)': - dependencies: - '@babel/core': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 + '@radix-ui/react-dialog@1.1.15(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.27)(react@18.3.1) + aria-hidden: 1.2.6 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-remove-scroll: 2.7.2(@types/react@18.3.27)(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.27 + '@types/react-dom': 18.3.7(@types/react@18.3.27) - '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.28.0)': + '@radix-ui/react-direction@1.1.1(@types/react@18.3.27)(react@18.3.1)': dependencies: - '@babel/core': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.27 - '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.28.0)': + '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/core': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@18.3.27)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.27 + '@types/react-dom': 18.3.7(@types/react@18.3.27) - '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.28.0)': + '@radix-ui/react-focus-guards@1.1.3(@types/react@18.3.27)(react@18.3.1)': dependencies: - '@babel/core': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.27 - '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.28.0)': + '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/core': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.27)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.27 + '@types/react-dom': 18.3.7(@types/react@18.3.27) - '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.28.0)': + '@radix-ui/react-id@1.1.1(@types/react@18.3.27)(react@18.3.1)': dependencies: - '@babel/core': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.27)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.27 - '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.0)': - dependencies: - '@babel/core': 7.28.0 - '@babel/helper-plugin-utils': 7.27.1 + '@radix-ui/react-navigation-menu@1.2.14(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-use-previous': 1.1.1(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.27 + '@types/react-dom': 18.3.7(@types/react@18.3.27) - '@babel/runtime@7.28.4': {} + '@radix-ui/react-popover@1.1.15(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.3(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.27)(react@18.3.1) + aria-hidden: 1.2.6 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-remove-scroll: 2.7.2(@types/react@18.3.27)(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.27 + '@types/react-dom': 18.3.7(@types/react@18.3.27) - '@babel/template@7.27.2': - dependencies: - '@babel/code-frame': 7.27.1 - '@babel/parser': 7.28.0 - '@babel/types': 7.28.2 + '@radix-ui/react-popper@1.2.8(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@floating-ui/react-dom': 2.1.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-arrow': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-use-rect': 1.1.1(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.1(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/rect': 1.1.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.27 + '@types/react-dom': 18.3.7(@types/react@18.3.27) - '@babel/traverse@7.28.0': + '@radix-ui/react-portal@1.1.9(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/code-frame': 7.27.1 - '@babel/generator': 7.28.0 - '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.28.0 - '@babel/template': 7.27.2 - '@babel/types': 7.28.2 - debug: 4.4.1 - transitivePeerDependencies: - - supports-color + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.27)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.27 + '@types/react-dom': 18.3.7(@types/react@18.3.27) - '@babel/types@7.28.2': + '@radix-ui/react-presence@1.1.5(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/helper-string-parser': 7.27.1 - '@babel/helper-validator-identifier': 7.27.1 - - '@bcoe/v8-coverage@0.2.3': {} - - '@biomejs/biome@2.1.1': + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.27)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) optionalDependencies: - '@biomejs/cli-darwin-arm64': 2.1.1 - '@biomejs/cli-darwin-x64': 2.1.1 - '@biomejs/cli-linux-arm64': 2.1.1 - '@biomejs/cli-linux-arm64-musl': 2.1.1 - '@biomejs/cli-linux-x64': 2.1.1 - '@biomejs/cli-linux-x64-musl': 2.1.1 - '@biomejs/cli-win32-arm64': 2.1.1 - '@biomejs/cli-win32-x64': 2.1.1 - - '@biomejs/cli-darwin-arm64@2.1.1': - optional: true + '@types/react': 18.3.27 + '@types/react-dom': 18.3.7(@types/react@18.3.27) - '@biomejs/cli-darwin-x64@2.1.1': - optional: true + '@radix-ui/react-primitive@2.1.3(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-slot': 1.2.3(@types/react@18.3.27)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.27 + '@types/react-dom': 18.3.7(@types/react@18.3.27) - '@biomejs/cli-linux-arm64-musl@2.1.1': - optional: true + '@radix-ui/react-roving-focus@1.1.11(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.27)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.27 + '@types/react-dom': 18.3.7(@types/react@18.3.27) - '@biomejs/cli-linux-arm64@2.1.1': - optional: true + '@radix-ui/react-scroll-area@1.2.10(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/number': 1.1.1 + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-context': 1.1.2(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.27)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.27 + '@types/react-dom': 18.3.7(@types/react@18.3.27) - '@biomejs/cli-linux-x64-musl@2.1.1': - optional: true + '@radix-ui/react-slot@1.2.3(@types/react@18.3.27)(react@18.3.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.27)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.27 - '@biomejs/cli-linux-x64@2.1.1': - optional: true + '@radix-ui/react-slot@1.2.4(@types/react@18.3.27)(react@18.3.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.27)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.27 - '@biomejs/cli-win32-arm64@2.1.1': - optional: true + '@radix-ui/react-tabs@1.1.13(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-context': 1.1.2(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-id': 1.1.1(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@18.3.27)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.27 + '@types/react-dom': 18.3.7(@types/react@18.3.27) - '@biomejs/cli-win32-x64@2.1.1': - optional: true + '@radix-ui/react-use-callback-ref@1.1.1(@types/react@18.3.27)(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.27 - '@istanbuljs/load-nyc-config@1.1.0': + '@radix-ui/react-use-controllable-state@1.2.2(@types/react@18.3.27)(react@18.3.1)': dependencies: - camelcase: 5.3.1 - find-up: 4.1.0 - get-package-type: 0.1.0 - js-yaml: 3.14.1 - resolve-from: 5.0.0 + '@radix-ui/react-use-effect-event': 0.0.2(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.27)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.27 - '@istanbuljs/schema@0.1.3': {} + '@radix-ui/react-use-effect-event@0.0.2(@types/react@18.3.27)(react@18.3.1)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.27)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.27 - '@jest/console@29.7.0': + '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@18.3.27)(react@18.3.1)': dependencies: - '@jest/types': 29.6.3 - '@types/node': 20.19.9 - chalk: 4.1.2 - jest-message-util: 29.7.0 - jest-util: 29.7.0 - slash: 3.0.0 + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@18.3.27)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.27 - '@jest/core@29.7.0': + '@radix-ui/react-use-layout-effect@1.1.1(@types/react@18.3.27)(react@18.3.1)': dependencies: - '@jest/console': 29.7.0 - '@jest/reporters': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 20.19.9 - ansi-escapes: 4.3.2 - chalk: 4.1.2 - ci-info: 3.9.0 - exit: 0.1.2 - graceful-fs: 4.2.11 - jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@20.19.9) - jest-haste-map: 29.7.0 - jest-message-util: 29.7.0 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-resolve-dependencies: 29.7.0 - jest-runner: 29.7.0 - jest-runtime: 29.7.0 - jest-snapshot: 29.7.0 - jest-util: 29.7.0 - jest-validate: 29.7.0 - jest-watcher: 29.7.0 - micromatch: 4.0.8 - pretty-format: 29.7.0 - slash: 3.0.0 - strip-ansi: 6.0.1 - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - - ts-node + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.27 - '@jest/environment@29.7.0': + '@radix-ui/react-use-previous@1.1.1(@types/react@18.3.27)(react@18.3.1)': dependencies: - '@jest/fake-timers': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 20.19.9 - jest-mock: 29.7.0 + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.27 - '@jest/expect-utils@29.7.0': + '@radix-ui/react-use-rect@1.1.1(@types/react@18.3.27)(react@18.3.1)': dependencies: - jest-get-type: 29.6.3 + '@radix-ui/rect': 1.1.1 + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.27 - '@jest/expect@29.7.0': + '@radix-ui/react-use-size@1.1.1(@types/react@18.3.27)(react@18.3.1)': dependencies: - expect: 29.7.0 - jest-snapshot: 29.7.0 - transitivePeerDependencies: - - supports-color + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@18.3.27)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.27 - '@jest/fake-timers@29.7.0': + '@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@jest/types': 29.6.3 - '@sinonjs/fake-timers': 10.3.0 - '@types/node': 20.19.9 - jest-message-util: 29.7.0 - jest-mock: 29.7.0 - jest-util: 29.7.0 + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.27 + '@types/react-dom': 18.3.7(@types/react@18.3.27) - '@jest/globals@29.7.0': + '@radix-ui/rect@1.1.1': {} + + '@shikijs/core@2.5.0': dependencies: - '@jest/environment': 29.7.0 - '@jest/expect': 29.7.0 - '@jest/types': 29.6.3 - jest-mock: 29.7.0 - transitivePeerDependencies: - - supports-color + '@shikijs/engine-javascript': 2.5.0 + '@shikijs/engine-oniguruma': 2.5.0 + '@shikijs/types': 2.5.0 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + hast-util-to-html: 9.0.5 - '@jest/reporters@29.7.0': + '@shikijs/engine-javascript@2.5.0': dependencies: - '@bcoe/v8-coverage': 0.2.3 - '@jest/console': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - '@jridgewell/trace-mapping': 0.3.29 - '@types/node': 20.19.9 - chalk: 4.1.2 - collect-v8-coverage: 1.0.2 - exit: 0.1.2 - glob: 7.2.3 - graceful-fs: 4.2.11 - istanbul-lib-coverage: 3.2.2 - istanbul-lib-instrument: 6.0.3 - istanbul-lib-report: 3.0.1 - istanbul-lib-source-maps: 4.0.1 - istanbul-reports: 3.1.7 - jest-message-util: 29.7.0 - jest-util: 29.7.0 - jest-worker: 29.7.0 - slash: 3.0.0 - string-length: 4.0.2 - strip-ansi: 6.0.1 - v8-to-istanbul: 9.3.0 - transitivePeerDependencies: - - supports-color + '@shikijs/types': 2.5.0 + '@shikijs/vscode-textmate': 10.0.2 + oniguruma-to-es: 3.1.1 - '@jest/schemas@29.6.3': + '@shikijs/engine-oniguruma@2.5.0': dependencies: - '@sinclair/typebox': 0.27.8 + '@shikijs/types': 2.5.0 + '@shikijs/vscode-textmate': 10.0.2 - '@jest/source-map@29.6.3': + '@shikijs/engine-oniguruma@3.21.0': dependencies: - '@jridgewell/trace-mapping': 0.3.29 - callsites: 3.1.0 - graceful-fs: 4.2.11 + '@shikijs/types': 3.21.0 + '@shikijs/vscode-textmate': 10.0.2 - '@jest/test-result@29.7.0': + '@shikijs/langs@2.5.0': dependencies: - '@jest/console': 29.7.0 - '@jest/types': 29.6.3 - '@types/istanbul-lib-coverage': 2.0.6 - collect-v8-coverage: 1.0.2 + '@shikijs/types': 2.5.0 - '@jest/test-sequencer@29.7.0': + '@shikijs/langs@3.21.0': dependencies: - '@jest/test-result': 29.7.0 - graceful-fs: 4.2.11 - jest-haste-map: 29.7.0 - slash: 3.0.0 + '@shikijs/types': 3.21.0 - '@jest/transform@29.7.0': + '@shikijs/rehype@2.5.0': dependencies: - '@babel/core': 7.28.0 - '@jest/types': 29.6.3 - '@jridgewell/trace-mapping': 0.3.29 - babel-plugin-istanbul: 6.1.1 - chalk: 4.1.2 - convert-source-map: 2.0.0 - fast-json-stable-stringify: 2.1.0 - graceful-fs: 4.2.11 - jest-haste-map: 29.7.0 - jest-regex-util: 29.6.3 - jest-util: 29.7.0 - micromatch: 4.0.8 - pirates: 4.0.7 - slash: 3.0.0 - write-file-atomic: 4.0.2 - transitivePeerDependencies: - - supports-color + '@shikijs/types': 2.5.0 + '@types/hast': 3.0.4 + hast-util-to-string: 3.0.1 + shiki: 2.5.0 + unified: 11.0.5 + unist-util-visit: 5.0.0 - '@jest/types@29.6.3': + '@shikijs/themes@2.5.0': dependencies: - '@jest/schemas': 29.6.3 - '@types/istanbul-lib-coverage': 2.0.6 - '@types/istanbul-reports': 3.0.4 - '@types/node': 20.19.9 - '@types/yargs': 17.0.33 - chalk: 4.1.2 + '@shikijs/types': 2.5.0 - '@jridgewell/gen-mapping@0.3.12': + '@shikijs/themes@3.21.0': dependencies: - '@jridgewell/sourcemap-codec': 1.5.4 - '@jridgewell/trace-mapping': 0.3.29 + '@shikijs/types': 3.21.0 - '@jridgewell/resolve-uri@3.1.2': {} + '@shikijs/transformers@2.5.0': + dependencies: + '@shikijs/core': 2.5.0 + '@shikijs/types': 2.5.0 - '@jridgewell/sourcemap-codec@1.5.4': {} + '@shikijs/types@2.5.0': + dependencies: + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 - '@jridgewell/trace-mapping@0.3.29': + '@shikijs/types@3.21.0': dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.4 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + '@shikijs/vscode-textmate@10.0.2': {} '@sinclair/typebox@0.27.8': {} @@ -2420,6 +5865,13 @@ snapshots: - bufferutil - utf-8-validate + '@swc/counter@0.1.3': {} + + '@swc/helpers@0.5.5': + dependencies: + '@swc/counter': 0.1.3 + tslib: 2.8.1 + '@testing-library/dom@9.3.4': dependencies: '@babel/code-frame': 7.27.1 @@ -2454,7 +5906,7 @@ snapshots: dependencies: '@testing-library/dom': 9.3.4 - '@thesis-co/biome-config@https://codeload.github.com/thesis/biome-config/tar.gz/6e8586bfa74c62c9ede2ca12abbcac1dc0ad4606': + '@thesis-co/biome-config@https://codeload.github.com/thesis/biome-config/tar.gz/c38100c9023d10a1c486bc0eca388f3cf8ca4046': dependencies: '@biomejs/biome': 2.1.1 @@ -2483,10 +5935,24 @@ snapshots: dependencies: '@babel/types': 7.28.2 + '@types/debug@4.1.12': + dependencies: + '@types/ms': 2.1.0 + + '@types/estree-jsx@1.0.5': + dependencies: + '@types/estree': 1.0.8 + + '@types/estree@1.0.8': {} + '@types/graceful-fs@4.1.9': dependencies: '@types/node': 20.19.9 + '@types/hast@3.0.4': + dependencies: + '@types/unist': 3.0.3 + '@types/istanbul-lib-coverage@2.0.6': {} '@types/istanbul-lib-report@3.0.3': @@ -2508,6 +5974,18 @@ snapshots: '@types/tough-cookie': 4.0.5 parse5: 7.3.0 + '@types/lz-string@1.5.0': + dependencies: + lz-string: 1.5.0 + + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/mdx@2.0.13': {} + + '@types/ms@2.1.0': {} + '@types/node@20.19.9': dependencies: undici-types: 6.21.0 @@ -2529,6 +6007,13 @@ snapshots: '@types/tough-cookie@4.0.5': {} + '@types/trusted-types@2.0.7': + optional: true + + '@types/unist@2.0.11': {} + + '@types/unist@3.0.3': {} + '@types/ws@8.18.1': dependencies: '@types/node': 20.19.9 @@ -2539,6 +6024,8 @@ snapshots: dependencies: '@types/yargs-parser': 21.0.3 + '@ungap/structured-clone@1.3.0': {} + abab@2.0.6: {} acorn-globals@7.0.1: @@ -2546,10 +6033,18 @@ snapshots: acorn: 8.15.0 acorn-walk: 8.3.4 + acorn-jsx@5.3.2(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + + acorn-walk@8.3.2: {} + acorn-walk@8.3.4: dependencies: acorn: 8.15.0 + acorn@8.14.0: {} + acorn@8.15.0: {} agent-base@6.0.2: @@ -2570,15 +6065,25 @@ snapshots: ansi-styles@5.2.0: {} + any-promise@1.3.0: {} + anymatch@3.1.3: dependencies: normalize-path: 3.0.0 picomatch: 2.3.1 + arg@5.0.2: {} + argparse@1.0.10: dependencies: sprintf-js: 1.0.3 + argparse@2.0.1: {} + + aria-hidden@1.2.6: + dependencies: + tslib: 2.8.1 + aria-query@5.1.3: dependencies: deep-equal: 2.2.3 @@ -2590,10 +6095,29 @@ snapshots: call-bound: 1.0.4 is-array-buffer: 3.0.5 + as-table@1.0.55: + dependencies: + printable-characters: 1.0.42 + + ast-types@0.14.2: + dependencies: + tslib: 2.8.1 + + astring@1.9.0: {} + async@3.2.6: {} asynckit@0.4.0: {} + autoprefixer@10.4.23(postcss@8.5.6): + dependencies: + browserslist: 4.28.1 + caniuse-lite: 1.0.30001764 + fraction.js: 5.3.4 + picocolors: 1.1.1 + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + available-typed-arrays@1.0.7: dependencies: possible-typed-array-names: 1.1.0 @@ -2653,8 +6177,16 @@ snapshots: babel-plugin-jest-hoist: 29.6.3 babel-preset-current-node-syntax: 1.1.0(@babel/core@7.28.0) + bail@2.0.2: {} + balanced-match@1.0.2: {} + baseline-browser-mapping@2.9.14: {} + + binary-extensions@2.3.0: {} + + blake3-wasm@2.1.5: {} + brace-expansion@1.1.12: dependencies: balanced-match: 1.0.2 @@ -2675,6 +6207,14 @@ snapshots: node-releases: 2.0.19 update-browserslist-db: 1.1.3(browserslist@4.25.1) + browserslist@4.28.1: + dependencies: + baseline-browser-mapping: 2.9.14 + caniuse-lite: 1.0.30001764 + electron-to-chromium: 1.5.267 + node-releases: 2.0.27 + update-browserslist-db: 1.2.3(browserslist@4.28.1) + bs-logger@0.2.6: dependencies: fast-json-stable-stringify: 2.1.0 @@ -2685,6 +6225,10 @@ snapshots: buffer-from@1.1.2: {} + busboy@1.6.0: + dependencies: + streamsearch: 1.1.0 + call-bind-apply-helpers@1.0.2: dependencies: es-errors: 1.3.0 @@ -2704,31 +6248,73 @@ snapshots: callsites@3.1.0: {} + camelcase-css@2.0.1: {} + camelcase@5.3.1: {} camelcase@6.3.0: {} caniuse-lite@1.0.30001727: {} + caniuse-lite@1.0.30001764: {} + + ccount@2.0.1: {} + chalk@4.1.2: dependencies: ansi-styles: 4.3.0 supports-color: 7.2.0 + chalk@5.6.2: {} + char-regex@1.0.2: {} + character-entities-html4@2.1.0: {} + + character-entities-legacy@3.0.0: {} + + character-entities@2.0.2: {} + + character-reference-invalid@2.0.1: {} + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + ci-info@3.9.0: {} cjs-module-lexer@1.4.3: {} + class-variance-authority@0.7.1: + dependencies: + clsx: 2.1.1 + + client-only@0.0.1: {} + cliui@8.0.1: dependencies: string-width: 4.2.3 strip-ansi: 6.0.1 wrap-ansi: 7.0.0 + clsx@2.1.1: {} + co@4.6.0: {} + collapse-white-space@2.1.0: {} + collect-v8-coverage@1.0.2: {} color-convert@2.0.1: @@ -2737,14 +6323,38 @@ snapshots: color-name@1.1.4: {} + color-string@1.9.1: + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.4 + optional: true + + color@4.2.3: + dependencies: + color-convert: 2.0.1 + color-string: 1.9.1 + optional: true + combined-stream@1.0.8: dependencies: delayed-stream: 1.0.0 + comma-separated-tokens@2.0.3: {} + + commander@11.1.0: {} + + commander@4.1.1: {} + + compute-scroll-into-view@3.1.1: {} + concat-map@0.0.1: {} convert-source-map@2.0.0: {} + cookie@0.5.0: {} + + cookie@0.7.2: {} + create-jest@29.7.0(@types/node@20.19.9): dependencies: '@jest/types': 29.6.3 @@ -2768,6 +6378,8 @@ snapshots: css.escape@1.5.1: {} + cssesc@3.0.0: {} + cssom@0.3.8: {} cssom@0.5.0: {} @@ -2778,6 +6390,8 @@ snapshots: csstype@3.2.3: {} + data-uri-to-buffer@2.0.2: {} + data-urls@3.0.2: dependencies: abab: 2.0.6 @@ -2790,6 +6404,10 @@ snapshots: decimal.js@10.6.0: {} + decode-named-character-reference@1.2.0: + dependencies: + character-entities: 2.0.2 + dedent@1.6.0: {} deep-equal@2.2.3: @@ -2827,12 +6445,29 @@ snapshots: has-property-descriptors: 1.0.2 object-keys: 1.1.1 + defu@6.1.4: {} + delayed-stream@1.0.0: {} + dequal@2.0.3: {} + + detect-libc@2.1.2: + optional: true + detect-newline@3.1.0: {} + detect-node-es@1.1.0: {} + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + + didyoumean@1.2.2: {} + diff-sequences@29.6.3: {} + dlv@1.1.3: {} + dom-accessibility-api@0.5.16: {} dom-accessibility-api@0.6.3: {} @@ -2841,6 +6476,10 @@ snapshots: dependencies: webidl-conversions: 7.0.0 + dompurify@3.2.7: + optionalDependencies: + '@types/trusted-types': 2.0.7 + dunder-proto@1.0.1: dependencies: call-bind-apply-helpers: 1.0.2 @@ -2853,47 +6492,238 @@ snapshots: electron-to-chromium@1.5.190: {} + electron-to-chromium@1.5.267: {} + emittery@0.13.1: {} + emoji-regex-xs@1.0.0: {} + emoji-regex@8.0.0: {} + entities@4.5.0: {} + entities@6.0.1: {} error-ex@1.3.2: dependencies: is-arrayish: 0.2.1 - es-define-property@1.0.1: {} + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-get-iterator@1.1.3: + dependencies: + call-bind: 1.0.8 + get-intrinsic: 1.3.0 + has-symbols: 1.1.0 + is-arguments: 1.2.0 + is-map: 2.0.3 + is-set: 2.0.3 + is-string: 1.1.1 + isarray: 2.0.5 + stop-iteration-iterator: 1.1.0 + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + esast-util-from-estree@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + unist-util-position-from-estree: 2.0.0 + + esast-util-from-js@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + acorn: 8.15.0 + esast-util-from-estree: 2.0.0 + vfile-message: 4.0.3 + + esbuild-android-64@0.15.18: + optional: true + + esbuild-android-arm64@0.15.18: + optional: true + + esbuild-darwin-64@0.15.18: + optional: true + + esbuild-darwin-arm64@0.15.18: + optional: true + + esbuild-freebsd-64@0.15.18: + optional: true + + esbuild-freebsd-arm64@0.15.18: + optional: true + + esbuild-linux-32@0.15.18: + optional: true + + esbuild-linux-64@0.15.18: + optional: true + + esbuild-linux-arm64@0.15.18: + optional: true + + esbuild-linux-arm@0.15.18: + optional: true + + esbuild-linux-mips64le@0.15.18: + optional: true + + esbuild-linux-ppc64le@0.15.18: + optional: true + + esbuild-linux-riscv64@0.15.18: + optional: true + + esbuild-linux-s390x@0.15.18: + optional: true + + esbuild-netbsd-64@0.15.18: + optional: true + + esbuild-openbsd-64@0.15.18: + optional: true - es-errors@1.3.0: {} + esbuild-sunos-64@0.15.18: + optional: true - es-get-iterator@1.1.3: - dependencies: - call-bind: 1.0.8 - get-intrinsic: 1.3.0 - has-symbols: 1.1.0 - is-arguments: 1.2.0 - is-map: 2.0.3 - is-set: 2.0.3 - is-string: 1.1.1 - isarray: 2.0.5 - stop-iteration-iterator: 1.1.0 + esbuild-windows-32@0.15.18: + optional: true - es-object-atoms@1.1.1: - dependencies: - es-errors: 1.3.0 + esbuild-windows-64@0.15.18: + optional: true - es-set-tostringtag@2.1.0: - dependencies: - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - has-tostringtag: 1.0.2 - hasown: 2.0.2 + esbuild-windows-arm64@0.15.18: + optional: true + + esbuild@0.15.18: + optionalDependencies: + '@esbuild/android-arm': 0.15.18 + '@esbuild/linux-loong64': 0.15.18 + esbuild-android-64: 0.15.18 + esbuild-android-arm64: 0.15.18 + esbuild-darwin-64: 0.15.18 + esbuild-darwin-arm64: 0.15.18 + esbuild-freebsd-64: 0.15.18 + esbuild-freebsd-arm64: 0.15.18 + esbuild-linux-32: 0.15.18 + esbuild-linux-64: 0.15.18 + esbuild-linux-arm: 0.15.18 + esbuild-linux-arm64: 0.15.18 + esbuild-linux-mips64le: 0.15.18 + esbuild-linux-ppc64le: 0.15.18 + esbuild-linux-riscv64: 0.15.18 + esbuild-linux-s390x: 0.15.18 + esbuild-netbsd-64: 0.15.18 + esbuild-openbsd-64: 0.15.18 + esbuild-sunos-64: 0.15.18 + esbuild-windows-32: 0.15.18 + esbuild-windows-64: 0.15.18 + esbuild-windows-arm64: 0.15.18 + + esbuild@0.17.19: + optionalDependencies: + '@esbuild/android-arm': 0.17.19 + '@esbuild/android-arm64': 0.17.19 + '@esbuild/android-x64': 0.17.19 + '@esbuild/darwin-arm64': 0.17.19 + '@esbuild/darwin-x64': 0.17.19 + '@esbuild/freebsd-arm64': 0.17.19 + '@esbuild/freebsd-x64': 0.17.19 + '@esbuild/linux-arm': 0.17.19 + '@esbuild/linux-arm64': 0.17.19 + '@esbuild/linux-ia32': 0.17.19 + '@esbuild/linux-loong64': 0.17.19 + '@esbuild/linux-mips64el': 0.17.19 + '@esbuild/linux-ppc64': 0.17.19 + '@esbuild/linux-riscv64': 0.17.19 + '@esbuild/linux-s390x': 0.17.19 + '@esbuild/linux-x64': 0.17.19 + '@esbuild/netbsd-x64': 0.17.19 + '@esbuild/openbsd-x64': 0.17.19 + '@esbuild/sunos-x64': 0.17.19 + '@esbuild/win32-arm64': 0.17.19 + '@esbuild/win32-ia32': 0.17.19 + '@esbuild/win32-x64': 0.17.19 + + esbuild@0.24.2: + optionalDependencies: + '@esbuild/aix-ppc64': 0.24.2 + '@esbuild/android-arm': 0.24.2 + '@esbuild/android-arm64': 0.24.2 + '@esbuild/android-x64': 0.24.2 + '@esbuild/darwin-arm64': 0.24.2 + '@esbuild/darwin-x64': 0.24.2 + '@esbuild/freebsd-arm64': 0.24.2 + '@esbuild/freebsd-x64': 0.24.2 + '@esbuild/linux-arm': 0.24.2 + '@esbuild/linux-arm64': 0.24.2 + '@esbuild/linux-ia32': 0.24.2 + '@esbuild/linux-loong64': 0.24.2 + '@esbuild/linux-mips64el': 0.24.2 + '@esbuild/linux-ppc64': 0.24.2 + '@esbuild/linux-riscv64': 0.24.2 + '@esbuild/linux-s390x': 0.24.2 + '@esbuild/linux-x64': 0.24.2 + '@esbuild/netbsd-arm64': 0.24.2 + '@esbuild/netbsd-x64': 0.24.2 + '@esbuild/openbsd-arm64': 0.24.2 + '@esbuild/openbsd-x64': 0.24.2 + '@esbuild/sunos-x64': 0.24.2 + '@esbuild/win32-arm64': 0.24.2 + '@esbuild/win32-ia32': 0.24.2 + '@esbuild/win32-x64': 0.24.2 + + esbuild@0.27.2: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.2 + '@esbuild/android-arm': 0.27.2 + '@esbuild/android-arm64': 0.27.2 + '@esbuild/android-x64': 0.27.2 + '@esbuild/darwin-arm64': 0.27.2 + '@esbuild/darwin-x64': 0.27.2 + '@esbuild/freebsd-arm64': 0.27.2 + '@esbuild/freebsd-x64': 0.27.2 + '@esbuild/linux-arm': 0.27.2 + '@esbuild/linux-arm64': 0.27.2 + '@esbuild/linux-ia32': 0.27.2 + '@esbuild/linux-loong64': 0.27.2 + '@esbuild/linux-mips64el': 0.27.2 + '@esbuild/linux-ppc64': 0.27.2 + '@esbuild/linux-riscv64': 0.27.2 + '@esbuild/linux-s390x': 0.27.2 + '@esbuild/linux-x64': 0.27.2 + '@esbuild/netbsd-arm64': 0.27.2 + '@esbuild/netbsd-x64': 0.27.2 + '@esbuild/openbsd-arm64': 0.27.2 + '@esbuild/openbsd-x64': 0.27.2 + '@esbuild/openharmony-arm64': 0.27.2 + '@esbuild/sunos-x64': 0.27.2 + '@esbuild/win32-arm64': 0.27.2 + '@esbuild/win32-ia32': 0.27.2 + '@esbuild/win32-x64': 0.27.2 escalade@3.2.0: {} escape-string-regexp@2.0.0: {} + escape-string-regexp@4.0.0: {} + + escape-string-regexp@5.0.0: {} + escodegen@2.1.0: dependencies: esprima: 4.0.1 @@ -2906,6 +6736,45 @@ snapshots: estraverse@5.3.0: {} + estree-util-attach-comments@3.0.0: + dependencies: + '@types/estree': 1.0.8 + + estree-util-build-jsx@3.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + estree-walker: 3.0.3 + + estree-util-is-identifier-name@3.0.0: {} + + estree-util-scope@1.0.0: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + + estree-util-to-js@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + astring: 1.9.0 + source-map: 0.7.6 + + estree-util-value-to-estree@3.5.0: + dependencies: + '@types/estree': 1.0.8 + + estree-util-visit@2.0.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/unist': 3.0.3 + + estree-walker@0.6.1: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.8 + esutils@2.0.3: {} execa@5.1.1: @@ -2920,6 +6789,8 @@ snapshots: signal-exit: 3.0.7 strip-final-newline: 2.0.0 + exit-hook@2.2.1: {} + exit@0.1.2: {} expect@29.7.0: @@ -2930,12 +6801,36 @@ snapshots: jest-message-util: 29.7.0 jest-util: 29.7.0 + exsolve@1.0.8: {} + + extend-shallow@2.0.1: + dependencies: + is-extendable: 0.1.1 + + extend@3.0.2: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + fast-json-stable-stringify@2.1.0: {} + fastq@1.20.1: + dependencies: + reusify: 1.1.0 + fb-watchman@2.0.2: dependencies: bser: 2.1.1 + fdir@6.5.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 + filelist@1.0.4: dependencies: minimatch: 5.1.6 @@ -2961,11 +6856,82 @@ snapshots: hasown: 2.0.2 mime-types: 2.1.35 + fraction.js@5.3.4: {} + fs.realpath@1.0.0: {} fsevents@2.3.3: optional: true + fumadocs-core@14.7.7(@types/react@18.3.27)(next@14.2.35(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@formatjs/intl-localematcher': 0.5.10 + '@orama/orama': 2.1.1 + '@shikijs/rehype': 2.5.0 + '@shikijs/transformers': 2.5.0 + github-slugger: 2.0.0 + hast-util-to-estree: 3.1.3 + hast-util-to-jsx-runtime: 2.3.6 + image-size: 1.2.1 + negotiator: 1.0.0 + react-remove-scroll: 2.7.2(@types/react@18.3.27)(react@18.3.1) + remark: 15.0.1 + remark-gfm: 4.0.1 + scroll-into-view-if-needed: 3.1.0 + shiki: 2.5.0 + unist-util-visit: 5.0.0 + optionalDependencies: + next: 14.2.35(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + transitivePeerDependencies: + - '@types/react' + - supports-color + + fumadocs-mdx@10.1.0(fumadocs-core@14.7.7(@types/react@18.3.27)(next@14.2.35(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(next@14.2.35(react-dom@18.3.1(react@18.3.1))(react@18.3.1)): + dependencies: + '@mdx-js/mdx': 3.1.1 + chokidar: 4.0.3 + cross-spawn: 7.0.6 + esbuild: 0.24.2 + estree-util-value-to-estree: 3.5.0 + fast-glob: 3.3.3 + fumadocs-core: 14.7.7(@types/react@18.3.27)(next@14.2.35(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + gray-matter: 4.0.3 + micromatch: 4.0.8 + next: 14.2.35(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + zod: 3.25.76 + transitivePeerDependencies: + - supports-color + + fumadocs-ui@14.7.7(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(fumadocs-core@14.7.7(@types/react@18.3.27)(next@14.2.35(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(next@14.2.35(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.2)): + dependencies: + '@radix-ui/react-accordion': 1.2.12(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-collapsible': 1.1.12(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-dialog': 1.1.15(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-direction': 1.1.1(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-navigation-menu': 1.2.14(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-popover': 1.1.15(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-scroll-area': 1.2.10(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.2.4(@types/react@18.3.27)(react@18.3.1) + '@radix-ui/react-tabs': 1.1.13(@types/react-dom@18.3.7(@types/react@18.3.27))(@types/react@18.3.27)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + class-variance-authority: 0.7.1 + fumadocs-core: 14.7.7(@types/react@18.3.27)(next@14.2.35(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + lodash.merge: 4.6.2 + lucide-react: 0.473.0(react@18.3.1) + next: 14.2.35(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next-themes: 0.4.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + postcss-selector-parser: 7.1.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-medium-image-zoom: 5.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + tailwind-merge: 2.6.0 + optionalDependencies: + tailwindcss: 3.4.19(tsx@4.21.0)(yaml@2.8.2) + transitivePeerDependencies: + - '@types/react' + - '@types/react-dom' + function-bind@1.1.2: {} functions-have-names@1.2.3: {} @@ -2987,6 +6953,8 @@ snapshots: hasown: 2.0.2 math-intrinsics: 1.1.0 + get-nonce@1.0.1: {} + get-package-type@0.1.0: {} get-proto@1.0.1: @@ -2994,8 +6962,29 @@ snapshots: dunder-proto: 1.0.1 es-object-atoms: 1.1.1 + get-source@2.0.12: + dependencies: + data-uri-to-buffer: 2.0.2 + source-map: 0.6.1 + get-stream@6.0.1: {} + get-tsconfig@4.13.0: + dependencies: + resolve-pkg-maps: 1.0.0 + + github-slugger@2.0.0: {} + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + glob-to-regexp@0.4.1: {} + glob@7.2.3: dependencies: fs.realpath: 1.0.0 @@ -3009,6 +6998,13 @@ snapshots: graceful-fs@4.2.11: {} + gray-matter@4.0.3: + dependencies: + js-yaml: 3.14.1 + kind-of: 6.0.3 + section-matter: 1.0.0 + strip-bom-string: 1.0.0 + has-bigints@1.1.0: {} has-flag@4.0.0: {} @@ -3027,12 +7023,77 @@ snapshots: dependencies: function-bind: 1.1.2 + hast-util-to-estree@3.1.3: + dependencies: + '@types/estree': 1.0.8 + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-attach-comments: 3.0.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.21 + unist-util-position: 5.0.0 + zwitch: 2.0.4 + transitivePeerDependencies: + - supports-color + + hast-util-to-html@9.0.5: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + comma-separated-tokens: 2.0.3 + hast-util-whitespace: 3.0.0 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + stringify-entities: 4.0.4 + zwitch: 2.0.4 + + hast-util-to-jsx-runtime@2.3.6: + dependencies: + '@types/estree': 1.0.8 + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.21 + unist-util-position: 5.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + + hast-util-to-string@3.0.1: + dependencies: + '@types/hast': 3.0.4 + + hast-util-whitespace@3.0.0: + dependencies: + '@types/hast': 3.0.4 + html-encoding-sniffer@3.0.0: dependencies: whatwg-encoding: 2.0.0 html-escaper@2.0.2: {} + html-void-elements@3.0.0: {} + http-proxy-agent@5.0.0: dependencies: '@tootallnate/once': 2.0.0 @@ -3056,6 +7117,10 @@ snapshots: dependencies: safer-buffer: 2.1.2 + image-size@1.2.1: + dependencies: + queue: 6.0.2 + import-local@3.2.0: dependencies: pkg-dir: 4.2.0 @@ -3072,12 +7137,21 @@ snapshots: inherits@2.0.4: {} + inline-style-parser@0.2.7: {} + internal-slot@1.1.0: dependencies: es-errors: 1.3.0 hasown: 2.0.2 side-channel: 1.1.0 + is-alphabetical@2.0.1: {} + + is-alphanumerical@2.0.1: + dependencies: + is-alphabetical: 2.0.1 + is-decimal: 2.0.1 + is-arguments@1.2.0: dependencies: call-bound: 1.0.4 @@ -3091,10 +7165,17 @@ snapshots: is-arrayish@0.2.1: {} + is-arrayish@0.3.4: + optional: true + is-bigint@1.1.0: dependencies: has-bigints: 1.1.0 + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + is-boolean-object@1.2.2: dependencies: call-bound: 1.0.4 @@ -3111,10 +7192,22 @@ snapshots: call-bound: 1.0.4 has-tostringtag: 1.0.2 + is-decimal@2.0.1: {} + + is-extendable@0.1.1: {} + + is-extglob@2.1.1: {} + is-fullwidth-code-point@3.0.0: {} is-generator-fn@2.1.0: {} + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-hexadecimal@2.0.1: {} + is-map@2.0.3: {} is-number-object@1.1.1: @@ -3124,6 +7217,8 @@ snapshots: is-number@7.0.0: {} + is-plain-obj@4.1.0: {} + is-potential-custom-element-name@1.0.1: {} is-regex@1.2.1: @@ -3534,6 +7629,8 @@ snapshots: - supports-color - ts-node + jiti@1.21.7: {} + js-tokens@4.0.0: {} js-yaml@3.14.1: @@ -3541,6 +7638,10 @@ snapshots: argparse: 1.0.10 esprima: 4.0.1 + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 + jsdom@20.0.3: dependencies: abab: 2.0.6 @@ -3580,18 +7681,30 @@ snapshots: json5@2.2.3: {} + kind-of@6.0.3: {} + kleur@3.0.3: {} leven@3.1.0: {} + lilconfig@3.1.3: {} + lines-and-columns@1.2.4: {} + linkify-it@5.0.0: + dependencies: + uc.micro: 2.1.0 + locate-path@5.0.0: dependencies: p-locate: 4.1.0 lodash.memoize@4.1.2: {} + lodash.merge@4.6.2: {} + + longest-streak@3.1.0: {} + loose-envify@1.4.0: dependencies: js-tokens: 4.0.0 @@ -3600,8 +7713,18 @@ snapshots: dependencies: yallist: 3.1.1 + lucide-react@0.473.0(react@18.3.1): + dependencies: + react: 18.3.1 + + lunr@2.3.9: {} + lz-string@1.5.0: {} + magic-string@0.25.9: + dependencies: + sourcemap-codec: 1.4.8 + make-dir@4.0.0: dependencies: semver: 7.7.2 @@ -3612,10 +7735,456 @@ snapshots: dependencies: tmpl: 1.0.5 + markdown-extensions@2.0.0: {} + + markdown-it@14.1.0: + dependencies: + argparse: 2.0.1 + entities: 4.5.0 + linkify-it: 5.0.0 + mdurl: 2.0.0 + punycode.js: 2.3.1 + uc.micro: 2.1.0 + + markdown-table@3.0.4: {} + + marked@14.0.0: {} + math-intrinsics@1.1.0: {} + mdast-util-find-and-replace@3.0.2: + dependencies: + '@types/mdast': 4.0.4 + escape-string-regexp: 5.0.0 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + mdast-util-from-markdown@2.0.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + decode-named-character-reference: 1.2.0 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.2 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-decode-string: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-autolink-literal@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-find-and-replace: 3.0.2 + micromark-util-character: 2.1.1 + + mdast-util-gfm-footnote@2.1.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + micromark-util-normalize-identifier: 2.0.1 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-strikethrough@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-table@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + markdown-table: 3.0.4 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-task-list-item@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm@3.1.0: + dependencies: + mdast-util-from-markdown: 2.0.2 + mdast-util-gfm-autolink-literal: 2.0.1 + mdast-util-gfm-footnote: 2.1.0 + mdast-util-gfm-strikethrough: 2.0.0 + mdast-util-gfm-table: 2.0.0 + mdast-util-gfm-task-list-item: 2.0.0 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-expression@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-jsx@3.2.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + parse-entities: 4.0.2 + stringify-entities: 4.0.4 + unist-util-stringify-position: 4.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx@3.0.0: + dependencies: + mdast-util-from-markdown: 2.0.2 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdxjs-esm@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-phrasing@4.1.0: + dependencies: + '@types/mdast': 4.0.4 + unist-util-is: 6.0.1 + + mdast-util-to-hast@13.2.1: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.3.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.1 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + + mdast-util-to-markdown@2.1.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + longest-streak: 3.1.0 + mdast-util-phrasing: 4.1.0 + mdast-util-to-string: 4.0.0 + micromark-util-classify-character: 2.0.1 + micromark-util-decode-string: 2.0.1 + unist-util-visit: 5.0.0 + zwitch: 2.0.4 + + mdast-util-to-string@4.0.0: + dependencies: + '@types/mdast': 4.0.4 + + mdurl@2.0.0: {} + merge-stream@2.0.0: {} + merge2@1.4.1: {} + + micromark-core-commonmark@2.0.3: + dependencies: + decode-named-character-reference: 1.2.0 + devlop: 1.1.0 + micromark-factory-destination: 2.0.1 + micromark-factory-label: 2.0.1 + micromark-factory-space: 2.0.1 + micromark-factory-title: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-html-tag-name: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-autolink-literal@2.1.0: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-footnote@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-strikethrough@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-table@2.1.1: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-tagfilter@2.0.0: + dependencies: + micromark-util-types: 2.0.2 + + micromark-extension-gfm-task-list-item@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm@3.0.0: + dependencies: + micromark-extension-gfm-autolink-literal: 2.1.0 + micromark-extension-gfm-footnote: 2.1.0 + micromark-extension-gfm-strikethrough: 2.1.0 + micromark-extension-gfm-table: 2.1.1 + micromark-extension-gfm-tagfilter: 2.0.0 + micromark-extension-gfm-task-list-item: 2.1.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-mdx-expression@3.0.1: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-factory-mdx-expression: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-mdx-jsx@3.0.2: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + micromark-factory-mdx-expression: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + vfile-message: 4.0.3 + + micromark-extension-mdx-md@2.0.0: + dependencies: + micromark-util-types: 2.0.2 + + micromark-extension-mdxjs-esm@3.0.0: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.3 + + micromark-extension-mdxjs@3.0.0: + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + micromark-extension-mdx-expression: 3.0.1 + micromark-extension-mdx-jsx: 3.0.2 + micromark-extension-mdx-md: 2.0.0 + micromark-extension-mdxjs-esm: 3.0.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-destination@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-label@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-mdx-expression@2.0.3: + dependencies: + '@types/estree': 1.0.8 + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-events-to-acorn: 2.0.3 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-position-from-estree: 2.0.0 + vfile-message: 4.0.3 + + micromark-factory-space@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.2 + + micromark-factory-title@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-whitespace@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-chunked@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-classify-character@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-combine-extensions@2.0.1: + dependencies: + micromark-util-chunked: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-decode-numeric-character-reference@2.0.2: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-decode-string@2.0.1: + dependencies: + decode-named-character-reference: 1.2.0 + micromark-util-character: 2.1.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-symbol: 2.0.1 + + micromark-util-encode@2.0.1: {} + + micromark-util-events-to-acorn@2.0.3: + dependencies: + '@types/estree': 1.0.8 + '@types/unist': 3.0.3 + devlop: 1.1.0 + estree-util-visit: 2.0.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + vfile-message: 4.0.3 + + micromark-util-html-tag-name@2.0.1: {} + + micromark-util-normalize-identifier@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-resolve-all@2.0.1: + dependencies: + micromark-util-types: 2.0.2 + + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + + micromark-util-subtokenize@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-symbol@2.0.1: {} + + micromark-util-types@2.0.2: {} + + micromark@4.0.2: + dependencies: + '@types/debug': 4.1.12 + debug: 4.4.1 + decode-named-character-reference: 1.2.0 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-combine-extensions: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-encode: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + transitivePeerDependencies: + - supports-color + micromatch@4.0.8: dependencies: braces: 3.0.3 @@ -3627,10 +8196,29 @@ snapshots: dependencies: mime-db: 1.52.0 + mime@3.0.0: {} + mimic-fn@2.1.0: {} min-indent@1.0.1: {} + miniflare@3.20250718.3: + dependencies: + '@cspotcode/source-map-support': 0.8.1 + acorn: 8.14.0 + acorn-walk: 8.3.2 + exit-hook: 2.2.1 + glob-to-regexp: 0.4.1 + stoppable: 1.1.0 + undici: 5.29.0 + workerd: 1.20250718.0 + ws: 8.18.0 + youch: 3.3.4 + zod: 3.22.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + minimatch@3.1.2: dependencies: brace-expansion: 1.1.12 @@ -3639,14 +8227,67 @@ snapshots: dependencies: brace-expansion: 2.0.2 - ms@2.1.3: {} + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.2 + + monaco-editor@0.55.1: + dependencies: + dompurify: 3.2.7 + marked: 14.0.0 + + ms@2.1.3: {} + + mustache@4.2.0: {} + + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + + nanoid@3.3.11: {} natural-compare@1.4.0: {} + negotiator@1.0.0: {} + + next-themes@0.4.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + next@14.2.35(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@next/env': 14.2.35 + '@swc/helpers': 0.5.5 + busboy: 1.6.0 + caniuse-lite: 1.0.30001727 + graceful-fs: 4.2.11 + postcss: 8.4.31 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + styled-jsx: 5.1.1(react@18.3.1) + optionalDependencies: + '@next/swc-darwin-arm64': 14.2.33 + '@next/swc-darwin-x64': 14.2.33 + '@next/swc-linux-arm64-gnu': 14.2.33 + '@next/swc-linux-arm64-musl': 14.2.33 + '@next/swc-linux-x64-gnu': 14.2.33 + '@next/swc-linux-x64-musl': 14.2.33 + '@next/swc-win32-arm64-msvc': 14.2.33 + '@next/swc-win32-ia32-msvc': 14.2.33 + '@next/swc-win32-x64-msvc': 14.2.33 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + node-int64@0.4.0: {} node-releases@2.0.19: {} + node-releases@2.0.27: {} + normalize-path@3.0.0: {} npm-run-path@4.0.1: @@ -3655,6 +8296,10 @@ snapshots: nwsapi@2.2.23: {} + object-assign@4.1.1: {} + + object-hash@3.0.0: {} + object-inspect@1.13.4: {} object-is@1.1.6: @@ -3673,6 +8318,8 @@ snapshots: has-symbols: 1.1.0 object-keys: 1.1.1 + ohash@2.0.11: {} + once@1.4.0: dependencies: wrappy: 1.0.2 @@ -3681,6 +8328,12 @@ snapshots: dependencies: mimic-fn: 2.1.0 + oniguruma-to-es@3.1.1: + dependencies: + emoji-regex-xs: 1.0.0 + regex: 6.1.0 + regex-recursion: 6.0.2 + p-limit@2.3.0: dependencies: p-try: 2.2.0 @@ -3695,6 +8348,21 @@ snapshots: p-try@2.2.0: {} + package-manager-manager@0.2.0: + dependencies: + js-yaml: 4.1.1 + shellac: 0.8.0 + + parse-entities@4.0.2: + dependencies: + '@types/unist': 2.0.11 + character-entities-legacy: 3.0.0 + character-reference-invalid: 2.0.1 + decode-named-character-reference: 1.2.0 + is-alphanumerical: 2.0.1 + is-decimal: 2.0.1 + is-hexadecimal: 2.0.1 + parse-json@5.2.0: dependencies: '@babel/code-frame': 7.27.1 @@ -3714,10 +8382,20 @@ snapshots: path-parse@1.0.7: {} + path-to-regexp@6.3.0: {} + + pathe@2.0.3: {} + + pcre-to-regexp@1.1.0: {} + picocolors@1.1.1: {} picomatch@2.3.1: {} + picomatch@4.0.3: {} + + pify@2.3.0: {} + pirates@4.0.7: {} pkg-dir@4.2.0: @@ -3726,6 +8404,56 @@ snapshots: possible-typed-array-names@1.1.0: {} + postcss-import@15.1.0(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-value-parser: 4.2.0 + read-cache: 1.0.0 + resolve: 1.22.10 + + postcss-js@4.1.0(postcss@8.5.6): + dependencies: + camelcase-css: 2.0.1 + postcss: 8.5.6 + + postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.6)(tsx@4.21.0)(yaml@2.8.2): + dependencies: + lilconfig: 3.1.3 + optionalDependencies: + jiti: 1.21.7 + postcss: 8.5.6 + tsx: 4.21.0 + yaml: 2.8.2 + + postcss-nested@6.2.0(postcss@8.5.6): + dependencies: + postcss: 8.5.6 + postcss-selector-parser: 6.1.2 + + postcss-selector-parser@6.1.2: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-selector-parser@7.1.1: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-value-parser@4.2.0: {} + + postcss@8.4.31: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + postcss@8.5.6: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + pretty-format@27.5.1: dependencies: ansi-regex: 5.0.1 @@ -3738,21 +8466,33 @@ snapshots: ansi-styles: 5.2.0 react-is: 18.3.1 + printable-characters@1.0.42: {} + prompts@2.4.2: dependencies: kleur: 3.0.3 sisteransi: 1.0.5 + property-information@7.1.0: {} + psl@1.15.0: dependencies: punycode: 2.3.1 + punycode.js@2.3.1: {} + punycode@2.3.1: {} pure-rand@6.1.0: {} querystringify@2.2.0: {} + queue-microtask@1.2.3: {} + + queue@6.0.2: + dependencies: + inherits: 2.0.4 + react-dom@18.3.1(react@18.3.1): dependencies: loose-envify: 1.4.0 @@ -3763,15 +8503,96 @@ snapshots: react-is@18.3.1: {} + react-medium-image-zoom@5.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + react-remove-scroll-bar@2.3.8(@types/react@18.3.27)(react@18.3.1): + dependencies: + react: 18.3.1 + react-style-singleton: 2.2.3(@types/react@18.3.27)(react@18.3.1) + tslib: 2.8.1 + optionalDependencies: + '@types/react': 18.3.27 + + react-remove-scroll@2.7.2(@types/react@18.3.27)(react@18.3.1): + dependencies: + react: 18.3.1 + react-remove-scroll-bar: 2.3.8(@types/react@18.3.27)(react@18.3.1) + react-style-singleton: 2.2.3(@types/react@18.3.27)(react@18.3.1) + tslib: 2.8.1 + use-callback-ref: 1.3.3(@types/react@18.3.27)(react@18.3.1) + use-sidecar: 1.1.3(@types/react@18.3.27)(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.27 + + react-style-singleton@2.2.3(@types/react@18.3.27)(react@18.3.1): + dependencies: + get-nonce: 1.0.1 + react: 18.3.1 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 18.3.27 + react@18.3.1: dependencies: loose-envify: 1.4.0 + read-cache@1.0.0: + dependencies: + pify: 2.3.0 + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + readdirp@4.1.2: {} + + recma-build-jsx@1.0.0: + dependencies: + '@types/estree': 1.0.8 + estree-util-build-jsx: 3.0.1 + vfile: 6.0.3 + + recma-jsx@1.0.1(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + estree-util-to-js: 2.0.0 + recma-parse: 1.0.0 + recma-stringify: 1.0.0 + unified: 11.0.5 + + recma-parse@1.0.0: + dependencies: + '@types/estree': 1.0.8 + esast-util-from-js: 2.0.1 + unified: 11.0.5 + vfile: 6.0.3 + + recma-stringify@1.0.0: + dependencies: + '@types/estree': 1.0.8 + estree-util-to-js: 2.0.0 + unified: 11.0.5 + vfile: 6.0.3 + redent@3.0.0: dependencies: indent-string: 4.0.0 strip-indent: 3.0.0 + regex-recursion@6.0.2: + dependencies: + regex-utilities: 2.3.0 + + regex-utilities@2.3.0: {} + + regex@6.1.0: + dependencies: + regex-utilities: 2.3.0 + regexp.prototype.flags@1.5.4: dependencies: call-bind: 1.0.8 @@ -3781,6 +8602,66 @@ snapshots: gopd: 1.2.0 set-function-name: 2.0.2 + reghex@1.0.2: {} + + rehype-recma@1.0.0: + dependencies: + '@types/estree': 1.0.8 + '@types/hast': 3.0.4 + hast-util-to-estree: 3.1.3 + transitivePeerDependencies: + - supports-color + + remark-gfm@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-gfm: 3.1.0 + micromark-extension-gfm: 3.0.0 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-mdx@3.1.1: + dependencies: + mdast-util-mdx: 3.0.0 + micromark-extension-mdxjs: 3.0.0 + transitivePeerDependencies: + - supports-color + + remark-parse@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.2 + micromark-util-types: 2.0.2 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-rehype@11.1.2: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + mdast-util-to-hast: 13.2.1 + unified: 11.0.5 + vfile: 6.0.3 + + remark-stringify@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-to-markdown: 2.1.2 + unified: 11.0.5 + + remark@15.0.1: + dependencies: + '@types/mdast': 4.0.4 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + require-directory@2.1.1: {} requires-port@1.0.0: {} @@ -3791,6 +8672,8 @@ snapshots: resolve-from@5.0.0: {} + resolve-pkg-maps@1.0.0: {} + resolve.exports@2.0.3: {} resolve@1.22.10: @@ -3799,6 +8682,26 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 + reusify@1.1.0: {} + + rollup-plugin-inject@3.0.2: + dependencies: + estree-walker: 0.6.1 + magic-string: 0.25.9 + rollup-pluginutils: 2.8.2 + + rollup-plugin-node-polyfills@0.2.1: + dependencies: + rollup-plugin-inject: 3.0.2 + + rollup-pluginutils@2.8.2: + dependencies: + estree-walker: 0.6.1 + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + safe-regex-test@1.1.0: dependencies: call-bound: 1.0.4 @@ -3815,6 +8718,15 @@ snapshots: dependencies: loose-envify: 1.4.0 + scroll-into-view-if-needed@3.1.0: + dependencies: + compute-scroll-into-view: 3.1.1 + + section-matter@1.0.0: + dependencies: + extend-shallow: 2.0.1 + kind-of: 6.0.3 + semver@6.3.1: {} semver@7.7.2: {} @@ -3835,12 +8747,54 @@ snapshots: functions-have-names: 1.2.3 has-property-descriptors: 1.0.2 + sharp@0.33.5: + dependencies: + color: 4.2.3 + detect-libc: 2.1.2 + semver: 7.7.2 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.33.5 + '@img/sharp-darwin-x64': 0.33.5 + '@img/sharp-libvips-darwin-arm64': 1.0.4 + '@img/sharp-libvips-darwin-x64': 1.0.4 + '@img/sharp-libvips-linux-arm': 1.0.5 + '@img/sharp-libvips-linux-arm64': 1.0.4 + '@img/sharp-libvips-linux-s390x': 1.0.4 + '@img/sharp-libvips-linux-x64': 1.0.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + '@img/sharp-linux-arm': 0.33.5 + '@img/sharp-linux-arm64': 0.33.5 + '@img/sharp-linux-s390x': 0.33.5 + '@img/sharp-linux-x64': 0.33.5 + '@img/sharp-linuxmusl-arm64': 0.33.5 + '@img/sharp-linuxmusl-x64': 0.33.5 + '@img/sharp-wasm32': 0.33.5 + '@img/sharp-win32-ia32': 0.33.5 + '@img/sharp-win32-x64': 0.33.5 + optional: true + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 shebang-regex@3.0.0: {} + shellac@0.8.0: + dependencies: + reghex: 1.0.2 + + shiki@2.5.0: + dependencies: + '@shikijs/core': 2.5.0 + '@shikijs/engine-javascript': 2.5.0 + '@shikijs/engine-oniguruma': 2.5.0 + '@shikijs/langs': 2.5.0 + '@shikijs/themes': 2.5.0 + '@shikijs/types': 2.5.0 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + side-channel-list@1.0.0: dependencies: es-errors: 1.3.0 @@ -3871,10 +8825,17 @@ snapshots: signal-exit@3.0.7: {} + simple-swizzle@0.2.4: + dependencies: + is-arrayish: 0.3.4 + optional: true + sisteransi@1.0.5: {} slash@3.0.0: {} + source-map-js@1.2.1: {} + source-map-support@0.5.13: dependencies: buffer-from: 1.1.2 @@ -3882,17 +8843,34 @@ snapshots: source-map@0.6.1: {} + source-map@0.7.6: {} + + sourcemap-codec@1.4.8: {} + + space-separated-tokens@2.0.2: {} + sprintf-js@1.0.3: {} stack-utils@2.0.6: dependencies: escape-string-regexp: 2.0.0 + stacktracey@2.1.8: + dependencies: + as-table: 1.0.55 + get-source: 2.0.12 + + state-local@1.0.7: {} + stop-iteration-iterator@1.1.0: dependencies: es-errors: 1.3.0 internal-slot: 1.1.0 + stoppable@1.1.0: {} + + streamsearch@1.1.0: {} + string-length@4.0.2: dependencies: char-regex: 1.0.2 @@ -3904,10 +8882,17 @@ snapshots: is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 + stringify-entities@4.0.4: + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 + strip-bom-string@1.0.0: {} + strip-bom@4.0.0: {} strip-final-newline@2.0.0: {} @@ -3918,6 +8903,29 @@ snapshots: strip-json-comments@3.1.1: {} + style-to-js@1.1.21: + dependencies: + style-to-object: 1.0.14 + + style-to-object@1.0.14: + dependencies: + inline-style-parser: 0.2.7 + + styled-jsx@5.1.1(react@18.3.1): + dependencies: + client-only: 0.0.1 + react: 18.3.1 + + sucrase@3.35.1: + dependencies: + '@jridgewell/gen-mapping': 0.3.12 + commander: 4.1.1 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.7 + tinyglobby: 0.2.15 + ts-interface-checker: 0.1.13 + supports-color@7.2.0: dependencies: has-flag: 4.0.0 @@ -3930,12 +8938,55 @@ snapshots: symbol-tree@3.2.4: {} + tailwind-merge@2.6.0: {} + + tailwindcss@3.4.19(tsx@4.21.0)(yaml@2.8.2): + dependencies: + '@alloc/quick-lru': 5.2.0 + arg: 5.0.2 + chokidar: 3.6.0 + didyoumean: 1.2.2 + dlv: 1.1.3 + fast-glob: 3.3.3 + glob-parent: 6.0.2 + is-glob: 4.0.3 + jiti: 1.21.7 + lilconfig: 3.1.3 + micromatch: 4.0.8 + normalize-path: 3.0.0 + object-hash: 3.0.0 + picocolors: 1.1.1 + postcss: 8.5.6 + postcss-import: 15.1.0(postcss@8.5.6) + postcss-js: 4.1.0(postcss@8.5.6) + postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.6)(tsx@4.21.0)(yaml@2.8.2) + postcss-nested: 6.2.0(postcss@8.5.6) + postcss-selector-parser: 6.1.2 + resolve: 1.22.10 + sucrase: 3.35.1 + transitivePeerDependencies: + - tsx + - yaml + test-exclude@6.0.0: dependencies: '@istanbuljs/schema': 0.1.3 glob: 7.2.3 minimatch: 3.1.2 + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + tmpl@1.0.5: {} to-regex-range@5.0.1: @@ -3953,6 +9004,12 @@ snapshots: dependencies: punycode: 2.3.1 + trim-lines@3.0.1: {} + + trough@2.2.0: {} + + ts-interface-checker@0.1.13: {} + ts-jest@29.4.0(@babel/core@7.28.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.28.0))(jest-util@29.7.0)(jest@29.7.0(@types/node@20.19.9))(typescript@5.5.4): dependencies: bs-logger: 0.2.6 @@ -3975,6 +9032,13 @@ snapshots: tslib@2.8.1: {} + tsx@4.21.0: + dependencies: + esbuild: 0.27.2 + get-tsconfig: 4.13.0 + optionalDependencies: + fsevents: 2.3.3 + turbo-darwin-64@2.7.3: optional: true @@ -4008,10 +9072,76 @@ snapshots: type-fest@4.41.0: {} + typedoc-plugin-markdown@4.9.0(typedoc@0.28.16(typescript@5.5.4)): + dependencies: + typedoc: 0.28.16(typescript@5.5.4) + + typedoc@0.28.16(typescript@5.5.4): + dependencies: + '@gerrit0/mini-shiki': 3.21.0 + lunr: 2.3.9 + markdown-it: 14.1.0 + minimatch: 9.0.5 + typescript: 5.5.4 + yaml: 2.8.2 + typescript@5.5.4: {} + uc.micro@2.1.0: {} + + ufo@1.6.2: {} + undici-types@6.21.0: {} + undici@5.29.0: + dependencies: + '@fastify/busboy': 2.1.1 + + unenv@2.0.0-rc.14: + dependencies: + defu: 6.1.4 + exsolve: 1.0.8 + ohash: 2.0.11 + pathe: 2.0.3 + ufo: 1.6.2 + + unified@11.0.5: + dependencies: + '@types/unist': 3.0.3 + bail: 2.0.2 + devlop: 1.1.0 + extend: 3.0.2 + is-plain-obj: 4.1.0 + trough: 2.2.0 + vfile: 6.0.3 + + unist-util-is@6.0.1: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position-from-estree@2.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-parents@6.0.2: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + + unist-util-visit@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + universalify@0.2.0: {} update-browserslist-db@1.1.3(browserslist@4.25.1): @@ -4020,17 +9150,50 @@ snapshots: escalade: 3.2.0 picocolors: 1.1.1 + update-browserslist-db@1.2.3(browserslist@4.28.1): + dependencies: + browserslist: 4.28.1 + escalade: 3.2.0 + picocolors: 1.1.1 + url-parse@1.5.10: dependencies: querystringify: 2.2.0 requires-port: 1.0.0 + use-callback-ref@1.3.3(@types/react@18.3.27)(react@18.3.1): + dependencies: + react: 18.3.1 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 18.3.27 + + use-sidecar@1.1.3(@types/react@18.3.27)(react@18.3.1): + dependencies: + detect-node-es: 1.1.0 + react: 18.3.1 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 18.3.27 + + util-deprecate@1.0.2: {} + v8-to-istanbul@9.3.0: dependencies: '@jridgewell/trace-mapping': 0.3.29 '@types/istanbul-lib-coverage': 2.0.6 convert-source-map: 2.0.0 + vfile-message@4.0.3: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.3 + w3c-xmlserializer@4.0.0: dependencies: xml-name-validator: 4.0.0 @@ -4081,6 +9244,33 @@ snapshots: dependencies: isexe: 2.0.0 + workerd@1.20250718.0: + optionalDependencies: + '@cloudflare/workerd-darwin-64': 1.20250718.0 + '@cloudflare/workerd-darwin-arm64': 1.20250718.0 + '@cloudflare/workerd-linux-64': 1.20250718.0 + '@cloudflare/workerd-linux-arm64': 1.20250718.0 + '@cloudflare/workerd-windows-64': 1.20250718.0 + + wrangler@3.114.16: + dependencies: + '@cloudflare/kv-asset-handler': 0.3.4 + '@cloudflare/unenv-preset': 2.0.2(unenv@2.0.0-rc.14)(workerd@1.20250718.0) + '@esbuild-plugins/node-globals-polyfill': 0.2.3(esbuild@0.17.19) + '@esbuild-plugins/node-modules-polyfill': 0.2.2(esbuild@0.17.19) + blake3-wasm: 2.1.5 + esbuild: 0.17.19 + miniflare: 3.20250718.3 + path-to-regexp: 6.3.0 + unenv: 2.0.0-rc.14 + workerd: 1.20250718.0 + optionalDependencies: + fsevents: 2.3.3 + sharp: 0.33.5 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 @@ -4094,6 +9284,8 @@ snapshots: imurmurhash: 0.1.4 signal-exit: 3.0.7 + ws@8.18.0: {} + ws@8.19.0: {} xml-name-validator@4.0.0: {} @@ -4104,6 +9296,8 @@ snapshots: yallist@3.1.1: {} + yaml@2.8.2: {} + yargs-parser@21.1.1: {} yargs@17.7.2: @@ -4118,4 +9312,16 @@ snapshots: yocto-queue@0.1.0: {} + youch@3.3.4: + dependencies: + cookie: 0.7.2 + mustache: 4.2.0 + stacktracey: 2.1.8 + + zod@3.22.3: {} + + zod@3.25.76: {} + zod@4.3.5: {} + + zwitch@2.0.4: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 18ec407..4e708bd 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,2 +1,3 @@ packages: - 'packages/*' + - 'apps/*'