From 782e056687201c243d5c4109f4d4566a1d6dfa68 Mon Sep 17 00:00:00 2001 From: nathan Date: Sun, 2 Aug 2026 20:24:50 -0400 Subject: [PATCH] added packages back in, replaced var w/ let --- build/lotus-denoise.js | 82 ++++++------- package-lock.json | 172 +++++++++++++++++++++++++++- package.json | 6 +- src/app/utils/translation/engine.ts | 4 +- 4 files changed, 219 insertions(+), 45 deletions(-) diff --git a/build/lotus-denoise.js b/build/lotus-denoise.js index b108765eb..98f7b5e54 100644 --- a/build/lotus-denoise.js +++ b/build/lotus-denoise.js @@ -19,10 +19,11 @@ * * Any failure falls back to the unprocessed mic so calls never break. */ +// TODO: MAKE THIS A TS FILE (function () { 'use strict'; - var params; + let params; try { params = new URLSearchParams(window.location.search); if (params.get('lotusDenoise') !== 'ml') return; @@ -33,31 +34,31 @@ // Derive the parent origin for postMessage targetOrigin from the parentUrl // widget param (a full URL) so denoise-status messages aren't broadcast with // '*'. Fall back to this frame's own origin if parentUrl is missing/malformed. - var targetOrigin; + let targetOrigin; try { - var parentUrl = params.get('parentUrl'); + let parentUrl = params.get('parentUrl'); targetOrigin = parentUrl ? new URL(parentUrl).origin : window.location.origin; } catch (e) { targetOrigin = window.location.origin; } - var md = navigator.mediaDevices; + let md = navigator.mediaDevices; if (!md || typeof md.getUserMedia !== 'function') return; if (typeof AudioWorkletNode === 'undefined' || typeof AudioContext === 'undefined') return; - var ASSET_BASE = './denoise/'; + let ASSET_BASE = './denoise/'; - var MODEL = params.get('lotusModel') || 'rnnoise'; + let MODEL = params.get('lotusModel') || 'rnnoise'; // DTLN (@workadventure) targets 16 kHz and does not resample internally, so // its whole graph runs in a 16 kHz context; RNNoise/Speex (sapphi) and // DeepFilterNet 3 are 48 kHz fullband. The processed MediaStreamTrack is // published to LiveKit either way (WebRTC/Opus resamples as needed). - var SAMPLE_RATE = MODEL === 'dtln' ? 16000 : 48000; - var USE_NATIVE_NS = params.get('lotusNativeNS') === 'true'; - var USE_GATE = params.get('lotusGate') === 'true'; - var GATE_THRESHOLD = parseFloat(params.get('lotusGateThreshold') || '-45'); + let SAMPLE_RATE = MODEL === 'dtln' ? 16000 : 48000; + let USE_NATIVE_NS = params.get('lotusNativeNS') === 'true'; + let USE_GATE = params.get('lotusGate') === 'true'; + let GATE_THRESHOLD = parseFloat(params.get('lotusGateThreshold') || '-45'); - var PROCESSORS = { + let PROCESSORS = { rnnoise: { name: '@sapphi-red/web-noise-suppressor/rnnoise', script: 'rnnoiseWorklet.js', @@ -91,9 +92,9 @@ }, }; - var origGetUserMedia = md.getUserMedia.bind(md); - var wasmPromises = {}; - var ctxPromise = null; + let origGetUserMedia = md.getUserMedia.bind(md); + let wasmPromises = {}; + let ctxPromise = null; function checkSimd() { try { @@ -112,12 +113,12 @@ function loadWasm(modelId) { if (wasmPromises[modelId]) return wasmPromises[modelId]; - var p = PROCESSORS[modelId]; + let p = PROCESSORS[modelId]; if (!p || !p.wasm) return Promise.resolve(null); wasmPromises[modelId] = (modelId === 'rnnoise' ? checkSimd() : Promise.resolve(false)).then( function (simd) { - var file = simd && p.simdWasm ? p.simdWasm : p.wasm; + let file = simd && p.simdWasm ? p.simdWasm : p.wasm; return fetch(ASSET_BASE + file).then(function (r) { if (!r.ok) { if (simd && p.simdWasm) @@ -137,7 +138,7 @@ function getContext() { if (!ctxPromise) { ctxPromise = (function () { - var ctx = new AudioContext({ sampleRate: SAMPLE_RATE }); + let ctx = new AudioContext({ sampleRate: SAMPLE_RATE }); if (ctx.sampleRate !== SAMPLE_RATE) { try { ctx.close(); @@ -146,7 +147,7 @@ } // Load worklet modules. DTLN registers its own processor via the // dynamic-imported helper (see buildMlNode), so it needs nothing here. - var scripts = []; + let scripts = []; if (MODEL === 'rnnoise' || MODEL === 'speex') scripts.push(PROCESSORS[MODEL].script); if (USE_GATE) scripts.push(PROCESSORS.gate.script); @@ -169,7 +170,7 @@ return ctxPromise; } - var hasNotifiedActive = false; + let hasNotifiedActive = false; // Build the ML denoise AudioWorkletNode. RNNoise/Speex are flat sapphi // worklets we instantiate directly with the fetched WASM binary. DTLN comes @@ -187,9 +188,9 @@ if (MODEL === 'deepfilternet') { // Resolve an absolute self-hosted base so the package's cdnUrl override // fetches our vendored df_bg.wasm + ONNX model (never the upstream CDN). - var dfnBase = new URL(ASSET_BASE + 'deepfilternet', window.location.href).href; + let dfnBase = new URL(ASSET_BASE + 'deepfilternet', window.location.href).href; return import(ASSET_BASE + PROCESSORS.deepfilternet.esm).then(function (mod) { - var core = new mod.DeepFilterNet3Core({ + let core = new mod.DeepFilterNet3Core({ sampleRate: SAMPLE_RATE, noiseReductionLevel: 80, assetConfig: { cdnUrl: dfnBase }, @@ -212,7 +213,8 @@ }); }); } - var node = new AudioWorkletNode(ctx, PROCESSORS[MODEL].name, { + + let node = new AudioWorkletNode(ctx, PROCESSORS[MODEL].name, { channelCount: 1, numberOfInputs: 1, numberOfOutputs: 1, @@ -230,21 +232,21 @@ } function processStream(stream) { - var audioTracks = stream.getAudioTracks(); + let audioTracks = stream.getAudioTracks(); if (audioTracks.length === 0) return Promise.resolve(stream); return Promise.all([loadWasm(MODEL), getContext()]) .then(function (res) { - var wasmBinary = res[0]; - var ctx = res[1]; + let wasmBinary = res[0]; + let ctx = res[1]; - var source = ctx.createMediaStreamSource(stream); - var dest = ctx.createMediaStreamDestination(); - var head = source; + let source = ctx.createMediaStreamSource(stream); + let dest = ctx.createMediaStreamDestination(); + let head = source; // 1. Optional Noise Gate if (USE_GATE) { - var gateNode = new AudioWorkletNode(ctx, PROCESSORS.gate.name, { + let gateNode = new AudioWorkletNode(ctx, PROCESSORS.gate.name, { processorOptions: { openThreshold: GATE_THRESHOLD, closeThreshold: GATE_THRESHOLD - 5, @@ -258,7 +260,7 @@ // 2. ML Processor return buildMlNode(ctx, wasmBinary).then(function (ml) { - var mlNode = ml.node; + let mlNode = ml.node; head.connect(mlNode); mlNode.connect(dest); @@ -266,15 +268,15 @@ // the track handoff — audio flows via bypassUntilReady meanwhile. if (ml.ready && typeof ml.ready.then === 'function') { ml.ready.catch(function (err) { - var m = err instanceof Error ? err.message : String(err); + let m = err instanceof Error ? err.message : String(err); console.error('[lotus-denoise] ' + MODEL + ' init failed:', m); }); } - var origTrack = audioTracks[0]; - var processedTrack = dest.stream.getAudioTracks()[0]; + let origTrack = audioTracks[0]; + let processedTrack = dest.stream.getAudioTracks()[0]; - var torndown = false; + let torndown = false; function cleanup() { if (torndown) return; torndown = true; @@ -293,7 +295,7 @@ } catch (e) {} } - var rawStop = processedTrack.stop.bind(processedTrack); + let rawStop = processedTrack.stop.bind(processedTrack); processedTrack.stop = function () { cleanup(); rawStop(); @@ -319,7 +321,7 @@ ); } - var out = new MediaStream(); + let out = new MediaStream(); out.addTrack(processedTrack); stream.getVideoTracks().forEach(function (t) { out.addTrack(t); @@ -328,7 +330,7 @@ }); }) .catch(function (e) { - var msg = e instanceof Error ? e.message : String(e); + let msg = e instanceof Error ? e.message : String(e); console.error('[lotus-denoise] Setup failed:', msg); window.parent.postMessage( { type: 'lotus-denoise-status', active: false, error: msg }, @@ -339,10 +341,10 @@ } navigator.mediaDevices.getUserMedia = function (constraints) { - var wantsAudio = !!(constraints && constraints.audio); - var effective = constraints; + let wantsAudio = !!(constraints && constraints.audio); + let effective = constraints; if (wantsAudio) { - var audioC = + let audioC = typeof constraints.audio === 'object' ? Object.assign({}, constraints.audio) : {}; audioC.noiseSuppression = USE_NATIVE_NS; audioC.channelCount = 1; diff --git a/package-lock.json b/package-lock.json index b8b8dbb45..d21f69a9b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,9 +18,11 @@ "@fontsource-variable/inter": "5.2.8", "@giphy/js-types": "5.1.0", "@giphy/react-components": "10.1.2", + "@sapphi-red/web-noise-suppressor": "0.3.5", "@tanstack/react-query": "5.100.13", "@tanstack/react-query-devtools": "5.100.13", "@tanstack/react-virtual": "3.13.25", + "@workadventure/noise-suppression": "0.1.1", "await-to-js": "3.0.0", "badwords-list": "2.0.1-4", "blurhash": "2.0.5", @@ -28,6 +30,7 @@ "chroma-js": "3.2.0", "classnames": "2.5.1", "dayjs": "1.11.20", + "deepfilternet3-noise-filter": "1.3.0", "domhandler": "6.0.1", "emojibase": "17.0.0", "emojibase-data": "17.0.0", @@ -3025,6 +3028,63 @@ "url": "https://github.com/sponsors/Boshen" } }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.5.tgz", + "integrity": "sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.1.tgz", + "integrity": "sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.1.tgz", + "integrity": "sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==", + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.2.tgz", + "integrity": "sha512-b1UQwcEZ4yCnMCD8DAL1VlbvBJE9/IX4FTIp7BG1xYpf29SLazLSrqUkj4w7Y5y7cCVP6E5tcqqcI0xemPkHug==", + "license": "BSD-3-Clause" + }, "node_modules/@react-types/shared": { "version": "3.36.1", "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.36.1.tgz", @@ -3034,6 +3094,15 @@ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, + "node_modules/@ricky0123/vad-web": { + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/@ricky0123/vad-web/-/vad-web-0.0.30.tgz", + "integrity": "sha512-cJyYrh4YeeUBJcbR9Bic/bFDyB9qBkAepvpuWM3vLxnAi7bC3VHzf51UeNdT+OtY4D7MLAgV8iJMc4z41ZnaWg==", + "license": "ISC", + "dependencies": { + "onnxruntime-web": "^1.17.0" + } + }, "node_modules/@rolldown/binding-android-arm64": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.1.tgz", @@ -3888,6 +3957,12 @@ "win32" ] }, + "node_modules/@sapphi-red/web-noise-suppressor": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@sapphi-red/web-noise-suppressor/-/web-noise-suppressor-0.3.5.tgz", + "integrity": "sha512-jh3+V9yM+zxLriQexoGm0GatoPaJWjs6ypFIbFYwQp+AoUb55eUXrjKtKQyuC5zShzzeAQUl0M5JzqB7SSrsRA==", + "license": "MIT" + }, "node_modules/@swc/helpers": { "version": "0.5.23", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.23.tgz", @@ -4055,7 +4130,6 @@ "version": "25.9.1", "resolved": "https://registry.npmjs.org/@types/node/-/node-25.9.1.tgz", "integrity": "sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg==", - "dev": true, "license": "MIT", "dependencies": { "undici-types": ">=7.24.0 <7.24.7" @@ -4553,6 +4627,16 @@ } } }, + "node_modules/@workadventure/noise-suppression": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@workadventure/noise-suppression/-/noise-suppression-0.1.1.tgz", + "integrity": "sha512-G2RmkYpLgHy44mFasv+XNQUqQv27r0XqO9lJ2FSr9fnK2QWP97gXPrgRRPtsoqChb5849Cdk0AhbeW1Zc1tKPw==", + "license": "MIT", + "dependencies": { + "@ricky0123/vad-web": "^0.0.30", + "fft.js": "^4.0.4" + } + }, "node_modules/@xobotyi/scrollbar-width": { "version": "1.9.5", "resolved": "https://registry.npmjs.org/@xobotyi/scrollbar-width/-/scrollbar-width-1.9.5.tgz", @@ -5605,6 +5689,18 @@ "dev": true, "license": "MIT" }, + "node_modules/deepfilternet3-noise-filter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/deepfilternet3-noise-filter/-/deepfilternet3-noise-filter-1.3.0.tgz", + "integrity": "sha512-yYFUlPuvPguqcd/R6/OSsr0noGqlqOE50JkCWYHogk+PjLj9qrNgwTt5zKraVkKnw0l4+eXJagkz2SUWtUl4sQ==", + "license": "(Apache-2.0 OR MIT)", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "livekit-client": "^2.0.0" + } + }, "node_modules/deepmerge": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", @@ -6705,6 +6801,12 @@ } } }, + "node_modules/fft.js": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/fft.js/-/fft.js-4.0.4.tgz", + "integrity": "sha512-f9c00hphOgeQTlDyavwTtu6RiK8AIFjD6+jvXkNkpeQ7rirK3uFWVpalkoS4LAwbdX7mfZ8aoBfFVQX1Re/8aw==", + "license": "MIT" + }, "node_modules/file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", @@ -6801,6 +6903,12 @@ "node": ">=16" } }, + "node_modules/flatbuffers": { + "version": "25.9.23", + "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-25.9.23.tgz", + "integrity": "sha512-MI1qs7Lo4Syw0EOzUl0xjs2lsoeqFku44KpngfIduHBYvzm8h2+7K8YMQh1JtVVVrUvhLpNwqVi4DERegUJhPQ==", + "license": "Apache-2.0" + }, "node_modules/flatted": { "version": "3.4.4", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.4.tgz", @@ -7122,6 +7230,12 @@ "dev": true, "license": "ISC" }, + "node_modules/guid-typescript": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/guid-typescript/-/guid-typescript-1.0.9.tgz", + "integrity": "sha512-Y8T4vYhEfwJOTbouREvG+3XDsjr8E3kIr7uf+JZ0BYloFsttiHU0WfvANVsR7TxNUJa/WpCnw/Ino/p+DeBhBQ==", + "license": "ISC" + }, "node_modules/has-bigints": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", @@ -8734,6 +8848,12 @@ "url": "https://tidelift.com/funding/github/npm/loglevel" } }, + "node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -9116,6 +9236,26 @@ "node": ">=18" } }, + "node_modules/onnxruntime-common": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/onnxruntime-common/-/onnxruntime-common-1.27.0.tgz", + "integrity": "sha512-3KxL5wIVqa8Ex08jxSzncm9CMgw8CjOFyOQ7SxvG9o0cVLlhTNKXyIQuTbtX4tGPJEf73OER2xrjt4HJSBL4ow==", + "license": "MIT" + }, + "node_modules/onnxruntime-web": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/onnxruntime-web/-/onnxruntime-web-1.27.0.tgz", + "integrity": "sha512-ogDLsqIozHZwifPuN37OproAo0byX6t43/bP8GzeZWBWD6MOGExswFAx3up4NS/vvWBOg2u2PXomDt3rMmdQSg==", + "license": "MIT", + "dependencies": { + "flatbuffers": "^25.1.24", + "guid-typescript": "^1.0.9", + "long": "^5.2.3", + "onnxruntime-common": "1.27.0", + "platform": "^1.3.6", + "protobufjs": "^7.2.4" + } + }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -9350,6 +9490,12 @@ "pathe": "^2.0.1" } }, + "node_modules/platform": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz", + "integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==", + "license": "MIT" + }, "node_modules/pngjs": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz", @@ -9462,6 +9608,29 @@ "react-is": "^16.13.1" } }, + "node_modules/protobufjs": { + "version": "7.6.5", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.6.5.tgz", + "integrity": "sha512-/FPD0nUc9jH6rfFjji9IBqOz4pcSE3CsT1m7Ep6Mdb0LxSUMj8hgl6GomOvZzpNpAqqGaXA0P3VSrZLFzIhQrw==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.5", + "@protobufjs/eventemitter": "^1.1.1", + "@protobufjs/fetch": "^1.1.1", + "@protobufjs/float": "^1.0.2", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.1", + "@types/node": ">=13.7.0", + "long": "^5.3.2" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -11264,7 +11433,6 @@ "version": "7.24.6", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz", "integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==", - "dev": true, "license": "MIT" }, "node_modules/unhomoglyph": { diff --git a/package.json b/package.json index 29e511f64..2d3d7ca3b 100644 --- a/package.json +++ b/package.json @@ -43,9 +43,11 @@ "@fontsource-variable/inter": "5.2.8", "@giphy/js-types": "5.1.0", "@giphy/react-components": "10.1.2", + "@sapphi-red/web-noise-suppressor": "0.3.5", "@tanstack/react-query": "5.100.13", "@tanstack/react-query-devtools": "5.100.13", "@tanstack/react-virtual": "3.13.25", + "@workadventure/noise-suppression": "0.1.1", "await-to-js": "3.0.0", "badwords-list": "2.0.1-4", "blurhash": "2.0.5", @@ -53,6 +55,7 @@ "chroma-js": "3.2.0", "classnames": "2.5.1", "dayjs": "1.11.20", + "deepfilternet3-noise-filter": "1.3.0", "domhandler": "6.0.1", "emojibase": "17.0.0", "emojibase-data": "17.0.0", @@ -139,6 +142,7 @@ "js-cookie": ">=3.0.6" }, "allowScripts": { - "esbuild@0.28.1": true + "esbuild@0.28.1": true, + "protobufjs@7.6.5": true } } diff --git a/src/app/utils/translation/engine.ts b/src/app/utils/translation/engine.ts index b73fae613..257ecafe5 100644 --- a/src/app/utils/translation/engine.ts +++ b/src/app/utils/translation/engine.ts @@ -69,7 +69,7 @@ export interface ChromeLanguageDetectorFactory { declare global { // eslint-disable-next-line vars-on-top - var Translator: ChromeTranslatorFactory | undefined; + let Translator: ChromeTranslatorFactory | undefined; // eslint-disable-next-line vars-on-top - var LanguageDetector: ChromeLanguageDetectorFactory | undefined; + let LanguageDetector: ChromeLanguageDetectorFactory | undefined; }