@viji-dev/core 0.6.2 → 0.7.4

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.
@@ -1,4 +1,4 @@
1
- import { g as kn } from "./index-DfAcgMbB.js";
1
+ import { g as kn } from "./index-DmQ5U_50.js";
2
2
  function jn(Oe, ot) {
3
3
  for (var ve = 0; ve < ot.length; ve++) {
4
4
  const Z = ot[ve];
@@ -3374,4 +3374,4 @@ const xn = /* @__PURE__ */ kn(yi), Ln = /* @__PURE__ */ jn({
3374
3374
  export {
3375
3375
  Ln as e
3376
3376
  };
3377
- //# sourceMappingURL=essentia-wasm.web-BdXqrou4.js.map
3377
+ //# sourceMappingURL=essentia-wasm.web-BgpNs-yB.js.map
@@ -3,7 +3,7 @@ class S extends Error {
3
3
  super(A), this.code = B, this.context = I, this.name = "VijiCoreError";
4
4
  }
5
5
  }
6
- const CB = '"use strict";(()=>{function L(e){switch(e.type){case"init":{let t=e,r=[];t.data?.canvas&&r.push(t.data.canvas);let n=t.data?.cvWasmFiles;return n&&r.push(n.simdLoaderJs,n.simdBinary,n.nosimdLoaderJs,n.nosimdBinary),t.data?.controlPort&&r.push(t.data.controlPort),r}case"video-canvas-setup":{let t=e;return t.data?.offscreenCanvas?[t.data.offscreenCanvas]:[]}case"video-frame-update":{let t=e;return t.data?.imageBitmap?[t.data.imageBitmap]:[]}case"video-frame-direct":{let t=e;return t.data?.imageBitmap?[t.data.imageBitmap]:[]}case"parameter-update":return e.data?.transferList??[];case"parameter-batch-update":return e.data?.transferList??[];case"audio-analysis-update":{let t=e,r=[];return t.data?.frequencyData?.buffer&&r.push(t.data.frequencyData.buffer),t.data?.waveformData?.buffer&&r.push(t.data.waveformData.buffer),r}case"capture-frame-result":case"auto-capture-result":{let t=e.data;return t?.bitmap?[t.bitmap]:[]}default:return[]}}var d=null,y=null,s=null,v=null,a=null,I=!1,H=!1;function j(){return document.readyState==="loading"?new Promise(e=>{document.addEventListener("DOMContentLoaded",()=>e(),{once:!0})}):Promise.resolve()}async function A(){await j();let e={type:"iframe-ready",protocolVersion:1,environment:{crossOriginIsolated:window.crossOriginIsolated,isSecureContext:window.isSecureContext,origin:self.origin}};window.parent.postMessage(e,"*")}function S(){window.addEventListener("message",e=>{if(e.source===window.parent){if(d===null)d=e.origin,y=window.parent;else if(e.origin!==d)return;X(e.data).catch(t=>{m(t)})}})}function g(e,t=[]){if(d===null||y===null)return;let r=d==="null"?"*":d;y.postMessage(e,r,t)}function m(e){let t=e,r=t?.stack?{type:"iframe-error",message:t.message??String(e),stack:t.stack}:{type:"iframe-error",message:t?.message??String(e)};C(r)}function Y(e){let t={type:"iframe-error",message:e.message?`Worker error: ${e.message}`:"Worker error: (no detail \\u2014 likely cross-origin opacity)",...e.error&&e.error.stack?{stack:e.error.stack}:{},...e.filename?{filename:e.filename}:{},...e.lineno?{lineno:e.lineno}:{},...e.colno?{colno:e.colno}:{}};C(t)}function C(e){if(d&&y){let t=d==="null"?"*":d;y.postMessage(e,t)}else window.parent.postMessage(e,"*")}async function X(e){switch(e.type){case"viji-bootstrap":await K(e);return;case"viji-host-message":z(e.payload);return;case"viji-resize":_(e.width,e.height);return;case"viji-enable-sensors":W(e.enabled);return;case"viji-enable-interaction":T(e.enabled);return;case"viji-terminate":J();return}}async function K(e){if(s)return;a=document.createElement("canvas"),a.id="viji-canvas",a.width=e.init.canvasWidth,a.height=e.init.canvasHeight,a.style.width="100%",a.style.height="100%",a.style.display="block",a.tabIndex=0,a.style.outline="none",document.body.appendChild(a);let t=a.transferControlToOffscreen();v=URL.createObjectURL(new Blob([e.workerCode],{type:"application/javascript"})),s=new Worker(v,{type:"classic"}),s.onerror=i=>{Y(i)},s.onmessage=i=>{U(i.data)};let r=`init_${Date.now()}`,n={type:"init",id:r,timestamp:Date.now(),data:{canvas:t,isHeadless:e.init.isHeadless,sc:e.init.sc,rh:e.init.rh,cvWasmFiles:e.wasmFiles,controlPort:e.controlPort}},f=V(i=>i&&i.type==="init-response"&&i.id===r);s.postMessage(n,[t,e.wasmFiles.simdLoaderJs,e.wasmFiles.simdBinary,e.wasmFiles.nosimdLoaderJs,e.wasmFiles.nosimdBinary,e.controlPort]),await f,e.init.allowInteraction&&!e.init.isHeadless&&T(!0),e.init.allowSensors&&!e.init.isHeadless&&W(!0),a&&a.addEventListener("contextmenu",i=>i.preventDefault()),g({type:"viji-ready"})}function V(e){return new Promise((t,r)=>{if(!s){r(new Error("worker not spawned"));return}let n=s,f=i=>{e(i.data)&&(n.removeEventListener("message",f),t(i.data))};n.addEventListener("message",f)})}function z(e){if(!(!s||!e))try{let t=L(e);s.postMessage(e,t)}catch(t){m(t)}}function U(e){if(e)try{let t=L(e);g({type:"worker-message",payload:e},t)}catch(t){m(t)}}function _(e,t){s&&s.postMessage({type:"resolution-update",id:`resize_${Date.now()}`,timestamp:Date.now(),data:{effectiveWidth:e,effectiveHeight:t,displayScale:1}})}var M=!1;function T(e){e!==I&&a&&(e?(a.addEventListener("mousedown",u,{passive:!1}),a.addEventListener("mousemove",u,{passive:!1}),a.addEventListener("mouseup",u,{passive:!1}),a.addEventListener("mouseenter",x,{passive:!1}),a.addEventListener("mouseleave",B,{passive:!1}),a.addEventListener("wheel",R,{passive:!1}),a.addEventListener("touchstart",l,{passive:!1}),a.addEventListener("touchmove",l,{passive:!1}),a.addEventListener("touchend",l,{passive:!1}),a.addEventListener("touchcancel",l,{passive:!1}),document.addEventListener("keydown",w,{passive:!1}),document.addEventListener("keyup",w,{passive:!1}),a.addEventListener("mousedown",h),a.addEventListener("touchstart",h),I=!0):(a.removeEventListener("mousedown",u),a.removeEventListener("mousemove",u),a.removeEventListener("mouseup",u),a.removeEventListener("mouseenter",x),a.removeEventListener("mouseleave",B),a.removeEventListener("wheel",R),a.removeEventListener("touchstart",l),a.removeEventListener("touchmove",l),a.removeEventListener("touchend",l),a.removeEventListener("touchcancel",l),document.removeEventListener("keydown",w),document.removeEventListener("keyup",w),a.removeEventListener("mousedown",h),a.removeEventListener("touchstart",h),I=!1))}function h(){a&&a.focus()}function E(e,t){s&&s.postMessage({type:e,id:`${e}_${Date.now()}`,timestamp:Date.now(),data:t}),g({type:"interaction-event",kind:e,data:t})}function u(e){if(!a)return;e.preventDefault();let t=a.getBoundingClientRect(),r=(e.clientX-t.left)*(a.width/t.width),n=(e.clientY-t.top)*(a.height/t.height);E("mouse-update",{x:r,y:n,buttons:e.buttons,deltaX:e.movementX||0,deltaY:e.movementY||0,wheelDeltaX:0,wheelDeltaY:0,isInCanvas:M,timestamp:performance.now()})}function x(e){M=!0,u(e)}function B(e){M=!1,u(e)}function R(e){if(!a)return;e.preventDefault();let t=a.getBoundingClientRect(),r=(e.clientX-t.left)*(a.width/t.width),n=(e.clientY-t.top)*(a.height/t.height);E("mouse-update",{x:r,y:n,buttons:e.buttons,deltaX:0,deltaY:0,wheelDeltaX:e.deltaX,wheelDeltaY:e.deltaY,isInCanvas:M,timestamp:performance.now()})}var G=new Set(["Tab","F1","F2","F3","F4","F5","F11","F12"]);function w(e){G.has(e.key)||e.preventDefault(),E("keyboard-update",{type:e.type,key:e.key,code:e.code,keyCode:e.keyCode,shiftKey:e.shiftKey,ctrlKey:e.ctrlKey,altKey:e.altKey,metaKey:e.metaKey,timestamp:performance.now()})}function l(e){if(!a)return;e.preventDefault();let t=a.getBoundingClientRect(),r=a.width/t.width,n=a.height/t.height,f=a.width,i=a.height,D=o=>{let c=(o.clientX-t.left)*r,p=(o.clientY-t.top)*n;return{identifier:o.identifier,clientX:c,clientY:p,radiusX:o.radiusX??0,radiusY:o.radiusY??0,rotationAngle:o.rotationAngle??0,force:o.force??0,isInCanvas:c>=0&&c<=f&&p>=0&&p<=i}},b=new Map;for(let o=0;o<e.changedTouches.length;o++){let c=e.changedTouches[o];b.set(c.identifier,D(c))}let k=Array.from(e.touches).map(o=>b.get(o.identifier)??D(o));if(e.type==="touchend"||e.type==="touchcancel"){let o=new Set(k.map(c=>c.identifier));for(let[c,p]of b)o.has(c)||k.push({...p,ended:!0})}E("touch-update",{type:e.type,touches:k,timestamp:performance.now()})}function W(e){e!==H&&(e?(window.addEventListener("devicemotion",O),window.addEventListener("deviceorientation",F),H=!0):(window.removeEventListener("devicemotion",O),window.removeEventListener("deviceorientation",F),H=!1))}function O(e){!e.acceleration&&!e.accelerationIncludingGravity&&!e.rotationRate||g({type:"sensor-event",kind:"motion",data:{acceleration:e.acceleration?{x:e.acceleration.x,y:e.acceleration.y,z:e.acceleration.z}:null,accelerationIncludingGravity:e.accelerationIncludingGravity?{x:e.accelerationIncludingGravity.x,y:e.accelerationIncludingGravity.y,z:e.accelerationIncludingGravity.z}:null,rotationRate:e.rotationRate?{alpha:e.rotationRate.alpha,beta:e.rotationRate.beta,gamma:e.rotationRate.gamma}:null,interval:e.interval||16}})}function F(e){g({type:"sensor-event",kind:"orientation",data:{alpha:e.alpha,beta:e.beta,gamma:e.gamma,absolute:e.absolute||!1}})}function J(){T(!1),W(!1),s&&(s.terminate(),s=null),v&&(URL.revokeObjectURL(v),v=null)}S();A().catch(e=>m(e));window.addEventListener("error",e=>{m(e.error??new Error(e.message))});window.addEventListener("unhandledrejection",e=>{m(e.reason??new Error("Unhandled promise rejection"))});})();\n', GB = "accelerometer; gyroscope; magnetometer; camera; microphone", uA = "null";
6
+ const CB = '"use strict";(()=>{function L(e){switch(e.type){case"init":{let t=e,r=[];t.data?.canvas&&r.push(t.data.canvas);let n=t.data?.cvWasmFiles;return n&&r.push(n.simdLoaderJs,n.simdBinary,n.nosimdLoaderJs,n.nosimdBinary),t.data?.controlPort&&r.push(t.data.controlPort),r}case"video-canvas-setup":{let t=e;return t.data?.offscreenCanvas?[t.data.offscreenCanvas]:[]}case"video-frame-update":{let t=e;return t.data?.imageBitmap?[t.data.imageBitmap]:[]}case"video-frame-direct":{let t=e;return t.data?.imageBitmap?[t.data.imageBitmap]:[]}case"parameter-update":return e.data?.transferList??[];case"parameter-batch-update":return e.data?.transferList??[];case"audio-analysis-update":{let t=e,r=[];return t.data?.frequencyData?.buffer&&r.push(t.data.frequencyData.buffer),t.data?.waveformData?.buffer&&r.push(t.data.waveformData.buffer),r}case"capture-frame-result":case"auto-capture-result":{let t=e.data;return t?.bitmap?[t.bitmap]:[]}default:return[]}}var d=null,y=null,s=null,v=null,a=null,I=!1,H=!1;function A(){return document.readyState==="loading"?new Promise(e=>{document.addEventListener("DOMContentLoaded",()=>e(),{once:!0})}):Promise.resolve()}async function j(){await A();let e={type:"iframe-ready",protocolVersion:1,environment:{crossOriginIsolated:window.crossOriginIsolated,isSecureContext:window.isSecureContext,origin:self.origin}};window.parent.postMessage(e,"*")}function S(){window.addEventListener("message",e=>{if(e.source===window.parent){if(d===null)d=e.origin,y=window.parent;else if(e.origin!==d)return;X(e.data).catch(t=>{m(t)})}})}function g(e,t=[]){if(d===null||y===null)return;let r=d==="null"?"*":d;y.postMessage(e,r,t)}function m(e){let t=e,r=t?.stack?{type:"iframe-error",message:t.message??String(e),stack:t.stack}:{type:"iframe-error",message:t?.message??String(e)};F(r)}function Y(e){let t={type:"iframe-error",message:e.message?`Worker error: ${e.message}`:"Worker error: (no detail \\u2014 likely cross-origin opacity)",...e.error&&e.error.stack?{stack:e.error.stack}:{},...e.filename?{filename:e.filename}:{},...e.lineno?{lineno:e.lineno}:{},...e.colno?{colno:e.colno}:{}};F(t)}function F(e){if(d&&y){let t=d==="null"?"*":d;y.postMessage(e,t)}else window.parent.postMessage(e,"*")}async function X(e){switch(e.type){case"viji-bootstrap":await K(e);return;case"viji-host-message":U(e.payload);return;case"viji-resize":_(e.width,e.height);return;case"viji-enable-sensors":W(e.enabled);return;case"viji-enable-interaction":T(e.enabled);return;case"viji-terminate":J();return}}async function K(e){if(s)return;a=document.createElement("canvas"),a.id="viji-canvas",a.width=e.init.canvasWidth,a.height=e.init.canvasHeight,a.style.width="100%",a.style.height="100%",a.style.display="block",a.tabIndex=0,a.style.outline="none",document.body.appendChild(a);let t=a.transferControlToOffscreen();v=URL.createObjectURL(new Blob([e.workerCode],{type:"application/javascript"})),s=new Worker(v,{type:"classic"}),s.onerror=i=>{Y(i)},s.onmessage=i=>{z(i.data)};let r=`init_${Date.now()}`,n={type:"init",id:r,timestamp:Date.now(),data:{canvas:t,isHeadless:e.init.isHeadless,sc:e.init.sc,rh:e.init.rh,cvWasmFiles:e.wasmFiles,controlPort:e.controlPort,reporterConfig:e.init.reporterConfig}},f=V(i=>i&&i.type==="init-response"&&i.id===r);s.postMessage(n,[t,e.wasmFiles.simdLoaderJs,e.wasmFiles.simdBinary,e.wasmFiles.nosimdLoaderJs,e.wasmFiles.nosimdBinary,e.controlPort]),await f,e.init.allowInteraction&&!e.init.isHeadless&&T(!0),e.init.allowSensors&&!e.init.isHeadless&&W(!0),a&&a.addEventListener("contextmenu",i=>i.preventDefault()),g({type:"viji-ready"})}function V(e){return new Promise((t,r)=>{if(!s){r(new Error("worker not spawned"));return}let n=s,f=i=>{e(i.data)&&(n.removeEventListener("message",f),t(i.data))};n.addEventListener("message",f)})}function U(e){if(!(!s||!e))try{let t=L(e);s.postMessage(e,t)}catch(t){m(t)}}function z(e){if(e)try{let t=L(e);g({type:"worker-message",payload:e},t)}catch(t){m(t)}}function _(e,t){s&&s.postMessage({type:"resolution-update",id:`resize_${Date.now()}`,timestamp:Date.now(),data:{effectiveWidth:e,effectiveHeight:t,displayScale:1}})}var w=!1;function T(e){e!==I&&a&&(e?(a.addEventListener("mousedown",u,{passive:!1}),a.addEventListener("mousemove",u,{passive:!1}),a.addEventListener("mouseup",u,{passive:!1}),a.addEventListener("mouseenter",x,{passive:!1}),a.addEventListener("mouseleave",B,{passive:!1}),a.addEventListener("wheel",C,{passive:!1}),a.addEventListener("touchstart",l,{passive:!1}),a.addEventListener("touchmove",l,{passive:!1}),a.addEventListener("touchend",l,{passive:!1}),a.addEventListener("touchcancel",l,{passive:!1}),document.addEventListener("keydown",M,{passive:!1}),document.addEventListener("keyup",M,{passive:!1}),a.addEventListener("mousedown",h),a.addEventListener("touchstart",h),I=!0):(a.removeEventListener("mousedown",u),a.removeEventListener("mousemove",u),a.removeEventListener("mouseup",u),a.removeEventListener("mouseenter",x),a.removeEventListener("mouseleave",B),a.removeEventListener("wheel",C),a.removeEventListener("touchstart",l),a.removeEventListener("touchmove",l),a.removeEventListener("touchend",l),a.removeEventListener("touchcancel",l),document.removeEventListener("keydown",M),document.removeEventListener("keyup",M),a.removeEventListener("mousedown",h),a.removeEventListener("touchstart",h),I=!1))}function h(){a&&a.focus()}function b(e,t){s&&s.postMessage({type:e,id:`${e}_${Date.now()}`,timestamp:Date.now(),data:t}),g({type:"interaction-event",kind:e,data:t})}function u(e){if(!a)return;e.preventDefault();let t=a.getBoundingClientRect(),r=(e.clientX-t.left)*(a.width/t.width),n=(e.clientY-t.top)*(a.height/t.height);b("mouse-update",{x:r,y:n,buttons:e.buttons,deltaX:e.movementX||0,deltaY:e.movementY||0,wheelDeltaX:0,wheelDeltaY:0,isInCanvas:w,timestamp:performance.now()})}function x(e){w=!0,u(e)}function B(e){w=!1,u(e)}function C(e){if(!a)return;e.preventDefault();let t=a.getBoundingClientRect(),r=(e.clientX-t.left)*(a.width/t.width),n=(e.clientY-t.top)*(a.height/t.height);b("mouse-update",{x:r,y:n,buttons:e.buttons,deltaX:0,deltaY:0,wheelDeltaX:e.deltaX,wheelDeltaY:e.deltaY,isInCanvas:w,timestamp:performance.now()})}var G=new Set(["Tab","F1","F2","F3","F4","F5","F11","F12"]);function M(e){G.has(e.key)||e.preventDefault(),b("keyboard-update",{type:e.type,key:e.key,code:e.code,keyCode:e.keyCode,shiftKey:e.shiftKey,ctrlKey:e.ctrlKey,altKey:e.altKey,metaKey:e.metaKey,timestamp:performance.now()})}function l(e){if(!a)return;e.preventDefault();let t=a.getBoundingClientRect(),r=a.width/t.width,n=a.height/t.height,f=a.width,i=a.height,D=o=>{let c=(o.clientX-t.left)*r,p=(o.clientY-t.top)*n;return{identifier:o.identifier,clientX:c,clientY:p,radiusX:o.radiusX??0,radiusY:o.radiusY??0,rotationAngle:o.rotationAngle??0,force:o.force??0,isInCanvas:c>=0&&c<=f&&p>=0&&p<=i}},E=new Map;for(let o=0;o<e.changedTouches.length;o++){let c=e.changedTouches[o];E.set(c.identifier,D(c))}let k=Array.from(e.touches).map(o=>E.get(o.identifier)??D(o));if(e.type==="touchend"||e.type==="touchcancel"){let o=new Set(k.map(c=>c.identifier));for(let[c,p]of E)o.has(c)||k.push({...p,ended:!0})}b("touch-update",{type:e.type,touches:k,timestamp:performance.now()})}function W(e){e!==H&&(e?(window.addEventListener("devicemotion",R),window.addEventListener("deviceorientation",O),H=!0):(window.removeEventListener("devicemotion",R),window.removeEventListener("deviceorientation",O),H=!1))}function R(e){!e.acceleration&&!e.accelerationIncludingGravity&&!e.rotationRate||g({type:"sensor-event",kind:"motion",data:{acceleration:e.acceleration?{x:e.acceleration.x,y:e.acceleration.y,z:e.acceleration.z}:null,accelerationIncludingGravity:e.accelerationIncludingGravity?{x:e.accelerationIncludingGravity.x,y:e.accelerationIncludingGravity.y,z:e.accelerationIncludingGravity.z}:null,rotationRate:e.rotationRate?{alpha:e.rotationRate.alpha,beta:e.rotationRate.beta,gamma:e.rotationRate.gamma}:null,interval:e.interval||16}})}function O(e){g({type:"sensor-event",kind:"orientation",data:{alpha:e.alpha,beta:e.beta,gamma:e.gamma,absolute:e.absolute||!1}})}function J(){T(!1),W(!1),s&&(s.terminate(),s=null),v&&(URL.revokeObjectURL(v),v=null)}S();j().catch(e=>m(e));window.addEventListener("error",e=>{m(e.error??new Error(e.message))});window.addEventListener("unhandledrejection",e=>{m(e.reason??new Error("Unhandled promise rejection"))});})();\n', GB = "accelerometer; gyroscope; magnetometer; camera; microphone", uA = "null";
7
7
  function iB(R) {
8
8
  switch (R.type) {
9
9
  case "init": {
@@ -80,7 +80,7 @@ class DB {
80
80
  * 5s safety timer that rejects `iframeReadyPromise` if the inline-script
81
81
  * never emits `iframe-ready` (e.g. blob script error). Promoted from
82
82
  * closure-captured local to instance state so `destroy()` can clear it
83
- * on cancellation (docs/14 rule 5).
83
+ * on cancellation.
84
84
  */
85
85
  iframeReadyTimeoutId = null;
86
86
  lockedOrigin = null;
@@ -536,7 +536,7 @@ class DB {
536
536
  }
537
537
  }
538
538
  }
539
- const oB = "" + new URL("assets/viji.worker-DPYPVetq.js", import.meta.url).href, hB = new URL("assets/wasm/vision_wasm_internal.js", import.meta.url).href, RB = new URL("assets/wasm/vision_wasm_internal.wasm", import.meta.url).href, wB = new URL("assets/wasm/vision_wasm_nosimd_internal.js", import.meta.url).href, sB = new URL("assets/wasm/vision_wasm_nosimd_internal.wasm", import.meta.url).href;
539
+ const oB = "" + new URL("assets/viji.worker-Dq2EQ0Wd.js", import.meta.url).href, hB = new URL("assets/wasm/vision_wasm_internal.js", import.meta.url).href, RB = new URL("assets/wasm/vision_wasm_internal.wasm", import.meta.url).href, wB = new URL("assets/wasm/vision_wasm_nosimd_internal.js", import.meta.url).href, sB = new URL("assets/wasm/vision_wasm_nosimd_internal.wasm", import.meta.url).href;
540
540
  class FB {
541
541
  constructor(A, B, I) {
542
542
  this.iframeManager = A, this.sceneCode = B, this.init = I;
@@ -554,9 +554,9 @@ class FB {
554
554
  * port instead of through the iframe relay — one cross-process hop
555
555
  * instead of two for every per-frame message.
556
556
  *
557
- * Single-owner discipline (docs/14, rule 5): IFrameManager owns the
558
- * channel lifecycle and closes `port1` on destroy. WorkerManager only
559
- * detaches its `onmessage` listener.
557
+ * Single-owner discipline: IFrameManager owns the channel lifecycle and
558
+ * closes `port1` on destroy. WorkerManager only detaches its `onmessage`
559
+ * listener.
560
560
  */
561
561
  controlPort = null;
562
562
  onControlPortMessageBound = null;
@@ -621,7 +621,8 @@ class FB {
621
621
  allowInteraction: this.init.allowInteraction,
622
622
  allowSensors: this.init.allowSensors,
623
623
  sc: this.init.sc,
624
- rh: this.init.rh
624
+ rh: this.init.rh,
625
+ reporterConfig: this.init.reporterConfig
625
626
  }
626
627
  }, D = new Promise((h, G) => {
627
628
  this.bootstrapReject = G, this.bootstrapTimeoutId = setTimeout(() => {
@@ -1185,7 +1186,7 @@ class MB {
1185
1186
  o.fluxHistory.length >= 2 && (y += o.fluxHistory[o.fluxHistory.length - 2] * 0.5), o.fluxHistory.length >= 3 && (y += o.fluxHistory[o.fluxHistory.length - 3] * 0.25), y /= 1.75, o.lastFlux = y, o.lastEnergy = a;
1186
1187
  const M = a - o.prevEnergy * 0.95, Y = Math.max(y, y + M * 0.2), U = Y / Math.max(1e-3, Q), J = Math.min(1, U / 0.08), N = this.recentEnergies.get(G), l = this.recentFluxes.get(G);
1187
1188
  N.push(a), l.push(y), N.length > this.STATS_WINDOW_SIZE && N.shift(), l.length > this.STATS_WINDOW_SIZE && l.shift();
1188
- const H = 6e4 / this.currentBPM, Z = Math.max(150, Math.min(350, H * 0.45)), t = H / 4, L = G === "high" || G === "highMid" ? t * 0.45 : t * 0.9, n = Math.max(G === "high" || G === "highMid" ? 60 : 80, Math.min(G === "high" || G === "highMid" ? 150 : 250, L)), z = G === "low" ? Z : n, T = G === "high" ? 0.85 : 1, x = o.cutoff * T, O = y > w.minFlux, _ = a > x, q = a > w.minThreshold, $ = I - o.lastOnsetTime > z, r = O && _ && q && $;
1189
+ const H = 6e4 / this.currentBPM, Z = Math.max(150, Math.min(350, H * 0.45)), t = H / 4, L = G === "high" || G === "highMid" ? t * 0.45 : t * 0.9, q = Math.max(G === "high" || G === "highMid" ? 60 : 80, Math.min(G === "high" || G === "highMid" ? 150 : 250, L)), z = G === "low" ? Z : q, T = G === "high" ? 0.85 : 1, x = o.cutoff * T, O = y > w.minFlux, _ = a > x, n = a > w.minThreshold, $ = I - o.lastOnsetTime > z, r = O && _ && n && $;
1189
1190
  if (G === "low" || this.debugMode && G === "high") {
1190
1191
  const b = G === "low" ? "low" : "high";
1191
1192
  if (r) {
@@ -1197,8 +1198,8 @@ class MB {
1197
1198
  const m = 6e4 / this.currentBPM / 4;
1198
1199
  console.log(` 📊 Sharpness: ${J.toFixed(3)} | Raw Flux: ${y.toFixed(3)} | Emphasized: ${Y.toFixed(3)}`), console.log(` ⏱️ BPM: ${this.currentBPM.toFixed(1)} → 16th=${m.toFixed(0)}ms → Debounce=${z.toFixed(0)}ms`), G === "high" && console.log(` 🎚️ Sensitivity: 85% (adjusted cutoff: ${x.toFixed(2)} vs base: ${o.cutoff.toFixed(2)})`);
1199
1200
  }
1200
- } else if ([O, _, q, $].filter((m) => m).length >= 3) {
1201
- const m = O ? _ ? q ? "debounce" : "minThresh" : "cutoff" : "flux";
1201
+ } else if ([O, _, n, $].filter((m) => m).length >= 3) {
1202
+ const m = O ? _ ? n ? "debounce" : "minThresh" : "cutoff" : "flux";
1202
1203
  if (this.consecutiveMisses[b] || (this.consecutiveMisses[b] = { count: 0, lastReason: "" }), this.consecutiveMisses[b].count++, this.consecutiveMisses[b].lastReason = m, this.debugMode && this.consecutiveMisses[b].count === 1) {
1203
1204
  const X = (I - o.lastOnsetTime).toFixed(0), d = G === "high" ? x : o.cutoff;
1204
1205
  console.log(`⚠️ [${b}] MISS (${m}) flux=${y.toFixed(3)} energy=${a.toFixed(2)} cutoff=${d.toFixed(2)} lastOnset=${X}ms ago`);
@@ -1519,7 +1520,7 @@ class YB {
1519
1520
  if (!this.isInitialized)
1520
1521
  return this.initPromise ? this.initPromise : (this.initPromise = (async () => {
1521
1522
  try {
1522
- const A = await import("./essentia.js-core.es-CC_3Ap1i.js"), B = await import("./essentia-wasm.web-BdXqrou4.js").then((g) => g.e), I = A.Essentia || A.default?.Essentia || A.default;
1523
+ const A = await import("./essentia.js-core.es-CC_3Ap1i.js"), B = await import("./essentia-wasm.web-BgpNs-yB.js").then((g) => g.e), I = A.Essentia || A.default?.Essentia || A.default;
1523
1524
  let Q = B.default || B.EssentiaWASM || B.default?.EssentiaWASM;
1524
1525
  if (!Q)
1525
1526
  throw new Error("WASM module not found - check essentia-wasm.web.js export");
@@ -1633,21 +1634,21 @@ class YB {
1633
1634
  this.adaptiveLambda.snare,
1634
1635
  // 1.4 - balanced
1635
1636
  "snare"
1636
- ), M = this.detectionHistory.complex.slice(-3), Y = this.detectionHistory.hfc.slice(-3), U = this.detectionHistory.flux.slice(-3), J = this.temporalIntegration(M, "kick"), N = this.temporalIntegration(Y, "hat"), l = this.temporalIntegration(U, "snare"), H = Math.min(5, Math.max(0, J)), Z = Math.max(0, N), t = Math.min(5, Math.max(0, l)), L = this.calculateSharpness(J, M), u = this.calculateSharpness(l, U), p = this.calculateSharpness(N, Y), n = i - this.lastOnsetTime.kick, z = i - this.lastOnsetTime.snare, T = i - this.lastOnsetTime.hat, x = n >= this.minOnsetInterval.kick, O = z >= this.minOnsetInterval.snare, _ = T >= this.minOnsetInterval.hat, q = x && H > F && Q.low > this.bandThresholds.low, $ = _ && Z > k && (Q.high > this.bandThresholds.high || Q.highMid > this.bandThresholds.highMid), r = O && t > y && Q.mid > this.bandThresholds.mid, V = Q.high + Q.highMid > 5e-4, v = Q.mid > 5e-4, b = $ && Q.high + Q.highMid > Q.mid * 2 + 1e-9, m = r && v && !b, X = $ && V, d = q || m || X;
1637
- q && (this.lastOnsetTime.kick = i), m && (this.lastOnsetTime.snare = i), X && (this.lastOnsetTime.hat = i), d && (this.lastOnsetTime.global = i), d && this.debugFrameCount++;
1637
+ ), M = this.detectionHistory.complex.slice(-3), Y = this.detectionHistory.hfc.slice(-3), U = this.detectionHistory.flux.slice(-3), J = this.temporalIntegration(M, "kick"), N = this.temporalIntegration(Y, "hat"), l = this.temporalIntegration(U, "snare"), H = Math.min(5, Math.max(0, J)), Z = Math.max(0, N), t = Math.min(5, Math.max(0, l)), L = this.calculateSharpness(J, M), u = this.calculateSharpness(l, U), p = this.calculateSharpness(N, Y), q = i - this.lastOnsetTime.kick, z = i - this.lastOnsetTime.snare, T = i - this.lastOnsetTime.hat, x = q >= this.minOnsetInterval.kick, O = z >= this.minOnsetInterval.snare, _ = T >= this.minOnsetInterval.hat, n = x && H > F && Q.low > this.bandThresholds.low, $ = _ && Z > k && (Q.high > this.bandThresholds.high || Q.highMid > this.bandThresholds.highMid), r = O && t > y && Q.mid > this.bandThresholds.mid, V = Q.high + Q.highMid > 5e-4, v = Q.mid > 5e-4, b = $ && Q.high + Q.highMid > Q.mid * 2 + 1e-9, m = r && v && !b, X = $ && V, d = n || m || X;
1638
+ n && (this.lastOnsetTime.kick = i), m && (this.lastOnsetTime.snare = i), X && (this.lastOnsetTime.hat = i), d && (this.lastOnsetTime.global = i), d && this.debugFrameCount++;
1638
1639
  const e = Math.max(0, Math.min(1, Math.max(J, N, l)));
1639
1640
  return {
1640
1641
  onset: d,
1641
1642
  strength: e,
1642
1643
  bands: {
1643
1644
  low: {
1644
- onset: q,
1645
+ onset: n,
1645
1646
  strength: H,
1646
1647
  energy: Q.low,
1647
1648
  sharpness: L
1648
1649
  },
1649
1650
  lowMid: {
1650
- onset: q,
1651
+ onset: n,
1651
1652
  strength: H,
1652
1653
  energy: Q.lowMid,
1653
1654
  sharpness: L
@@ -1914,7 +1915,7 @@ class YB {
1914
1915
  }
1915
1916
  }
1916
1917
  }
1917
- const QA = 60, j = 200, lB = 85, UB = 180, NB = 200, qA = 4, hA = 10, HB = ["low", "lowMid", "mid", "highMid", "high"];
1918
+ const QA = 60, j = 200, lB = 85, UB = 180, NB = 200, nA = 4, hA = 10, HB = ["low", "lowMid", "mid", "highMid", "high"];
1918
1919
  class SB {
1919
1920
  // Autocorrelation state
1920
1921
  onsetEnvelope = [];
@@ -2132,7 +2133,7 @@ class SB {
2132
2133
  const B = /* @__PURE__ */ new Map(), I = [];
2133
2134
  for (const G of HB) {
2134
2135
  const a = A.getBandHistory(G), o = this.analyzeBandRhythm(a);
2135
- if (B.set(G, o), o.sampleCount >= qA && o.dominantInterval > 0) {
2136
+ if (B.set(G, o), o.sampleCount >= nA && o.dominantInterval > 0) {
2136
2137
  let w = 6e4 / o.dominantInterval;
2137
2138
  for (; w > j; ) w /= 2;
2138
2139
  for (; w < QA; ) w *= 2;
@@ -2228,7 +2229,7 @@ class SB {
2228
2229
  * Analyze rhythm pattern for a single band
2229
2230
  */
2230
2231
  analyzeBandRhythm(A) {
2231
- if (A.length < qA)
2232
+ if (A.length < nA)
2232
2233
  return { dominantInterval: 500, consistency: 0, sampleCount: 0 };
2233
2234
  const B = [...A].sort((h, G) => h - G), I = [];
2234
2235
  for (let h = 1; h < B.length; h++) {
@@ -2370,15 +2371,15 @@ class SB {
2370
2371
  let H = y, Z = J;
2371
2372
  for (const L of l) {
2372
2373
  if (L < QA || L > j) continue;
2373
- const u = this.scoreGridAlignment(L, this.getRecentOnsets(), I), p = L / j * 0.5, n = u + p;
2374
- n > Z && (H = L, Z = n);
2374
+ const u = this.scoreGridAlignment(L, this.getRecentOnsets(), I), p = L / j * 0.5, q = u + p;
2375
+ q > Z && (H = L, Z = q);
2375
2376
  }
2376
2377
  let t = !0;
2377
2378
  if (H > 140 && B.bpm >= 80 && B.bpm <= 150 && B.confidence > 0.5) {
2378
2379
  const L = H / B.bpm, u = Math.abs(H - B.bpm);
2379
2380
  if (L >= 1.25 && L <= 3.5 || u > 30) {
2380
- const p = this.scoreGridAlignment(B.bpm, this.getRecentOnsets(), I), n = this.scoreGridAlignment(H, this.getRecentOnsets(), I);
2381
- p > n * 0.8 && (H = B.bpm, i = B.bpm, h = "ioi", D = B.confidence, t = !1);
2381
+ const p = this.scoreGridAlignment(B.bpm, this.getRecentOnsets(), I), q = this.scoreGridAlignment(H, this.getRecentOnsets(), I);
2382
+ p > q * 0.8 && (H = B.bpm, i = B.bpm, h = "ioi", D = B.confidence, t = !1);
2382
2383
  }
2383
2384
  }
2384
2385
  t && (this.gridLockBPM = H, this.gridLockScore = Z, this.gridLockTime = I), i = H;
@@ -2771,7 +2772,7 @@ class SB {
2771
2772
  };
2772
2773
  }
2773
2774
  }
2774
- const nA = 0.3, ZB = 0.1, dB = 0.5, bB = 0.15, LB = 0.08, WB = 3e4, pA = 1e4, tB = 0.3;
2775
+ const qA = 0.3, ZB = 0.1, dB = 0.5, bB = 0.15, LB = 0.08, WB = 3e4, pA = 1e4, tB = 0.3;
2775
2776
  class mB {
2776
2777
  /** Current phase (0-1) */
2777
2778
  phase = 0;
@@ -2798,7 +2799,7 @@ class mB {
2798
2799
  /** Whether in a tempo transition */
2799
2800
  inTransition = !1;
2800
2801
  /** Adaptive PLL gain (calculated each frame) */
2801
- currentGain = nA;
2802
+ currentGain = qA;
2802
2803
  /** ========== PHASE 4: DUAL-GATE BAR ADVANCEMENT STATE ========== */
2803
2804
  /** Last time a bar was advanced (for debounce) */
2804
2805
  lastBarAdvanceTime = 0;
@@ -3121,7 +3122,7 @@ class mB {
3121
3122
  * Reset all state
3122
3123
  */
3123
3124
  reset() {
3124
- this.phase = 0, this.lastBeatTime = 0, this.periodMs = 500, this.trackedBPM = 120, this.beatCounter = 0, this.lastOnsetTime = 0, this.bpmHistory = [], this.driftRate = 0, this.inBreakdown = !1, this.tempoConfidence = 0.5, this.inTransition = !1, this.currentGain = nA, this.lastBarAdvanceTime = 0, this.pendingBarAdvance = !1, this.lastPhaseWrapTime = 0, this.consecutiveAlignedKicks = 0, this.lastHardSyncTime = 0, this.trackingStartTime = 0, this.kickPhaseHistory = [], this.phaseOffsetCalibrated = 0, this.lastCalibrationTime = 0;
3125
+ this.phase = 0, this.lastBeatTime = 0, this.periodMs = 500, this.trackedBPM = 120, this.beatCounter = 0, this.lastOnsetTime = 0, this.bpmHistory = [], this.driftRate = 0, this.inBreakdown = !1, this.tempoConfidence = 0.5, this.inTransition = !1, this.currentGain = qA, this.lastBarAdvanceTime = 0, this.pendingBarAdvance = !1, this.lastPhaseWrapTime = 0, this.consecutiveAlignedKicks = 0, this.lastHardSyncTime = 0, this.trackingStartTime = 0, this.kickPhaseHistory = [], this.phaseOffsetCalibrated = 0, this.lastCalibrationTime = 0;
3125
3126
  }
3126
3127
  // ─────────────────────────────────────────────────────────────────────────
3127
3128
  // State serialization (for VijiCore.exportFullState same-process transfer)
@@ -3172,7 +3173,7 @@ class mB {
3172
3173
  function EA(R, A) {
3173
3174
  return R > 0 ? R + A : 0;
3174
3175
  }
3175
- const eB = 2e3, uB = 1e4, rA = 25e3, qB = rA, nB = 0.3, zA = 0.6, dA = 2e3, bA = 3e4, VA = 0.25, CA = 60;
3176
+ const eB = 2e3, uB = 1e4, rA = 25e3, nB = rA, qB = 0.3, zA = 0.6, dA = 2e3, bA = 3e4, VA = 0.25, CA = 60;
3176
3177
  class pB {
3177
3178
  // State machine
3178
3179
  state = "TRACKING";
@@ -3351,7 +3352,7 @@ class pB {
3351
3352
  * Prune old samples from rolling windows (> 25 seconds old for slow window)
3352
3353
  */
3353
3354
  pruneRollingWindows(A) {
3354
- const B = A - qB;
3355
+ const B = A - nB;
3355
3356
  this.adaptiveProfiles.kick.samples = this.adaptiveProfiles.kick.samples.filter(
3356
3357
  (I) => I.time > B
3357
3358
  ), this.adaptiveProfiles.snareIndependent.samples = this.adaptiveProfiles.snareIndependent.samples.filter(
@@ -3518,7 +3519,7 @@ class pB {
3518
3519
  g >= zA ? (this.transitionTo("LOCKED", I), this.lockedBPM = B.getBPM()) : Q > dA && this.transitionTo("BREAKDOWN", I);
3519
3520
  break;
3520
3521
  case "LOCKED":
3521
- Q > dA ? this.transitionTo("BREAKDOWN", I) : g < nB && this.transitionTo("TRACKING", I);
3522
+ Q > dA ? this.transitionTo("BREAKDOWN", I) : g < qB && this.transitionTo("TRACKING", I);
3522
3523
  break;
3523
3524
  case "BREAKDOWN":
3524
3525
  Q < dA ? g >= zA ? this.transitionTo("LOCKED", I) : this.transitionTo("TRACKING", I) : (Q > bA || B.isExtrapolationLimitReached()) && this.transitionTo("LOST", I);
@@ -3784,10 +3785,10 @@ class pB {
3784
3785
  }), this.adaptiveProfiles.kick.samples.length >= 2 && this.calculateAdaptiveThresholds();
3785
3786
  }
3786
3787
  const H = Y > 200, Z = I.mid.onset, t = I.mid.sharpness ?? 1, L = H ? this.adaptiveThresholds.snareIndependent.minSharpness : this.adaptiveThresholds.snareLayered.minSharpness, u = l && F < 0.12 && // Mid ratio way too low for a real snare
3787
- c > 0.7, p = Z && I.mid.strength >= 0.18 && I.mid.energy >= 2e-5 && t > L * 0.6 && !u, n = Z && I.mid.strength >= Math.max(0.18, this.adaptiveThresholds.snareIndependent.minStrength * 0.7) && F >= this.adaptiveThresholds.snareIndependent.minMidRatio * 0.7 && t > L * 0.8 && !u, z = Z && G && g > i * 1.05 && t > L * 0.8 && // Slightly relaxed to reduce misses
3788
+ c > 0.7, p = Z && I.mid.strength >= 0.18 && I.mid.energy >= 2e-5 && t > L * 0.6 && !u, q = Z && I.mid.strength >= Math.max(0.18, this.adaptiveThresholds.snareIndependent.minStrength * 0.7) && F >= this.adaptiveThresholds.snareIndependent.minMidRatio * 0.7 && t > L * 0.8 && !u, z = Z && G && g > i * 1.05 && t > L * 0.8 && // Slightly relaxed to reduce misses
3788
3789
  !u && // Block kick harmonics
3789
3790
  // Mode 0: TRUST ESSENTIA when flux is clear even if ratios are low (prevents midRatio misses)
3790
- (p || n || // Mode 1: INDEPENDENT snare (no kick present)
3791
+ (p || q || // Mode 1: INDEPENDENT snare (no kick present)
3791
3792
  // Use thresholds learned from independent snares
3792
3793
  H && // Strong Essentia flux + reasonable mid ratio
3793
3794
  (I.mid.strength >= this.adaptiveThresholds.snareIndependent.minStrength && F >= this.adaptiveThresholds.snareIndependent.minMidRatio * 0.9 || // Fallback: strong flux alone (trust Essentia)
@@ -3810,22 +3811,22 @@ class pB {
3810
3811
  time: M
3811
3812
  }), (this.adaptiveProfiles.snareIndependent.samples.length >= 2 || this.adaptiveProfiles.snareLayered.samples.length >= 2) && this.calculateAdaptiveThresholds());
3812
3813
  }
3813
- const T = I.high.onset || I.highMid.onset, x = Y <= 200, O = Math.max(I.high.strength, I.highMid.strength), _ = Math.max(I.high.sharpness ?? 1, I.highMid.sharpness ?? 1), q = A.ratios.trebleBassFree, $ = x ? this.adaptiveThresholds.hatLayered.minSharpness : this.adaptiveThresholds.hatIndependent.minSharpness, r = T && O > 800 && q > 0.1, V = T && a && (r || E > D * 1.02) && // Bypass floor check for strong Essentia hats (always)
3814
+ const T = I.high.onset || I.highMid.onset, x = Y <= 200, O = Math.max(I.high.strength, I.highMid.strength), _ = Math.max(I.high.sharpness ?? 1, I.highMid.sharpness ?? 1), n = A.ratios.trebleBassFree, $ = x ? this.adaptiveThresholds.hatLayered.minSharpness : this.adaptiveThresholds.hatIndependent.minSharpness, r = T && O > 800 && n > 0.1, V = T && a && (r || E > D * 1.02) && // Bypass floor check for strong Essentia hats (always)
3814
3815
  _ > $ * 0.6 && // relax sharpness for soft/synth hats
3815
3816
  (r || // Also bypass strength/treble checks for strong Essentia hats (always)
3816
- (x ? O >= this.adaptiveThresholds.hatLayered.minStrength && q >= this.adaptiveThresholds.hatLayered.minTrebleRatio : O >= this.adaptiveThresholds.hatIndependent.minStrength && q >= this.adaptiveThresholds.hatIndependent.minTrebleRatio));
3817
+ (x ? O >= this.adaptiveThresholds.hatLayered.minStrength && n >= this.adaptiveThresholds.hatLayered.minTrebleRatio : O >= this.adaptiveThresholds.hatIndependent.minStrength && n >= this.adaptiveThresholds.hatIndependent.minTrebleRatio));
3817
3818
  if (V) {
3818
3819
  const d = Y <= 200, e = Math.max(I.high.strength, I.highMid.strength), P = Math.max(I.high.energy, I.highMid.energy), AA = Math.max(I.high.sharpness ?? 1, I.highMid.sharpness ?? 1);
3819
- AA > 0.05 && q > 0.08 && // Use bass-invariant ratio for quality gate
3820
+ AA > 0.05 && n > 0.08 && // Use bass-invariant ratio for quality gate
3820
3821
  e > 0.01 && (d ? this.adaptiveProfiles.hatLayered.samples.push({
3821
3822
  strength: e,
3822
- trebleRatio: q,
3823
+ trebleRatio: n,
3823
3824
  energy: P,
3824
3825
  sharpness: AA,
3825
3826
  time: M
3826
3827
  }) : this.adaptiveProfiles.hatIndependent.samples.push({
3827
3828
  strength: e,
3828
- trebleRatio: q,
3829
+ trebleRatio: n,
3829
3830
  energy: P,
3830
3831
  sharpness: AA,
3831
3832
  time: M
@@ -5011,7 +5012,7 @@ f.prototype._transform4 = function() {
5011
5012
  var G = g >>> 2;
5012
5013
  for (E = 0; E < B; E += g)
5013
5014
  for (var a = E + G, o = E, w = 0; o < a; o += 2, w += Q) {
5014
- const s = o, c = s + G, F = c + G, k = F + G, y = A[s], M = A[s + 1], Y = A[c], U = A[c + 1], J = A[F], N = A[F + 1], l = A[k], H = A[k + 1], Z = y, t = M, L = h[w], u = D * h[w + 1], p = Y * L - U * u, n = Y * u + U * L, z = h[2 * w], T = D * h[2 * w + 1], x = J * z - N * T, O = J * T + N * z, _ = h[3 * w], q = D * h[3 * w + 1], $ = l * _ - H * q, r = l * q + H * _, V = Z + x, v = t + O, b = Z - x, m = t - O, X = p + $, d = n + r, e = D * (p - $), P = D * (n - r), AA = V + X, FA = v + d, JA = V - X, YA = v - d, lA = b + P, UA = m - e, NA = b - P, HA = m + e;
5015
+ const s = o, c = s + G, F = c + G, k = F + G, y = A[s], M = A[s + 1], Y = A[c], U = A[c + 1], J = A[F], N = A[F + 1], l = A[k], H = A[k + 1], Z = y, t = M, L = h[w], u = D * h[w + 1], p = Y * L - U * u, q = Y * u + U * L, z = h[2 * w], T = D * h[2 * w + 1], x = J * z - N * T, O = J * T + N * z, _ = h[3 * w], n = D * h[3 * w + 1], $ = l * _ - H * n, r = l * n + H * _, V = Z + x, v = t + O, b = Z - x, m = t - O, X = p + $, d = q + r, e = D * (p - $), P = D * (q - r), AA = V + X, FA = v + d, JA = V - X, YA = v - d, lA = b + P, UA = m - e, NA = b - P, HA = m + e;
5015
5016
  A[s] = AA, A[s + 1] = FA, A[c] = lA, A[c + 1] = UA, A[F] = JA, A[F + 1] = YA, A[k] = NA, A[k + 1] = HA;
5016
5017
  }
5017
5018
  }
@@ -5021,8 +5022,8 @@ f.prototype._singleTransform2 = function(A, B, I) {
5021
5022
  Q[A] = h, Q[A + 1] = G, Q[A + 2] = a, Q[A + 3] = o;
5022
5023
  };
5023
5024
  f.prototype._singleTransform4 = function(A, B, I) {
5024
- const Q = this._out, g = this._data, E = this._inv ? -1 : 1, C = I * 2, i = I * 3, D = g[B], h = g[B + 1], G = g[B + I], a = g[B + I + 1], o = g[B + C], w = g[B + C + 1], s = g[B + i], c = g[B + i + 1], F = D + o, k = h + w, y = D - o, M = h - w, Y = G + s, U = a + c, J = E * (G - s), N = E * (a - c), l = F + Y, H = k + U, Z = y + N, t = M - J, L = F - Y, u = k - U, p = y - N, n = M + J;
5025
- Q[A] = l, Q[A + 1] = H, Q[A + 2] = Z, Q[A + 3] = t, Q[A + 4] = L, Q[A + 5] = u, Q[A + 6] = p, Q[A + 7] = n;
5025
+ const Q = this._out, g = this._data, E = this._inv ? -1 : 1, C = I * 2, i = I * 3, D = g[B], h = g[B + 1], G = g[B + I], a = g[B + I + 1], o = g[B + C], w = g[B + C + 1], s = g[B + i], c = g[B + i + 1], F = D + o, k = h + w, y = D - o, M = h - w, Y = G + s, U = a + c, J = E * (G - s), N = E * (a - c), l = F + Y, H = k + U, Z = y + N, t = M - J, L = F - Y, u = k - U, p = y - N, q = M + J;
5026
+ Q[A] = l, Q[A + 1] = H, Q[A + 2] = Z, Q[A + 3] = t, Q[A + 4] = L, Q[A + 5] = u, Q[A + 6] = p, Q[A + 7] = q;
5026
5027
  };
5027
5028
  f.prototype._realTransform4 = function() {
5028
5029
  var A = this._out, B = this._csize, I = this._width, Q = 1 << I, g = B / Q << 1, E, C, i = this._bitrev;
@@ -5042,7 +5043,7 @@ f.prototype._realTransform4 = function() {
5042
5043
  var G = g >>> 1, a = G >>> 1, o = a >>> 1;
5043
5044
  for (E = 0; E < B; E += g)
5044
5045
  for (var w = 0, s = 0; w <= o; w += 2, s += Q) {
5045
- var c = E + w, F = c + a, k = F + a, y = k + a, M = A[c], Y = A[c + 1], U = A[F], J = A[F + 1], N = A[k], l = A[k + 1], H = A[y], Z = A[y + 1], t = M, L = Y, u = h[s], p = D * h[s + 1], n = U * u - J * p, z = U * p + J * u, T = h[2 * s], x = D * h[2 * s + 1], O = N * T - l * x, _ = N * x + l * T, q = h[3 * s], $ = D * h[3 * s + 1], r = H * q - Z * $, V = H * $ + Z * q, v = t + O, b = L + _, m = t - O, X = L - _, d = n + r, e = z + V, P = D * (n - r), AA = D * (z - V), FA = v + d, JA = b + e, YA = m + AA, lA = X - P;
5046
+ var c = E + w, F = c + a, k = F + a, y = k + a, M = A[c], Y = A[c + 1], U = A[F], J = A[F + 1], N = A[k], l = A[k + 1], H = A[y], Z = A[y + 1], t = M, L = Y, u = h[s], p = D * h[s + 1], q = U * u - J * p, z = U * p + J * u, T = h[2 * s], x = D * h[2 * s + 1], O = N * T - l * x, _ = N * x + l * T, n = h[3 * s], $ = D * h[3 * s + 1], r = H * n - Z * $, V = H * $ + Z * n, v = t + O, b = L + _, m = t - O, X = L - _, d = q + r, e = z + V, P = D * (q - r), AA = D * (z - V), FA = v + d, JA = b + e, YA = m + AA, lA = X - P;
5046
5047
  if (A[c] = FA, A[c + 1] = JA, A[F] = YA, A[F + 1] = lA, w === 0) {
5047
5048
  var UA = v - d, NA = b - e;
5048
5049
  A[k] = UA, A[k + 1] = NA;
@@ -6753,6 +6754,11 @@ function WA(R, A) {
6753
6754
  function tA(R) {
6754
6755
  return R.toString(16).padStart(2, "0");
6755
6756
  }
6757
+ function aI(R) {
6758
+ const A = {};
6759
+ let B = !1;
6760
+ return R.errorCoalescingWindowMs !== void 0 && (A.errorCoalescingWindowMs = R.errorCoalescingWindowMs, B = !0), R.consoleCoalescingWindowMs !== void 0 && (A.consoleCoalescingWindowMs = R.consoleCoalescingWindowMs, B = !0), R.consoleArgMaxBytes !== void 0 && (A.consoleArgMaxBytes = R.consoleArgMaxBytes, B = !0), R.consoleMaxArgsPerCall !== void 0 && (A.consoleMaxArgsPerCall = R.consoleMaxArgsPerCall, B = !0), R.consoleMaxUniqueSignaturesPerSecond !== void 0 && (A.consoleMaxUniqueSignaturesPerSecond = R.consoleMaxUniqueSignaturesPerSecond, B = !0), B ? A : void 0;
6761
+ }
6756
6762
  function OA(R, A) {
6757
6763
  return R && A && typeof R == "object" && typeof A == "object" && "x" in R && "x" in A && "y" in R && "y" in A ? R.x === A.x && R.y === A.y : !1;
6758
6764
  }
@@ -6843,6 +6849,11 @@ class K {
6843
6849
  // version or shape validation; consumers surface meaningful UI feedback
6844
6850
  // rather than relying on console.warn.
6845
6851
  stateImportErrorListeners = /* @__PURE__ */ new Set();
6852
+ // Scene error reporting listeners. Consumers (AI chat, toast UIs, dev
6853
+ // tooling) subscribe via `onSceneRuntimeError` / `onSceneConsole`. Cleared
6854
+ // in `destroy()`.
6855
+ sceneRuntimeErrorListeners = /* @__PURE__ */ new Set();
6856
+ sceneConsoleListeners = /* @__PURE__ */ new Set();
6846
6857
  // Performance tracking (basic for Phase 1)
6847
6858
  stats = {
6848
6859
  frameTime: 0,
@@ -6981,7 +6992,8 @@ class K {
6981
6992
  allowInteraction: this.currentInteractionEnabled,
6982
6993
  allowSensors: !!this.deviceSensorManager,
6983
6994
  sc: this.config._sc,
6984
- rh: this.config._rh
6995
+ rh: this.config._rh,
6996
+ reporterConfig: aI(this.config)
6985
6997
  }
6986
6998
  ), this.setupCommunication(), await this.workerManager.createWorker(), this.isDestroyed)
6987
6999
  throw new S("Initialization cancelled", "INITIALIZATION_CANCELLED");
@@ -7093,6 +7105,10 @@ class K {
7093
7105
  setupCommunication() {
7094
7106
  this.workerManager && (this.workerManager.onMessage("error", (A) => {
7095
7107
  console.error("Worker error:", A);
7108
+ }), this.workerManager.onMessage("scene-error", (A) => {
7109
+ console.error("Scene error:", A), this.fireSceneRuntimeError(A);
7110
+ }), this.workerManager.onMessage("scene-console", (A) => {
7111
+ this.fireSceneConsole(A);
7096
7112
  }), this.workerManager.onMessage("performance-warning", (A) => {
7097
7113
  console.warn("Performance warning:", A);
7098
7114
  }), this.workerManager.onMessage("performance-update", (A) => {
@@ -7610,7 +7626,7 @@ class K {
7610
7626
  */
7611
7627
  importFullState(A, B) {
7612
7628
  this.validateReady();
7613
- const I = aI(A);
7629
+ const I = DI(A);
7614
7630
  if (I) {
7615
7631
  this.fireStateImportError(I);
7616
7632
  return;
@@ -7641,6 +7657,64 @@ class K {
7641
7657
  console.error("Error in onStateImportError listener:", I);
7642
7658
  }
7643
7659
  }
7660
+ /**
7661
+ * Listen for scene runtime errors surfaced by the worker. Errors caused by
7662
+ * the artist's scene code (`SCENE_CODE_ERROR`, `RENDER_ERROR`,
7663
+ * `SHADER_COMPILE_ERROR`, `P5_INIT_ERROR`, plus async / unhandled-rejection
7664
+ * paths originating in the scene) are coalesced on the worker side: identical
7665
+ * signatures within `VijiCoreConfig.errorCoalescingWindowMs` (default 1s)
7666
+ * collapse to a single leading-edge listener call plus an optional trailing
7667
+ * rollup with the final `count`.
7668
+ *
7669
+ * The legacy `console.error('Worker error:', data)` host log continues to
7670
+ * fire alongside this listener (tee semantics, never silenced).
7671
+ *
7672
+ * @returns Unsubscribe function. Call to remove the listener.
7673
+ */
7674
+ onSceneRuntimeError(A) {
7675
+ return this.sceneRuntimeErrorListeners.add(A), () => {
7676
+ this.sceneRuntimeErrorListeners.delete(A);
7677
+ };
7678
+ }
7679
+ fireSceneRuntimeError(A) {
7680
+ for (const B of this.sceneRuntimeErrorListeners)
7681
+ try {
7682
+ B(A);
7683
+ } catch (I) {
7684
+ console.error("Error in onSceneRuntimeError listener:", I);
7685
+ }
7686
+ }
7687
+ /**
7688
+ * Listen for `console.*` calls made from the artist's scene code. The
7689
+ * worker injects a wrapped `console` as an additional function-argument
7690
+ * binding to the artist's IIFE; the wrapper calls the real `console[level]`
7691
+ * first (preserving DevTools output) and then forwards a coalesced, bounded
7692
+ * envelope through this listener.
7693
+ *
7694
+ * Coalescing window: `VijiCoreConfig.consoleCoalescingWindowMs` (default 1s).
7695
+ * Argument bounds: `consoleArgMaxBytes` (default 512B per arg),
7696
+ * `consoleMaxArgsPerCall` (default 8 args). Rate cap on distinct signatures:
7697
+ * `consoleMaxUniqueSignaturesPerSecond` (default 32).
7698
+ *
7699
+ * Only the four forwarded levels (`log`, `info`, `warn`, `error`) reach
7700
+ * this listener. Other console methods (`debug`, `trace`, `dir`, `group`,
7701
+ * etc.) pass through to the real console unchanged but are not surfaced.
7702
+ *
7703
+ * @returns Unsubscribe function. Call to remove the listener.
7704
+ */
7705
+ onSceneConsole(A) {
7706
+ return this.sceneConsoleListeners.add(A), () => {
7707
+ this.sceneConsoleListeners.delete(A);
7708
+ };
7709
+ }
7710
+ fireSceneConsole(A) {
7711
+ for (const B of this.sceneConsoleListeners)
7712
+ try {
7713
+ B(A);
7714
+ } catch (I) {
7715
+ console.error("Error in onSceneConsole listener:", I);
7716
+ }
7717
+ }
7644
7718
  /**
7645
7719
  * Notify parameter change listeners
7646
7720
  */
@@ -8265,7 +8339,7 @@ class K {
8265
8339
  */
8266
8340
  async destroy() {
8267
8341
  if (!this.isDestroyed) {
8268
- this.isDestroyed = !0, this.parameterGroups.clear(), this.parameterValues.clear(), this.parameterListeners.clear(), this.parameterDefinedListeners.clear(), this.parameterErrorListeners.clear(), this.capabilitiesChangeListeners.clear(), this.stateImportErrorListeners.clear(), this.unlinkEventSource(), this.unlinkFrameSources();
8342
+ this.isDestroyed = !0, this.parameterGroups.clear(), this.parameterValues.clear(), this.parameterListeners.clear(), this.parameterDefinedListeners.clear(), this.parameterErrorListeners.clear(), this.capabilitiesChangeListeners.clear(), this.stateImportErrorListeners.clear(), this.sceneRuntimeErrorListeners.clear(), this.sceneConsoleListeners.clear(), this.unlinkEventSource(), this.unlinkFrameSources();
8269
8343
  for (const [A] of this.deviceVideoCoordinators)
8270
8344
  await this.clearDeviceVideo(A);
8271
8345
  this.deviceVideoCoordinators.clear(), this.deviceVideoStreamIndices.clear(), this.deviceSensorManager && (this.deviceSensorManager.destroy(), this.deviceSensorManager = null);
@@ -8313,7 +8387,7 @@ class K {
8313
8387
  }
8314
8388
  }
8315
8389
  }
8316
- function aI(R) {
8390
+ function DI(R) {
8317
8391
  if (R === null || typeof R != "object")
8318
8392
  return { code: "malformed", details: "payload is not an object" };
8319
8393
  const A = R;
@@ -8324,12 +8398,12 @@ function aI(R) {
8324
8398
  expectedVersion: 1
8325
8399
  } : typeof A.senderTime != "number" ? { code: "invalid-field", details: "senderTime must be a number", field: "senderTime" } : null;
8326
8400
  }
8327
- const DI = "0.5.7";
8401
+ const oI = "0.7.4";
8328
8402
  export {
8329
8403
  yA as A,
8330
- DI as V,
8404
+ oI as V,
8331
8405
  K as a,
8332
8406
  S as b,
8333
8407
  vB as g
8334
8408
  };
8335
- //# sourceMappingURL=index-DfAcgMbB.js.map
8409
+ //# sourceMappingURL=index-DmQ5U_50.js.map