@camstack/addon-pipeline 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/audio-analyzer/index.js +723 -0
- package/dist/audio-analyzer/index.js.map +1 -0
- package/dist/audio-analyzer/index.mjs +683 -0
- package/dist/audio-analyzer/index.mjs.map +1 -0
- package/dist/audio-codec-nodeav/index.js +467 -0
- package/dist/audio-codec-nodeav/index.js.map +1 -0
- package/dist/audio-codec-nodeav/index.mjs +467 -0
- package/dist/audio-codec-nodeav/index.mjs.map +1 -0
- package/dist/decoder-nodeav/index.js +929 -0
- package/dist/decoder-nodeav/index.js.map +1 -0
- package/dist/decoder-nodeav/index.mjs +907 -0
- package/dist/decoder-nodeav/index.mjs.map +1 -0
- package/dist/detection-pipeline/index.js +5766 -0
- package/dist/detection-pipeline/index.js.map +1 -0
- package/dist/detection-pipeline/index.mjs +5725 -0
- package/dist/detection-pipeline/index.mjs.map +1 -0
- package/dist/index-D_cl0Qqb.js +5791 -0
- package/dist/index-D_cl0Qqb.js.map +1 -0
- package/dist/index-UbcdLS7a.mjs +5790 -0
- package/dist/index-UbcdLS7a.mjs.map +1 -0
- package/dist/motion-wasm/index.js +476 -0
- package/dist/motion-wasm/index.js.map +1 -0
- package/dist/motion-wasm/index.mjs +454 -0
- package/dist/motion-wasm/index.mjs.map +1 -0
- package/dist/pipeline-runner/index.js +1669 -0
- package/dist/pipeline-runner/index.js.map +1 -0
- package/dist/pipeline-runner/index.mjs +1647 -0
- package/dist/pipeline-runner/index.mjs.map +1 -0
- package/dist/stream-broker/@mf-types/compiled-types/stream-broker/widgets/StreamBrokerPanel.d.ts +21 -0
- package/dist/stream-broker/@mf-types/compiled-types/stream-broker/widgets/index.d.ts +13 -0
- package/dist/stream-broker/@mf-types/widgets.d.ts +2 -0
- package/dist/stream-broker/@mf-types.d.ts +3 -0
- package/dist/stream-broker/@mf-types.zip +0 -0
- package/dist/stream-broker/__mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_sdk__loadShare__.mjs-h5aXOPSA.mjs +12 -0
- package/dist/stream-broker/__mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.mjs-C-URP6DW.mjs +17 -0
- package/dist/stream-broker/__mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.mjs-69eEmXwl.mjs +20 -0
- package/dist/stream-broker/__mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_tanstack_mf_1_react_mf_2_query__loadShare__.mjs-U1EUeEPs.mjs +104 -0
- package/dist/stream-broker/__mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_trpc_mf_1_client__loadShare__.mjs-DeouEaSs.mjs +85 -0
- package/dist/stream-broker/__mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_trpc_mf_1_react_mf_2_query__loadShare__.mjs-DHUwjbb9.mjs +62 -0
- package/dist/stream-broker/__mfe_internal__addon_stream_broker_widgets__loadShare__react__loadShare__.mjs-DePVYdid.mjs +85 -0
- package/dist/stream-broker/__mfe_internal__addon_stream_broker_widgets__loadShare__react__loadShare__.mjs_commonjs-proxy-CBlCGyx5.mjs +29 -0
- package/dist/stream-broker/__mfe_internal__addon_stream_broker_widgets__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.mjs-gBEZsQrp.mjs +36 -0
- package/dist/stream-broker/__mfe_internal__addon_stream_broker_widgets__loadShare__react_mf_2_dom__loadShare__.mjs-DYEKzzY-.mjs +45 -0
- package/dist/stream-broker/__mfe_internal__addon_stream_broker_widgets__loadShare__react_mf_2_dom__loadShare__.mjs_commonjs-proxy-DZchZKbW.mjs +6 -0
- package/dist/stream-broker/__mfe_internal__addon_stream_broker_widgets__loadShare__react_mf_2_dom_mf_1_client__loadShare__.mjs-DICOtMTl.mjs +34 -0
- package/dist/stream-broker/_stub.js +752 -0
- package/dist/stream-broker/_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-D6o1e2ed.mjs +156 -0
- package/dist/stream-broker/client-BK73l2KT.mjs +10063 -0
- package/dist/stream-broker/getErrorShape-BPSzUA7W-TlK8ipWe.mjs +211 -0
- package/dist/stream-broker/hostInit-RCeroTVY.mjs +168 -0
- package/dist/stream-broker/index-BYclbfM0.mjs +15806 -0
- package/dist/stream-broker/index-BhXZh4lQ.mjs +1617 -0
- package/dist/stream-broker/index-BxHaCH3N.mjs +725 -0
- package/dist/stream-broker/index-D2-K2YJ7.mjs +19268 -0
- package/dist/stream-broker/index-IUYKHbxX.mjs +185 -0
- package/dist/stream-broker/index-Ss9m7Jum.mjs +2603 -0
- package/dist/stream-broker/index-ns1fRD30.mjs +435 -0
- package/dist/stream-broker/index-xncRG7-x.mjs +2713 -0
- package/dist/stream-broker/index.js +11171 -0
- package/dist/stream-broker/index.js.map +1 -0
- package/dist/stream-broker/index.mjs +11130 -0
- package/dist/stream-broker/index.mjs.map +1 -0
- package/dist/stream-broker/jsx-runtime-ZdY5pIZz.mjs +55 -0
- package/dist/stream-broker/remoteEntry.js +2973 -0
- package/dist/stream-broker/virtualExposes-pCd777Rp.mjs +42 -0
- package/package.json +258 -0
- package/python/__pycache__/inference_pool.cpython-313.pyc +0 -0
- package/python/inference_pool.py +1088 -0
- package/python/postprocessors/__init__.py +24 -0
- package/python/postprocessors/__pycache__/__init__.cpython-312.pyc +0 -0
- package/python/postprocessors/__pycache__/__init__.cpython-313.pyc +0 -0
- package/python/postprocessors/__pycache__/_safety.cpython-313.pyc +0 -0
- package/python/postprocessors/__pycache__/arcface.cpython-312.pyc +0 -0
- package/python/postprocessors/__pycache__/arcface.cpython-313.pyc +0 -0
- package/python/postprocessors/__pycache__/ctc.cpython-312.pyc +0 -0
- package/python/postprocessors/__pycache__/ctc.cpython-313.pyc +0 -0
- package/python/postprocessors/__pycache__/saliency.cpython-312.pyc +0 -0
- package/python/postprocessors/__pycache__/saliency.cpython-313.pyc +0 -0
- package/python/postprocessors/__pycache__/scrfd.cpython-312.pyc +0 -0
- package/python/postprocessors/__pycache__/scrfd.cpython-313.pyc +0 -0
- package/python/postprocessors/__pycache__/softmax.cpython-312.pyc +0 -0
- package/python/postprocessors/__pycache__/softmax.cpython-313.pyc +0 -0
- package/python/postprocessors/__pycache__/yamnet.cpython-312.pyc +0 -0
- package/python/postprocessors/__pycache__/yamnet.cpython-313.pyc +0 -0
- package/python/postprocessors/__pycache__/yolo.cpython-312.pyc +0 -0
- package/python/postprocessors/__pycache__/yolo.cpython-313.pyc +0 -0
- package/python/postprocessors/__pycache__/yolo_seg.cpython-312.pyc +0 -0
- package/python/postprocessors/__pycache__/yolo_seg.cpython-313.pyc +0 -0
- package/python/postprocessors/arcface.py +31 -0
- package/python/postprocessors/ctc.py +68 -0
- package/python/postprocessors/saliency.py +44 -0
- package/python/postprocessors/scrfd.py +212 -0
- package/python/postprocessors/softmax.py +43 -0
- package/python/postprocessors/yamnet.py +41 -0
- package/python/postprocessors/yolo.py +278 -0
- package/python/postprocessors/yolo_seg.py +247 -0
- package/python/requirements-coreml.txt +4 -0
- package/python/requirements-onnxruntime.txt +3 -0
- package/python/requirements-openvino.txt +3 -0
- package/python/requirements.txt +9 -0
- package/swift/audio-analyzer/apple-sound-classifier +0 -0
- package/swift/audio-analyzer/apple-sound-classifier.swift +213 -0
- package/swift/detection-pipeline/apple-sound-classifier +0 -0
- package/swift/detection-pipeline/apple-sound-classifier.swift +196 -0
- package/wasm/assembly/index.ts +290 -0
- package/wasm/assembly/tsconfig.json +4 -0
- package/wasm/motion.wasm +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/audio-analyzer/audio-pipeline.ts","../../src/audio-analyzer/addons/analyzer/index.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access -- existing audio pipeline carries unsafe ONNX runtime calls; pre-existing tech debt, not introduced by Phase E. */\n/**\n * Audio classification pipeline.\n *\n * - macOS: Apple SoundAnalysis framework (303 built-in sound categories)\n * - Cross-platform: YAMNet ONNX via onnxruntime-node\n *\n * This is independent from the video pipeline — different input (audio samples),\n * different engine (no shared pool), different output cadence.\n */\nimport type { IScopedLogger } from '@camstack/types'\nimport * as path from 'node:path'\nimport * as fs from 'node:fs'\nimport { errMsg, HF_BASE_URL } from '@camstack/types'\n// eslint-disable-next-line no-restricted-imports -- downloadFile is a build-time dep used to materialise the YAMNet model on first boot. Mirrors the waiver detection-pipeline + addon-embedding-encoder use for the same reason. Single source of truth lives in `@camstack/core/download/model-downloader`; consolidating it via `ctx.deps.downloadFile` would require extending `IAddonDepsManager` across every kernel context — out of scope for this addon's first auto-download wiring.\nimport { downloadFile } from '@camstack/core'\n\n// `__dirname` is shimmed by tsup (`shims: true`) for both CJS and ESM\n// output, so it works whether this bundle is loaded by `require` or by\n// `await import(...)` (the agent path).\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface AudioClassificationResult {\n readonly classifications: readonly {\n readonly className: string\n readonly score: number\n }[]\n readonly inferenceMs: number\n}\n\nexport interface AudioChunk {\n readonly data: Float32Array\n readonly sampleRate: number\n readonly channels: number\n}\n\nexport interface IAudioPipeline {\n initialize(): Promise<void>\n classify(chunk: AudioChunk): Promise<AudioClassificationResult>\n dispose(): Promise<void>\n}\n\nexport type AudioBackend = 'yamnet-onnx' | 'apple-soundanalysis'\n\nexport interface AudioPipelineOptions {\n readonly backend?: AudioBackend\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\n/**\n * Create the appropriate audio pipeline.\n *\n * - 'yamnet-onnx': Cross-platform YAMNet ONNX (requires model download)\n * - 'apple-soundanalysis': macOS 12+ Apple SoundAnalysis (zero model download, Neural Engine)\n * - undefined: auto-detect (Apple SA on macOS, YAMNet on Linux)\n */\nexport async function createAudioPipeline(\n modelsDir: string,\n logger: IScopedLogger,\n options?: AudioPipelineOptions,\n): Promise<IAudioPipeline> {\n const backend = options?.backend ?? (process.platform === 'darwin' ? 'apple-soundanalysis' : 'yamnet-onnx')\n\n if (backend === 'apple-soundanalysis') {\n return new AppleSoundAnalysisPipeline(logger)\n }\n return new YamnetOnnxPipeline(modelsDir, logger)\n}\n\n// ---------------------------------------------------------------------------\n// YAMNet ONNX (cross-platform)\n// ---------------------------------------------------------------------------\n\n/**\n * Canonical model URLs on the camstack HuggingFace mirror. Mirrors the\n * convention every detection model follows (single point of truth =\n * `HF_BASE_URL` from `@camstack/types`); the auto-download path uses\n * `downloadFile` from `@camstack/core`, the SAME helper detection-\n * pipeline uses to materialise its YOLO/face/plate models. Missing\n * model on disk → fetch from HF; cached file → no-op.\n *\n * Repo layout follows the detection-pipeline pattern:\n * {domain}/{family}/{format}/{filename}\n * For YAMNet that's `audioClassification/yamnet/onnx/camstack-yamnet.onnx`,\n * with the labels JSON sitting one level up (`audioClassification/yamnet/`)\n * because they're format-agnostic (same 521 AudioSet class names whether\n * the runtime is ONNX, OpenVINO, or TF).\n */\nconst YAMNET_MODEL_URL = `${HF_BASE_URL}/audioClassification/yamnet/onnx/camstack-yamnet.onnx`\nconst YAMNET_LABELS_URL = `${HF_BASE_URL}/audioClassification/yamnet/camstack-yamnet-labels.json`\n\nclass YamnetOnnxPipeline implements IAudioPipeline {\n private session: import('onnxruntime-node').InferenceSession | null = null\n private inputName = ''\n private labels: readonly string[] = []\n private readonly log: IScopedLogger\n\n constructor(\n private readonly modelsDir: string,\n logger: IScopedLogger,\n ) {\n this.log = logger\n }\n\n async initialize(): Promise<void> {\n const ort = await import('onnxruntime-node')\n const modelPath = path.join(this.modelsDir, 'camstack-yamnet.onnx')\n const labelsPath = path.join(this.modelsDir, 'camstack-yamnet-labels.json')\n\n // Auto-download model + labels from the camstack HF mirror — same\n // pattern as detection-pipeline's `ensureModel`. `downloadFile` is\n // a no-op when the file is already on disk; on first boot it\n // streams atomically (`.downloading` tmp + rename on success).\n if (!fs.existsSync(modelPath)) {\n this.log.info('YAMNet ONNX model not found locally — downloading from HuggingFace', {\n meta: { url: YAMNET_MODEL_URL, dest: modelPath },\n })\n await downloadFile(YAMNET_MODEL_URL, modelPath)\n this.log.info('YAMNet ONNX model downloaded', {\n meta: { sizeBytes: fs.statSync(modelPath).size },\n })\n }\n if (!fs.existsSync(labelsPath)) {\n this.log.info('YAMNet labels not found locally — downloading from HuggingFace', {\n meta: { url: YAMNET_LABELS_URL, dest: labelsPath },\n })\n await downloadFile(YAMNET_LABELS_URL, labelsPath)\n }\n\n this.session = await ort.InferenceSession.create(modelPath)\n this.inputName = this.session.inputNames[0] ?? 'waveform'\n\n if (fs.existsSync(labelsPath)) {\n this.labels = JSON.parse(fs.readFileSync(labelsPath, 'utf8')) as string[]\n } else {\n this.log.warn('YAMNet labels file not found — classifications will use numeric indices')\n }\n\n this.log.info(`YAMNet ONNX pipeline initialized (${this.labels.length} labels)`)\n }\n\n async classify(chunk: AudioChunk): Promise<AudioClassificationResult> {\n if (!this.session) {\n throw new Error('YAMNet pipeline not initialized')\n }\n\n const start = Date.now()\n const ort = await import('onnxruntime-node')\n\n // Resample to 16kHz mono if needed\n const waveform = chunk.sampleRate === 16000 && chunk.channels === 1\n ? chunk.data\n : resampleMono16k(chunk)\n\n // Create ONNX tensor — YAMNet expects 1D float32 waveform\n const tensor = new ort.Tensor('float32', waveform, [waveform.length])\n const feeds: Record<string, import('onnxruntime-node').Tensor> = { [this.inputName]: tensor }\n\n const results = await this.session.run(feeds)\n\n // output_0: [N_frames, 521] scores\n const scoresData = results[this.session.outputNames[0]!]\n if (!scoresData) {\n throw new Error('YAMNet returned no output')\n }\n\n const scores = scoresData.data as Float32Array\n const numClasses = 521\n const numFrames = scores.length / numClasses\n\n // Average across frames\n const avgScores = new Float32Array(numClasses)\n for (let f = 0; f < numFrames; f++) {\n for (let c = 0; c < numClasses; c++) {\n avgScores[c]! += scores[f * numClasses + c]!\n }\n }\n for (let c = 0; c < numClasses; c++) {\n avgScores[c] = avgScores[c]! / numFrames\n }\n\n // Collect above threshold, sorted\n const minScore = 0.05\n const classifications: { className: string; score: number }[] = []\n for (let c = 0; c < numClasses; c++) {\n const score = avgScores[c]!\n if (score >= minScore) {\n const label = c < this.labels.length ? this.labels[c]! : String(c)\n classifications.push({ className: label, score: Math.round(score * 1000) / 1000 })\n }\n }\n classifications.sort((a, b) => b.score - a.score)\n\n return {\n classifications: classifications.slice(0, 10),\n inferenceMs: Date.now() - start,\n }\n }\n\n async dispose(): Promise<void> {\n if (this.session) {\n await this.session.release()\n this.session = null\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Apple SoundAnalysis (macOS)\n// ---------------------------------------------------------------------------\n\nclass AppleSoundAnalysisPipeline implements IAudioPipeline {\n private readonly log: IScopedLogger\n private process: import('node:child_process').ChildProcess | null = null\n private receiveBuffer: Buffer = Buffer.alloc(0)\n private pendingResolve: ((value: Record<string, unknown>) => void) | null = null\n private pendingReject: ((reason: Error) => void) | null = null\n private binaryPath: string | null = null\n private debugCount = 0\n\n constructor(logger: IScopedLogger) {\n this.log = logger\n }\n\n async initialize(): Promise<void> {\n this.binaryPath = await this.resolveSwiftBinary()\n if (!this.binaryPath) {\n throw new Error('Apple SoundAnalysis: Swift CLI not found and compilation failed. macOS with Xcode CLI tools required.')\n }\n\n const { spawn } = await import('node:child_process')\n this.process = spawn(this.binaryPath, ['--sample-rate=16000', '--top-k=10'], {\n stdio: ['pipe', 'pipe', 'pipe'],\n })\n\n this.process.stderr?.on('data', (chunk: Buffer) => {\n const lines = chunk.toString().split('\\n')\n for (const line of lines) {\n const trimmed = line.trim()\n if (trimmed) this.log.warn(trimmed)\n }\n })\n\n this.process.on('error', (err) => {\n this.log.error('Swift process error', { meta: { error: err.message } })\n this.pendingReject?.(err)\n this.pendingReject = null\n this.pendingResolve = null\n })\n\n this.process.on('exit', (code) => {\n if (code !== 0 && code !== null) {\n this.log.error('Swift process exited', { meta: { code } })\n const err = new Error(`Apple SoundAnalysis: process exited with code ${code}`)\n this.pendingReject?.(err)\n this.pendingReject = null\n this.pendingResolve = null\n }\n })\n\n this.process.stdout!.on('data', (chunk: Buffer) => {\n this.receiveBuffer = Buffer.concat([this.receiveBuffer, chunk])\n this.tryReceive()\n })\n\n const ready = await this.receiveMessage()\n if (ready['status'] !== 'ready') {\n throw new Error(`Apple SoundAnalysis: unexpected init response: ${JSON.stringify(ready)}`)\n }\n this.log.info('Apple SoundAnalysis pipeline initialized (macOS built-in, Swift CLI bridge)')\n }\n\n async classify(chunk: AudioChunk): Promise<AudioClassificationResult> {\n if (!this.process?.stdin) {\n throw new Error('Apple SoundAnalysis: process not initialized')\n }\n\n const waveform = chunk.sampleRate === 16000 && chunk.channels === 1\n ? chunk.data\n : resampleMono16k(chunk)\n\n const audioBuffer = Buffer.from(waveform.buffer, waveform.byteOffset, waveform.byteLength)\n const lengthBuf = Buffer.allocUnsafe(4)\n lengthBuf.writeUInt32LE(audioBuffer.length, 0)\n this.process.stdin.write(Buffer.concat([lengthBuf, audioBuffer]))\n\n const result = await this.receiveMessage()\n const classifications = (result['classifications'] as Array<{ className: string; score: number }>) ?? []\n const inferenceMs = (result['inferenceMs'] as number) ?? 0\n\n if (this.debugCount < 3) {\n const keys = Object.keys(result)\n this.log.info('classify debug sample', {\n meta: {\n phase: 'apple-sa',\n index: this.debugCount,\n keys,\n classifications: classifications.length,\n inferenceMs,\n audioBytes: Buffer.from(chunk.data.buffer, chunk.data.byteOffset, chunk.data.byteLength).length,\n sampleRate: chunk.sampleRate,\n channels: chunk.channels,\n },\n })\n if (result['error']) {\n this.log.error('Swift error', { meta: { phase: 'apple-sa', error: result['error'] } })\n }\n this.debugCount++\n }\n\n return { classifications, inferenceMs }\n }\n\n async dispose(): Promise<void> {\n const proc = this.process\n if (!proc) return\n this.process = null\n proc.stdin?.end()\n proc.kill('SIGTERM')\n\n const exited = await new Promise<boolean>((resolve) => {\n const timer = setTimeout(() => resolve(false), 5_000)\n proc.once('exit', () => { clearTimeout(timer); resolve(true) })\n })\n if (!exited) {\n try { proc.kill('SIGKILL') } catch { /* already dead */ }\n this.log.warn('Swift process did not exit gracefully — sent SIGKILL')\n }\n }\n\n private receiveMessage(): Promise<Record<string, unknown>> {\n return new Promise<Record<string, unknown>>((resolve, reject) => {\n this.pendingResolve = resolve\n this.pendingReject = reject\n })\n }\n\n private tryReceive(): void {\n if (this.receiveBuffer.length < 4) return\n const length = this.receiveBuffer.readUInt32LE(0)\n if (this.receiveBuffer.length < 4 + length) return\n\n const jsonBytes = this.receiveBuffer.subarray(4, 4 + length)\n this.receiveBuffer = this.receiveBuffer.subarray(4 + length)\n\n const resolve = this.pendingResolve\n const reject = this.pendingReject\n this.pendingResolve = null\n this.pendingReject = null\n\n if (!resolve) return\n try {\n const parsed = JSON.parse(jsonBytes.toString('utf8')) as Record<string, unknown>\n resolve(parsed)\n } catch (err) {\n reject?.(err instanceof Error ? err : new Error(String(err)))\n }\n }\n\n /** Find pre-compiled binary or compile from Swift source. */\n private async resolveSwiftBinary(): Promise<string | null> {\n // Phase D bundle merge: audio-analyzer ships inside\n // `@camstack/addon-pipeline/dist/audio-analyzer/`, with swift\n // sources at the bundle's `swift/audio-analyzer/` sub-folder.\n // From `dist/audio-analyzer/index.js`, that's `../../swift/audio-analyzer`.\n const candidates = [\n path.join(__dirname, '../../swift/audio-analyzer/apple-sound-classifier'),\n // Fallback for in-tree dev (src/<id>/swift/) and pre-merge layouts.\n path.join(__dirname, '../swift/apple-sound-classifier'),\n path.join(__dirname, '../../swift/apple-sound-classifier'),\n path.join(__dirname, '../../../swift/apple-sound-classifier'),\n ]\n\n for (const p of candidates) {\n if (fs.existsSync(p)) {\n this.log.info('Found pre-compiled Swift CLI', { meta: { path: p } })\n return p\n }\n }\n\n const sourceCandidates = [\n path.join(__dirname, '../../swift/audio-analyzer/apple-sound-classifier.swift'),\n path.join(__dirname, '../swift/apple-sound-classifier.swift'),\n path.join(__dirname, '../../swift/apple-sound-classifier.swift'),\n path.join(__dirname, '../../../swift/apple-sound-classifier.swift'),\n ]\n const sourcePath = sourceCandidates.find(p => fs.existsSync(p))\n if (!sourcePath) {\n this.log.error('Swift source not found', { meta: { searched: sourceCandidates } })\n return null\n }\n\n const outputPath = sourcePath.replace('.swift', '')\n this.log.info('Compiling Swift CLI...', { meta: { source: sourcePath, output: outputPath } })\n\n const { execFileSync } = await import('node:child_process')\n try {\n execFileSync('swiftc', ['-O', '-o', outputPath, sourcePath], {\n timeout: 60_000,\n stdio: 'pipe',\n })\n this.log.info('Swift CLI compiled successfully')\n return outputPath\n } catch (err) {\n this.log.error('Swift compilation failed — install Xcode Command Line Tools', {\n meta: { error: errMsg(err) },\n })\n return null\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Audio helpers\n// ---------------------------------------------------------------------------\n\n/** Simple resample to 16kHz mono by linear interpolation. */\nfunction resampleMono16k(chunk: AudioChunk): Float32Array {\n const { data, sampleRate, channels } = chunk\n const numSamples = data.length / channels\n\n // Mix to mono\n const mono = new Float32Array(numSamples)\n for (let i = 0; i < numSamples; i++) {\n let sum = 0\n for (let c = 0; c < channels; c++) {\n sum += data[i * channels + c]!\n }\n mono[i] = sum / channels\n }\n\n // Resample to 16kHz\n const ratio = 16000 / sampleRate\n const outLen = Math.floor(numSamples * ratio)\n const out = new Float32Array(outLen)\n for (let i = 0; i < outLen; i++) {\n const srcIdx = i / ratio\n const lo = Math.floor(srcIdx)\n const hi = Math.min(lo + 1, numSamples - 1)\n const frac = srcIdx - lo\n out[i] = mono[lo]! * (1 - frac) + mono[hi]! * frac\n }\n return out\n}\n","import type {\n AudioAnalyzerGlobalConfig,\n AudioBackendChoice,\n AudioChunkInput,\n AudioAnalysisResult,\n AudioAnalysisSettings,\n IAudioAnalyzer,\n ConfigUISchema,\n ConfigUISchemaWithValues,\n ProviderRegistration,\n} from '@camstack/types'\nimport {\n AUDIO_BACKEND_CHOICES,\n BaseAddon,\n DEFAULT_AUDIO_ANALYZER_CONFIG,\n audioAnalysisCapability,\n audioAnalyzerCapability,\n errMsg,\n hydrateSchema,\n mapAudioLabelToMacro,\n} from '@camstack/types'\nimport type { AudioClassificationResult } from '@camstack/types'\nimport type { IScopedLogger } from '@camstack/types'\nimport type { AudioBackend, IAudioPipeline } from '../../audio-pipeline.js'\nimport { createAudioPipeline } from '../../audio-pipeline.js'\n\n/**\n * Choices presented in the Audio Model dropdown. YAMNet runs via ONNX\n * when backend=yamnet-onnx; Apple SoundAnalysis is a built-in macOS\n * model and has no swappable modelId — the backend IS the model.\n */\nconst AUDIO_MODEL_OPTIONS = [\n { value: '', label: 'Auto (matches backend)' },\n { value: 'yamnet-onnx', label: 'YAMNet (ONNX)' },\n { value: 'apple-soundanalysis', label: 'Apple SoundAnalysis (built-in)' },\n] as const\n\n/**\n * AudioAnalyzerProvider — implements IAudioAnalyzer.\n *\n * Computes dB/RMS on every chunk and classifies via the in-process\n * IAudioPipeline (YAMNet ONNX / Apple SoundAnalysis). No tRPC roundtrip\n * to a separate audio-classifier addon.\n */\n\n// Suppress repeated classify-error logs. Timeouts are expected during\n// pipeline startup or under CPU pressure — log once, then silence for 30s.\nconst CLASSIFY_ERROR_SUPPRESS_MS = 30_000\n\n// Minimum ms between inference calls per camera. Prevents a single camera\n// from immediately re-queuing on the same pipeline after finishing.\nconst CLASSIFY_MIN_INTERVAL_MS = 500\n\n// Sentinel key used when no deviceId is supplied (legacy callers).\nconst GLOBAL_DEVICE_KEY = -1\n\ninterface CameraClassifyState {\n inProgress: boolean\n lastEndMs: number\n}\n\nexport class AudioAnalyzerProvider implements IAudioAnalyzer {\n private readonly log: IScopedLogger\n private classifyCallCount = 0\n private lastClassifyErrorMs = 0\n private suppressedClassifyErrors = 0\n private classifyCount = 0\n private backendName = 'unknown'\n /** Per-camera in-flight state. Key = deviceId (or GLOBAL_DEVICE_KEY for legacy callers). */\n private readonly cameraState = new Map<number, CameraClassifyState>()\n /** Global pipeline lock — Apple SA and ONNX are single-channel: only one classify() can\n * run at a time. Without this, concurrent calls from different cameras overwrite the\n * single pendingResolve slot in AppleSoundAnalysisPipeline, causing 30s timeouts. */\n private pipelineBusy = false\n\n constructor(\n logger: IScopedLogger,\n private readonly pipeline: IAudioPipeline,\n /** The backend that ACTUALLY backs `pipeline` — passed in by the\n * addon's `onInitialize` after `resolveAudioBackend()` has picked\n * the effective choice (operator override or platform default).\n * Used only for `engine:` log tagging on classify samples. */\n backendName: string,\n private readonly deviceSettingsResolver: (deviceId: number) => Promise<AudioAnalysisSettings | null>,\n private readonly deviceContributionResolver: (deviceId: number) => Promise<ConfigUISchemaWithValues | null>,\n private readonly deviceSettingsPatcher: (deviceId: number, patch: Record<string, unknown>) => Promise<void>,\n private readonly reprobeImpl: () => Promise<{ backend: string }>,\n ) {\n this.log = logger\n this.backendName = backendName\n }\n\n // ── Device-details aggregator contribution ──────────────────────────────\n\n async getDeviceSettingsContribution(input: { deviceId: number }): Promise<ConfigUISchemaWithValues | null> {\n return this.deviceContributionResolver(input.deviceId)\n }\n\n async getDeviceLiveContribution(_input: { deviceId: number }): Promise<ConfigUISchemaWithValues | null> {\n return null\n }\n\n async applyDeviceSettingsPatch(input: { deviceId: number; patch: Record<string, unknown> }): Promise<{ success: true }> {\n await this.deviceSettingsPatcher(input.deviceId, input.patch)\n return { success: true as const }\n }\n\n /**\n * Return the effective per-device audio-analyzer settings, resolved via\n * the kernel's 3-level settings resolver (schema default → global →\n * device override). Orchestrator consumers call this method so they\n * never need to know the audio-analyzer schema field names.\n */\n async resolveDeviceSettings({ deviceId }: { deviceId: number }): Promise<AudioAnalysisSettings | null> {\n return this.deviceSettingsResolver(deviceId)\n }\n\n async analyseChunk({\n chunk,\n settings,\n }: {\n chunk: AudioChunkInput\n settings: AudioAnalysisSettings\n }): Promise<AudioAnalysisResult | null> {\n const samples = chunk.data\n\n // ── Compute dB/RMS levels (always) ──\n let sumSquares = 0\n for (let i = 0; i < samples.length; i++) {\n sumSquares += samples[i]! * samples[i]!\n }\n const rms = Math.sqrt(sumSquares / samples.length)\n const dbfs = rms > 0 ? 20 * Math.log10(rms) : -96\n\n const level = {\n rms: Math.round(rms * 10000) / 10000,\n dbfs: Math.round(dbfs * 10) / 10,\n }\n\n // ── Classification (in-process pipeline) ──\n let classification: AudioAnalysisResult['classification'] | undefined\n\n try {\n const result = await this.classify(chunk)\n if (this.classifyCallCount < 3) {\n const topRaw = result.labels.slice(0, 5).map(l => `${l.className}(${(l.score * 100).toFixed(0)}%)`).join(', ')\n this.log.info('classify debug sample', {\n tags: chunk.deviceId !== undefined ? { deviceId: chunk.deviceId } : undefined,\n meta: {\n index: this.classifyCallCount,\n labelCount: result.labels.length,\n top: topRaw,\n inferenceMs: result.inferenceMs,\n minConf: settings.minConfidence,\n allowedClasses: settings.allowedClasses,\n },\n })\n }\n this.classifyCallCount++\n\n if (result.inferenceMs > 0) {\n // Apply filtering (analyzer responsibility — settings come from per-device config)\n const minConf = settings.minConfidence\n const allowedSet = settings.allowedClasses.length > 0\n ? new Set(settings.allowedClasses.map(c => c.toLowerCase()))\n : null\n\n let filtered = result.labels.filter(c => c.score >= minConf)\n if (allowedSet) {\n filtered = filtered.filter(c => allowedSet.has(c.className.toLowerCase()))\n }\n\n if (filtered.length > 0) {\n classification = {\n labels: filtered,\n inferenceMs: result.inferenceMs,\n }\n }\n }\n } catch (err: unknown) {\n const now = Date.now()\n const sinceLastMs = now - this.lastClassifyErrorMs\n if (sinceLastMs >= CLASSIFY_ERROR_SUPPRESS_MS) {\n const suppressed = this.suppressedClassifyErrors\n this.suppressedClassifyErrors = 0\n this.lastClassifyErrorMs = now\n const msg = errMsg(err)\n const stack = err instanceof Error ? err.stack : undefined\n this.log.warn('Audio classification failed', {\n tags: chunk.deviceId !== undefined ? { deviceId: chunk.deviceId } : undefined,\n meta: { error: msg, stack, suppressedSince: suppressed > 0 ? suppressed : undefined },\n })\n } else {\n this.suppressedClassifyErrors++\n }\n }\n\n return { level, classification, timestamp: chunk.timestamp }\n }\n\n async classify(chunk: AudioChunkInput): Promise<AudioClassificationResult> {\n // Per-camera concurrency guard: at most 1 chunk in flight per device.\n // Drops the incoming call immediately if that camera already has one\n // in progress or hasn't waited the minimum interval since its last call.\n // Cameras are isolated — camera A classifying does NOT block camera B.\n const camKey = chunk.deviceId ?? GLOBAL_DEVICE_KEY\n const now = Date.now()\n const state = this.cameraState.get(camKey)\n if (state?.inProgress || (state !== undefined && (now - state.lastEndMs) < CLASSIFY_MIN_INTERVAL_MS)) {\n return { labels: [], rawLabels: [], inferenceMs: 0 }\n }\n\n if (this.pipelineBusy) {\n return { labels: [], rawLabels: [], inferenceMs: 0 }\n }\n\n this.cameraState.set(camKey, { inProgress: true, lastEndMs: state?.lastEndMs ?? 0 })\n this.pipelineBusy = true\n const result = await this.pipeline.classify({\n data: chunk.data,\n sampleRate: chunk.sampleRate,\n channels: chunk.channels,\n }).finally(() => {\n this.pipelineBusy = false\n this.cameraState.set(camKey, { inProgress: false, lastEndMs: Date.now() })\n })\n\n // Log raw labels at regular intervals during debug\n if (this.classifyCount < 3 || this.classifyCount % 100 === 0) {\n const rawTop = result.classifications.slice(0, 5).map(c => `\"${c.className}\"(${(c.score * 100).toFixed(0)}%)`).join(', ')\n this.log.info('classify debug sample', {\n tags: chunk.deviceId !== undefined ? { deviceId: chunk.deviceId } : undefined,\n meta: {\n index: this.classifyCount,\n engine: this.backendName,\n rawLabelCount: result.classifications.length,\n top: rawTop,\n inferenceMs: result.inferenceMs,\n },\n })\n }\n this.classifyCount++\n\n // Map raw labels → macro classes, aggregate scores per macro class.\n const macroAccum = new Map<string, { score: number; rawTop: string }>()\n for (const c of result.classifications) {\n const macro = mapAudioLabelToMacro(c.className)\n if (!macro) continue\n const prev = macroAccum.get(macro)\n if (!prev || c.score > prev.score) {\n macroAccum.set(macro, { score: c.score, rawTop: c.className })\n }\n }\n\n // Sort by score descending\n const labels = [...macroAccum.entries()]\n .sort((a, b) => b[1].score - a[1].score)\n .map(([className, { score, rawTop }]) => ({ className, originalClass: rawTop, score }))\n\n // Raw backend-native labels (no macro aggregation), sorted by score descending.\n const rawLabels = [...result.classifications]\n .sort((a, b) => b.score - a.score)\n .map((c) => ({ className: c.className, originalClass: c.className, score: c.score }))\n\n return { labels, rawLabels, inferenceMs: result.inferenceMs }\n }\n\n isReady(): boolean {\n return this.pipeline !== null\n }\n\n async dispose(): Promise<void> {\n await this.pipeline.dispose()\n }\n\n // Expose via the cap so the reprobe button in the UI reaches the\n // right worker. Delegates to the addon-owned reprobe (it touches\n // `ctx.settings.writeAddonStore` which only the addon has access to).\n async reprobeAudioEngine(): Promise<{ backend: string }> {\n return this.reprobeImpl()\n }\n}\n\n/**\n * Audio Analyzer addon — provides the `audio-analyzer` capability.\n *\n * Owns the IAudioPipeline directly — no tRPC roundtrip to a separate\n * audio-classifier addon.\n */\nexport class AudioAnalyzerAddon extends BaseAddon<AudioAnalyzerGlobalConfig> {\n readonly id = 'audio-analyzer'\n\n private provider: AudioAnalyzerProvider | null = null\n private pipeline: IAudioPipeline | null = null\n\n constructor() { super(DEFAULT_AUDIO_ANALYZER_CONFIG) }\n\n protected globalSettingsSchema(): ConfigUISchema {\n return {\n sections: [\n {\n id: 'audio-engine',\n title: 'Audio',\n // Co-located with detection-pipeline's `engine` section under\n // a single \"Engine\" tab. Both sections handle inference-engine\n // selection but for different modalities — distinct purposes\n // are conveyed through section titles (\"Detection engine\" vs\n // \"Audio inference engine\") and descriptions, not separate\n // tabs.\n tab: 'engine',\n // Renders after detection-pipeline's `engine` section\n // (`order: 0`) on the \"Inference Engine\" tab.\n order: 10,\n description:\n 'Audio classification backend (Apple SoundAnalysis or YAMNet ONNX). Independent from the vision-detection engine above. \"Auto\" picks Apple SoundAnalysis on macOS, YAMNet on Linux. Click the refresh icon next to \"Probed best\" to re-run the probe.',\n // Field order — `probedBest*` lives at the top so the operator\n // sees the auto-detected hint first and can compare it against\n // their override below at a glance. Same convention as the\n // detection-pipeline section.\n fields: [\n {\n type: 'text' as const,\n key: 'probedBestAudioBackend',\n label: 'Probed best',\n description: 'Auto-detected best audio backend on this host. Click the refresh icon to re-run the probe.',\n readonlyField: true,\n default: '',\n actions: [\n { action: 'reprobe-audio-engine', icon: 'refresh-cw', tooltip: 'Re-probe audio engine' },\n ],\n },\n {\n type: 'select' as const,\n key: 'audioBackend',\n label: 'Audio backend',\n options: AUDIO_BACKEND_CHOICES.map(o => ({ value: o.value, label: o.label })),\n default: DEFAULT_AUDIO_ANALYZER_CONFIG.audioBackend,\n immediate: true,\n requiresRestart: true,\n },\n {\n type: 'select' as const,\n key: 'selectedAudioModel',\n label: 'Classification model',\n description:\n 'Empty = auto (matches backend). Device-level settings can only inherit / enable / disable this step; model + class filters live here at the node level.',\n options: AUDIO_MODEL_OPTIONS.map(o => ({ value: o.value, label: o.label })),\n default: DEFAULT_AUDIO_ANALYZER_CONFIG.selectedAudioModel,\n immediate: true,\n requiresRestart: true,\n },\n ],\n },\n ],\n }\n }\n\n /**\n * Cascade override — narrow the `selectedAudioModel` options to the\n * subset compatible with the currently-selected `audioBackend`.\n *\n * Same pattern as detection-pipeline's `engineRuntime → engineBackend\n * → engineDevice` cascade: the base schema ships every option\n * (Auto + YAMNet + Apple SA); this override drops the rows that\n * belong to a backend the operator didn't pick. With `immediate:\n * true` on the `audioBackend` select, the UI refetches schema after\n * every flip and the model dropdown updates instantly.\n *\n * `overlay` carries the operator's tentative choices for benchmark/\n * preview mode (operator typed but didn't save yet) — same\n * semantics detection-pipeline relies on.\n */\n override async getGlobalSettings(overlay?: Record<string, unknown>): Promise<ConfigUISchemaWithValues> {\n const ctx = this.ctxIfReady\n const stored = ctx?.settings ? ((await ctx.settings.readAddonStore()) ?? {}) : {}\n const merged = overlay ? { ...stored, ...overlay } : stored\n\n // Resolve the effective backend the same way the runtime would.\n const operatorChoice = typeof merged.audioBackend === 'string' ? merged.audioBackend : DEFAULT_AUDIO_ANALYZER_CONFIG.audioBackend\n const effectiveBackend: AudioBackend =\n operatorChoice === 'apple-soundanalysis' ? 'apple-soundanalysis'\n : operatorChoice === 'yamnet-onnx' ? 'yamnet-onnx'\n : process.platform === 'darwin' ? 'apple-soundanalysis' : 'yamnet-onnx'\n\n // The \"Auto\" entry always passes through — it just resolves to the\n // effective backend at runtime. The other rows are filtered to\n // match the current backend so the UI doesn't suggest impossible\n // combos (e.g. picking \"Apple SoundAnalysis (built-in)\" while\n // backend=yamnet-onnx).\n const filteredModels = AUDIO_MODEL_OPTIONS.filter(\n (o) => o.value === '' || o.value === effectiveBackend,\n )\n\n // Re-project the persisted `selectedAudioModel` onto the narrowed\n // option list — if the previous backend's model is no longer valid\n // for the new backend, snap to \"Auto\" so the dropdown doesn't\n // render an empty value.\n const storedModel = typeof merged.selectedAudioModel === 'string' ? merged.selectedAudioModel : ''\n const validModel = filteredModels.find((o) => o.value === storedModel)?.value ?? ''\n const raw = { ...merged, selectedAudioModel: validModel }\n\n const schema = this.globalSettingsSchema()\n const patched: ConfigUISchema = {\n ...schema,\n sections: schema.sections.map((section) => ({\n ...section,\n fields: section.fields.map((field) => {\n if (field.type === 'select' && field.key === 'selectedAudioModel') {\n return { ...field, options: filteredModels.map((o) => ({ value: o.value, label: o.label })) }\n }\n return field\n }),\n })),\n }\n return hydrateSchema(patched, raw)\n }\n\n /**\n * Re-run the platform probe and persist the detected backend into\n * `probedBestAudioBackend`. Operator `audioBackend` setting is not\n * touched — only the hint.\n */\n async reprobeAudioEngine(): Promise<{ backend: string }> {\n const backend: AudioBackend = process.platform === 'darwin' ? 'apple-soundanalysis' : 'yamnet-onnx'\n await this.ctx.settings?.writeAddonStore({ probedBestAudioBackend: backend })\n this.ctx.logger.info('reprobeAudioEngine: wrote probedBestAudioBackend', { meta: { backend } })\n return { backend }\n }\n\n /** Resolve the effective backend from the operator choice, falling back to the platform heuristic when 'auto'. */\n private resolveAudioBackend(): AudioBackend {\n const choice: AudioBackendChoice = this.config.audioBackend\n if (choice === 'apple-soundanalysis') return 'apple-soundanalysis'\n if (choice === 'yamnet-onnx') return 'yamnet-onnx'\n return process.platform === 'darwin' ? 'apple-soundanalysis' : 'yamnet-onnx'\n }\n\n protected async onInitialize(): Promise<ProviderRegistration[]> {\n const logger = this.ctx.logger as IScopedLogger\n\n // Enable/disable is driven by the binding system (per-device\n // `audio-analysis` wrapper) + the pipeline tree\n // (`addonDefaults['audio-classifier'].enabled`). The addon itself\n // always boots its pipeline; consumers not bound / not in the tree\n // simply don't invoke `classify`.\n\n // Initialize the audio pipeline (YAMNet ONNX / Apple SoundAnalysis)\n const modelsDir = await this.ctx.api.storage.resolve.query({ location: 'models', relativePath: '' })\n .catch(() => 'camstack-data/models')\n const backend = this.resolveAudioBackend()\n logger.info('audio-analyzer: resolving pipeline', {\n meta: { operatorChoice: this.config.audioBackend, effectiveBackend: backend, selectedModel: this.config.selectedAudioModel || null },\n })\n const p = await createAudioPipeline(modelsDir, logger, { backend })\n await p.initialize()\n this.pipeline = p\n\n // Auto-seed probedBestAudioBackend so the UI shows the effective\n // platform default on first boot (matches what we just booted).\n if (!this.config.probedBestAudioBackend) {\n this.reprobeAudioEngine().catch((err: unknown) => {\n logger.warn('audio: auto-reprobe failed', {\n meta: { error: err instanceof Error ? err.message : String(err) },\n })\n })\n }\n\n // Device settings resolver — pulls the audio-classifier step's\n // `settings` map from the orchestrator's resolved pipeline. The\n // settings live on the audio-classifier step (in\n // `agent.addonDefaults['audio-classifier'].settings` overlaid with\n // any per-device patch). No per-device store on this addon.\n const self = this\n const deviceSettingsResolver = async (deviceId: number): Promise<AudioAnalysisSettings | null> => {\n try {\n const resolved = await self.ctx.api.pipelineOrchestrator.resolvePipeline.query({ deviceId })\n const stepSettings = resolved.audio?.settings ?? {}\n const minConfidence = typeof stepSettings['minConfidence'] === 'number'\n ? (stepSettings['minConfidence'] as number)\n : 0.3\n const allowedClasses = Array.isArray(stepSettings['enabledAudioClasses'])\n ? (stepSettings['enabledAudioClasses'] as string[])\n : []\n return { minConfidence, allowedClasses }\n } catch (err) {\n logger.warn('audio: resolveDeviceSettings via orchestrator failed', {\n tags: { deviceId },\n meta: { error: err instanceof Error ? err.message : String(err) },\n })\n return null\n }\n }\n\n const deviceContributionResolver = async (_deviceId: number): Promise<ConfigUISchemaWithValues | null> => {\n // No device-level surface — settings live on the audio-classifier\n // pipeline step (Orchestrator tab).\n return null\n }\n const deviceSettingsPatcher = async (_deviceId: number, _patch: Record<string, unknown>): Promise<void> => {\n // No-op: per-device audio settings moved to the audio-classifier step.\n }\n\n this.provider = new AudioAnalyzerProvider(\n logger,\n this.pipeline,\n backend,\n deviceSettingsResolver,\n deviceContributionResolver,\n deviceSettingsPatcher,\n () => this.reprobeAudioEngine(),\n )\n // Split registration mirrors stream-broker/camera-streams + snapshot/snapshot-provider:\n // - audio-analyzer (system): compute path (analyseChunk / classify / isReady / dispose)\n // - audio-analysis (device, wrapper defaultActive): per-device surface — resolveDeviceSettings,\n // the three DeviceSettingsContribution methods and the onAudioLevel event.\n // Every camera gets a binding row; operators disable per-device via setWrapperActive.\n return [\n { capability: audioAnalyzerCapability, provider: this.provider },\n {\n capability: audioAnalysisCapability,\n provider: this.provider,\n kind: 'wrapper',\n defaultActive: true,\n },\n ]\n }\n\n protected async onShutdown(): Promise<void> {\n if (this.provider) {\n await this.provider.dispose()\n this.provider = null\n }\n this.pipeline = null\n }\n\n // ── Standard ICamstackAddon — three-level settings API ─────\n //\n // Per-device audio settings (audio class filter + minConfidence) moved\n // to the audio-classifier pipeline step's `getConfigSchema()` and the\n // orchestrator owns the audio node assignment (`audioNodeId`). No\n // device-level settings remain on this addon.\n\n buildDeviceSchema(): ConfigUISchema {\n return { sections: [] }\n }\n\n async getDeviceSettings(deviceId: number): Promise<ConfigUISchemaWithValues> {\n const raw = (await this.ctx?.settings?.readDeviceStore(deviceId)) ?? {}\n return hydrateSchema(this.buildDeviceSchema(), raw)\n }\n\n async updateDeviceSettings(deviceId: number, patch: Record<string, unknown>): Promise<void> {\n await this.ctx?.settings?.writeDeviceStore(deviceId, patch)\n }\n}\n"],"names":["HF_BASE_URL","path","fs","downloadFile","errMsg","mapAudioLabelToMacro","BaseAddon","DEFAULT_AUDIO_ANALYZER_CONFIG","AUDIO_BACKEND_CHOICES","hydrateSchema","audioAnalyzerCapability","audioAnalysisCapability"],"mappings":"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"}
|