diff --git a/.github/workflows/ci-lib.yaml b/.github/workflows/ci-lib.yaml new file mode 100644 index 00000000..4447448d --- /dev/null +++ b/.github/workflows/ci-lib.yaml @@ -0,0 +1,39 @@ +name: CI - Lib + +on: + pull_request: + push: + branches: + - main + +jobs: + ci-lib: + runs-on: ubuntu-latest + defaults: + run: + working-directory: packages/lib + + steps: + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4 + - run: corepack enable + - uses: actions/setup-node@v4 + with: + node-version: 22 + corepack: true + cache: 'pnpm' + + - name: Install dependencies + run: pnpm i + working-directory: ./ + + - name: Run linters + run: pnpm lint + + # - name: Type check + # run: pnpm typecheck + + - name: Run unit test + run: pnpm test + + - name: Build the lib + run: pnpm build diff --git a/packages/app-client/.nvmrc b/packages/app-client/.nvmrc deleted file mode 120000 index 56976b9a..00000000 --- a/packages/app-client/.nvmrc +++ /dev/null @@ -1 +0,0 @@ -.nvmrc \ No newline at end of file diff --git a/packages/app-client/package.json b/packages/app-client/package.json index 7e128692..a8a72bb1 100644 --- a/packages/app-client/package.json +++ b/packages/app-client/package.json @@ -26,6 +26,7 @@ "typecheck": "tsc --noEmit" }, "dependencies": { + "@enclosed/lib": "workspace:*", "@kobalte/core": "^0.13.4", "@solidjs/router": "^0.14.3", "@unocss/reset": "^0.62.2", diff --git a/packages/app-client/src/modules/notes/components/note-password-field.tsx b/packages/app-client/src/modules/notes/components/note-password-field.tsx index 29f689af..6e3d193e 100644 --- a/packages/app-client/src/modules/notes/components/note-password-field.tsx +++ b/packages/app-client/src/modules/notes/components/note-password-field.tsx @@ -1,13 +1,13 @@ import { type Component, createSignal } from 'solid-js'; +import { createRandomPassword } from '../notes.models'; import { TextField } from '@/modules/ui/components/textfield'; import { Button } from '@/modules/ui/components/button'; -import { createRandomString } from '@/modules/shared/random/random'; export const NotePasswordField: Component<{ getPassword: () => string; setPassword: (value: string) => void }> = (props) => { const [getShowPassword, setShowPassword] = createSignal(false); const generateRandomPassword = () => { - const password = createRandomString({ length: 16 }); + const password = createRandomPassword({ length: 16 }); setShowPassword(true); props.setPassword(password); diff --git a/packages/app-client/src/modules/notes/notes.models.ts b/packages/app-client/src/modules/notes/notes.models.ts index d5efceda..7986ca51 100644 --- a/packages/app-client/src/modules/notes/notes.models.ts +++ b/packages/app-client/src/modules/notes/notes.models.ts @@ -1,41 +1,13 @@ -import { createBuffer, mergeBuffers } from '../shared/crypto/buffer'; -import { aesDecrypt, aesEncrypt, deriveKey } from '../shared/crypto/encryption'; +import _ from 'lodash-es'; -export { encryptNoteContent, decryptNoteContent, createNoteUrl, deriveMasterKey }; +export { createRandomPassword }; -function createBufferFromPassword({ password }: { password?: string }) { - if (!password) { - return new Uint8Array(0); - } +function createRandomPassword({ length = 16 }: { length?: number } = {}): string { + const alphabet = 'abcdefghijklmnopqrstuvwxyz'; + const numbers = '0123456789'; + const specialChars = '!@#$%^&*()_+'; - return new TextEncoder().encode(password); -} - -async function encryptNoteContent({ content, masterKey }: { content: string; masterKey: Uint8Array }) { - const contentBuffer = createBuffer({ value: content }); - const encryptedContent = await aesEncrypt({ data: contentBuffer, key: masterKey }); - - return encryptedContent; -} - -async function decryptNoteContent({ encryptedContent, masterKey }: { encryptedContent: string; masterKey: Uint8Array }) { - const decryptedContent = await aesDecrypt({ data: encryptedContent, key: masterKey }); - - return decryptedContent; -} - -function createNoteUrl({ noteId, encryptionKey }: { noteId: string; encryptionKey: string }): { noteUrl: string } { - const url = new URL(`/${noteId}`, window.location.origin); - url.hash = encryptionKey; - - const noteUrl = url.toString(); - - return { noteUrl }; -} - -function deriveMasterKey({ baseKey, password }: { baseKey: Uint8Array; password?: string }) { - const passwordBuffer = createBufferFromPassword({ password }); - const mergedBuffers = mergeBuffers(baseKey, passwordBuffer); + const corpus = alphabet + alphabet.toUpperCase() + numbers + specialChars; - return deriveKey({ key: mergedBuffers }); + return _.times(length, () => _.sample(corpus)).join(''); } diff --git a/packages/app-client/src/modules/notes/notes.services.ts b/packages/app-client/src/modules/notes/notes.services.ts index 7b4e9a02..517643cf 100644 --- a/packages/app-client/src/modules/notes/notes.services.ts +++ b/packages/app-client/src/modules/notes/notes.services.ts @@ -1,8 +1,8 @@ import { apiClient } from '../shared/http/http-client'; -export { createNote, fetchNoteById }; +export { storeNote, fetchNoteById }; -async function createNote({ content, isPasswordProtected, ttlInSeconds, deleteAfterReading }: { content: string; isPasswordProtected: boolean; ttlInSeconds: number; deleteAfterReading: boolean }) { +async function storeNote({ content, isPasswordProtected, ttlInSeconds, deleteAfterReading }: { content: string; isPasswordProtected: boolean; ttlInSeconds: number; deleteAfterReading: boolean }) { const { noteId } = await apiClient<{ noteId: string }>({ path: '/api/notes', method: 'POST', diff --git a/packages/app-client/src/modules/notes/notes.usecases.ts b/packages/app-client/src/modules/notes/notes.usecases.ts index 12a589aa..b95f544e 100644 --- a/packages/app-client/src/modules/notes/notes.usecases.ts +++ b/packages/app-client/src/modules/notes/notes.usecases.ts @@ -1,54 +1,17 @@ -import { base64UrlToBuffer, bufferToBase64Url } from '../shared/crypto/buffer'; -import { createRandomBuffer } from '../shared/random/random'; -import { createNoteUrl, decryptNoteContent, deriveMasterKey, encryptNoteContent } from './notes.models'; -import { createNote } from './notes.services'; +import { createNote } from '@enclosed/lib'; +import { storeNote } from './notes.services'; -export { encryptAndCreateNote, decryptNote, encryptNote }; +export { encryptAndCreateNote }; -async function encryptAndCreateNote({ - content, - password, - ttlInSeconds, - deleteAfterReading, - storeNote = createNote, -}: { +async function encryptAndCreateNote(args: { content: string; password?: string; ttlInSeconds: number; deleteAfterReading: boolean; - storeNote?: (params: { content: string; isPasswordProtected: boolean; ttlInSeconds: number; deleteAfterReading: boolean }) => Promise<{ noteId: string }>; }) { - const { encryptedContent, encryptionKey } = await encryptNote({ content, password }); - - // Send the encrypted note to the server for storage, the server has no knowledge of the encryption key - const { noteId } = await storeNote({ content: encryptedContent, isPasswordProtected: Boolean(password), ttlInSeconds, deleteAfterReading }); - - // The base key is stored in the URL hash fragment - const { noteUrl } = createNoteUrl({ noteId, encryptionKey }); - - return { encryptedContent, noteId, encryptionKey, noteUrl }; -} - -async function encryptNote({ content, password }: { content: string; password?: string }) { - // The base key ensure e2e encryption even if the user does not provide a password - const baseKey = createRandomBuffer({ length: 32 }); - - // If the user provides a password, we derive a master key from the base key and the password using PBKDF2 - const masterKey = await deriveMasterKey({ baseKey, password }); - - const encryptedContent = await encryptNoteContent({ content, masterKey }); - - const encryptionKey = bufferToBase64Url({ buffer: baseKey }); - - return { encryptedContent, encryptionKey }; -} - -async function decryptNote({ encryptedContent, password, encryptionKey }: { encryptedContent: string; password?: string; encryptionKey: string }) { - const baseKey = base64UrlToBuffer({ base64Url: encryptionKey }); - - const masterKey = await deriveMasterKey({ baseKey, password }); - - const decryptedContent = await decryptNoteContent({ encryptedContent, masterKey }); - - return { decryptedContent }; + return createNote({ + ...args, + storeNote, + clientBaseUrl: window.location.origin, + }); } diff --git a/packages/app-client/src/modules/notes/pages/view-note.page.tsx b/packages/app-client/src/modules/notes/pages/view-note.page.tsx index b5b6f212..d21ddfd2 100644 --- a/packages/app-client/src/modules/notes/pages/view-note.page.tsx +++ b/packages/app-client/src/modules/notes/pages/view-note.page.tsx @@ -1,7 +1,7 @@ import { useLocation, useParams } from '@solidjs/router'; import { type Component, Match, Show, Switch, createSignal, onMount } from 'solid-js'; +import { decryptNote } from '@enclosed/lib'; import { fetchNoteById } from '../notes.services'; -import { decryptNote } from '../notes.usecases'; import { TextField, TextFieldLabel, TextFieldRoot } from '@/modules/ui/components/textfield'; import { Card, CardContent, CardDescription, CardHeader } from '@/modules/ui/components/card'; import { Button } from '@/modules/ui/components/button'; diff --git a/packages/app-client/src/modules/shared/crypto/buffer.ts b/packages/app-client/src/modules/shared/crypto/buffer.ts deleted file mode 100644 index 278639d2..00000000 --- a/packages/app-client/src/modules/shared/crypto/buffer.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { trimEnd } from 'lodash-es'; - -export { createRandomBuffer, mergeBuffers, createBuffer, bufferToBase64Url, base64UrlToBuffer }; - -function createRandomBuffer({ length = 16 }: { length?: number } = {}): Uint8Array { - const randomValues = new Uint8Array(length); - crypto.getRandomValues(randomValues); - - return randomValues; -} - -function mergeBuffers(...buffers: Uint8Array[]): Uint8Array { - const totalLength = buffers.reduce((acc, buffer) => acc + buffer.length, 0); - const mergedBuffer = new Uint8Array(totalLength); - - let offset = 0; - buffers.forEach((buffer) => { - mergedBuffer.set(buffer, offset); - offset += buffer.length; - }); - - return mergedBuffer; -} - -function createBuffer({ value }: { value: string }): Uint8Array { - return new TextEncoder().encode(value); -} - -function bufferToBase64Url({ buffer }: { buffer: Uint8Array }): string { - const base64 = btoa(String.fromCharCode(...buffer)); - const base64Url = trimEnd(base64, '=') - .replace(/\+/g, '-') - .replace(/\//g, '_'); - - return base64Url; -} - -function base64UrlToBuffer({ base64Url }: { base64Url: string }): Uint8Array { - const base64 = base64Url - .padEnd(base64Url.length + (4 - base64Url.length % 4) % 4, '=') - .replace(/-/g, '+') - .replace(/_/g, '/'); - - const buffer = new Uint8Array(atob(base64).split('').map(char => char.charCodeAt(0))); - - return buffer; -} diff --git a/packages/app-client/src/modules/shared/crypto/encryption.ts b/packages/app-client/src/modules/shared/crypto/encryption.ts deleted file mode 100644 index da77ede2..00000000 --- a/packages/app-client/src/modules/shared/crypto/encryption.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { base64UrlToBuffer, bufferToBase64Url, createRandomBuffer } from './buffer'; - -export { aesEncrypt, aesDecrypt, deriveKey }; - -async function aesEncrypt({ data, key: rawKey }: { data: Uint8Array; key: Uint8Array }): Promise { - const iv = createRandomBuffer({ length: 12 }); - - const key = await crypto.subtle.importKey('raw', rawKey, 'AES-GCM', false, ['encrypt']); - const encrypted = await crypto.subtle.encrypt({ name: 'AES-GCM', iv }, key, data); - - const ivString = bufferToBase64Url({ buffer: iv }); - const encryptedString = bufferToBase64Url({ buffer: new Uint8Array(encrypted) }); - - return `${ivString}:${encryptedString}`; -} - -async function aesDecrypt({ data, key: rawKey }: { data: string; key: Uint8Array }): Promise { - const [ivString, encryptedString] = data.split(':').map(part => part.trim()); - - if (!ivString || !encryptedString) { - throw new Error('Invalid data'); - } - - const iv = base64UrlToBuffer({ base64Url: ivString }); - const encrypted = base64UrlToBuffer({ base64Url: encryptedString }); - - const key = await crypto.subtle.importKey('raw', rawKey, 'AES-GCM', false, ['decrypt']); - const decrypted = await crypto.subtle.decrypt({ name: 'AES-GCM', iv }, key, encrypted); - - return new TextDecoder().decode(decrypted); -} - -async function deriveKey({ key: originalKey, iterations = 100_000 }: { key: Uint8Array; iterations?: number }): Promise { - // The salt is deterministically derived from the key - const saltHash = await crypto.subtle.digest('SHA-256', originalKey); - const salt = new Uint8Array(saltHash).slice(0, 16); - - const key = await crypto.subtle.importKey('raw', originalKey, 'PBKDF2', false, ['deriveKey']); - - const derivedKey = await crypto.subtle.deriveKey( - { - name: 'PBKDF2', - salt, - iterations, - hash: 'SHA-256', - }, - key, - { name: 'AES-GCM', length: 256 }, - true, // Extractable - ['encrypt', 'decrypt'], - ); - - const exportedKey = await crypto.subtle.exportKey('raw', derivedKey); - - return new Uint8Array(exportedKey); -} diff --git a/packages/app-client/src/modules/shared/random/random.ts b/packages/app-client/src/modules/shared/random/random.ts deleted file mode 100644 index e0cdf063..00000000 --- a/packages/app-client/src/modules/shared/random/random.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { bufferToBase64Url } from '../crypto/buffer'; - -export { createRandomString, createRandomBuffer }; - -function createRandomBuffer({ length = 16 }: { length?: number } = {}): Uint8Array { - const randomValues = new Uint8Array(length); - crypto.getRandomValues(randomValues); - - return randomValues; -} - -function createRandomString({ length = 16 }: { length?: number } = {}): string { - const bufferLength = Math.ceil((length * 3) / 4); - const randomValues = createRandomBuffer({ length: bufferLength }); - return bufferToBase64Url({ buffer: randomValues }); -} diff --git a/packages/lib/build.config.ts b/packages/lib/build.config.ts new file mode 100644 index 00000000..5eb30780 --- /dev/null +++ b/packages/lib/build.config.ts @@ -0,0 +1,14 @@ +import { defineBuildConfig } from 'unbuild'; + +export default defineBuildConfig({ + entries: [ + 'src/index.node', + 'src/index.web', + ], + + declaration: true, + sourcemap: true, + rollup: { + emitCJS: true, + }, +}); diff --git a/packages/lib/eslint.config.js b/packages/lib/eslint.config.js new file mode 100644 index 00000000..e0175daf --- /dev/null +++ b/packages/lib/eslint.config.js @@ -0,0 +1,21 @@ +import antfu from '@antfu/eslint-config'; + +export default antfu({ + stylistic: { + semi: true, + }, + + rules: { + // To allow export on top of files + 'ts/no-use-before-define': ['error', { allowNamedExports: true, functions: false }], + 'curly': ['error', 'all'], + 'vitest/consistent-test-it': ['error', { fn: 'test' }], + 'ts/consistent-type-definitions': ['error', 'type'], + 'style/brace-style': ['error', '1tbs', { allowSingleLine: false }], + 'unused-imports/no-unused-vars': ['error', { + argsIgnorePattern: '^_', + varsIgnorePattern: '^_', + caughtErrorsIgnorePattern: '^_', + }], + }, +}); diff --git a/packages/lib/package.json b/packages/lib/package.json new file mode 100644 index 00000000..dd0ccb95 --- /dev/null +++ b/packages/lib/package.json @@ -0,0 +1,88 @@ +{ + "name": "@enclosed/lib", + "type": "module", + "version": "0.0.0", + "packageManager": "pnpm@9.9.0", + "description": "Enclosed lib to create secure notes.", + "author": "Corentin Thomasset (https://corentin.tech)", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/CorentinTh/enclosed" + }, + "exports": { + "./package.json": "./package.json", + ".": { + "browser": "./dist/index.web.mjs", + "bun": "./dist/index.web.mjs", + "deno": "./dist/index.web.mjs", + "edge-light": "./dist/index.web.mjs", + "edge-routine": "./dist/index.web.mjs", + "netlify": "./dist/index.web.mjs", + "react-native": "./dist/index.web.mjs", + "wintercg": "./dist/index.web.mjs", + "worker": "./dist/index.web.mjs", + "workerd": "./dist/index.web.mjs", + "node": { + "import": { + "types": "./dist/index.node.d.mts", + "default": "./dist/index.node.mjs" + }, + "require": { + "types": "./dist/index.node.d.cts", + "default": "./dist/index.node.cjs" + } + }, + "types": "./dist/index.web.d.mts", + "import": { + "types": "./dist/index.web.d.mts", + "default": "./dist/index.web.mjs" + }, + "require": { + "types": "./dist/index.node.d.cts", + "default": "./dist/index.node.cjs" + }, + "default": "./dist/index.web.mjs" + }, + "./node": { + "import": { + "types": "./dist/index.node.d.mts", + "default": "./dist/index.node.mjs" + }, + "require": { + "types": "./dist/index.node.d.cts", + "default": "./dist/index.node.cjs" + } + } + }, + "main": "./dist/index.node.cjs", + "module": "./dist/index.web.mjs", + "types": "./dist/index.web.d.ts", + "files": ["dist"], + "engines": { + "node": ">=22.0.0" + }, + "react-native": "./dist/index.web.mjs", + "scripts": { + "prepare": "pnpm run build", + "build": "unbuild", + "lint": "eslint .", + "lint:fix": "eslint --fix .", + "test": "pnpm run test:unit", + "test:unit": "vitest run", + "test:unit:watch": "vitest watch", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "ofetch": "^1.3.4" + }, + "devDependencies": { + "@antfu/eslint-config": "^2.27.0", + "@vitest/coverage-v8": "^2.0.5", + "dotenv": "^16.4.5", + "eslint": "^9.9.0", + "typescript": "^5.5.4", + "unbuild": "^2.0.0", + "vitest": "^2.0.5" + } +} diff --git a/packages/lib/src/crypto/crypto.types.ts b/packages/lib/src/crypto/crypto.types.ts new file mode 100644 index 00000000..dd6d76e4 --- /dev/null +++ b/packages/lib/src/crypto/crypto.types.ts @@ -0,0 +1,3 @@ +export type CryptoServices = { + encryptNote: (args: { content: string; password?: string }) => Promise<{ encryptedContent: string; encryptionKey: string }>; +}; diff --git a/packages/app-client/src/modules/notes/notes.usecases.test.ts b/packages/lib/src/crypto/crypto.usecases.test.ts similarity index 59% rename from packages/app-client/src/modules/notes/notes.usecases.test.ts rename to packages/lib/src/crypto/crypto.usecases.test.ts index 49bcfb30..a306b9f6 100644 --- a/packages/app-client/src/modules/notes/notes.usecases.test.ts +++ b/packages/lib/src/crypto/crypto.usecases.test.ts @@ -1,7 +1,17 @@ import { describe, expect, test } from 'vitest'; -import { decryptNote, encryptNote } from './notes.usecases'; - -describe('notes usecases', () => { +import { createDecryptUsecase, createEncryptUsecase } from './crypto.usecases'; +import * as nodeCryptoLib from './node/crypto.node.usecases'; +import * as webCryptoLib from './web/crypto.web.usecases'; + +export { runCommonCryptoUsecasesTests }; + +function runCommonCryptoUsecasesTests({ + encryptNote, + decryptNote, +}: { + encryptNote: (args: { content: string; password?: string }) => Promise<{ encryptedContent: string; encryptionKey: string }>; + decryptNote: (args: { encryptedContent: string; password?: string; encryptionKey: string }) => Promise<{ decryptedContent: string }>; +}) { describe('encryption and decryption', () => { describe('without password', () => { test('a note can be decrypted with the same key used for encryption', async () => { @@ -62,6 +72,23 @@ describe('notes usecases', () => { }), ).rejects.toThrow(); }); + + test('an empty string as a password is the same as no password', async () => { + const content = 'Hello, world!'; + + const { encryptedContent, encryptionKey } = await encryptNote({ + content, + password: '', + }); + + const { decryptedContent } = await decryptNote({ + encryptedContent, + encryptionKey, + password: '', + }); + + expect(decryptedContent).toBe(content); + }); }); describe('with password', () => { @@ -153,5 +180,71 @@ describe('notes usecases', () => { ).rejects.toThrow(); }); }); + + test('if the encrypted content does not include the iv, the note cannot be decrypted', async () => { + const content = 'Hello, world!'; + const password = 'password'; + + const { encryptedContent, encryptionKey } = await encryptNote({ + content, + password, + }); + + const [_ivString, encryptedStringWithAuthTag] = encryptedContent.split(':').map(part => part.trim()); + + const encryptedContentWithoutIv = encryptedStringWithAuthTag; + + expect( + decryptNote({ + encryptedContent: encryptedContentWithoutIv, + encryptionKey, + password, + }), + ).rejects.toThrow(); + }); + }); +} + +describe('cross-environment encryption and decryption', () => { + test('a note encrypted in the web environment can be decrypted in the node environment', async () => { + const content = 'Hello, world!'; + const password = 'password'; + + const { encryptNote } = createEncryptUsecase(webCryptoLib); + const { decryptNote } = createDecryptUsecase(nodeCryptoLib); + + const { encryptedContent, encryptionKey } = await encryptNote({ + content, + password, + }); + + const { decryptedContent } = await decryptNote({ + encryptedContent, + encryptionKey, + password, + }); + + expect(decryptedContent).toBe(content); + }); + + test('a note encrypted in the node environment can be decrypted in the web environment', async () => { + const content = 'Hello, world!'; + const password = 'password'; + + const { encryptNote } = createEncryptUsecase(nodeCryptoLib); + const { decryptNote } = createDecryptUsecase(webCryptoLib); + + const { encryptedContent, encryptionKey } = await encryptNote({ + content, + password, + }); + + const { decryptedContent } = await decryptNote({ + encryptedContent, + encryptionKey, + password, + }); + + expect(decryptedContent).toBe(content); }); }); diff --git a/packages/lib/src/crypto/crypto.usecases.ts b/packages/lib/src/crypto/crypto.usecases.ts new file mode 100644 index 00000000..3a94e877 --- /dev/null +++ b/packages/lib/src/crypto/crypto.usecases.ts @@ -0,0 +1,47 @@ +import { base64UrlToBuffer, bufferToBase64Url } from './web/crypto.web.models'; + +export { createEncryptUsecase, createDecryptUsecase }; + +function createEncryptUsecase({ + generateBaseKey, + deriveMasterKey, + encryptNoteContent, +}: { + generateBaseKey: () => { baseKey: Uint8Array }; + deriveMasterKey: ({ baseKey, password }: { baseKey: Uint8Array; password?: string }) => Promise<{ masterKey: Uint8Array }>; + encryptNoteContent: ({ content, masterKey }: { content: string; masterKey: Uint8Array }) => Promise<{ encryptedContent: string }>; +}) { + return { + encryptNote: async ({ content, password }: { content: string; password?: string }) => { + const { baseKey } = generateBaseKey(); + + const { masterKey } = await deriveMasterKey({ baseKey, password }); + + const { encryptedContent } = await encryptNoteContent({ content, masterKey }); + + const encryptionKey = bufferToBase64Url({ buffer: baseKey }); + + return { encryptedContent, encryptionKey }; + }, + }; +} + +function createDecryptUsecase({ + deriveMasterKey, + decryptNoteContent, +}: { + deriveMasterKey: ({ baseKey, password }: { baseKey: Uint8Array; password?: string }) => Promise<{ masterKey: Uint8Array }>; + decryptNoteContent: ({ encryptedContent, masterKey }: { encryptedContent: string; masterKey: Uint8Array }) => Promise<{ decryptedContent: string }>; +}) { + return { + decryptNote: async ({ encryptedContent, password, encryptionKey }: { encryptedContent: string; password?: string; encryptionKey: string }) => { + const baseKey = base64UrlToBuffer({ base64Url: encryptionKey }); + + const { masterKey } = await deriveMasterKey({ baseKey, password }); + + const { decryptedContent } = await decryptNoteContent({ encryptedContent, masterKey }); + + return { decryptedContent }; + }, + }; +} diff --git a/packages/lib/src/crypto/node/crypto.node.models.test.ts b/packages/lib/src/crypto/node/crypto.node.models.test.ts new file mode 100644 index 00000000..71060393 --- /dev/null +++ b/packages/lib/src/crypto/node/crypto.node.models.test.ts @@ -0,0 +1,37 @@ +import { describe, expect, test } from 'vitest'; +import { base64UrlToBuffer, bufferToBase64Url } from './crypto.node.models'; + +describe('crypto node models', () => { + describe('bufferToBase64Url', () => { + test('an 8-bit buffer is converted to a base64url string (no "+", "/", or "=")', () => { + const buffer = new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); + const base64Url = bufferToBase64Url({ buffer }); + + expect(base64Url).toBe('AAECAwQFBgcICQ'); + }); + + test('the trailing "=" characters are removed from the base64url string', () => { + // "a" char is encoded as "YQ==" in regular base64 + const buffer = new Uint8Array([97]); + const base64Url = bufferToBase64Url({ buffer }); + + expect(base64Url).toBe('YQ'); + }); + + test('the "+" characters are replaced with "-" in the base64url string and the "/" characters are replaced with "_"', () => { + // this buffer translate to An1aThIn/OeGWQUn+e4o2nEXvdtEagY2lJxCQN1SgKc= in regular base64 + const buffer = new Uint8Array([2, 125, 90, 78, 18, 39, 252, 231, 134, 89, 5, 39, 249, 238, 40, 218, 113, 23, 189, 219, 68, 106, 6, 54, 148, 156, 66, 64, 221, 82, 128, 167]); + + const base64Url = bufferToBase64Url({ buffer }); + + expect(base64Url).toBe('An1aThIn_OeGWQUn-e4o2nEXvdtEagY2lJxCQN1SgKc'); + }); + }); + + describe('base64UrlToBuffer', () => { + test('a base64url string is converted to an 8-bit buffer', () => { + expect(base64UrlToBuffer({ base64Url: 'AAECAwQFBgcICQ' })).to.eql(new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])); + expect(base64UrlToBuffer({ base64Url: 'An1aThIn_OeGWQUn-e4o2nEXvdtEagY2lJxCQN1SgKc' })).to.eql(new Uint8Array([2, 125, 90, 78, 18, 39, 252, 231, 134, 89, 5, 39, 249, 238, 40, 218, 113, 23, 189, 219, 68, 106, 6, 54, 148, 156, 66, 64, 221, 82, 128, 167])); + }); + }); +}); diff --git a/packages/lib/src/crypto/node/crypto.node.models.ts b/packages/lib/src/crypto/node/crypto.node.models.ts new file mode 100644 index 00000000..79bcc1f7 --- /dev/null +++ b/packages/lib/src/crypto/node/crypto.node.models.ts @@ -0,0 +1,15 @@ +import { Buffer } from 'node:buffer'; + +export { bufferToBase64Url, base64UrlToBuffer }; + +function bufferToBase64Url({ buffer }: { buffer: Uint8Array }): string { + const base64Url = Buffer.from(buffer).toString('base64url'); + + return base64Url; +} + +function base64UrlToBuffer({ base64Url }: { base64Url: string }): Uint8Array { + const buffer = Buffer.from(base64Url, 'base64url'); + + return new Uint8Array(buffer); +} diff --git a/packages/lib/src/crypto/node/crypto.node.usecases.test.ts b/packages/lib/src/crypto/node/crypto.node.usecases.test.ts new file mode 100644 index 00000000..c08e397f --- /dev/null +++ b/packages/lib/src/crypto/node/crypto.node.usecases.test.ts @@ -0,0 +1,14 @@ +import { describe } from 'vitest'; +import { runCommonCryptoUsecasesTests } from '../crypto.usecases.test'; +import { createDecryptUsecase, createEncryptUsecase } from '../crypto.usecases'; + +import * as nodeCryptoLib from './crypto.node.usecases'; + +describe('crypto usecases', () => { + describe('node', () => { + runCommonCryptoUsecasesTests({ + ...createEncryptUsecase({ ...nodeCryptoLib }), + ...createDecryptUsecase({ ...nodeCryptoLib }), + }); + }); +}); diff --git a/packages/lib/src/crypto/node/crypto.node.usecases.ts b/packages/lib/src/crypto/node/crypto.node.usecases.ts new file mode 100644 index 00000000..a991c3e6 --- /dev/null +++ b/packages/lib/src/crypto/node/crypto.node.usecases.ts @@ -0,0 +1,66 @@ +import { createCipheriv, createDecipheriv, pbkdf2, randomBytes } from 'node:crypto'; +import { TextEncoder, promisify } from 'node:util'; +import { base64UrlToBuffer, bufferToBase64Url } from './crypto.node.models'; + +export { generateBaseKey, deriveMasterKey, encryptNoteContent, decryptNoteContent }; + +const deriveWithPbkdf2 = promisify(pbkdf2); + +function generateBaseKey(): { baseKey: Uint8Array } { + return { baseKey: createRandomBuffer({ length: 32 }) }; +} + +function createRandomBuffer({ length = 16 }: { length?: number } = {}): Uint8Array { + const randomValues = randomBytes(length); + + return randomValues; +} + +async function deriveMasterKey({ baseKey, password = '' }: { baseKey: Uint8Array; password?: string }): Promise<{ masterKey: Uint8Array }> { + const passwordBuffer = new TextEncoder().encode(password); + const mergedBuffers = new Uint8Array([...baseKey, ...passwordBuffer]); + + const masterKey = await deriveWithPbkdf2(mergedBuffers, baseKey, 100_000, 32, 'sha256'); + + return { + masterKey, + }; +} + +async function encryptNoteContent({ content, masterKey }: { content: string; masterKey: Uint8Array }) { + const iv = createRandomBuffer({ length: 12 }); + + const cipher = createCipheriv('aes-256-gcm', masterKey, iv); + + const encryptedBuffer = new Uint8Array([...cipher.update(content), ...cipher.final(), ...cipher.getAuthTag()]); + const encrypted = bufferToBase64Url({ buffer: encryptedBuffer }); + + return { + encryptedContent: `${bufferToBase64Url({ buffer: iv })}:${encrypted}`, + }; +} + +async function decryptNoteContent({ encryptedContent, masterKey }: { encryptedContent: string; masterKey: Uint8Array }) { + const [ivString, encryptedStringWithAuthTag] = encryptedContent.split(':').map(part => part.trim()); + + if (!ivString || !encryptedStringWithAuthTag) { + throw new Error('Invalid encrypted content'); + } + + const iv = base64UrlToBuffer({ base64Url: ivString }); + const encryptedContentAndTagBuffer = base64UrlToBuffer({ base64Url: encryptedStringWithAuthTag }); + + const encryptedBuffer = encryptedContentAndTagBuffer.slice(0, -16); + const authTag = encryptedContentAndTagBuffer.slice(-16); + + const decipher = createDecipheriv('aes-256-gcm', masterKey, iv); + decipher.setAuthTag(authTag); + + const decryptedBuffer = new Uint8Array([...decipher.update(encryptedBuffer), ...decipher.final()]); + + const decryptedContent = new TextDecoder().decode(decryptedBuffer); + + return { + decryptedContent, + }; +} diff --git a/packages/app-client/src/modules/shared/crypto/buffer.test.ts b/packages/lib/src/crypto/web/crypto.web.models.test.ts similarity index 73% rename from packages/app-client/src/modules/shared/crypto/buffer.test.ts rename to packages/lib/src/crypto/web/crypto.web.models.test.ts index adf1dad6..b1665e98 100644 --- a/packages/app-client/src/modules/shared/crypto/buffer.test.ts +++ b/packages/lib/src/crypto/web/crypto.web.models.test.ts @@ -1,7 +1,7 @@ import { describe, expect, test } from 'vitest'; -import { base64UrlToBuffer, bufferToBase64Url } from './buffer'; +import { base64UrlToBuffer, bufferToBase64Url } from './crypto.web.models'; -describe('buffer', () => { +describe('crypto models', () => { describe('bufferToBase64Url', () => { test('an 8-bit buffer is converted to a base64url string (no "+", "/", or "=")', () => { const buffer = new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); @@ -30,10 +30,8 @@ describe('buffer', () => { describe('base64UrlToBuffer', () => { test('a base64url string is converted to an 8-bit buffer', () => { - const base64Url = 'AAECAwQFBgcICQ'; - const buffer = base64UrlToBuffer({ base64Url }); - - expect(buffer).toEqual(new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])); + expect(base64UrlToBuffer({ base64Url: 'AAECAwQFBgcICQ' })).to.eql(new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])); + expect(base64UrlToBuffer({ base64Url: 'An1aThIn_OeGWQUn-e4o2nEXvdtEagY2lJxCQN1SgKc' })).to.eql(new Uint8Array([2, 125, 90, 78, 18, 39, 252, 231, 134, 89, 5, 39, 249, 238, 40, 218, 113, 23, 189, 219, 68, 106, 6, 54, 148, 156, 66, 64, 221, 82, 128, 167])); }); }); }); diff --git a/packages/lib/src/crypto/web/crypto.web.models.ts b/packages/lib/src/crypto/web/crypto.web.models.ts new file mode 100644 index 00000000..5886c2aa --- /dev/null +++ b/packages/lib/src/crypto/web/crypto.web.models.ts @@ -0,0 +1,22 @@ +export { bufferToBase64Url, base64UrlToBuffer }; + +function bufferToBase64Url({ buffer }: { buffer: Uint8Array }): string { + const base64 = btoa(String.fromCharCode(...buffer)); + const base64Url = base64 + .replace(/\+/g, '-') + .replace(/\//g, '_') + .replace(/=/g, ''); + + return base64Url; +} + +function base64UrlToBuffer({ base64Url }: { base64Url: string }): Uint8Array { + const base64 = base64Url + .padEnd(base64Url.length + (4 - base64Url.length % 4) % 4, '=') + .replace(/-/g, '+') + .replace(/_/g, '/'); + + const buffer = new Uint8Array(atob(base64).split('').map(char => char.charCodeAt(0))); + + return buffer; +} diff --git a/packages/lib/src/crypto/web/crypto.web.usecases.test.ts b/packages/lib/src/crypto/web/crypto.web.usecases.test.ts new file mode 100644 index 00000000..51660954 --- /dev/null +++ b/packages/lib/src/crypto/web/crypto.web.usecases.test.ts @@ -0,0 +1,14 @@ +import { describe } from 'vitest'; +import { runCommonCryptoUsecasesTests } from '../crypto.usecases.test'; +import { createDecryptUsecase, createEncryptUsecase } from '../crypto.usecases'; + +import * as webCryptoLib from './crypto.web.usecases'; + +describe('crypto usecases', () => { + describe('web', () => { + runCommonCryptoUsecasesTests({ + ...createEncryptUsecase({ ...webCryptoLib }), + ...createDecryptUsecase({ ...webCryptoLib }), + }); + }); +}); diff --git a/packages/lib/src/crypto/web/crypto.web.usecases.ts b/packages/lib/src/crypto/web/crypto.web.usecases.ts new file mode 100644 index 00000000..552633d1 --- /dev/null +++ b/packages/lib/src/crypto/web/crypto.web.usecases.ts @@ -0,0 +1,73 @@ +import { base64UrlToBuffer, bufferToBase64Url } from './crypto.web.models'; + +export { generateBaseKey, deriveMasterKey, encryptNoteContent, decryptNoteContent }; + +function createRandomBuffer({ length = 16 }: { length?: number } = {}): Uint8Array { + const randomValues = new Uint8Array(length); + crypto.getRandomValues(randomValues); + + return randomValues; +} + +function generateBaseKey(): { baseKey: Uint8Array } { + return { baseKey: createRandomBuffer({ length: 32 }) }; +} + +async function deriveMasterKey({ baseKey, password = '' }: { baseKey: Uint8Array; password?: string }) { + const passwordBuffer = new TextEncoder().encode(password); + const mergedBuffers = new Uint8Array([...baseKey, ...passwordBuffer]); + + const key = await crypto.subtle.importKey('raw', mergedBuffers, 'PBKDF2', false, ['deriveKey']); + + const derivedKey = await crypto.subtle.deriveKey( + { + name: 'PBKDF2', + salt: baseKey, + iterations: 100_000, + hash: 'SHA-256', + }, + key, + { name: 'AES-GCM', length: 256 }, + true, // Extractable + ['encrypt', 'decrypt'], + ); + + const exportedKey = await crypto.subtle.exportKey('raw', derivedKey); + + return { + masterKey: new Uint8Array(exportedKey), + }; +} + +async function encryptNoteContent({ content, masterKey }: { content: string; masterKey: Uint8Array }) { + const contentBuffer = new TextEncoder().encode(content); + const iv = createRandomBuffer({ length: 12 }); + + const key = await crypto.subtle.importKey('raw', masterKey, 'AES-GCM', false, ['encrypt']); + const encrypted = await crypto.subtle.encrypt({ name: 'AES-GCM', iv }, key, contentBuffer); + + const ivString = bufferToBase64Url({ buffer: iv }); + const encryptedString = bufferToBase64Url({ buffer: new Uint8Array(encrypted) }); + + return { + encryptedContent: `${ivString}:${encryptedString}`, + }; +} + +async function decryptNoteContent({ encryptedContent, masterKey }: { encryptedContent: string; masterKey: Uint8Array }) { + const [ivString, encryptedString] = encryptedContent.split(':').map(part => part.trim()); + + if (!ivString || !encryptedString) { + throw new Error('Invalid data'); + } + + const iv = base64UrlToBuffer({ base64Url: ivString }); + const encrypted = base64UrlToBuffer({ base64Url: encryptedString }); + + const key = await crypto.subtle.importKey('raw', masterKey, 'AES-GCM', false, ['decrypt']); + const decrypted = await crypto.subtle.decrypt({ name: 'AES-GCM', iv }, key, encrypted); + + const decryptedContent = new TextDecoder().decode(decrypted); + + return { decryptedContent }; +} diff --git a/packages/lib/src/index.node.ts b/packages/lib/src/index.node.ts new file mode 100644 index 00000000..49873aec --- /dev/null +++ b/packages/lib/src/index.node.ts @@ -0,0 +1,9 @@ +import { createEnclosedLib } from './notes/notes.usecases'; +import { decryptNoteContent, deriveMasterKey, encryptNoteContent, generateBaseKey } from './crypto/node/crypto.node.usecases'; +import { storeNote } from './notes/notes.services'; +import { createDecryptUsecase, createEncryptUsecase } from './crypto/crypto.usecases'; + +export const { encryptNote } = createEncryptUsecase({ generateBaseKey, deriveMasterKey, encryptNoteContent }); +export const { decryptNote } = createDecryptUsecase({ deriveMasterKey, decryptNoteContent }); + +export const { createNote } = createEnclosedLib({ encryptNote, storeNote }); diff --git a/packages/lib/src/index.web.ts b/packages/lib/src/index.web.ts new file mode 100644 index 00000000..551f1710 --- /dev/null +++ b/packages/lib/src/index.web.ts @@ -0,0 +1,9 @@ +import { createEnclosedLib } from './notes/notes.usecases'; +import { decryptNoteContent, deriveMasterKey, encryptNoteContent, generateBaseKey } from './crypto/web/crypto.web.usecases'; +import { storeNote } from './notes/notes.services'; +import { createDecryptUsecase, createEncryptUsecase } from './crypto/crypto.usecases'; + +export const { encryptNote } = createEncryptUsecase({ generateBaseKey, deriveMasterKey, encryptNoteContent }); +export const { decryptNote } = createDecryptUsecase({ deriveMasterKey, decryptNoteContent }); + +export const { createNote } = createEnclosedLib({ encryptNote, storeNote }); diff --git a/packages/lib/src/notes/notes.models.test.ts b/packages/lib/src/notes/notes.models.test.ts new file mode 100644 index 00000000..49bcc484 --- /dev/null +++ b/packages/lib/src/notes/notes.models.test.ts @@ -0,0 +1,22 @@ +import { describe, expect, test } from 'vitest'; +import { createNoteUrl } from './notes.models'; + +describe('note models', () => { + describe('createNoteUrl', () => { + test('a sharable note url contains the note id as path and the encryption key as hash', () => { + expect( + createNoteUrl({ noteId: '123', encryptionKey: 'abc', clientBaseUrl: 'https://example.com' }), + ).to.eql({ + noteUrl: 'https://example.com/123#abc', + }); + }); + + test('trailing slash in the base url is handled', () => { + expect( + createNoteUrl({ noteId: '123', encryptionKey: 'abc', clientBaseUrl: 'https://example.com/' }), + ).to.eql({ + noteUrl: 'https://example.com/123#abc', + }); + }); + }); +}); diff --git a/packages/lib/src/notes/notes.models.ts b/packages/lib/src/notes/notes.models.ts new file mode 100644 index 00000000..421df3e1 --- /dev/null +++ b/packages/lib/src/notes/notes.models.ts @@ -0,0 +1,10 @@ +export { createNoteUrl }; + +function createNoteUrl({ noteId, encryptionKey, clientBaseUrl }: { noteId: string; encryptionKey: string; clientBaseUrl: string }): { noteUrl: string } { + const url = new URL(`/${noteId}`, clientBaseUrl); + url.hash = encryptionKey; + + const noteUrl = url.toString(); + + return { noteUrl }; +} diff --git a/packages/lib/src/notes/notes.services.ts b/packages/lib/src/notes/notes.services.ts new file mode 100644 index 00000000..7b79c64d --- /dev/null +++ b/packages/lib/src/notes/notes.services.ts @@ -0,0 +1,41 @@ +import { ofetch } from 'ofetch'; + +export { storeNote }; + +async function storeNote({ + content, + isPasswordProtected, + ttlInSeconds, + deleteAfterReading, + noteCreationApiUrl, +}: { + content: string; + isPasswordProtected: boolean; + ttlInSeconds: number; + deleteAfterReading: boolean; + noteCreationApiUrl: string; +}): Promise<{ noteId: string }> { + try { + const { noteId } = await ofetch<{ noteId: string }>( + noteCreationApiUrl, + { + method: 'POST', + body: { + content, + isPasswordProtected, + ttlInSeconds, + deleteAfterReading, + }, + }, + ); + + return { noteId }; + } catch (baseError) { + const error = new Error('Failed to store note'); + Object.assign(error, { + cause: baseError, + }); + + throw error; + } +} diff --git a/packages/lib/src/notes/notes.usecases.ts b/packages/lib/src/notes/notes.usecases.ts new file mode 100644 index 00000000..a2d5c0c3 --- /dev/null +++ b/packages/lib/src/notes/notes.usecases.ts @@ -0,0 +1,50 @@ +import { createNoteUrl as createNoteUrlImpl } from './notes.models'; + +export { createEnclosedLib }; + +const ONE_HOUR_IN_SECONDS = 60 * 60; +const BASE_URL = 'https://enclosed.cc'; +const DEFAULT_NOTE_CREATION_API_URL = 'https://enclosed.cc/api/notes'; + +function createEnclosedLib({ + encryptNote, + storeNote: storeNoteImpl, +}: { + encryptNote: (args: { content: string; password?: string }) => Promise<{ encryptedContent: string; encryptionKey: string }>; + storeNote: (params: { content: string; isPasswordProtected: boolean; ttlInSeconds: number; deleteAfterReading: boolean; noteCreationApiUrl: string }) => Promise<{ noteId: string }>; +}) { + return { + createNote: async ({ + content, + password, + ttlInSeconds = ONE_HOUR_IN_SECONDS, + deleteAfterReading = false, + noteCreationApiUrl = DEFAULT_NOTE_CREATION_API_URL, + clientBaseUrl = BASE_URL, + createNoteUrl = createNoteUrlImpl, + storeNote = params => storeNoteImpl({ ...params, noteCreationApiUrl }), + }: { + content: string; + password?: string; + ttlInSeconds?: number; + deleteAfterReading?: boolean; + clientBaseUrl?: string; + noteCreationApiUrl?: string; + createNoteUrl?: (args: { noteId: string; encryptionKey: string; clientBaseUrl: string }) => { noteUrl: string }; + storeNote?: (params: { content: string; isPasswordProtected: boolean; ttlInSeconds: number; deleteAfterReading: boolean }) => Promise<{ noteId: string }>; + }) => { + const { encryptedContent, encryptionKey } = await encryptNote({ content, password }); + + const { noteId } = await storeNote({ content: encryptedContent, isPasswordProtected: Boolean(password), ttlInSeconds, deleteAfterReading }); + + const { noteUrl } = createNoteUrl({ noteId, encryptionKey, clientBaseUrl }); + + return { + encryptedContent, + encryptionKey, + noteId, + noteUrl, + }; + }, + }; +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 96129c14..83d0e8f1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,6 +10,9 @@ importers: packages/app-client: dependencies: + '@enclosed/lib': + specifier: workspace:* + version: link:../lib '@kobalte/core': specifier: ^0.13.4 version: 0.13.6(solid-js@1.8.22) @@ -147,6 +150,34 @@ importers: packages/deploy-cloudflare: {} + packages/lib: + dependencies: + ofetch: + specifier: ^1.3.4 + version: 1.3.4 + devDependencies: + '@antfu/eslint-config': + specifier: ^2.27.0 + version: 2.27.3(@typescript-eslint/utils@8.3.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4))(@vue/compiler-sfc@3.4.38)(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4)(vitest@2.0.5(@types/node@22.5.1)(jsdom@25.0.0)(terser@5.31.6)) + '@vitest/coverage-v8': + specifier: ^2.0.5 + version: 2.0.5(vitest@2.0.5(@types/node@22.5.1)(jsdom@25.0.0)(terser@5.31.6)) + dotenv: + specifier: ^16.4.5 + version: 16.4.5 + eslint: + specifier: ^9.9.0 + version: 9.9.1(jiti@1.21.6) + typescript: + specifier: ^5.5.4 + version: 5.5.4 + unbuild: + specifier: ^2.0.0 + version: 2.0.0(typescript@5.5.4) + vitest: + specifier: ^2.0.5 + version: 2.0.5(@types/node@22.5.1)(jsdom@25.0.0)(terser@5.31.6) + packages: '@ampproject/remapping@2.3.0': @@ -330,6 +361,10 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/standalone@7.25.6': + resolution: {integrity: sha512-Kf2ZcZVqsKbtYhlA7sP0z5A3q5hmCVYMKMWRWNK/5OVwHIve3JY1djVRmIVAx8FMueLIfZGKQDIILK2w8zO4mg==} + engines: {node: '>=6.9.0'} + '@babel/template@7.25.0': resolution: {integrity: sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==} engines: {node: '>=6.9.0'} @@ -421,6 +456,12 @@ packages: peerDependencies: esbuild: '*' + '@esbuild/aix-ppc64@0.19.12': + resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + '@esbuild/aix-ppc64@0.21.5': resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} engines: {node: '>=12'} @@ -439,6 +480,12 @@ packages: cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.19.12': + resolution: {integrity: sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm64@0.21.5': resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} engines: {node: '>=12'} @@ -457,6 +504,12 @@ packages: cpu: [arm] os: [android] + '@esbuild/android-arm@0.19.12': + resolution: {integrity: sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + '@esbuild/android-arm@0.21.5': resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} engines: {node: '>=12'} @@ -475,6 +528,12 @@ packages: cpu: [x64] os: [android] + '@esbuild/android-x64@0.19.12': + resolution: {integrity: sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + '@esbuild/android-x64@0.21.5': resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} engines: {node: '>=12'} @@ -493,6 +552,12 @@ packages: cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.19.12': + resolution: {integrity: sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-arm64@0.21.5': resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} engines: {node: '>=12'} @@ -511,6 +576,12 @@ packages: cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.19.12': + resolution: {integrity: sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + '@esbuild/darwin-x64@0.21.5': resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} engines: {node: '>=12'} @@ -529,6 +600,12 @@ packages: cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.19.12': + resolution: {integrity: sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-arm64@0.21.5': resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} engines: {node: '>=12'} @@ -547,6 +624,12 @@ packages: cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.19.12': + resolution: {integrity: sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + '@esbuild/freebsd-x64@0.21.5': resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} engines: {node: '>=12'} @@ -565,6 +648,12 @@ packages: cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.19.12': + resolution: {integrity: sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm64@0.21.5': resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} engines: {node: '>=12'} @@ -583,6 +672,12 @@ packages: cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.19.12': + resolution: {integrity: sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + '@esbuild/linux-arm@0.21.5': resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} engines: {node: '>=12'} @@ -601,6 +696,12 @@ packages: cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.19.12': + resolution: {integrity: sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-ia32@0.21.5': resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} engines: {node: '>=12'} @@ -619,6 +720,12 @@ packages: cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.19.12': + resolution: {integrity: sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-loong64@0.21.5': resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} engines: {node: '>=12'} @@ -637,6 +744,12 @@ packages: cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.19.12': + resolution: {integrity: sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-mips64el@0.21.5': resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} engines: {node: '>=12'} @@ -655,6 +768,12 @@ packages: cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.19.12': + resolution: {integrity: sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-ppc64@0.21.5': resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} engines: {node: '>=12'} @@ -673,6 +792,12 @@ packages: cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.19.12': + resolution: {integrity: sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-riscv64@0.21.5': resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} engines: {node: '>=12'} @@ -691,6 +816,12 @@ packages: cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.19.12': + resolution: {integrity: sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-s390x@0.21.5': resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} engines: {node: '>=12'} @@ -709,6 +840,12 @@ packages: cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.19.12': + resolution: {integrity: sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + '@esbuild/linux-x64@0.21.5': resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} engines: {node: '>=12'} @@ -727,6 +864,12 @@ packages: cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.19.12': + resolution: {integrity: sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + '@esbuild/netbsd-x64@0.21.5': resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} engines: {node: '>=12'} @@ -751,6 +894,12 @@ packages: cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.19.12': + resolution: {integrity: sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + '@esbuild/openbsd-x64@0.21.5': resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} engines: {node: '>=12'} @@ -769,6 +918,12 @@ packages: cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.19.12': + resolution: {integrity: sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + '@esbuild/sunos-x64@0.21.5': resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} engines: {node: '>=12'} @@ -787,6 +942,12 @@ packages: cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.19.12': + resolution: {integrity: sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-arm64@0.21.5': resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} engines: {node: '>=12'} @@ -805,6 +966,12 @@ packages: cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.19.12': + resolution: {integrity: sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-ia32@0.21.5': resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} engines: {node: '>=12'} @@ -823,6 +990,12 @@ packages: cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.19.12': + resolution: {integrity: sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + '@esbuild/win32-x64@0.21.5': resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} engines: {node: '>=12'} @@ -1056,6 +1229,51 @@ packages: '@polka/url@1.0.0-next.25': resolution: {integrity: sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==} + '@rollup/plugin-alias@5.1.0': + resolution: {integrity: sha512-lpA3RZ9PdIG7qqhEfv79tBffNaoDuukFDrmhLqg9ifv99u/ehn+lOg30x2zmhf8AQqQUZaMk/B9fZraQ6/acDQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-commonjs@25.0.8': + resolution: {integrity: sha512-ZEZWTK5n6Qde0to4vS9Mr5x/0UZoqCxPVR9KRUjU4kA2sO7GEUn1fop0DAwpO6z0Nw/kJON9bDmSxdWxO/TT1A==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.68.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-json@6.1.0': + resolution: {integrity: sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-node-resolve@15.2.3': + resolution: {integrity: sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.78.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-replace@5.0.7': + resolution: {integrity: sha512-PqxSfuorkHz/SPpyngLyg5GCEkOcee9M1bkxiVDr41Pd61mqP1PLOoDPbpl44SB2mQGKwV/In74gqQmGITOhEQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + '@rollup/pluginutils@5.1.0': resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} engines: {node: '>=14.0.0'} @@ -1240,6 +1458,10 @@ packages: '@total-typescript/ts-reset@0.6.0': resolution: {integrity: sha512-HWZnkM+5z3INAUZMohVXvX8/vm9sjmfmV2NRAswvv5WsU2m+OZsHAVZ0fl8xf2QH9kyPkinghVW6g3DOQ2xt5Q==} + '@trysound/sax@0.2.0': + resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} + engines: {node: '>=10.13.0'} + '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} @@ -1291,6 +1513,9 @@ packages: '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} + '@types/resolve@1.20.2': + resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} + '@types/unist@2.0.11': resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} @@ -1564,6 +1789,13 @@ packages: resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} engines: {node: '>=8.0.0'} + autoprefixer@10.4.20: + resolution: {integrity: sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 + babel-plugin-jsx-dom-expressions@0.38.1: resolution: {integrity: sha512-4FD4H69Cu4jHx2uLDEvx4YC5T/fC/Dmaafhsm8hXm7SjHYzjr09gBVyHdoFza+91f/g9e6tIzjbLCMkOXwmlew==} peerDependencies: @@ -1629,6 +1861,9 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} + caniuse-api@3.0.0: + resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} + caniuse-lite@1.0.30001653: resolution: {integrity: sha512-XGWQVB8wFQ2+9NZwZ10GxTYC5hk0Fa+q8cSkr0tgvMhYhMHP/QC+WTgrePMDBWiWc/pV+1ik82Al20XOK25Gcw==} @@ -1647,6 +1882,10 @@ packages: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} + chalk@5.3.0: + resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + character-entities-legacy@1.1.4: resolution: {integrity: sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==} @@ -1707,6 +1946,9 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + colord@2.9.3: + resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} + colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} @@ -1717,10 +1959,17 @@ packages: commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + commander@7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + comment-parser@1.4.1: resolution: {integrity: sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==} engines: {node: '>= 12.0.0'} + commondir@1.0.1: + resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} + concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} @@ -1756,15 +2005,54 @@ packages: uWebSockets.js: optional: true + css-declaration-sorter@7.2.0: + resolution: {integrity: sha512-h70rUM+3PNFuaBDTLe8wF/cdWu+dOZmb7pJt8Z2sedYbAcQVQV/tEchueg3GWxwqS0cxtbxmaHEdkNACqcvsow==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.0.9 + + css-select@5.1.0: + resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} + + css-tree@2.2.1: + resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + css-tree@2.3.1: resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + css-what@6.1.0: + resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} + engines: {node: '>= 6'} + cssesc@3.0.0: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} engines: {node: '>=4'} hasBin: true + cssnano-preset-default@7.0.5: + resolution: {integrity: sha512-Jbzja0xaKwc5JzxPQoc+fotKpYtWEu4wQLMQe29CM0FjjdRjA4omvbGHl2DTGgARKxSTpPssBsok+ixv8uTBqw==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + cssnano-utils@5.0.0: + resolution: {integrity: sha512-Uij0Xdxc24L6SirFr25MlwC2rCFX6scyUmuKpzI+JQ7cyqDEwD42fJ0xfB3yLfOnRDU5LKGgjQ9FA6LYh76GWQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + cssnano@7.0.5: + resolution: {integrity: sha512-Aq0vqBLtpTT5Yxj+hLlLfNPFuRQCDIjx5JQAhhaedQKLNDvDGeVziF24PS+S1f0Z5KCxWvw0QVI3VNHNBITxVQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + csso@5.0.5: + resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + cssstyle@4.0.1: resolution: {integrity: sha512-8ZYiJ3A/3OkDd093CBT/0UKDWry7ak4BdPTFP2+QEP7cmhouyq/Up709ASSj2cK02BbZiMgk7kYjZNS4QP5qrQ==} engines: {node: '>=18'} @@ -1809,6 +2097,10 @@ packages: deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + defu@6.1.4: resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} @@ -1824,10 +2116,27 @@ packages: engines: {node: '>=0.10'} hasBin: true + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + doctrine@3.0.0: resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} engines: {node: '>=6.0.0'} + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + domutils@3.1.0: + resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==} + dotenv@16.4.5: resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} engines: {node: '>=12'} @@ -1866,6 +2175,11 @@ packages: engines: {node: '>=12'} hasBin: true + esbuild@0.19.12: + resolution: {integrity: sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==} + engines: {node: '>=12'} + hasBin: true + esbuild@0.21.5: resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} engines: {node: '>=12'} @@ -2163,6 +2477,12 @@ packages: resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} engines: {node: '>= 6'} + fraction.js@4.3.7: + resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} + + 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} @@ -2210,6 +2530,11 @@ packages: resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} hasBin: true + glob@8.1.0: + resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} + engines: {node: '>=12'} + deprecated: Glob versions prior to v9 are no longer supported + globals@11.12.0: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} engines: {node: '>=4'} @@ -2226,6 +2551,10 @@ packages: resolution: {integrity: sha512-SmSKyLLKFbSr6rptvP8izbyxJL4ILwqO9Jg23UA0sDlGlu58V59D1//I3vlc0KJphVdUR7vMjHIplYnzBxorQA==} engines: {node: '>=18'} + globby@13.2.2: + resolution: {integrity: sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} @@ -2255,6 +2584,9 @@ packages: resolution: {integrity: sha512-zz8ktqMDRrZETjxBrv8C5PQRFbrTRCLNVAjD1SNQyOzv4VjmX68Uxw83xQ6oxdAB60HiWnGEatiKA8V3SZLDkQ==} engines: {node: '>=16.0.0'} + hookable@5.5.3: + resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} + hosted-git-info@2.8.9: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} @@ -2310,6 +2642,13 @@ packages: 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==} + iron-webcrypto@1.2.1: resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} @@ -2362,6 +2701,9 @@ packages: engines: {node: '>=14.16'} hasBin: true + is-module@1.0.0: + resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} + is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} @@ -2373,6 +2715,9 @@ packages: is-potential-custom-element-name@1.0.1: resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + is-reference@1.2.1: + resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} + is-stream@3.0.0: resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -2488,6 +2833,10 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} + lilconfig@3.1.2: + resolution: {integrity: sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==} + engines: {node: '>=14'} + lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} @@ -2514,9 +2863,15 @@ packages: lodash-es@4.17.21: resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + 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==} + lodash.uniq@4.5.0: + resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} + lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} @@ -2548,6 +2903,9 @@ packages: mdast-util-to-string@2.0.0: resolution: {integrity: sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==} + mdn-data@2.0.28: + resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==} + mdn-data@2.0.30: resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} @@ -2602,6 +2960,10 @@ packages: 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'} @@ -2610,6 +2972,21 @@ packages: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} + mkdist@1.5.4: + resolution: {integrity: sha512-GEmKYJG5K1YGFIq3t0K3iihZ8FTgXphLf/4UjbmpXIAtBFn4lEjXk3pXNTSfy7EtcEXhp2Nn1vzw5pIus6RY3g==} + hasBin: true + peerDependencies: + sass: ^1.77.8 + typescript: '>=5.5.3' + vue-tsc: ^1.8.27 || ^2.0.21 + peerDependenciesMeta: + sass: + optional: true + typescript: + optional: true + vue-tsc: + optional: true + mlly@1.7.1: resolution: {integrity: sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==} @@ -2666,6 +3043,10 @@ packages: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} + normalize-range@0.1.2: + resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} + engines: {node: '>=0.10.0'} + npm-run-path@5.3.0: resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -2686,6 +3067,9 @@ packages: resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} engines: {node: '>=14.0.0'} + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + onetime@6.0.0: resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} engines: {node: '>=12'} @@ -2764,6 +3148,10 @@ packages: path-to-regexp@6.2.2: resolution: {integrity: sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==} + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + pathe@1.1.2: resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} @@ -2802,10 +3190,181 @@ packages: resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} engines: {node: '>=4'} + postcss-calc@10.0.2: + resolution: {integrity: sha512-DT/Wwm6fCKgpYVI7ZEWuPJ4az8hiEHtCUeYjZXqU7Ou4QqYh1Df2yCQ7Ca6N7xqKPFkxN3fhf+u9KSoOCJNAjg==} + engines: {node: ^18.12 || ^20.9 || >=22.0} + peerDependencies: + postcss: ^8.4.38 + + postcss-colormin@7.0.2: + resolution: {integrity: sha512-YntRXNngcvEvDbEjTdRWGU606eZvB5prmHG4BF0yLmVpamXbpsRJzevyy6MZVyuecgzI2AWAlvFi8DAeCqwpvA==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-convert-values@7.0.3: + resolution: {integrity: sha512-yJhocjCs2SQer0uZ9lXTMOwDowbxvhwFVrZeS6NPEij/XXthl73ggUmfwVvJM+Vaj5gtCKJV1jiUu4IhAUkX/Q==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-discard-comments@7.0.2: + resolution: {integrity: sha512-/Hje9Ls1IYcB9duELO/AyDUJI6aQVY3h5Rj1ziXgaLYCTi1iVBLnjg/TS0D6NszR/kDG6I86OwLmAYe+bvJjiQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-discard-duplicates@7.0.1: + resolution: {integrity: sha512-oZA+v8Jkpu1ct/xbbrntHRsfLGuzoP+cpt0nJe5ED2FQF8n8bJtn7Bo28jSmBYwqgqnqkuSXJfSUEE7if4nClQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-discard-empty@7.0.0: + resolution: {integrity: sha512-e+QzoReTZ8IAwhnSdp/++7gBZ/F+nBq9y6PomfwORfP7q9nBpK5AMP64kOt0bA+lShBFbBDcgpJ3X4etHg4lzA==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-discard-overridden@7.0.0: + resolution: {integrity: sha512-GmNAzx88u3k2+sBTZrJSDauR0ccpE24omTQCVmaTTZFz1du6AasspjaUPMJ2ud4RslZpoFKyf+6MSPETLojc6w==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-merge-longhand@7.0.3: + resolution: {integrity: sha512-8waYomFxshdv6M9Em3QRM9MettRLDRcH2JQi2l0Z1KlYD/vhal3gbkeSES0NuACXOlZBB0V/B0AseHZaklzWOA==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-merge-rules@7.0.3: + resolution: {integrity: sha512-2eSas2p3voPxNfdI5sQrvIkMaeUHpVc3EezgVs18hz/wRTQAC9U99tp9j3W5Jx9/L3qHkEDvizEx/LdnmumIvQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-minify-font-values@7.0.0: + resolution: {integrity: sha512-2ckkZtgT0zG8SMc5aoNwtm5234eUx1GGFJKf2b1bSp8UflqaeFzR50lid4PfqVI9NtGqJ2J4Y7fwvnP/u1cQog==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-minify-gradients@7.0.0: + resolution: {integrity: sha512-pdUIIdj/C93ryCHew0UgBnL2DtUS3hfFa5XtERrs4x+hmpMYGhbzo6l/Ir5de41O0GaKVpK1ZbDNXSY6GkXvtg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-minify-params@7.0.2: + resolution: {integrity: sha512-nyqVLu4MFl9df32zTsdcLqCFfE/z2+f8GE1KHPxWOAmegSo6lpV2GNy5XQvrzwbLmiU7d+fYay4cwto1oNdAaQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-minify-selectors@7.0.3: + resolution: {integrity: sha512-SxTgUQSgBk6wEqzQZKEv1xQYIp9UBju6no9q+npohzSdhuSICQdkqmD1UMKkZWItS3olJSJMDDEY9WOJ5oGJew==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-nested@6.2.0: + resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.2.14 + + postcss-normalize-charset@7.0.0: + resolution: {integrity: sha512-ABisNUXMeZeDNzCQxPxBCkXexvBrUHV+p7/BXOY+ulxkcjUZO0cp8ekGBwvIh2LbCwnWbyMPNJVtBSdyhM2zYQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-display-values@7.0.0: + resolution: {integrity: sha512-lnFZzNPeDf5uGMPYgGOw7v0BfB45+irSRz9gHQStdkkhiM0gTfvWkWB5BMxpn0OqgOQuZG/mRlZyJxp0EImr2Q==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-positions@7.0.0: + resolution: {integrity: sha512-I0yt8wX529UKIGs2y/9Ybs2CelSvItfmvg/DBIjTnoUSrPxSV7Z0yZ8ShSVtKNaV/wAY+m7bgtyVQLhB00A1NQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-repeat-style@7.0.0: + resolution: {integrity: sha512-o3uSGYH+2q30ieM3ppu9GTjSXIzOrRdCUn8UOMGNw7Af61bmurHTWI87hRybrP6xDHvOe5WlAj3XzN6vEO8jLw==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-string@7.0.0: + resolution: {integrity: sha512-w/qzL212DFVOpMy3UGyxrND+Kb0fvCiBBujiaONIihq7VvtC7bswjWgKQU/w4VcRyDD8gpfqUiBQ4DUOwEJ6Qg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-timing-functions@7.0.0: + resolution: {integrity: sha512-tNgw3YV0LYoRwg43N3lTe3AEWZ66W7Dh7lVEpJbHoKOuHc1sLrzMLMFjP8SNULHaykzsonUEDbKedv8C+7ej6g==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-unicode@7.0.2: + resolution: {integrity: sha512-ztisabK5C/+ZWBdYC+Y9JCkp3M9qBv/XFvDtSw0d/XwfT3UaKeW/YTm/MD/QrPNxuecia46vkfEhewjwcYFjkg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-url@7.0.0: + resolution: {integrity: sha512-+d7+PpE+jyPX1hDQZYG+NaFD+Nd2ris6r8fPTBAjE8z/U41n/bib3vze8x7rKs5H1uEw5ppe9IojewouHk0klQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-whitespace@7.0.0: + resolution: {integrity: sha512-37/toN4wwZErqohedXYqWgvcHUGlT8O/m2jVkAfAe9Bd4MzRqlBmXrJRePH0e9Wgnz2X7KymTgTOaaFizQe3AQ==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-ordered-values@7.0.1: + resolution: {integrity: sha512-irWScWRL6nRzYmBOXReIKch75RRhNS86UPUAxXdmW/l0FcAsg0lvAXQCby/1lymxn/o0gVa6Rv/0f03eJOwHxw==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-reduce-initial@7.0.2: + resolution: {integrity: sha512-pOnu9zqQww7dEKf62Nuju6JgsW2V0KRNBHxeKohU+JkHd/GAH5uvoObqFLqkeB2n20mr6yrlWDvo5UBU5GnkfA==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-reduce-transforms@7.0.0: + resolution: {integrity: sha512-pnt1HKKZ07/idH8cpATX/ujMbtOGhUfE+m8gbqwJE05aTaNw8gbo34a2e3if0xc0dlu75sUOiqvwCGY3fzOHew==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + postcss-selector-parser@6.1.2: resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} engines: {node: '>=4'} + postcss-svgo@7.0.1: + resolution: {integrity: sha512-0WBUlSL4lhD9rA5k1e5D8EN5wCEyZD6HJk0jIvRxl+FDVOMlJ7DePHYWGGVc5QRqrJ3/06FTXM0bxjmJpmTPSA==} + engines: {node: ^18.12.0 || ^20.9.0 || >= 18} + peerDependencies: + postcss: ^8.4.31 + + postcss-unique-selectors@7.0.2: + resolution: {integrity: sha512-CjSam+7Vf8cflJQsHrMS0P2hmy9u0+n/P001kb5eAszLmhjMqrt/i5AqQuNFihhViwDvEAezqTmXqaYXL2ugMw==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + postcss@8.4.41: resolution: {integrity: sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==} engines: {node: ^10 || ^12 || >=14} @@ -2814,6 +3373,10 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} + pretty-bytes@6.1.1: + resolution: {integrity: sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==} + engines: {node: ^14.13.1 || >=16.0.0} + printable-characters@1.0.42: resolution: {integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==} @@ -2905,6 +3468,13 @@ packages: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + rollup-plugin-dts@6.1.1: + resolution: {integrity: sha512-aSHRcJ6KG2IHIioYlvAOcEq6U99sVtqDDKVhnwt70rW6tsz3tv5OSjEiWcgzfsHdLyGXZ/3b/7b/+Za3Y6r1XA==} + engines: {node: '>=16'} + peerDependencies: + rollup: ^3.29.4 || ^4 + typescript: ^4.5 || ^5.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. @@ -2915,6 +3485,11 @@ packages: rollup-pluginutils@2.8.2: resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==} + rollup@3.29.4: + resolution: {integrity: sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==} + engines: {node: '>=14.18.0', npm: '>=8.0.0'} + hasBin: true + rollup@4.21.0: resolution: {integrity: sha512-vo+S/lfA2lMS7rZ2Qoubi6I5hwZwzXeUIctILZLbHI+laNtvhhOIon2S1JksA5UEDQ7l3vberd0fxK44lTYjbQ==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} @@ -2947,6 +3522,9 @@ packages: resolution: {integrity: sha512-3A6sD0WYP7+QrjbfNA2FN3FsOaGGFoekCVgTyypy53gPxhbkCIjtO6YWgdrfM+n/8sI8JeXZOIxsHjMTNxQ4nQ==} engines: {node: ^14.0.0 || >=16.0.0} + scule@1.3.0: + resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} + selfsigned@2.4.1: resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==} engines: {node: '>=10'} @@ -2996,6 +3574,10 @@ packages: sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + slash@4.0.0: + resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==} + engines: {node: '>=12'} + slashes@3.0.12: resolution: {integrity: sha512-Q9VME8WyGkc7pJf6QEkj3wE+2CnvZMI+XJhwdTPR8Z/kWQRXi7boAWLDibRPyHRTUTPx5FaU7MsyrjI3yLB4HA==} @@ -3101,6 +3683,12 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} + stylehacks@7.0.3: + resolution: {integrity: sha512-4DqtecvI/Nd+2BCvW9YEF6lhBN5UM50IJ1R3rnEAhBwbCKf4VehRf+uqvnVArnBayjYD/WtT3g0G/HSRxWfTRg==} + engines: {node: ^18.12.0 || ^20.9.0 || >=22.0} + peerDependencies: + postcss: ^8.4.31 + supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} @@ -3113,6 +3701,11 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + svgo@3.3.2: + resolution: {integrity: sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==} + engines: {node: '>=14.0.0'} + hasBin: true + symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} @@ -3237,6 +3830,15 @@ packages: ulid-workers@2.1.0: resolution: {integrity: sha512-D4+5fwPt5FEoGdMQtx5YwRHUZ4SDWSypraDZiXT3Y8U7T0C6h99dXhpWJQScNckoVRU+zi+BDuoBKHAffrn9vg==} + unbuild@2.0.0: + resolution: {integrity: sha512-JWCUYx3Oxdzvw2J9kTAp+DKE8df/BnH/JTSj6JyA4SH40ECdFu7FoJJcrm8G92B7TjofQ6GZGjJs50TRxoH6Wg==} + hasBin: true + peerDependencies: + typescript: ^5.1.6 + peerDependenciesMeta: + typescript: + optional: true + unconfig@0.5.5: resolution: {integrity: sha512-VQZ5PT9HDX+qag0XdgQi8tJepPhXiR/yVOkn707gJDKo31lGjRilPREiQJ9Z6zd/Ugpv6ZvO5VxVIcatldYcNQ==} @@ -3329,6 +3931,10 @@ packages: resolution: {integrity: sha512-4luGP9LMYszMRZwsvyUd9MrxgEGZdZuZgpVQHEEX0lCYFESasVRvZd0EYpCkOIbJKHMuv0LskpXc/8Un+MJzEQ==} hasBin: true + untyped@1.4.2: + resolution: {integrity: sha512-nC5q0DnPEPVURPhfPQLahhSTnemVtPzdx7ofiRxXpOB2SYnb3MfdU3DVGyJdS8Lx+tBWeAePO8BfU/3EgksM7Q==} + hasBin: true + update-browserslist-db@1.1.0: resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==} hasBin: true @@ -3499,6 +4105,9 @@ packages: resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} engines: {node: '>=12'} + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + ws@8.18.0: resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} engines: {node: '>=10.0.0'} @@ -3803,6 +4412,8 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/standalone@7.25.6': {} + '@babel/template@7.25.0': dependencies: '@babel/code-frame': 7.24.7 @@ -3897,6 +4508,9 @@ snapshots: escape-string-regexp: 4.0.0 rollup-plugin-node-polyfills: 0.2.1 + '@esbuild/aix-ppc64@0.19.12': + optional: true + '@esbuild/aix-ppc64@0.21.5': optional: true @@ -3906,6 +4520,9 @@ snapshots: '@esbuild/android-arm64@0.17.19': optional: true + '@esbuild/android-arm64@0.19.12': + optional: true + '@esbuild/android-arm64@0.21.5': optional: true @@ -3915,6 +4532,9 @@ snapshots: '@esbuild/android-arm@0.17.19': optional: true + '@esbuild/android-arm@0.19.12': + optional: true + '@esbuild/android-arm@0.21.5': optional: true @@ -3924,6 +4544,9 @@ snapshots: '@esbuild/android-x64@0.17.19': optional: true + '@esbuild/android-x64@0.19.12': + optional: true + '@esbuild/android-x64@0.21.5': optional: true @@ -3933,6 +4556,9 @@ snapshots: '@esbuild/darwin-arm64@0.17.19': optional: true + '@esbuild/darwin-arm64@0.19.12': + optional: true + '@esbuild/darwin-arm64@0.21.5': optional: true @@ -3942,6 +4568,9 @@ snapshots: '@esbuild/darwin-x64@0.17.19': optional: true + '@esbuild/darwin-x64@0.19.12': + optional: true + '@esbuild/darwin-x64@0.21.5': optional: true @@ -3951,6 +4580,9 @@ snapshots: '@esbuild/freebsd-arm64@0.17.19': optional: true + '@esbuild/freebsd-arm64@0.19.12': + optional: true + '@esbuild/freebsd-arm64@0.21.5': optional: true @@ -3960,6 +4592,9 @@ snapshots: '@esbuild/freebsd-x64@0.17.19': optional: true + '@esbuild/freebsd-x64@0.19.12': + optional: true + '@esbuild/freebsd-x64@0.21.5': optional: true @@ -3969,6 +4604,9 @@ snapshots: '@esbuild/linux-arm64@0.17.19': optional: true + '@esbuild/linux-arm64@0.19.12': + optional: true + '@esbuild/linux-arm64@0.21.5': optional: true @@ -3978,6 +4616,9 @@ snapshots: '@esbuild/linux-arm@0.17.19': optional: true + '@esbuild/linux-arm@0.19.12': + optional: true + '@esbuild/linux-arm@0.21.5': optional: true @@ -3987,6 +4628,9 @@ snapshots: '@esbuild/linux-ia32@0.17.19': optional: true + '@esbuild/linux-ia32@0.19.12': + optional: true + '@esbuild/linux-ia32@0.21.5': optional: true @@ -3996,6 +4640,9 @@ snapshots: '@esbuild/linux-loong64@0.17.19': optional: true + '@esbuild/linux-loong64@0.19.12': + optional: true + '@esbuild/linux-loong64@0.21.5': optional: true @@ -4005,6 +4652,9 @@ snapshots: '@esbuild/linux-mips64el@0.17.19': optional: true + '@esbuild/linux-mips64el@0.19.12': + optional: true + '@esbuild/linux-mips64el@0.21.5': optional: true @@ -4014,6 +4664,9 @@ snapshots: '@esbuild/linux-ppc64@0.17.19': optional: true + '@esbuild/linux-ppc64@0.19.12': + optional: true + '@esbuild/linux-ppc64@0.21.5': optional: true @@ -4023,6 +4676,9 @@ snapshots: '@esbuild/linux-riscv64@0.17.19': optional: true + '@esbuild/linux-riscv64@0.19.12': + optional: true + '@esbuild/linux-riscv64@0.21.5': optional: true @@ -4032,6 +4688,9 @@ snapshots: '@esbuild/linux-s390x@0.17.19': optional: true + '@esbuild/linux-s390x@0.19.12': + optional: true + '@esbuild/linux-s390x@0.21.5': optional: true @@ -4041,6 +4700,9 @@ snapshots: '@esbuild/linux-x64@0.17.19': optional: true + '@esbuild/linux-x64@0.19.12': + optional: true + '@esbuild/linux-x64@0.21.5': optional: true @@ -4050,6 +4712,9 @@ snapshots: '@esbuild/netbsd-x64@0.17.19': optional: true + '@esbuild/netbsd-x64@0.19.12': + optional: true + '@esbuild/netbsd-x64@0.21.5': optional: true @@ -4062,6 +4727,9 @@ snapshots: '@esbuild/openbsd-x64@0.17.19': optional: true + '@esbuild/openbsd-x64@0.19.12': + optional: true + '@esbuild/openbsd-x64@0.21.5': optional: true @@ -4071,6 +4739,9 @@ snapshots: '@esbuild/sunos-x64@0.17.19': optional: true + '@esbuild/sunos-x64@0.19.12': + optional: true + '@esbuild/sunos-x64@0.21.5': optional: true @@ -4080,6 +4751,9 @@ snapshots: '@esbuild/win32-arm64@0.17.19': optional: true + '@esbuild/win32-arm64@0.19.12': + optional: true + '@esbuild/win32-arm64@0.21.5': optional: true @@ -4089,6 +4763,9 @@ snapshots: '@esbuild/win32-ia32@0.17.19': optional: true + '@esbuild/win32-ia32@0.19.12': + optional: true + '@esbuild/win32-ia32@0.21.5': optional: true @@ -4098,6 +4775,9 @@ snapshots: '@esbuild/win32-x64@0.17.19': optional: true + '@esbuild/win32-x64@0.19.12': + optional: true + '@esbuild/win32-x64@0.21.5': optional: true @@ -4325,12 +5005,61 @@ snapshots: '@parcel/watcher-win32-ia32': 2.4.1 '@parcel/watcher-win32-x64': 2.4.1 - '@pkgjs/parseargs@0.11.0': - optional: true + '@pkgjs/parseargs@0.11.0': + optional: true + + '@pkgr/core@0.1.1': {} + + '@polka/url@1.0.0-next.25': {} + + '@rollup/plugin-alias@5.1.0(rollup@3.29.4)': + dependencies: + slash: 4.0.0 + optionalDependencies: + rollup: 3.29.4 + + '@rollup/plugin-commonjs@25.0.8(rollup@3.29.4)': + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@3.29.4) + commondir: 1.0.1 + estree-walker: 2.0.2 + glob: 8.1.0 + is-reference: 1.2.1 + magic-string: 0.30.11 + optionalDependencies: + rollup: 3.29.4 + + '@rollup/plugin-json@6.1.0(rollup@3.29.4)': + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@3.29.4) + optionalDependencies: + rollup: 3.29.4 - '@pkgr/core@0.1.1': {} + '@rollup/plugin-node-resolve@15.2.3(rollup@3.29.4)': + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@3.29.4) + '@types/resolve': 1.20.2 + deepmerge: 4.3.1 + is-builtin-module: 3.2.1 + is-module: 1.0.0 + resolve: 1.22.8 + optionalDependencies: + rollup: 3.29.4 - '@polka/url@1.0.0-next.25': {} + '@rollup/plugin-replace@5.0.7(rollup@3.29.4)': + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@3.29.4) + magic-string: 0.30.11 + optionalDependencies: + rollup: 3.29.4 + + '@rollup/pluginutils@5.1.0(rollup@3.29.4)': + dependencies: + '@types/estree': 1.0.5 + estree-walker: 2.0.2 + picomatch: 2.3.1 + optionalDependencies: + rollup: 3.29.4 '@rollup/pluginutils@5.1.0(rollup@4.21.0)': dependencies: @@ -4502,6 +5231,8 @@ snapshots: '@total-typescript/ts-reset@0.6.0': {} + '@trysound/sax@0.2.0': {} + '@types/babel__core@7.20.5': dependencies: '@babel/parser': 7.25.4 @@ -4570,6 +5301,8 @@ snapshots: '@types/normalize-package-data@2.4.4': {} + '@types/resolve@1.20.2': {} + '@types/unist@2.0.11': {} '@typescript-eslint/eslint-plugin@8.3.0(@typescript-eslint/parser@8.3.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4))(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4)': @@ -4966,6 +5699,16 @@ snapshots: atomic-sleep@1.0.0: {} + autoprefixer@10.4.20(postcss@8.4.41): + dependencies: + browserslist: 4.23.3 + caniuse-lite: 1.0.30001653 + fraction.js: 4.3.7 + normalize-range: 0.1.2 + picocolors: 1.0.1 + postcss: 8.4.41 + postcss-value-parser: 4.2.0 + babel-plugin-jsx-dom-expressions@0.38.1(@babel/core@7.25.2): dependencies: '@babel/core': 7.25.2 @@ -5029,6 +5772,13 @@ snapshots: callsites@3.1.0: {} + caniuse-api@3.0.0: + dependencies: + browserslist: 4.23.3 + caniuse-lite: 1.0.30001653 + lodash.memoize: 4.1.2 + lodash.uniq: 4.5.0 + caniuse-lite@1.0.30001653: {} capnp-ts@0.7.0: @@ -5057,6 +5807,8 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 + chalk@5.3.0: {} + character-entities-legacy@1.1.4: {} character-entities@1.2.4: {} @@ -5119,6 +5871,8 @@ snapshots: color-name@1.1.4: {} + colord@2.9.3: {} + colorette@2.0.20: {} combined-stream@1.0.8: @@ -5128,8 +5882,12 @@ snapshots: commander@2.20.3: optional: true + commander@7.2.0: {} + comment-parser@1.4.1: {} + commondir@1.0.1: {} + concat-map@0.0.1: {} confbox@0.1.7: {} @@ -5154,13 +5912,80 @@ snapshots: crossws@0.2.4: {} + css-declaration-sorter@7.2.0(postcss@8.4.41): + dependencies: + postcss: 8.4.41 + + css-select@5.1.0: + dependencies: + boolbase: 1.0.0 + css-what: 6.1.0 + domhandler: 5.0.3 + domutils: 3.1.0 + nth-check: 2.1.1 + + css-tree@2.2.1: + dependencies: + mdn-data: 2.0.28 + source-map-js: 1.2.0 + css-tree@2.3.1: dependencies: mdn-data: 2.0.30 source-map-js: 1.2.0 + css-what@6.1.0: {} + cssesc@3.0.0: {} + cssnano-preset-default@7.0.5(postcss@8.4.41): + dependencies: + browserslist: 4.23.3 + css-declaration-sorter: 7.2.0(postcss@8.4.41) + cssnano-utils: 5.0.0(postcss@8.4.41) + postcss: 8.4.41 + postcss-calc: 10.0.2(postcss@8.4.41) + postcss-colormin: 7.0.2(postcss@8.4.41) + postcss-convert-values: 7.0.3(postcss@8.4.41) + postcss-discard-comments: 7.0.2(postcss@8.4.41) + postcss-discard-duplicates: 7.0.1(postcss@8.4.41) + postcss-discard-empty: 7.0.0(postcss@8.4.41) + postcss-discard-overridden: 7.0.0(postcss@8.4.41) + postcss-merge-longhand: 7.0.3(postcss@8.4.41) + postcss-merge-rules: 7.0.3(postcss@8.4.41) + postcss-minify-font-values: 7.0.0(postcss@8.4.41) + postcss-minify-gradients: 7.0.0(postcss@8.4.41) + postcss-minify-params: 7.0.2(postcss@8.4.41) + postcss-minify-selectors: 7.0.3(postcss@8.4.41) + postcss-normalize-charset: 7.0.0(postcss@8.4.41) + postcss-normalize-display-values: 7.0.0(postcss@8.4.41) + postcss-normalize-positions: 7.0.0(postcss@8.4.41) + postcss-normalize-repeat-style: 7.0.0(postcss@8.4.41) + postcss-normalize-string: 7.0.0(postcss@8.4.41) + postcss-normalize-timing-functions: 7.0.0(postcss@8.4.41) + postcss-normalize-unicode: 7.0.2(postcss@8.4.41) + postcss-normalize-url: 7.0.0(postcss@8.4.41) + postcss-normalize-whitespace: 7.0.0(postcss@8.4.41) + postcss-ordered-values: 7.0.1(postcss@8.4.41) + postcss-reduce-initial: 7.0.2(postcss@8.4.41) + postcss-reduce-transforms: 7.0.0(postcss@8.4.41) + postcss-svgo: 7.0.1(postcss@8.4.41) + postcss-unique-selectors: 7.0.2(postcss@8.4.41) + + cssnano-utils@5.0.0(postcss@8.4.41): + dependencies: + postcss: 8.4.41 + + cssnano@7.0.5(postcss@8.4.41): + dependencies: + cssnano-preset-default: 7.0.5(postcss@8.4.41) + lilconfig: 3.1.2 + postcss: 8.4.41 + + csso@5.0.5: + dependencies: + css-tree: 2.2.1 + cssstyle@4.0.1: dependencies: rrweb-cssom: 0.6.0 @@ -5190,6 +6015,8 @@ snapshots: deep-is@0.1.4: {} + deepmerge@4.3.1: {} + defu@6.1.4: {} delayed-stream@1.0.0: {} @@ -5198,10 +6025,32 @@ snapshots: detect-libc@1.0.3: {} + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + doctrine@3.0.0: dependencies: esutils: 2.0.3 + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domelementtype@2.3.0: {} + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + domutils@3.1.0: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + dotenv@16.4.5: {} duplexer@0.1.2: {} @@ -5252,6 +6101,32 @@ snapshots: '@esbuild/win32-ia32': 0.17.19 '@esbuild/win32-x64': 0.17.19 + esbuild@0.19.12: + optionalDependencies: + '@esbuild/aix-ppc64': 0.19.12 + '@esbuild/android-arm': 0.19.12 + '@esbuild/android-arm64': 0.19.12 + '@esbuild/android-x64': 0.19.12 + '@esbuild/darwin-arm64': 0.19.12 + '@esbuild/darwin-x64': 0.19.12 + '@esbuild/freebsd-arm64': 0.19.12 + '@esbuild/freebsd-x64': 0.19.12 + '@esbuild/linux-arm': 0.19.12 + '@esbuild/linux-arm64': 0.19.12 + '@esbuild/linux-ia32': 0.19.12 + '@esbuild/linux-loong64': 0.19.12 + '@esbuild/linux-mips64el': 0.19.12 + '@esbuild/linux-ppc64': 0.19.12 + '@esbuild/linux-riscv64': 0.19.12 + '@esbuild/linux-s390x': 0.19.12 + '@esbuild/linux-x64': 0.19.12 + '@esbuild/netbsd-x64': 0.19.12 + '@esbuild/openbsd-x64': 0.19.12 + '@esbuild/sunos-x64': 0.19.12 + '@esbuild/win32-arm64': 0.19.12 + '@esbuild/win32-ia32': 0.19.12 + '@esbuild/win32-x64': 0.19.12 + esbuild@0.21.5: optionalDependencies: '@esbuild/aix-ppc64': 0.21.5 @@ -5683,6 +6558,10 @@ snapshots: combined-stream: 1.0.8 mime-types: 2.1.35 + fraction.js@4.3.7: {} + + fs.realpath@1.0.0: {} + fsevents@2.3.3: optional: true @@ -5726,6 +6605,14 @@ snapshots: package-json-from-dist: 1.0.0 path-scurry: 1.11.1 + glob@8.1.0: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 5.1.6 + once: 1.4.0 + globals@11.12.0: {} globals@13.24.0: @@ -5736,6 +6623,14 @@ snapshots: globals@15.9.0: {} + globby@13.2.2: + dependencies: + dir-glob: 3.0.1 + fast-glob: 3.3.2 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 4.0.0 + graceful-fs@4.2.11: {} graphemer@1.4.0: {} @@ -5769,6 +6664,8 @@ snapshots: hono@4.5.9: {} + hookable@5.5.3: {} + hosted-git-info@2.8.9: {} html-encoding-sniffer@4.0.0: @@ -5827,6 +6724,13 @@ snapshots: indent-string@4.0.0: {} + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + iron-webcrypto@1.2.1: {} is-alphabetical@1.0.4: {} @@ -5868,12 +6772,18 @@ snapshots: dependencies: is-docker: 3.0.0 + is-module@1.0.0: {} + is-number@7.0.0: {} is-path-inside@3.0.3: {} is-potential-custom-element-name@1.0.1: {} + is-reference@1.2.1: + dependencies: + '@types/estree': 1.0.5 + is-stream@3.0.0: {} is-what@4.1.16: {} @@ -5991,6 +6901,8 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 + lilconfig@3.1.2: {} + lines-and-columns@1.2.4: {} listhen@1.7.2: @@ -6033,8 +6945,12 @@ snapshots: lodash-es@4.17.21: {} + lodash.memoize@4.1.2: {} + lodash.merge@4.6.2: {} + lodash.uniq@4.5.0: {} + lodash@4.17.21: {} loupe@3.1.1: @@ -6077,6 +6993,8 @@ snapshots: mdast-util-to-string@2.0.0: {} + mdn-data@2.0.28: {} + mdn-data@2.0.30: {} merge-anything@5.1.7: @@ -6138,12 +7056,34 @@ snapshots: dependencies: brace-expansion: 1.1.11 + minimatch@5.1.6: + dependencies: + brace-expansion: 2.0.1 + minimatch@9.0.5: dependencies: brace-expansion: 2.0.1 minipass@7.1.2: {} + mkdist@1.5.4(typescript@5.5.4): + dependencies: + autoprefixer: 10.4.20(postcss@8.4.41) + citty: 0.1.6 + cssnano: 7.0.5(postcss@8.4.41) + defu: 6.1.4 + esbuild: 0.23.1 + fast-glob: 3.3.2 + jiti: 1.21.6 + mlly: 1.7.1 + pathe: 1.1.2 + pkg-types: 1.2.0 + postcss: 8.4.41 + postcss-nested: 6.2.0(postcss@8.4.41) + semver: 7.6.3 + optionalDependencies: + typescript: 5.5.4 + mlly@1.7.1: dependencies: acorn: 8.12.1 @@ -6188,6 +7128,8 @@ snapshots: normalize-path@3.0.0: {} + normalize-range@0.1.2: {} + npm-run-path@5.3.0: dependencies: path-key: 4.0.0 @@ -6208,6 +7150,10 @@ snapshots: on-exit-leak-free@2.1.2: {} + once@1.4.0: + dependencies: + wrappy: 1.0.2 + onetime@6.0.0: dependencies: mimic-fn: 4.0.0 @@ -6289,6 +7235,8 @@ snapshots: path-to-regexp@6.2.2: {} + path-type@4.0.0: {} + pathe@1.1.2: {} pathval@2.0.0: {} @@ -6330,11 +7278,167 @@ snapshots: pluralize@8.0.0: {} + postcss-calc@10.0.2(postcss@8.4.41): + dependencies: + postcss: 8.4.41 + postcss-selector-parser: 6.1.2 + postcss-value-parser: 4.2.0 + + postcss-colormin@7.0.2(postcss@8.4.41): + dependencies: + browserslist: 4.23.3 + caniuse-api: 3.0.0 + colord: 2.9.3 + postcss: 8.4.41 + postcss-value-parser: 4.2.0 + + postcss-convert-values@7.0.3(postcss@8.4.41): + dependencies: + browserslist: 4.23.3 + postcss: 8.4.41 + postcss-value-parser: 4.2.0 + + postcss-discard-comments@7.0.2(postcss@8.4.41): + dependencies: + postcss: 8.4.41 + postcss-selector-parser: 6.1.2 + + postcss-discard-duplicates@7.0.1(postcss@8.4.41): + dependencies: + postcss: 8.4.41 + + postcss-discard-empty@7.0.0(postcss@8.4.41): + dependencies: + postcss: 8.4.41 + + postcss-discard-overridden@7.0.0(postcss@8.4.41): + dependencies: + postcss: 8.4.41 + + postcss-merge-longhand@7.0.3(postcss@8.4.41): + dependencies: + postcss: 8.4.41 + postcss-value-parser: 4.2.0 + stylehacks: 7.0.3(postcss@8.4.41) + + postcss-merge-rules@7.0.3(postcss@8.4.41): + dependencies: + browserslist: 4.23.3 + caniuse-api: 3.0.0 + cssnano-utils: 5.0.0(postcss@8.4.41) + postcss: 8.4.41 + postcss-selector-parser: 6.1.2 + + postcss-minify-font-values@7.0.0(postcss@8.4.41): + dependencies: + postcss: 8.4.41 + postcss-value-parser: 4.2.0 + + postcss-minify-gradients@7.0.0(postcss@8.4.41): + dependencies: + colord: 2.9.3 + cssnano-utils: 5.0.0(postcss@8.4.41) + postcss: 8.4.41 + postcss-value-parser: 4.2.0 + + postcss-minify-params@7.0.2(postcss@8.4.41): + dependencies: + browserslist: 4.23.3 + cssnano-utils: 5.0.0(postcss@8.4.41) + postcss: 8.4.41 + postcss-value-parser: 4.2.0 + + postcss-minify-selectors@7.0.3(postcss@8.4.41): + dependencies: + cssesc: 3.0.0 + postcss: 8.4.41 + postcss-selector-parser: 6.1.2 + + postcss-nested@6.2.0(postcss@8.4.41): + dependencies: + postcss: 8.4.41 + postcss-selector-parser: 6.1.2 + + postcss-normalize-charset@7.0.0(postcss@8.4.41): + dependencies: + postcss: 8.4.41 + + postcss-normalize-display-values@7.0.0(postcss@8.4.41): + dependencies: + postcss: 8.4.41 + postcss-value-parser: 4.2.0 + + postcss-normalize-positions@7.0.0(postcss@8.4.41): + dependencies: + postcss: 8.4.41 + postcss-value-parser: 4.2.0 + + postcss-normalize-repeat-style@7.0.0(postcss@8.4.41): + dependencies: + postcss: 8.4.41 + postcss-value-parser: 4.2.0 + + postcss-normalize-string@7.0.0(postcss@8.4.41): + dependencies: + postcss: 8.4.41 + postcss-value-parser: 4.2.0 + + postcss-normalize-timing-functions@7.0.0(postcss@8.4.41): + dependencies: + postcss: 8.4.41 + postcss-value-parser: 4.2.0 + + postcss-normalize-unicode@7.0.2(postcss@8.4.41): + dependencies: + browserslist: 4.23.3 + postcss: 8.4.41 + postcss-value-parser: 4.2.0 + + postcss-normalize-url@7.0.0(postcss@8.4.41): + dependencies: + postcss: 8.4.41 + postcss-value-parser: 4.2.0 + + postcss-normalize-whitespace@7.0.0(postcss@8.4.41): + dependencies: + postcss: 8.4.41 + postcss-value-parser: 4.2.0 + + postcss-ordered-values@7.0.1(postcss@8.4.41): + dependencies: + cssnano-utils: 5.0.0(postcss@8.4.41) + postcss: 8.4.41 + postcss-value-parser: 4.2.0 + + postcss-reduce-initial@7.0.2(postcss@8.4.41): + dependencies: + browserslist: 4.23.3 + caniuse-api: 3.0.0 + postcss: 8.4.41 + + postcss-reduce-transforms@7.0.0(postcss@8.4.41): + dependencies: + postcss: 8.4.41 + postcss-value-parser: 4.2.0 + postcss-selector-parser@6.1.2: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 + postcss-svgo@7.0.1(postcss@8.4.41): + dependencies: + postcss: 8.4.41 + postcss-value-parser: 4.2.0 + svgo: 3.3.2 + + postcss-unique-selectors@7.0.2(postcss@8.4.41): + dependencies: + postcss: 8.4.41 + postcss-selector-parser: 6.1.2 + + postcss-value-parser@4.2.0: {} + postcss@8.4.41: dependencies: nanoid: 3.3.7 @@ -6343,6 +7447,8 @@ snapshots: prelude-ls@1.2.1: {} + pretty-bytes@6.1.1: {} + printable-characters@1.0.42: {} process-warning@4.0.0: {} @@ -6421,6 +7527,14 @@ snapshots: reusify@1.0.4: {} + rollup-plugin-dts@6.1.1(rollup@3.29.4)(typescript@5.5.4): + dependencies: + magic-string: 0.30.11 + rollup: 3.29.4 + typescript: 5.5.4 + optionalDependencies: + '@babel/code-frame': 7.24.7 + rollup-plugin-inject@3.0.2: dependencies: estree-walker: 0.6.1 @@ -6435,6 +7549,10 @@ snapshots: dependencies: estree-walker: 0.6.1 + rollup@3.29.4: + optionalDependencies: + fsevents: 2.3.3 + rollup@4.21.0: dependencies: '@types/estree': 1.0.5 @@ -6481,6 +7599,8 @@ snapshots: refa: 0.12.1 regexp-ast-analysis: 0.7.1 + scule@1.3.0: {} + selfsigned@2.4.1: dependencies: '@types/node-forge': 1.3.11 @@ -6516,6 +7636,8 @@ snapshots: sisteransi@1.0.5: {} + slash@4.0.0: {} + slashes@3.0.12: {} solid-js@1.8.22: @@ -6625,6 +7747,12 @@ snapshots: strip-json-comments@3.1.1: {} + stylehacks@7.0.3(postcss@8.4.41): + dependencies: + browserslist: 4.23.3 + postcss: 8.4.41 + postcss-selector-parser: 6.1.2 + supports-color@5.5.0: dependencies: has-flag: 3.0.0 @@ -6635,6 +7763,16 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} + svgo@3.3.2: + dependencies: + '@trysound/sax': 0.2.0 + commander: 7.2.0 + css-select: 5.1.0 + css-tree: 2.3.1 + css-what: 6.1.0 + csso: 5.0.5 + picocolors: 1.0.1 + symbol-tree@3.2.4: {} synckit@0.6.2: @@ -6739,6 +7877,39 @@ snapshots: ulid-workers@2.1.0: {} + unbuild@2.0.0(typescript@5.5.4): + dependencies: + '@rollup/plugin-alias': 5.1.0(rollup@3.29.4) + '@rollup/plugin-commonjs': 25.0.8(rollup@3.29.4) + '@rollup/plugin-json': 6.1.0(rollup@3.29.4) + '@rollup/plugin-node-resolve': 15.2.3(rollup@3.29.4) + '@rollup/plugin-replace': 5.0.7(rollup@3.29.4) + '@rollup/pluginutils': 5.1.0(rollup@3.29.4) + chalk: 5.3.0 + citty: 0.1.6 + consola: 3.2.3 + defu: 6.1.4 + esbuild: 0.19.12 + globby: 13.2.2 + hookable: 5.5.3 + jiti: 1.21.6 + magic-string: 0.30.11 + mkdist: 1.5.4(typescript@5.5.4) + mlly: 1.7.1 + pathe: 1.1.2 + pkg-types: 1.2.0 + pretty-bytes: 6.1.1 + rollup: 3.29.4 + rollup-plugin-dts: 6.1.1(rollup@3.29.4)(typescript@5.5.4) + scule: 1.3.0 + untyped: 1.4.2 + optionalDependencies: + typescript: 5.5.4 + transitivePeerDependencies: + - sass + - supports-color + - vue-tsc + unconfig@0.5.5: dependencies: '@antfu/utils': 0.7.10 @@ -6833,6 +8004,18 @@ snapshots: consola: 3.2.3 pathe: 1.1.2 + untyped@1.4.2: + dependencies: + '@babel/core': 7.25.2 + '@babel/standalone': 7.25.6 + '@babel/types': 7.25.4 + defu: 6.1.4 + jiti: 1.21.6 + mri: 1.2.0 + scule: 1.3.0 + transitivePeerDependencies: + - supports-color + update-browserslist-db@1.1.0(browserslist@4.23.3): dependencies: browserslist: 4.23.3 @@ -7029,6 +8212,8 @@ snapshots: string-width: 5.1.2 strip-ansi: 7.1.0 + wrappy@1.0.2: {} + ws@8.18.0: {} xml-name-validator@4.0.0: {}