@viji-dev/core 0.3.27 → 0.3.28

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.
@@ -3083,6 +3083,9 @@ ${error}`);
3083
3083
  for (let i = 0; i < ShaderWorkerAdapter.MAX_VIDEO_STREAMS; i++) {
3084
3084
  this.textureUnits.set(`u_videoStream${i}`, this.nextTextureUnit++);
3085
3085
  }
3086
+ for (let i = 0; i < ShaderWorkerAdapter.MAX_DEVICE_VIDEOS; i++) {
3087
+ this.textureUnits.set(`u_device${i}`, this.nextTextureUnit++);
3088
+ }
3086
3089
  if (this.backbufferEnabled) {
3087
3090
  this.textureUnits.set("backbuffer", this.nextTextureUnit++);
3088
3091
  }
@@ -3896,7 +3899,8 @@ ${error}`);
3896
3899
  }
3897
3900
  const texture = this.deviceTextures[index];
3898
3901
  if (!texture) return;
3899
- const textureUnit = 8 + index;
3902
+ const textureUnit = this.textureUnits.get(`u_device${index}`);
3903
+ if (textureUnit === void 0) return;
3900
3904
  this.gl.activeTexture(this.gl.TEXTURE0 + textureUnit);
3901
3905
  this.gl.bindTexture(this.gl.TEXTURE_2D, texture);
3902
3906
  const shouldFlip = frame instanceof OffscreenCanvas;
@@ -3918,6 +3922,11 @@ ${error}`);
3918
3922
  this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);
3919
3923
  this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
3920
3924
  this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
3925
+ const uniformName = `u_device${index}`;
3926
+ const location = this.uniformLocations.get(uniformName);
3927
+ if (location) {
3928
+ this.gl.uniform1i(location, textureUnit);
3929
+ }
3921
3930
  if (frame instanceof ImageBitmap) {
3922
3931
  frame.close();
3923
3932
  }
@@ -4068,6 +4077,394 @@ ${error}`);
4068
4077
  if (this.quadBuffer) gl.deleteBuffer(this.quadBuffer);
4069
4078
  }
4070
4079
  }
4080
+ const _PK = {
4081
+ kty: "EC",
4082
+ crv: "P-256",
4083
+ x: "6bkPbVZXx-c08blVs6qIwm0gfSRLS2nnf2Tsz19ggtM",
4084
+ y: "lhi486ASKQkS8TGbVee-FpdAu7qKaO3gad_4ScX8qJI"
4085
+ };
4086
+ const GRACE_SECONDS = 60;
4087
+ let _key = null;
4088
+ let _restricted = false;
4089
+ let _cache = null;
4090
+ let _expiry = 0;
4091
+ function _b64url(s) {
4092
+ const padded = s.replace(/-/g, "+").replace(/_/g, "/");
4093
+ const bin = atob(padded);
4094
+ const bytes = new Uint8Array(bin.length);
4095
+ for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i);
4096
+ return bytes;
4097
+ }
4098
+ async function init$1() {
4099
+ if (typeof crypto === "undefined" || !crypto.subtle) {
4100
+ _restricted = true;
4101
+ console.warn("[Viji] _SC: secure context required — restricted mode active");
4102
+ return;
4103
+ }
4104
+ try {
4105
+ _key = await crypto.subtle.importKey(
4106
+ "jwk",
4107
+ _PK,
4108
+ { name: "ECDSA", namedCurve: "P-256" },
4109
+ false,
4110
+ ["verify"]
4111
+ );
4112
+ } catch {
4113
+ _restricted = true;
4114
+ console.warn("[Viji] _SC: key import failed — restricted mode active");
4115
+ }
4116
+ }
4117
+ async function update(token) {
4118
+ if (_restricted || !_key) {
4119
+ _cache = null;
4120
+ _expiry = 0;
4121
+ return;
4122
+ }
4123
+ try {
4124
+ const parts = token.split(".");
4125
+ if (parts.length !== 3) throw new Error("malformed");
4126
+ const signingInput = new TextEncoder().encode(parts[0] + "." + parts[1]);
4127
+ const signature = _b64url(parts[2]);
4128
+ const valid = await crypto.subtle.verify(
4129
+ { name: "ECDSA", hash: "SHA-256" },
4130
+ _key,
4131
+ signature.buffer,
4132
+ signingInput.buffer
4133
+ );
4134
+ if (!valid) throw new Error("invalid signature");
4135
+ const payload = JSON.parse(new TextDecoder().decode(_b64url(parts[1])));
4136
+ _cache = payload.c ?? {};
4137
+ _expiry = payload.e ?? 0;
4138
+ } catch {
4139
+ _cache = null;
4140
+ _expiry = 0;
4141
+ }
4142
+ }
4143
+ function get$1(key, defaultValue) {
4144
+ if (_restricted || !_cache) return defaultValue;
4145
+ const now = Math.floor(Date.now() / 1e3);
4146
+ if (_expiry > 0 && _expiry + GRACE_SECONDS < now) {
4147
+ _cache = null;
4148
+ _expiry = 0;
4149
+ return defaultValue;
4150
+ }
4151
+ return typeof _cache[key] === "number" ? _cache[key] : defaultValue;
4152
+ }
4153
+ const FULL_W = 44, FULL_H = 74;
4154
+ const MINI_W = 44, MINI_H = 23;
4155
+ const STROKE_COLOR = "#F1F1F1";
4156
+ let _bufferFull = null;
4157
+ let _bufferMini = null;
4158
+ let _glTexFull = null;
4159
+ let _glTexMini = null;
4160
+ let _glProgram = null;
4161
+ let _glVbo = null;
4162
+ let _glVao = null;
4163
+ let _glInitFor = null;
4164
+ let _hint = 0;
4165
+ const VERT_SRC = `
4166
+ attribute vec2 a_pos;
4167
+ attribute vec2 a_uv;
4168
+ varying vec2 v_uv;
4169
+ void main() {
4170
+ v_uv = a_uv;
4171
+ gl_Position = vec4(a_pos, 0.0, 1.0);
4172
+ }`;
4173
+ const FRAG_SRC = `
4174
+ precision mediump float;
4175
+ uniform sampler2D u_tex;
4176
+ uniform float u_alpha;
4177
+ varying vec2 v_uv;
4178
+ void main() {
4179
+ gl_FragColor = texture2D(u_tex, v_uv) * u_alpha;
4180
+ }`;
4181
+ function renderFullLogo(ctx) {
4182
+ ctx.strokeStyle = STROKE_COLOR;
4183
+ ctx.lineCap = "round";
4184
+ ctx.lineWidth = 2.8;
4185
+ ctx.beginPath();
4186
+ ctx.moveTo(21.9991, 5);
4187
+ ctx.lineTo(5, 21.999);
4188
+ ctx.stroke();
4189
+ ctx.beginPath();
4190
+ ctx.moveTo(38.9981, 21.998);
4191
+ ctx.lineTo(21.999, 38.9971);
4192
+ ctx.stroke();
4193
+ ctx.beginPath();
4194
+ ctx.moveTo(38.9984, 5);
4195
+ ctx.lineTo(5, 38.9983);
4196
+ ctx.stroke();
4197
+ ctx.lineWidth = 3.5;
4198
+ ctx.beginPath();
4199
+ ctx.moveTo(5.00052, 5.00155);
4200
+ ctx.lineTo(5.00098, 5);
4201
+ ctx.stroke();
4202
+ ctx.beginPath();
4203
+ ctx.moveTo(38.9986, 38.9996);
4204
+ ctx.lineTo(38.999, 38.998);
4205
+ ctx.stroke();
4206
+ ctx.lineWidth = 2.8;
4207
+ ctx.lineJoin = "round";
4208
+ ctx.beginPath();
4209
+ ctx.moveTo(5.875, 53);
4210
+ ctx.lineTo(10.1417, 60);
4211
+ ctx.lineTo(13.875, 53);
4212
+ ctx.stroke();
4213
+ ctx.beginPath();
4214
+ ctx.moveTo(21, 53);
4215
+ ctx.lineTo(21, 60);
4216
+ ctx.stroke();
4217
+ ctx.beginPath();
4218
+ ctx.moveTo(38.125, 53);
4219
+ ctx.lineTo(38.125, 60);
4220
+ ctx.stroke();
4221
+ ctx.beginPath();
4222
+ ctx.moveTo(30, 53);
4223
+ ctx.lineTo(30, 62.1502);
4224
+ ctx.bezierCurveTo(30, 64.2764, 28.2764, 66, 26.1502, 66);
4225
+ ctx.lineTo(26, 66);
4226
+ ctx.stroke();
4227
+ }
4228
+ function renderMiniLogo(ctx) {
4229
+ ctx.strokeStyle = STROKE_COLOR;
4230
+ ctx.lineCap = "round";
4231
+ ctx.lineJoin = "round";
4232
+ ctx.lineWidth = 2.8;
4233
+ ctx.beginPath();
4234
+ ctx.moveTo(5.875, 5);
4235
+ ctx.lineTo(10.1417, 12);
4236
+ ctx.lineTo(13.875, 5);
4237
+ ctx.stroke();
4238
+ ctx.beginPath();
4239
+ ctx.moveTo(21, 5);
4240
+ ctx.lineTo(21, 12);
4241
+ ctx.stroke();
4242
+ ctx.beginPath();
4243
+ ctx.moveTo(38.125, 5);
4244
+ ctx.lineTo(38.125, 12);
4245
+ ctx.stroke();
4246
+ ctx.beginPath();
4247
+ ctx.moveTo(30, 5);
4248
+ ctx.lineTo(30, 14.1502);
4249
+ ctx.bezierCurveTo(30, 16.2764, 28.2764, 18, 26.1502, 18);
4250
+ ctx.lineTo(26, 18);
4251
+ ctx.stroke();
4252
+ }
4253
+ function init(_canvas) {
4254
+ try {
4255
+ _bufferFull = new OffscreenCanvas(FULL_W, FULL_H);
4256
+ const ctxFull = _bufferFull.getContext("2d");
4257
+ if (ctxFull) renderFullLogo(ctxFull);
4258
+ _bufferMini = new OffscreenCanvas(MINI_W, MINI_H);
4259
+ const ctxMini = _bufferMini.getContext("2d");
4260
+ if (ctxMini) renderMiniLogo(ctxMini);
4261
+ } catch (e) {
4262
+ console.warn("[Viji] overlay: init failed", e);
4263
+ }
4264
+ }
4265
+ function setRenderHint(h) {
4266
+ _hint = h;
4267
+ }
4268
+ function draw(canvas, ctx, gl, brandingMode, displayScale = 1) {
4269
+ if (brandingMode >= 2) return;
4270
+ if (!_bufferFull && !_bufferMini) return;
4271
+ const isMini = _hint === 1;
4272
+ const s = displayScale || 1;
4273
+ if (ctx) {
4274
+ draw2D(ctx, isMini, canvas.width, s);
4275
+ } else if (gl) {
4276
+ drawGL(gl, canvas, isMini, s);
4277
+ }
4278
+ }
4279
+ const GL_VERTEX_ARRAY_BINDING = 34229;
4280
+ function uploadTexture(gl, source) {
4281
+ if (!source) return null;
4282
+ const prevTexBinding = gl.getParameter(gl.TEXTURE_BINDING_2D);
4283
+ const prevFlipY = gl.getParameter(gl.UNPACK_FLIP_Y_WEBGL);
4284
+ const prevPremultiply = gl.getParameter(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL);
4285
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
4286
+ gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 0);
4287
+ const tex = gl.createTexture();
4288
+ gl.bindTexture(gl.TEXTURE_2D, tex);
4289
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
4290
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
4291
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
4292
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
4293
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source);
4294
+ gl.bindTexture(gl.TEXTURE_2D, prevTexBinding);
4295
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, prevFlipY ? 1 : 0);
4296
+ gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, prevPremultiply ? 1 : 0);
4297
+ return tex;
4298
+ }
4299
+ function initGL(gl) {
4300
+ if (_glInitFor === gl) return;
4301
+ _glInitFor = gl;
4302
+ _glTexFull = uploadTexture(gl, _bufferFull);
4303
+ _glTexMini = uploadTexture(gl, _bufferMini);
4304
+ const vs = gl.createShader(gl.VERTEX_SHADER);
4305
+ gl.shaderSource(vs, VERT_SRC);
4306
+ gl.compileShader(vs);
4307
+ const fs = gl.createShader(gl.FRAGMENT_SHADER);
4308
+ gl.shaderSource(fs, FRAG_SRC);
4309
+ gl.compileShader(fs);
4310
+ _glProgram = gl.createProgram();
4311
+ gl.attachShader(_glProgram, vs);
4312
+ gl.attachShader(_glProgram, fs);
4313
+ gl.linkProgram(_glProgram);
4314
+ gl.deleteShader(vs);
4315
+ gl.deleteShader(fs);
4316
+ if (!gl.getProgramParameter(_glProgram, gl.LINK_STATUS)) {
4317
+ console.warn("[Viji] overlay: shader link failed");
4318
+ _glProgram = null;
4319
+ return;
4320
+ }
4321
+ _glVbo = gl.createBuffer();
4322
+ const gl2 = gl;
4323
+ if (typeof gl2.createVertexArray === "function") {
4324
+ const prevVAO = gl.getParameter(GL_VERTEX_ARRAY_BINDING);
4325
+ const prevBuf = gl.getParameter(gl.ARRAY_BUFFER_BINDING);
4326
+ _glVao = gl2.createVertexArray();
4327
+ gl2.bindVertexArray(_glVao);
4328
+ gl.bindBuffer(gl.ARRAY_BUFFER, _glVbo);
4329
+ const aPos = gl.getAttribLocation(_glProgram, "a_pos");
4330
+ const aUv = gl.getAttribLocation(_glProgram, "a_uv");
4331
+ gl.enableVertexAttribArray(aPos);
4332
+ gl.enableVertexAttribArray(aUv);
4333
+ gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 16, 0);
4334
+ gl.vertexAttribPointer(aUv, 2, gl.FLOAT, false, 16, 8);
4335
+ gl2.bindVertexArray(prevVAO);
4336
+ gl.bindBuffer(gl.ARRAY_BUFFER, prevBuf);
4337
+ }
4338
+ }
4339
+ function draw2D(ctx, mini, canvasW, s) {
4340
+ const buffer = mini ? _bufferMini : _bufferFull;
4341
+ if (!buffer) return;
4342
+ const drawW = (mini ? MINI_W : FULL_W) * s;
4343
+ const drawH = (mini ? MINI_H : FULL_H) * s;
4344
+ const x = mini ? Math.round((canvasW - drawW) / 2) : Math.round(48 * s);
4345
+ const y = Math.round((mini ? 52 : 48) * s);
4346
+ ctx.save();
4347
+ ctx.globalAlpha = 0.85;
4348
+ ctx.drawImage(buffer, x, y, drawW, drawH);
4349
+ ctx.restore();
4350
+ }
4351
+ function drawGL(gl, canvas, mini, s) {
4352
+ initGL(gl);
4353
+ if (!_glProgram || !_glVbo) return;
4354
+ const tex = mini ? _glTexMini : _glTexFull;
4355
+ if (!tex) return;
4356
+ const logoW = (mini ? MINI_W : FULL_W) * s;
4357
+ const logoH = (mini ? MINI_H : FULL_H) * s;
4358
+ const cw = canvas.width;
4359
+ const ch = canvas.height;
4360
+ const px = mini ? Math.round((cw - logoW) / 2) : Math.round(48 * s);
4361
+ const py = Math.round((mini ? 52 : 48) * s);
4362
+ const x0 = px / cw * 2 - 1;
4363
+ const y0 = 1 - (py + logoH) / ch * 2;
4364
+ const x1 = (px + logoW) / cw * 2 - 1;
4365
+ const y1 = 1 - py / ch * 2;
4366
+ const gl2 = gl;
4367
+ const hasVAO = _glVao && typeof gl2.bindVertexArray === "function";
4368
+ const prevProgram = gl.getParameter(gl.CURRENT_PROGRAM);
4369
+ const prevActiveTexture = gl.getParameter(gl.ACTIVE_TEXTURE);
4370
+ gl.activeTexture(gl.TEXTURE0);
4371
+ const prevTex0 = gl.getParameter(gl.TEXTURE_BINDING_2D);
4372
+ const prevArrayBuffer = gl.getParameter(gl.ARRAY_BUFFER_BINDING);
4373
+ const prevFramebuffer = gl.getParameter(gl.FRAMEBUFFER_BINDING);
4374
+ const prevViewport = gl.getParameter(gl.VIEWPORT);
4375
+ const prevBlend = gl.isEnabled(gl.BLEND);
4376
+ const prevBlendSrcRGB = gl.getParameter(gl.BLEND_SRC_RGB);
4377
+ const prevBlendDstRGB = gl.getParameter(gl.BLEND_DST_RGB);
4378
+ const prevBlendSrcAlpha = gl.getParameter(gl.BLEND_SRC_ALPHA);
4379
+ const prevBlendDstAlpha = gl.getParameter(gl.BLEND_DST_ALPHA);
4380
+ const prevBlendEqRGB = gl.getParameter(gl.BLEND_EQUATION_RGB);
4381
+ const prevBlendEqAlpha = gl.getParameter(gl.BLEND_EQUATION_ALPHA);
4382
+ const prevDepthTest = gl.isEnabled(gl.DEPTH_TEST);
4383
+ const prevScissorTest = gl.isEnabled(gl.SCISSOR_TEST);
4384
+ const prevStencilTest = gl.isEnabled(gl.STENCIL_TEST);
4385
+ const prevCullFace = gl.isEnabled(gl.CULL_FACE);
4386
+ const prevColorMask = gl.getParameter(gl.COLOR_WRITEMASK);
4387
+ const prevUnpackFlipY = gl.getParameter(gl.UNPACK_FLIP_Y_WEBGL);
4388
+ const prevVAO = hasVAO ? gl.getParameter(GL_VERTEX_ARRAY_BINDING) : null;
4389
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
4390
+ gl.viewport(0, 0, cw, ch);
4391
+ gl.useProgram(_glProgram);
4392
+ gl.enable(gl.BLEND);
4393
+ gl.blendEquation(gl.FUNC_ADD);
4394
+ gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
4395
+ gl.disable(gl.DEPTH_TEST);
4396
+ gl.disable(gl.SCISSOR_TEST);
4397
+ gl.disable(gl.STENCIL_TEST);
4398
+ gl.disable(gl.CULL_FACE);
4399
+ gl.colorMask(true, true, true, true);
4400
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 0);
4401
+ gl.bindTexture(gl.TEXTURE_2D, tex);
4402
+ gl.uniform1i(gl.getUniformLocation(_glProgram, "u_tex"), 0);
4403
+ gl.uniform1f(gl.getUniformLocation(_glProgram, "u_alpha"), 0.85);
4404
+ const verts = new Float32Array([
4405
+ x0,
4406
+ y0,
4407
+ 0,
4408
+ 0,
4409
+ x1,
4410
+ y0,
4411
+ 1,
4412
+ 0,
4413
+ x0,
4414
+ y1,
4415
+ 0,
4416
+ 1,
4417
+ x0,
4418
+ y1,
4419
+ 0,
4420
+ 1,
4421
+ x1,
4422
+ y0,
4423
+ 1,
4424
+ 0,
4425
+ x1,
4426
+ y1,
4427
+ 1,
4428
+ 1
4429
+ ]);
4430
+ if (hasVAO) {
4431
+ gl2.bindVertexArray(_glVao);
4432
+ gl.bindBuffer(gl.ARRAY_BUFFER, _glVbo);
4433
+ gl.bufferData(gl.ARRAY_BUFFER, verts, gl.DYNAMIC_DRAW);
4434
+ } else {
4435
+ gl.bindBuffer(gl.ARRAY_BUFFER, _glVbo);
4436
+ gl.bufferData(gl.ARRAY_BUFFER, verts, gl.DYNAMIC_DRAW);
4437
+ const aPos = gl.getAttribLocation(_glProgram, "a_pos");
4438
+ const aUv = gl.getAttribLocation(_glProgram, "a_uv");
4439
+ gl.enableVertexAttribArray(aPos);
4440
+ gl.enableVertexAttribArray(aUv);
4441
+ gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 16, 0);
4442
+ gl.vertexAttribPointer(aUv, 2, gl.FLOAT, false, 16, 8);
4443
+ }
4444
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
4445
+ if (hasVAO) gl2.bindVertexArray(prevVAO);
4446
+ gl.bindFramebuffer(gl.FRAMEBUFFER, prevFramebuffer);
4447
+ gl.viewport(prevViewport[0], prevViewport[1], prevViewport[2], prevViewport[3]);
4448
+ gl.bindBuffer(gl.ARRAY_BUFFER, prevArrayBuffer);
4449
+ gl.colorMask(prevColorMask[0], prevColorMask[1], prevColorMask[2], prevColorMask[3]);
4450
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, prevUnpackFlipY ? 1 : 0);
4451
+ if (prevScissorTest) gl.enable(gl.SCISSOR_TEST);
4452
+ else gl.disable(gl.SCISSOR_TEST);
4453
+ if (prevStencilTest) gl.enable(gl.STENCIL_TEST);
4454
+ else gl.disable(gl.STENCIL_TEST);
4455
+ if (prevCullFace) gl.enable(gl.CULL_FACE);
4456
+ else gl.disable(gl.CULL_FACE);
4457
+ if (prevDepthTest) gl.enable(gl.DEPTH_TEST);
4458
+ else gl.disable(gl.DEPTH_TEST);
4459
+ if (prevBlend) gl.enable(gl.BLEND);
4460
+ else gl.disable(gl.BLEND);
4461
+ gl.blendFuncSeparate(prevBlendSrcRGB, prevBlendDstRGB, prevBlendSrcAlpha, prevBlendDstAlpha);
4462
+ gl.blendEquationSeparate(prevBlendEqRGB, prevBlendEqAlpha);
4463
+ gl.activeTexture(gl.TEXTURE0);
4464
+ gl.bindTexture(gl.TEXTURE_2D, prevTex0);
4465
+ gl.activeTexture(prevActiveTexture);
4466
+ gl.useProgram(prevProgram);
4467
+ }
4071
4468
  class VijiWorkerRuntime {
4072
4469
  canvas = null;
4073
4470
  ctx = null;
@@ -4087,6 +4484,8 @@ class VijiWorkerRuntime {
4087
4484
  // Shader adapter for shader mode
4088
4485
  shaderAdapter = null;
4089
4486
  rendererType = "native";
4487
+ _isHeadless = false;
4488
+ _displayScale = 1;
4090
4489
  // Pending capture requests (queue to handle multiple simultaneous requests)
4091
4490
  pendingCaptures = [];
4092
4491
  /**
@@ -4551,6 +4950,12 @@ class VijiWorkerRuntime {
4551
4950
  case "capture-frame":
4552
4951
  this.handleCaptureFrame(message);
4553
4952
  break;
4953
+ case "sc-update":
4954
+ update(message.data.t);
4955
+ break;
4956
+ case "rh-update":
4957
+ setRenderHint(message.data.h);
4958
+ break;
4554
4959
  }
4555
4960
  };
4556
4961
  }
@@ -4558,8 +4963,25 @@ class VijiWorkerRuntime {
4558
4963
  try {
4559
4964
  this.canvas = message.data.canvas;
4560
4965
  this.viji.canvas = this.canvas;
4966
+ this._isHeadless = !!message.data.isHeadless;
4967
+ const origGetContext = this.canvas.getContext.bind(this.canvas);
4968
+ this.canvas.getContext = (type, attrs) => {
4969
+ const result = origGetContext(type, attrs);
4970
+ if (result) {
4971
+ if (type === "2d") {
4972
+ this.ctx = result;
4973
+ this.viji.ctx = this.ctx;
4974
+ } else if (type === "webgl" || type === "webgl2") {
4975
+ this.gl = result;
4976
+ this.viji.gl = this.gl;
4977
+ }
4978
+ }
4979
+ return result;
4980
+ };
4561
4981
  this.viji.width = this.canvas.width;
4562
4982
  this.viji.height = this.canvas.height;
4983
+ init$1();
4984
+ init(this.canvas);
4563
4985
  this.startRenderLoop();
4564
4986
  this.postMessage("init-response", {
4565
4987
  id: message.id
@@ -4644,6 +5066,7 @@ class VijiWorkerRuntime {
4644
5066
  }
4645
5067
  this.viji.width = Math.round(message.data.effectiveWidth);
4646
5068
  this.viji.height = Math.round(message.data.effectiveHeight);
5069
+ this._displayScale = message.data.displayScale ?? 1;
4647
5070
  if (this.gl) {
4648
5071
  this.gl.viewport(0, 0, this.viji.width, this.viji.height);
4649
5072
  }
@@ -4663,8 +5086,8 @@ class VijiWorkerRuntime {
4663
5086
  }
4664
5087
  handleParameterBatchUpdate(message) {
4665
5088
  if (message.data && message.data.updates) {
4666
- for (const update of message.data.updates) {
4667
- this.parameterSystem.updateParameterValue(update.name, update.value);
5089
+ for (const update2 of message.data.updates) {
5090
+ this.parameterSystem.updateParameterValue(update2.name, update2.value);
4668
5091
  }
4669
5092
  this.parameterSystem.markInitialValuesSynced();
4670
5093
  this.debugLog("Parameter system initialized successfully");
@@ -5133,6 +5556,10 @@ class VijiWorkerRuntime {
5133
5556
  console.warn("[AutoCapture] Failed:", error);
5134
5557
  }
5135
5558
  }
5559
+ if (!this._isHeadless && this.canvas) {
5560
+ const brandingMode = get$1("b", 0);
5561
+ draw(this.canvas, this.ctx, this.gl, brandingMode, this._displayScale);
5562
+ }
5136
5563
  }
5137
5564
  this.reportPerformanceStats(currentTime);
5138
5565
  this.interactionSystem.frameStart();
@@ -26586,4 +27013,4 @@ async function setSceneCode(sceneCode) {
26586
27013
  }
26587
27014
  }
26588
27015
  self.setSceneCode = setSceneCode;
26589
- //# sourceMappingURL=viji.worker-jTmB7qoQ.js.map
27016
+ //# sourceMappingURL=viji.worker-CdHkRwxI.js.map