feat: replace Web Speech API with Kokoro TTS for high-quality voices

Adds kokoro-js (82M model, 28 distinct voices) as primary TTS engine with
automatic fallback to speechSynthesis while model loads. All 60+ voice
profiles mapped to real Kokoro voices. Common fight phrases pre-cached
for instant playback.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-03-08 17:30:36 +00:00
co-authored by Claude Opus 4.6
parent dc5ea69180
commit a540320901
5 changed files with 913 additions and 13 deletions
+1
View File
@@ -9,6 +9,7 @@
},
"dependencies": {
"kaplay": "^3001.0.19",
"kokoro-js": "^1.2.1",
"nostr-tools": "^2.23.3",
"vue": "^3.5.13",
"vue-router": "^4.5.1"
+35 -13
View File
@@ -1,4 +1,7 @@
// Procedural 8-bit sound system + announcer voice using Web Audio + Speech Synthesis
// Procedural 8-bit sound system + announcer voice using Web Audio + Kokoro TTS
// Falls back to Speech Synthesis if Kokoro model hasn't loaded yet
import { initKokoro, isKokoroReady, kokoroSpeak, kokoroSpeakAsync, kokoroStop, setAudioContext } from './tts'
let ctx: AudioContext | null = null
let musicGain: GainNode | null = null
let sfxGain: GainNode | null = null
@@ -307,12 +310,18 @@ let _speechQueueDepth = 0
const VOICE_VOLUME_SCALE = 0.7
function speak(text: string, profileName: string, cancelPrevious: boolean = false, _echo: boolean = false) {
if (typeof speechSynthesis === 'undefined') return
if (masterMuted) return
// Try Kokoro TTS first — high quality, no browser bugs
if (isKokoroReady() && sfxGain) {
const profile = voiceProfiles[profileName] || voiceProfiles.announcer
if (cancelPrevious) kokoroStop()
kokoroSpeak(text, profileName, sfxGain, profile.volume * VOICE_VOLUME_SCALE)
return
}
// Fallback: Web Speech API
if (typeof speechSynthesis === 'undefined') return
if (!voicesLoaded) loadVoices()
// Chrome bug: speechSynthesis can get stuck. Nudge it.
if (speechSynthesis.paused) speechSynthesis.resume()
// Flush if queue is getting deep — max 2 queued to prevent buildup
if (cancelPrevious || (speechSynthesis.pending && speechSynthesis.speaking)) {
if (_speechQueueDepth > 2) {
speechSynthesis.cancel()
@@ -329,7 +338,6 @@ function speak(text: string, profileName: string, cancelPrevious: boolean = fals
utter.onend = () => { _speechQueueDepth = Math.max(0, _speechQueueDepth - 1) }
utter.onerror = (ev) => {
_speechQueueDepth = Math.max(0, _speechQueueDepth - 1)
// Retry once on non-cancel errors (interrupted = browser killed it, not us)
if (ev.error !== 'canceled' && ev.error !== 'interrupted') {
setTimeout(() => {
if (!masterMuted && typeof speechSynthesis !== 'undefined') {
@@ -352,11 +360,19 @@ const _isIOS = typeof navigator !== 'undefined' && /iPad|iPhone|iPod/.test(navig
const _isDesktopChrome = typeof navigator !== 'undefined' && /Chrome/.test(navigator.userAgent) && !/Mobile/.test(navigator.userAgent)
/** Core async speak — resolves when speech finishes or bails fast if speech won't work */
function _speakAsyncCore(text: string, profileName: string, rateOverride?: number, cancelPrevious?: boolean): Promise<void> {
async function _speakAsyncCore(text: string, profileName: string, rateOverride?: number, cancelPrevious?: boolean): Promise<void> {
if (masterMuted) return
// Try Kokoro TTS first
if (isKokoroReady() && sfxGain) {
if (cancelPrevious) kokoroStop()
const profile = voiceProfiles[profileName] || voiceProfiles.announcer
const handled = await kokoroSpeakAsync(text, profileName, sfxGain, profile.volume * VOICE_VOLUME_SCALE)
if (handled) return
}
// Fallback: Web Speech API
return new Promise<void>((resolve) => {
if (typeof speechSynthesis === 'undefined' || masterMuted) { resolve(); return }
if (typeof speechSynthesis === 'undefined') { resolve(); return }
if (!voicesLoaded) loadVoices()
// No voices available = speech won't work, bail immediately
if (!voicesLoaded) { resolve(); return }
if (speechSynthesis.paused) speechSynthesis.resume()
if (cancelPrevious) { speechSynthesis.cancel(); _speechQueueDepth = 0 }
@@ -377,14 +393,10 @@ function _speakAsyncCore(text: string, profileName: string, rateOverride?: numbe
_speechQueueDepth = Math.max(0, _speechQueueDepth - 1)
resolve()
}
// Hard safety cap — never block longer than 8s
const safetyTimeout = setTimeout(cleanup, 8_000)
// Fast bail: if speech hasn't started within 500ms, it's not going to work (mobile/no gesture)
const startupCheck = setTimeout(() => {
if (!speechSynthesis.speaking && !speechSynthesis.pending) cleanup()
}, 500)
// Desktop Chrome keepalive: periodic pause/resume prevents Chrome's 15s silent cutoff
// Do NOT do this on iOS — it permanently kills speech on Safari
let keepalive: ReturnType<typeof setInterval> | null = null
if (_isDesktopChrome) {
keepalive = setInterval(() => {
@@ -412,6 +424,7 @@ function speakAsync(text: string, profileName: string, cancelPrevious: boolean =
export function stopAllAudio() {
stopMusic()
kokoroStop()
if (typeof speechSynthesis !== 'undefined') speechSynthesis.cancel()
_speechQueueDepth = 0
// Disconnect gain nodes to instantly kill all in-flight oscillators/buffers,
@@ -435,6 +448,11 @@ export function stopAllAudio() {
// Public voice functions
export function announce(text: string, pitch?: number, rate?: number) {
if (masterMuted) return
// Kokoro ignores pitch/rate overrides — just use the announcer profile
if (isKokoroReady()) {
speak(text, 'announcer')
return
}
if (pitch !== undefined || rate !== undefined) {
if (typeof speechSynthesis === 'undefined') return
if (!voicesLoaded) loadVoices()
@@ -2846,6 +2864,7 @@ export function setMasterMute(muted: boolean) {
if (muted) {
if (musicGain) musicGain.gain.value = 0
if (sfxGain) sfxGain.gain.value = 0
kokoroStop()
if (typeof speechSynthesis !== 'undefined') speechSynthesis.cancel()
} else {
if (musicGain) musicGain.gain.value = MUSIC_VOL
@@ -2863,7 +2882,10 @@ export async function ensureAudioContext() {
if (c.state === 'suspended') {
try { await c.resume() } catch {}
}
// Prime speech synthesis on user gesture — mobile browsers require
// Share AudioContext with kokoro and start loading the model
setAudioContext(c)
initKokoro()
// Prime speech synthesis as fallback — mobile browsers require
// a speak() call inside a user gesture to unlock speechSynthesis
if (typeof speechSynthesis !== 'undefined') {
if (!voicesLoaded) loadVoices()
+303
View File
@@ -0,0 +1,303 @@
// Kokoro TTS engine — high-quality client-side text-to-speech
// Lazy-loads the 86MB q8 model on first use, caches in browser storage.
// Falls through to speechSynthesis if model isn't ready yet.
import type { KokoroTTS as KokoroTTSType } from 'kokoro-js'
type KokoroVoice = 'af_heart' | 'af_alloy' | 'af_aoede' | 'af_bella' | 'af_jessica' | 'af_kore' |
'af_nicole' | 'af_nova' | 'af_river' | 'af_sarah' | 'af_sky' |
'am_adam' | 'am_echo' | 'am_eric' | 'am_fenrir' | 'am_liam' | 'am_michael' | 'am_onyx' | 'am_puck' | 'am_santa' |
'bf_emma' | 'bf_isabella' | 'bf_alice' | 'bf_lily' |
'bm_daniel' | 'bm_fable' | 'bm_george' | 'bm_lewis'
interface VoiceMapping {
voice: KokoroVoice
speed: number
}
// Map each voice profile to a kokoro voice + speed modifier.
// With 28 distinct voices, each profile gets a genuinely different voice.
const VOICE_MAP: Record<string, VoiceMapping> = {
// --- Authoritative / announcer ---
announcer: { voice: 'am_fenrir', speed: 0.95 },
deep: { voice: 'am_onyx', speed: 0.85 },
smooth: { voice: 'am_liam', speed: 0.95 },
question_reader:{ voice: 'af_kore', speed: 1.05 },
news: { voice: 'am_michael', speed: 1.0 },
// --- High energy ---
hype: { voice: 'af_heart', speed: 1.3 },
screamer: { voice: 'af_sarah', speed: 1.5 },
sportscaster: { voice: 'am_michael', speed: 1.4 },
auctioneer: { voice: 'am_puck', speed: 1.8 },
hyper: { voice: 'af_nova', speed: 1.8 },
punk: { voice: 'am_puck', speed: 1.2 },
drill: { voice: 'am_onyx', speed: 1.15 },
karen: { voice: 'af_jessica', speed: 1.4 },
terrified: { voice: 'af_sky', speed: 1.6 },
power_up: { voice: 'af_river', speed: 1.3 },
wrestler_v: { voice: 'am_fenrir', speed: 1.0 },
// --- Deep / menacing ---
boomer: { voice: 'bm_george', speed: 0.7 },
movie: { voice: 'am_echo', speed: 0.8 },
demon_v: { voice: 'bm_lewis', speed: 0.7 },
final_boss: { voice: 'am_echo', speed: 0.55 },
boss_taunt: { voice: 'am_onyx', speed: 0.9 },
game_over: { voice: 'am_fenrir', speed: 0.8 },
giant: { voice: 'bm_george', speed: 0.5 },
mainframe: { voice: 'am_adam', speed: 0.6 },
// --- Calm / wise ---
preacher: { voice: 'bm_daniel', speed: 0.75 },
wizard_v: { voice: 'am_echo', speed: 0.85 },
sensei: { voice: 'bm_fable', speed: 0.7 },
professor: { voice: 'bm_daniel', speed: 0.8 },
ancient: { voice: 'am_eric', speed: 0.45 },
opera: { voice: 'bf_emma', speed: 0.65 },
// --- Cute / high ---
chipmunk: { voice: 'af_nicole', speed: 1.7 },
baby: { voice: 'bf_lily', speed: 1.1 },
fairy: { voice: 'af_bella', speed: 1.2 },
angel: { voice: 'af_bella', speed: 0.9 },
tutorial: { voice: 'af_nicole', speed: 1.1 },
valley: { voice: 'af_heart', speed: 1.2 },
// --- Robots / computers ---
robot: { voice: 'am_adam', speed: 0.9 },
ai_core: { voice: 'af_alloy', speed: 1.0 },
mech: { voice: 'am_adam', speed: 0.8 },
android_v: { voice: 'af_alloy', speed: 1.05 },
siri: { voice: 'af_aoede', speed: 1.0 },
hal: { voice: 'am_echo', speed: 0.7 },
dial_up: { voice: 'af_sky', speed: 1.4 },
glitch: { voice: 'af_sarah', speed: 1.7 },
glitchbot: { voice: 'am_puck', speed: 1.8 },
// --- Accents ---
posh: { voice: 'bf_emma', speed: 0.85 },
aussie: { voice: 'bm_george', speed: 1.05 },
scottish: { voice: 'bm_lewis', speed: 1.1 },
french: { voice: 'bf_isabella', speed: 0.9 },
texan: { voice: 'am_eric', speed: 0.8 },
// --- Character voices ---
whisper: { voice: 'af_bella', speed: 0.7 },
surfer: { voice: 'am_liam', speed: 1.0 },
pirate_v: { voice: 'am_eric', speed: 0.95 },
cowboy_v: { voice: 'am_eric', speed: 0.85 },
ninja_v: { voice: 'bm_fable', speed: 1.05 },
alien_v: { voice: 'bf_alice', speed: 0.8 },
echo_v: { voice: 'am_echo', speed: 0.8 },
// --- Old people ---
grandpa: { voice: 'am_eric', speed: 0.6 },
grandma: { voice: 'bf_lily', speed: 0.55 },
crotchety: { voice: 'bm_daniel', speed: 1.0 },
// --- Misc characters ---
drunk: { voice: 'am_liam', speed: 0.6 },
sleepy: { voice: 'bm_fable', speed: 0.4 },
stoner: { voice: 'am_liam', speed: 0.5 },
npc: { voice: 'af_river', speed: 0.95 },
conspiracy: { voice: 'bm_fable', speed: 1.2 },
}
// Default fallback
const DEFAULT_VOICE: VoiceMapping = { voice: 'am_fenrir', speed: 1.0 }
let ttsInstance: KokoroTTSType | null = null
let ttsLoading = false
let ttsLoadFailed = false
let _audioCtx: AudioContext | null = null
// Audio cache: key = "voice:speed:text" → AudioBuffer
const audioCache = new Map<string, AudioBuffer>()
const MAX_CACHE = 200
// Currently playing sources (for stop)
const activeSources: Set<AudioBufferSourceNode> = new Set()
function getAudioCtx(): AudioContext {
if (!_audioCtx) _audioCtx = new AudioContext()
if (_audioCtx.state === 'suspended') _audioCtx.resume().catch(() => {})
return _audioCtx
}
/** Set the shared AudioContext (called from sounds.ts so we share one context) */
export function setAudioContext(ctx: AudioContext) {
_audioCtx = ctx
}
/** Is the kokoro model loaded and ready? */
export function isKokoroReady(): boolean {
return ttsInstance !== null
}
/** Is the kokoro model currently loading? */
export function isKokoroLoading(): boolean {
return ttsLoading
}
/** Start loading the kokoro model. Call early (e.g. on first user gesture). */
export async function initKokoro(onProgress?: (pct: number) => void): Promise<void> {
if (ttsInstance || ttsLoading || ttsLoadFailed) return
ttsLoading = true
try {
const { KokoroTTS } = await import('kokoro-js')
ttsInstance = await KokoroTTS.from_pretrained('onnx-community/Kokoro-82M-ONNX', {
dtype: 'q8',
device: null, // auto-detect (WebGPU → WASM fallback)
progress_callback: onProgress ? (p: any) => {
if (p.progress !== undefined) onProgress(p.progress)
} : undefined,
})
ttsLoading = false
// Pre-cache common fight phrases in the background
_precacheCommon()
} catch (e) {
console.warn('[kokoro] Failed to load TTS model:', e)
ttsLoading = false
ttsLoadFailed = true
}
}
// Common phrases to pre-generate so they play instantly
const PRECACHE_PHRASES: Array<{ text: string; profile: string }> = [
{ text: 'K. O.!', profile: 'announcer' },
{ text: 'Devastating!', profile: 'deep' },
{ text: 'Flawless victory!', profile: 'deep' },
{ text: 'Finish it!', profile: 'announcer' },
{ text: 'Fatality!', profile: 'deep' },
{ text: 'Round one!', profile: 'announcer' },
{ text: 'Round two!', profile: 'announcer' },
{ text: 'Round three!', profile: 'announcer' },
{ text: 'Fight!', profile: 'announcer' },
]
async function _precacheCommon() {
if (!ttsInstance) return
for (const { text, profile } of PRECACHE_PHRASES) {
try {
await _generateAndCache(text, profile)
} catch { /* swallow — non-critical */ }
}
}
function _cacheKey(text: string, profile: string): string {
const m = VOICE_MAP[profile] || DEFAULT_VOICE
return `${m.voice}:${m.speed}:${text}`
}
async function _generateAndCache(text: string, profile: string): Promise<AudioBuffer | null> {
if (!ttsInstance) return null
const key = _cacheKey(text, profile)
const cached = audioCache.get(key)
if (cached) return cached
const mapping = VOICE_MAP[profile] || DEFAULT_VOICE
const raw = await ttsInstance.generate(text, {
voice: mapping.voice,
speed: mapping.speed,
})
// Convert Float32Array → AudioBuffer
const ctx = getAudioCtx()
const buf = ctx.createBuffer(1, raw.audio.length, raw.sampling_rate)
buf.getChannelData(0).set(raw.audio)
// Evict oldest if cache is full
if (audioCache.size >= MAX_CACHE) {
const oldest = audioCache.keys().next().value
if (oldest) audioCache.delete(oldest)
}
audioCache.set(key, buf)
return buf
}
/**
* Play audio through the given destination node with volume control.
* Returns a promise that resolves when playback finishes.
*/
function _playBuffer(buf: AudioBuffer, dest: AudioNode, volume: number): Promise<void> {
return new Promise<void>((resolve) => {
const ctx = getAudioCtx()
const src = ctx.createBufferSource()
src.buffer = buf
const gain = ctx.createGain()
gain.gain.value = volume
src.connect(gain)
gain.connect(dest)
activeSources.add(src)
src.onended = () => {
activeSources.delete(src)
resolve()
}
src.start()
})
}
/**
* Generate and play TTS. Returns a promise that resolves when done.
* Returns null if kokoro isn't ready (caller should fall back).
*/
export async function kokoroSpeakAsync(
text: string,
profileName: string,
dest: AudioNode,
volume: number = 0.7,
): Promise<boolean> {
if (!ttsInstance) return false
try {
const buf = await _generateAndCache(text, profileName)
if (!buf) return false
await _playBuffer(buf, dest, volume)
return true
} catch (e) {
console.warn('[kokoro] Speech generation failed:', e)
return false
}
}
/**
* Fire-and-forget version. Returns true if kokoro handled it, false to fall back.
*/
export function kokoroSpeak(
text: string,
profileName: string,
dest: AudioNode,
volume: number = 0.7,
): boolean {
if (!ttsInstance) return false
// Check cache for instant playback
const key = _cacheKey(text, profileName)
const cached = audioCache.get(key)
if (cached) {
_playBuffer(cached, dest, volume)
return true
}
// Generate async — will play when ready
_generateAndCache(text, profileName).then(buf => {
if (buf) _playBuffer(buf, dest, volume)
}).catch(() => {})
return true
}
/** Stop all currently playing kokoro audio */
export function kokoroStop() {
for (const src of activeSources) {
try { src.stop() } catch {}
}
activeSources.clear()
}
/** Clear the audio cache */
export function kokoroClearCache() {
audioCache.clear()
}
/** Get the kokoro voice mapping for a profile name */
export function getKokoroVoice(profileName: string): VoiceMapping {
return VOICE_MAP[profileName] || DEFAULT_VOICE
}
+1
View File
@@ -28,6 +28,7 @@ export default defineConfig({
},
workbox: {
globPatterns: ['**/*.{js,css,html,svg,png,woff,woff2}'],
maximumFileSizeToCacheInBytes: 5 * 1024 * 1024, // 5MB — kokoro TTS chunk is ~2.2MB
cleanupOutdatedCaches: true,
skipWaiting: true,
clientsClaim: true,
+573
View File
@@ -23,6 +23,9 @@ importers:
kaplay:
specifier: ^3001.0.19
version: 3001.0.19
kokoro-js:
specifier: ^1.2.1
version: 1.2.1
nostr-tools:
specifier: ^2.23.3
version: 2.23.3(typescript@5.9.3)
@@ -611,6 +614,9 @@ packages:
'@drizzle-team/brocli@0.10.2':
resolution: {integrity: sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==}
'@emnapi/runtime@1.8.1':
resolution: {integrity: sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==}
'@esbuild-kit/core-utils@3.3.2':
resolution: {integrity: sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==}
deprecated: 'Merged into tsx: https://tsx.is'
@@ -1051,10 +1057,174 @@ packages:
peerDependencies:
hono: ^4
'@huggingface/jinja@0.5.5':
resolution: {integrity: sha512-xRlzazC+QZwr6z4ixEqYHo9fgwhTZ3xNSdljlKfUFGZSdlvt166DljRELFUfFytlYOYvo3vTisA/AFOuOAzFQQ==}
engines: {node: '>=18'}
'@huggingface/transformers@3.8.1':
resolution: {integrity: sha512-tsTk4zVjImqdqjS8/AOZg2yNLd1z9S5v+7oUPpXaasDRwEDhB+xnglK1k5cad26lL5/ZIaeREgWWy0bs9y9pPA==}
'@img/colour@1.1.0':
resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==}
engines: {node: '>=18'}
'@img/sharp-darwin-arm64@0.34.5':
resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [arm64]
os: [darwin]
'@img/sharp-darwin-x64@0.34.5':
resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [x64]
os: [darwin]
'@img/sharp-libvips-darwin-arm64@1.2.4':
resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==}
cpu: [arm64]
os: [darwin]
'@img/sharp-libvips-darwin-x64@1.2.4':
resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==}
cpu: [x64]
os: [darwin]
'@img/sharp-libvips-linux-arm64@1.2.4':
resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@img/sharp-libvips-linux-arm@1.2.4':
resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==}
cpu: [arm]
os: [linux]
libc: [glibc]
'@img/sharp-libvips-linux-ppc64@1.2.4':
resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==}
cpu: [ppc64]
os: [linux]
libc: [glibc]
'@img/sharp-libvips-linux-riscv64@1.2.4':
resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==}
cpu: [riscv64]
os: [linux]
libc: [glibc]
'@img/sharp-libvips-linux-s390x@1.2.4':
resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==}
cpu: [s390x]
os: [linux]
libc: [glibc]
'@img/sharp-libvips-linux-x64@1.2.4':
resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==}
cpu: [x64]
os: [linux]
libc: [glibc]
'@img/sharp-libvips-linuxmusl-arm64@1.2.4':
resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==}
cpu: [arm64]
os: [linux]
libc: [musl]
'@img/sharp-libvips-linuxmusl-x64@1.2.4':
resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==}
cpu: [x64]
os: [linux]
libc: [musl]
'@img/sharp-linux-arm64@0.34.5':
resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@img/sharp-linux-arm@0.34.5':
resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [arm]
os: [linux]
libc: [glibc]
'@img/sharp-linux-ppc64@0.34.5':
resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [ppc64]
os: [linux]
libc: [glibc]
'@img/sharp-linux-riscv64@0.34.5':
resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [riscv64]
os: [linux]
libc: [glibc]
'@img/sharp-linux-s390x@0.34.5':
resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [s390x]
os: [linux]
libc: [glibc]
'@img/sharp-linux-x64@0.34.5':
resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [x64]
os: [linux]
libc: [glibc]
'@img/sharp-linuxmusl-arm64@0.34.5':
resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [arm64]
os: [linux]
libc: [musl]
'@img/sharp-linuxmusl-x64@0.34.5':
resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [x64]
os: [linux]
libc: [musl]
'@img/sharp-wasm32@0.34.5':
resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [wasm32]
'@img/sharp-win32-arm64@0.34.5':
resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [arm64]
os: [win32]
'@img/sharp-win32-ia32@0.34.5':
resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [ia32]
os: [win32]
'@img/sharp-win32-x64@0.34.5':
resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
cpu: [x64]
os: [win32]
'@isaacs/cliui@9.0.0':
resolution: {integrity: sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==}
engines: {node: '>=18'}
'@isaacs/fs-minipass@4.0.1':
resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==}
engines: {node: '>=18.0.0'}
'@jridgewell/gen-mapping@0.3.13':
resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==}
@@ -1089,6 +1259,36 @@ packages:
'@petamoriken/float16@3.9.3':
resolution: {integrity: sha512-8awtpHXCx/bNpFt4mt2xdkgtgVvKqty8VbjHI/WWWQuEw+KLzFot3f4+LkQY9YmOtq7A5GdOnqoIC8Pdygjk2g==}
'@protobufjs/aspromise@1.1.2':
resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==}
'@protobufjs/base64@1.1.2':
resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==}
'@protobufjs/codegen@2.0.4':
resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==}
'@protobufjs/eventemitter@1.1.0':
resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==}
'@protobufjs/fetch@1.1.0':
resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==}
'@protobufjs/float@1.0.2':
resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==}
'@protobufjs/inquire@1.1.0':
resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==}
'@protobufjs/path@1.1.2':
resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==}
'@protobufjs/pool@1.1.0':
resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==}
'@protobufjs/utf8@1.1.0':
resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==}
'@rollup/plugin-babel@5.3.1':
resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==}
engines: {node: '>= 10.0.0'}
@@ -1579,6 +1779,10 @@ packages:
bl@4.1.0:
resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==}
boolean@3.2.0:
resolution: {integrity: sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==}
deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
brace-expansion@2.0.2:
resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==}
@@ -1635,6 +1839,10 @@ packages:
chownr@1.1.4:
resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==}
chownr@3.0.0:
resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==}
engines: {node: '>=18'}
cliui@8.0.1:
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
engines: {node: '>=12'}
@@ -1727,6 +1935,9 @@ packages:
resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
engines: {node: '>=8'}
detect-node@2.1.0:
resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==}
dotenv@17.3.1:
resolution: {integrity: sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA==}
engines: {node: '>=12'}
@@ -1881,6 +2092,9 @@ packages:
resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==}
engines: {node: '>= 0.4'}
es6-error@4.1.1:
resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==}
esbuild-register@3.6.0:
resolution: {integrity: sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==}
peerDependencies:
@@ -1905,6 +2119,10 @@ packages:
resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
engines: {node: '>=6'}
escape-string-regexp@4.0.0:
resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
engines: {node: '>=10'}
estree-walker@1.0.1:
resolution: {integrity: sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==}
@@ -1950,6 +2168,9 @@ packages:
filelist@1.0.6:
resolution: {integrity: sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA==}
flatbuffers@25.9.23:
resolution: {integrity: sha512-MI1qs7Lo4Syw0EOzUl0xjs2lsoeqFku44KpngfIduHBYvzm8h2+7K8YMQh1JtVVVrUvhLpNwqVi4DERegUJhPQ==}
for-each@0.3.5:
resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==}
engines: {node: '>= 0.4'}
@@ -2024,6 +2245,10 @@ packages:
deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
hasBin: true
global-agent@3.0.0:
resolution: {integrity: sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==}
engines: {node: '>=10.0'}
globalthis@1.0.4:
resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==}
engines: {node: '>= 0.4'}
@@ -2035,6 +2260,9 @@ packages:
graceful-fs@4.2.11:
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
guid-typescript@1.0.9:
resolution: {integrity: sha512-Y8T4vYhEfwJOTbouREvG+3XDsjr8E3kIr7uf+JZ0BYloFsttiHU0WfvANVsR7TxNUJa/WpCnw/Ino/p+DeBhBQ==}
has-bigints@1.1.0:
resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==}
engines: {node: '>= 0.4'}
@@ -2233,6 +2461,9 @@ packages:
json-schema@0.4.0:
resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==}
json-stringify-safe@5.0.1:
resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==}
json5@2.2.3:
resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==}
engines: {node: '>=6'}
@@ -2249,6 +2480,9 @@ packages:
resolution: {integrity: sha512-T8GdXGXvgv/vbYVA1lcHzuDNVhp3juOJJE8OZs0vR5MdGNElBvANEeTSnqAAhJpSXtNxpeNy29pqkok3RnXKtg==}
engines: {node: '>=20.0.0'}
kokoro-js@1.2.1:
resolution: {integrity: sha512-oq0HZJWis3t8lERkMJh84WLU86dpYD0EuBPtqYnLlQzyFP1OkyBRDcweAqCfhNOpltyN9j/azp1H6uuC47gShw==}
leven@3.1.0:
resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==}
engines: {node: '>=6'}
@@ -2336,6 +2570,9 @@ packages:
lodash@4.17.23:
resolution: {integrity: sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==}
long@5.3.2:
resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==}
loupe@3.2.1:
resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==}
@@ -2352,6 +2589,10 @@ packages:
magic-string@0.30.21:
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
matcher@3.0.0:
resolution: {integrity: sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==}
engines: {node: '>=10'}
math-intrinsics@1.1.0:
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
engines: {node: '>= 0.4'}
@@ -2379,6 +2620,10 @@ packages:
resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==}
engines: {node: '>=16 || 14 >=14.17'}
minizlib@3.1.0:
resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==}
engines: {node: '>= 18'}
mkdirp-classic@0.5.3:
resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==}
@@ -2434,6 +2679,19 @@ packages:
once@1.4.0:
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
onnxruntime-common@1.21.0:
resolution: {integrity: sha512-Q632iLLrtCAVOTO65dh2+mNbQir/QNTVBG3h/QdZBpns7mZ0RYbLRBgGABPbpU9351AgYy7SJf1WaeVwMrBFPQ==}
onnxruntime-common@1.22.0-dev.20250409-89f8206ba4:
resolution: {integrity: sha512-vDJMkfCfb0b1A836rgHj+ORuZf4B4+cc2bASQtpeoJLueuFc5DuYwjIZUBrSvx/fO5IrLjLz+oTrB3pcGlhovQ==}
onnxruntime-node@1.21.0:
resolution: {integrity: sha512-NeaCX6WW2L8cRCSqy3bInlo5ojjQqu2fD3D+9W5qb5irwxhEyWKXeH2vZ8W9r6VxaMPUan+4/7NDwZMtouZxEw==}
os: [win32, darwin, linux]
onnxruntime-web@1.22.0-dev.20250409-89f8206ba4:
resolution: {integrity: sha512-0uS76OPgH0hWCPrFKlL8kYVV7ckM7t/36HfbgoFw6Nd0CZVVbQC4PkrR8mBX8LtNUFZO25IQBqV2Hx2ho3FlbQ==}
own-keys@1.0.1:
resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==}
engines: {node: '>= 0.4'}
@@ -2462,6 +2720,9 @@ packages:
resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==}
engines: {node: '>= 14.16'}
phonemizer@1.2.1:
resolution: {integrity: sha512-v0KJ4mi2T4Q7eJQ0W15Xd4G9k4kICSXE8bpDeJ8jisL4RyJhNWsweKTOi88QXFc4r4LZlz5jVL5lCHhkpdT71A==}
picocolors@1.1.1:
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
@@ -2473,6 +2734,9 @@ packages:
resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==}
engines: {node: '>=12'}
platform@1.3.6:
resolution: {integrity: sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==}
possible-typed-array-names@1.1.0:
resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==}
engines: {node: '>= 0.4'}
@@ -2495,6 +2759,10 @@ packages:
resolution: {integrity: sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==}
engines: {node: ^14.13.1 || >=16.0.0}
protobufjs@7.5.4:
resolution: {integrity: sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==}
engines: {node: '>=12.0.0'}
pump@3.0.4:
resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==}
@@ -2555,6 +2823,10 @@ packages:
engines: {node: '>= 0.4'}
hasBin: true
roarr@2.15.4:
resolution: {integrity: sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==}
engines: {node: '>=8.0'}
rollup@2.80.0:
resolution: {integrity: sha512-cIFJOD1DESzpjOBl763Kp1AH7UE/0fcdHe6rZXUdQ9c50uvgigvW97u3IcSeBwOkgqL/PXPBktBCh0KEu5L8XQ==}
engines: {node: '>=10.0.0'}
@@ -2583,6 +2855,9 @@ packages:
resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==}
engines: {node: '>= 0.4'}
semver-compare@1.0.0:
resolution: {integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==}
semver@6.3.1:
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
hasBin: true
@@ -2592,6 +2867,10 @@ packages:
engines: {node: '>=10'}
hasBin: true
serialize-error@7.0.1:
resolution: {integrity: sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==}
engines: {node: '>=10'}
serialize-javascript@6.0.2:
resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==}
@@ -2607,6 +2886,10 @@ packages:
resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==}
engines: {node: '>= 0.4'}
sharp@0.34.5:
resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
shebang-command@2.0.0:
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
engines: {node: '>=8'}
@@ -2672,6 +2955,9 @@ packages:
resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==}
deprecated: Please use @jridgewell/sourcemap-codec instead
sprintf-js@1.1.3:
resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==}
stackback@0.0.2:
resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
@@ -2750,6 +3036,10 @@ packages:
resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==}
engines: {node: '>=6'}
tar@7.5.10:
resolution: {integrity: sha512-8mOPs1//5q/rlkNSPcCegA6hiHJYDmSLEI8aMH/CdSQJNWztHC9WHNam5zdQlfpTwB9Xp7IBEsHfV5LKMJGVAw==}
engines: {node: '>=18'}
temp-dir@2.0.0:
resolution: {integrity: sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==}
engines: {node: '>=8'}
@@ -2803,6 +3093,10 @@ packages:
tunnel-agent@0.6.0:
resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==}
type-fest@0.13.1:
resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==}
engines: {node: '>=10'}
type-fest@0.16.0:
resolution: {integrity: sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==}
engines: {node: '>=10'}
@@ -3079,6 +3373,10 @@ packages:
yallist@3.1.1:
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
yallist@5.0.0:
resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==}
engines: {node: '>=18'}
yargs-parser@21.1.1:
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
engines: {node: '>=12'}
@@ -3759,6 +4057,11 @@ snapshots:
'@drizzle-team/brocli@0.10.2': {}
'@emnapi/runtime@1.8.1':
dependencies:
tslib: 2.8.1
optional: true
'@esbuild-kit/core-utils@3.3.2':
dependencies:
esbuild: 0.18.20
@@ -3986,8 +4289,117 @@ snapshots:
dependencies:
hono: 4.12.5
'@huggingface/jinja@0.5.5': {}
'@huggingface/transformers@3.8.1':
dependencies:
'@huggingface/jinja': 0.5.5
onnxruntime-node: 1.21.0
onnxruntime-web: 1.22.0-dev.20250409-89f8206ba4
sharp: 0.34.5
'@img/colour@1.1.0': {}
'@img/sharp-darwin-arm64@0.34.5':
optionalDependencies:
'@img/sharp-libvips-darwin-arm64': 1.2.4
optional: true
'@img/sharp-darwin-x64@0.34.5':
optionalDependencies:
'@img/sharp-libvips-darwin-x64': 1.2.4
optional: true
'@img/sharp-libvips-darwin-arm64@1.2.4':
optional: true
'@img/sharp-libvips-darwin-x64@1.2.4':
optional: true
'@img/sharp-libvips-linux-arm64@1.2.4':
optional: true
'@img/sharp-libvips-linux-arm@1.2.4':
optional: true
'@img/sharp-libvips-linux-ppc64@1.2.4':
optional: true
'@img/sharp-libvips-linux-riscv64@1.2.4':
optional: true
'@img/sharp-libvips-linux-s390x@1.2.4':
optional: true
'@img/sharp-libvips-linux-x64@1.2.4':
optional: true
'@img/sharp-libvips-linuxmusl-arm64@1.2.4':
optional: true
'@img/sharp-libvips-linuxmusl-x64@1.2.4':
optional: true
'@img/sharp-linux-arm64@0.34.5':
optionalDependencies:
'@img/sharp-libvips-linux-arm64': 1.2.4
optional: true
'@img/sharp-linux-arm@0.34.5':
optionalDependencies:
'@img/sharp-libvips-linux-arm': 1.2.4
optional: true
'@img/sharp-linux-ppc64@0.34.5':
optionalDependencies:
'@img/sharp-libvips-linux-ppc64': 1.2.4
optional: true
'@img/sharp-linux-riscv64@0.34.5':
optionalDependencies:
'@img/sharp-libvips-linux-riscv64': 1.2.4
optional: true
'@img/sharp-linux-s390x@0.34.5':
optionalDependencies:
'@img/sharp-libvips-linux-s390x': 1.2.4
optional: true
'@img/sharp-linux-x64@0.34.5':
optionalDependencies:
'@img/sharp-libvips-linux-x64': 1.2.4
optional: true
'@img/sharp-linuxmusl-arm64@0.34.5':
optionalDependencies:
'@img/sharp-libvips-linuxmusl-arm64': 1.2.4
optional: true
'@img/sharp-linuxmusl-x64@0.34.5':
optionalDependencies:
'@img/sharp-libvips-linuxmusl-x64': 1.2.4
optional: true
'@img/sharp-wasm32@0.34.5':
dependencies:
'@emnapi/runtime': 1.8.1
optional: true
'@img/sharp-win32-arm64@0.34.5':
optional: true
'@img/sharp-win32-ia32@0.34.5':
optional: true
'@img/sharp-win32-x64@0.34.5':
optional: true
'@isaacs/cliui@9.0.0': {}
'@isaacs/fs-minipass@4.0.1':
dependencies:
minipass: 7.1.3
'@jridgewell/gen-mapping@0.3.13':
dependencies:
'@jridgewell/sourcemap-codec': 1.5.5
@@ -4022,6 +4434,29 @@ snapshots:
'@petamoriken/float16@3.9.3': {}
'@protobufjs/aspromise@1.1.2': {}
'@protobufjs/base64@1.1.2': {}
'@protobufjs/codegen@2.0.4': {}
'@protobufjs/eventemitter@1.1.0': {}
'@protobufjs/fetch@1.1.0':
dependencies:
'@protobufjs/aspromise': 1.1.2
'@protobufjs/inquire': 1.1.0
'@protobufjs/float@1.0.2': {}
'@protobufjs/inquire@1.1.0': {}
'@protobufjs/path@1.1.2': {}
'@protobufjs/pool@1.1.0': {}
'@protobufjs/utf8@1.1.0': {}
'@rollup/plugin-babel@5.3.1(@babel/core@7.29.0)(rollup@2.80.0)':
dependencies:
'@babel/core': 7.29.0
@@ -4480,6 +4915,8 @@ snapshots:
inherits: 2.0.4
readable-stream: 3.6.2
boolean@3.2.0: {}
brace-expansion@2.0.2:
dependencies:
balanced-match: 1.0.2
@@ -4543,6 +4980,8 @@ snapshots:
chownr@1.1.4: {}
chownr@3.0.0: {}
cliui@8.0.1:
dependencies:
string-width: 4.2.3
@@ -4632,6 +5071,8 @@ snapshots:
detect-libc@2.1.2: {}
detect-node@2.1.0: {}
dotenv@17.3.1: {}
drizzle-kit@0.30.6:
@@ -4757,6 +5198,8 @@ snapshots:
is-date-object: 1.1.0
is-symbol: 1.1.1
es6-error@4.1.1: {}
esbuild-register@3.6.0(esbuild@0.19.12):
dependencies:
debug: 4.4.3
@@ -4846,6 +5289,8 @@ snapshots:
escalade@3.2.0: {}
escape-string-regexp@4.0.0: {}
estree-walker@1.0.1: {}
estree-walker@2.0.2: {}
@@ -4876,6 +5321,8 @@ snapshots:
dependencies:
minimatch: 5.1.9
flatbuffers@25.9.23: {}
for-each@0.3.5:
dependencies:
is-callable: 1.2.7
@@ -4968,6 +5415,15 @@ snapshots:
package-json-from-dist: 1.0.1
path-scurry: 2.0.2
global-agent@3.0.0:
dependencies:
boolean: 3.2.0
es6-error: 4.1.1
matcher: 3.0.0
roarr: 2.15.4
semver: 7.7.4
serialize-error: 7.0.1
globalthis@1.0.4:
dependencies:
define-properties: 1.2.1
@@ -4977,6 +5433,8 @@ snapshots:
graceful-fs@4.2.11: {}
guid-typescript@1.0.9: {}
has-bigints@1.1.0: {}
has-flag@4.0.0: {}
@@ -5155,6 +5613,8 @@ snapshots:
json-schema@0.4.0: {}
json-stringify-safe@5.0.1: {}
json5@2.2.3: {}
jsonfile@6.2.0:
@@ -5167,6 +5627,11 @@ snapshots:
kaplay@3001.0.19: {}
kokoro-js@1.2.1:
dependencies:
'@huggingface/transformers': 3.8.1
phonemizer: 1.2.1
leven@3.1.0: {}
lightningcss-android-arm64@1.31.1:
@@ -5224,6 +5689,8 @@ snapshots:
lodash@4.17.23: {}
long@5.3.2: {}
loupe@3.2.1: {}
lru-cache@11.2.6: {}
@@ -5240,6 +5707,10 @@ snapshots:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.5
matcher@3.0.0:
dependencies:
escape-string-regexp: 4.0.0
math-intrinsics@1.1.0: {}
mimic-response@3.1.0: {}
@@ -5260,6 +5731,10 @@ snapshots:
minipass@7.1.3: {}
minizlib@3.1.0:
dependencies:
minipass: 7.1.3
mkdirp-classic@0.5.3: {}
ms@2.1.3: {}
@@ -5309,6 +5784,25 @@ snapshots:
dependencies:
wrappy: 1.0.2
onnxruntime-common@1.21.0: {}
onnxruntime-common@1.22.0-dev.20250409-89f8206ba4: {}
onnxruntime-node@1.21.0:
dependencies:
global-agent: 3.0.0
onnxruntime-common: 1.21.0
tar: 7.5.10
onnxruntime-web@1.22.0-dev.20250409-89f8206ba4:
dependencies:
flatbuffers: 25.9.23
guid-typescript: 1.0.9
long: 5.3.2
onnxruntime-common: 1.22.0-dev.20250409-89f8206ba4
platform: 1.3.6
protobufjs: 7.5.4
own-keys@1.0.1:
dependencies:
get-intrinsic: 1.3.0
@@ -5332,12 +5826,16 @@ snapshots:
pathval@2.0.1: {}
phonemizer@1.2.1: {}
picocolors@1.1.1: {}
picomatch@2.3.1: {}
picomatch@4.0.3: {}
platform@1.3.6: {}
possible-typed-array-names@1.1.0: {}
postcss@8.5.8:
@@ -5365,6 +5863,21 @@ snapshots:
pretty-bytes@6.1.1: {}
protobufjs@7.5.4:
dependencies:
'@protobufjs/aspromise': 1.1.2
'@protobufjs/base64': 1.1.2
'@protobufjs/codegen': 2.0.4
'@protobufjs/eventemitter': 1.1.0
'@protobufjs/fetch': 1.1.0
'@protobufjs/float': 1.0.2
'@protobufjs/inquire': 1.1.0
'@protobufjs/path': 1.1.2
'@protobufjs/pool': 1.1.0
'@protobufjs/utf8': 1.1.0
'@types/node': 22.19.15
long: 5.3.2
pump@3.0.4:
dependencies:
end-of-stream: 1.4.5
@@ -5442,6 +5955,15 @@ snapshots:
path-parse: 1.0.7
supports-preserve-symlinks-flag: 1.0.0
roarr@2.15.4:
dependencies:
boolean: 3.2.0
detect-node: 2.1.0
globalthis: 1.0.4
json-stringify-safe: 5.0.1
semver-compare: 1.0.0
sprintf-js: 1.1.3
rollup@2.80.0:
optionalDependencies:
fsevents: 2.3.3
@@ -5502,10 +6024,16 @@ snapshots:
es-errors: 1.3.0
is-regex: 1.2.1
semver-compare@1.0.0: {}
semver@6.3.1: {}
semver@7.7.4: {}
serialize-error@7.0.1:
dependencies:
type-fest: 0.13.1
serialize-javascript@6.0.2:
dependencies:
randombytes: 2.1.0
@@ -5532,6 +6060,37 @@ snapshots:
es-errors: 1.3.0
es-object-atoms: 1.1.1
sharp@0.34.5:
dependencies:
'@img/colour': 1.1.0
detect-libc: 2.1.2
semver: 7.7.4
optionalDependencies:
'@img/sharp-darwin-arm64': 0.34.5
'@img/sharp-darwin-x64': 0.34.5
'@img/sharp-libvips-darwin-arm64': 1.2.4
'@img/sharp-libvips-darwin-x64': 1.2.4
'@img/sharp-libvips-linux-arm': 1.2.4
'@img/sharp-libvips-linux-arm64': 1.2.4
'@img/sharp-libvips-linux-ppc64': 1.2.4
'@img/sharp-libvips-linux-riscv64': 1.2.4
'@img/sharp-libvips-linux-s390x': 1.2.4
'@img/sharp-libvips-linux-x64': 1.2.4
'@img/sharp-libvips-linuxmusl-arm64': 1.2.4
'@img/sharp-libvips-linuxmusl-x64': 1.2.4
'@img/sharp-linux-arm': 0.34.5
'@img/sharp-linux-arm64': 0.34.5
'@img/sharp-linux-ppc64': 0.34.5
'@img/sharp-linux-riscv64': 0.34.5
'@img/sharp-linux-s390x': 0.34.5
'@img/sharp-linux-x64': 0.34.5
'@img/sharp-linuxmusl-arm64': 0.34.5
'@img/sharp-linuxmusl-x64': 0.34.5
'@img/sharp-wasm32': 0.34.5
'@img/sharp-win32-arm64': 0.34.5
'@img/sharp-win32-ia32': 0.34.5
'@img/sharp-win32-x64': 0.34.5
shebang-command@2.0.0:
dependencies:
shebang-regex: 3.0.0
@@ -5597,6 +6156,8 @@ snapshots:
sourcemap-codec@1.4.8: {}
sprintf-js@1.1.3: {}
stackback@0.0.2: {}
std-env@3.10.0: {}
@@ -5702,6 +6263,14 @@ snapshots:
inherits: 2.0.4
readable-stream: 3.6.2
tar@7.5.10:
dependencies:
'@isaacs/fs-minipass': 4.0.1
chownr: 3.0.0
minipass: 7.1.3
minizlib: 3.1.0
yallist: 5.0.0
temp-dir@2.0.0: {}
tempy@0.6.0:
@@ -5752,6 +6321,8 @@ snapshots:
dependencies:
safe-buffer: 5.2.1
type-fest@0.13.1: {}
type-fest@0.16.0: {}
typed-array-buffer@1.0.3:
@@ -6124,6 +6695,8 @@ snapshots:
yallist@3.1.1: {}
yallist@5.0.0: {}
yargs-parser@21.1.1: {}
yargs@17.7.2: