@mindexec/cli 0.2.441 → 0.2.443

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.
Files changed (45) hide show
  1. package/package.json +1 -1
  2. package/remote-fast/osx-arm64/MacScreenCaptureKitH264.swift +339 -0
  3. package/remote-fast/osx-arm64/MacSystemAudioCapture.swift +214 -0
  4. package/remote-fast/osx-arm64/UnixRawCaptureHelper.mjs +80 -0
  5. package/remote-fast/osx-arm64/livedesk-raw-capture-resampler.mjs +73 -0
  6. package/remote-fast/osx-arm64/mindexec-remote-fast.dll +0 -0
  7. package/remote-fast/osx-x64/MacScreenCaptureKitH264.swift +339 -0
  8. package/remote-fast/osx-x64/MacSystemAudioCapture.swift +214 -0
  9. package/remote-fast/osx-x64/UnixRawCaptureHelper.mjs +80 -0
  10. package/remote-fast/osx-x64/livedesk-raw-capture-resampler.mjs +73 -0
  11. package/remote-fast/osx-x64/mindexec-remote-fast.dll +0 -0
  12. package/remote-fast/win-x64/NAudio.Asio.dll +0 -0
  13. package/remote-fast/win-x64/NAudio.Core.dll +0 -0
  14. package/remote-fast/win-x64/NAudio.Midi.dll +0 -0
  15. package/remote-fast/win-x64/NAudio.Wasapi.dll +0 -0
  16. package/remote-fast/win-x64/NAudio.WinForms.dll +0 -0
  17. package/remote-fast/win-x64/NAudio.WinMM.dll +0 -0
  18. package/remote-fast/win-x64/NAudio.dll +0 -0
  19. package/remote-fast/win-x64/SharpGen.Runtime.COM.dll +0 -0
  20. package/remote-fast/win-x64/SharpGen.Runtime.dll +0 -0
  21. package/remote-fast/win-x64/Vortice.DXGI.dll +0 -0
  22. package/remote-fast/win-x64/Vortice.Direct3D11.dll +0 -0
  23. package/remote-fast/win-x64/Vortice.DirectX.dll +0 -0
  24. package/remote-fast/win-x64/Vortice.Mathematics.dll +0 -0
  25. package/remote-fast/win-x64/mindexec-remote-fast.deps.json +238 -0
  26. package/remote-fast/win-x64/mindexec-remote-fast.dll +0 -0
  27. package/remote-fast/win-x64/mindexec-remote-fast.exe +0 -0
  28. package/remote-hub.js +75 -5
  29. package/server.js +32 -7
  30. package/wwwroot/_content/MindExecution.Shared/js/mind-map-css3d-manager.js +55 -9
  31. package/wwwroot/_content/MindExecution.Shared/js/mind-map-remote-codecs.js +199 -0
  32. package/wwwroot/_framework/{MindExecution.Core.808jj176e1.dll → MindExecution.Core.4moacskf64.dll} +0 -0
  33. package/wwwroot/_framework/{MindExecution.Kernel.75hxk08tt0.dll → MindExecution.Kernel.pa251cfsz4.dll} +0 -0
  34. package/wwwroot/_framework/{MindExecution.Plugins.Admin.0zkmk8wahq.dll → MindExecution.Plugins.Admin.dxyuwmxv1s.dll} +0 -0
  35. package/wwwroot/_framework/{MindExecution.Plugins.Business.vyw3769hrw.dll → MindExecution.Plugins.Business.7uj5erqhhn.dll} +0 -0
  36. package/wwwroot/_framework/{MindExecution.Plugins.Concept.cvmglrxsjb.dll → MindExecution.Plugins.Concept.108rmsxc96.dll} +0 -0
  37. package/wwwroot/_framework/{MindExecution.Plugins.Directory.jtw9q1dm9n.dll → MindExecution.Plugins.Directory.ccsy3g0fe5.dll} +0 -0
  38. package/wwwroot/_framework/{MindExecution.Plugins.PlanMaster.8hmc6ps1ux.dll → MindExecution.Plugins.PlanMaster.1vjpuoe9ff.dll} +0 -0
  39. package/wwwroot/_framework/{MindExecution.Plugins.YouTube.xb9sou9ox0.dll → MindExecution.Plugins.YouTube.q8ml98phj9.dll} +0 -0
  40. package/wwwroot/_framework/{MindExecution.Shared.pqab76cjb6.dll → MindExecution.Shared.2pywq19zjy.dll} +0 -0
  41. package/wwwroot/_framework/{MindExecution.Web.mc24u4bzol.dll → MindExecution.Web.qucbls1wfr.dll} +0 -0
  42. package/wwwroot/_framework/blazor.boot.json +21 -21
  43. package/wwwroot/index.html +2 -1
  44. package/wwwroot/service-worker-assets.js +28 -24
  45. package/wwwroot/service-worker.js +1 -1
package/server.js CHANGED
@@ -2454,7 +2454,7 @@ const remoteInputWsDiagnostics = {
2454
2454
  lastError: ''
2455
2455
  };
2456
2456
  const REMOTE_FRAME_WS_AUTO_START_LIMIT = 120;
2457
- const REMOTE_FRAME_WS_DEFAULT_FPS = 12;
2457
+ const REMOTE_FRAME_WS_DEFAULT_FPS = 20;
2458
2458
  const REMOTE_FRAME_WS_DEFAULT_MAX_WIDTH = 960;
2459
2459
  const REMOTE_FRAME_WS_DEFAULT_MAX_HEIGHT = 540;
2460
2460
  const REMOTE_FRAME_WS_DEFAULT_QUALITY = 60;
@@ -2563,7 +2563,10 @@ function updateRemoteFrameClientSubscription(ws, payload = {}) {
2563
2563
  timestamp: ws.remoteFrameSubscriptionUpdatedAt,
2564
2564
  deviceIds,
2565
2565
  mode: deviceIds.length > 0 ? 'selected-devices' : 'all-devices',
2566
- autoStartLive: ws.remoteFrameAutoStartLive === true
2566
+ autoStartLive: ws.remoteFrameAutoStartLive === true,
2567
+ streamPurpose: ws.remoteFrameAutoStartOptions.streamPurpose,
2568
+ fps: ws.remoteFrameAutoStartOptions.fps,
2569
+ frameMode: ws.remoteFrameAutoStartOptions.frameMode
2567
2570
  });
2568
2571
  maybeAutoStartRemoteFrameLiveStreams(ws, deviceIds);
2569
2572
  }
@@ -2578,14 +2581,18 @@ function clampRemoteFrameWsNumber(value, min, max, fallback) {
2578
2581
  }
2579
2582
 
2580
2583
  function normalizeRemoteFrameWsLiveOptions(payload = {}) {
2581
- const mode = String(payload.frameMode || payload.mode || 'remote-fast').trim() || 'remote-fast';
2584
+ const streamPurpose = String(payload.streamPurpose || '').trim().toLowerCase();
2585
+ const defaultMode = streamPurpose === 'control' ? 'mode3-h264-hw' : 'mode2-lzo';
2586
+ const mode = String(payload.frameMode || payload.mode || defaultMode).trim() || defaultMode;
2587
+ const defaultFps = streamPurpose === 'control' || mode === 'mode3-h264-hw' ? 30 : REMOTE_FRAME_WS_DEFAULT_FPS;
2582
2588
  return {
2583
- fps: clampRemoteFrameWsNumber(payload.fps, 1, 24, REMOTE_FRAME_WS_DEFAULT_FPS),
2589
+ fps: clampRemoteFrameWsNumber(payload.fps, 1, 30, defaultFps),
2584
2590
  maxWidth: clampRemoteFrameWsNumber(payload.maxWidth, 320, 2560, REMOTE_FRAME_WS_DEFAULT_MAX_WIDTH),
2585
2591
  maxHeight: clampRemoteFrameWsNumber(payload.maxHeight, 180, 1440, REMOTE_FRAME_WS_DEFAULT_MAX_HEIGHT),
2586
2592
  quality: clampRemoteFrameWsNumber(payload.quality, 20, 95, REMOTE_FRAME_WS_DEFAULT_QUALITY),
2587
2593
  mode,
2588
- frameMode: mode
2594
+ frameMode: mode,
2595
+ streamPurpose: streamPurpose || (mode === 'mode3-h264-hw' ? 'control' : 'wall')
2589
2596
  };
2590
2597
  }
2591
2598
 
@@ -2716,7 +2723,23 @@ function buildRemoteFrameBinaryPacket(frameEvent) {
2716
2723
  transport: frame.transport || '',
2717
2724
  contentHash: frame.contentHash || '',
2718
2725
  captureMs: Number(frame.captureMs || 0) || 0,
2719
- sameContentStreak: Number(frame.sameContentStreak || 0) || 0
2726
+ sameContentStreak: Number(frame.sameContentStreak || 0) || 0,
2727
+ streamPurpose: frame.streamPurpose || '',
2728
+ monitorIndex: Number.isFinite(Number(frame.monitorIndex)) ? Number(frame.monitorIndex) : 0,
2729
+ monitorCount: Number.isFinite(Number(frame.monitorCount)) ? Number(frame.monitorCount) : 0,
2730
+ pixelFormat: frame.pixelFormat || '',
2731
+ bytesPerPixel: Number.isFinite(Number(frame.bytesPerPixel)) ? Number(frame.bytesPerPixel) : 0,
2732
+ uncompressedByteLength: Number.isFinite(Number(frame.uncompressedByteLength)) ? Number(frame.uncompressedByteLength) : 0,
2733
+ sourceWidth: Number.isFinite(Number(frame.sourceWidth)) ? Number(frame.sourceWidth) : 0,
2734
+ sourceHeight: Number.isFinite(Number(frame.sourceHeight)) ? Number(frame.sourceHeight) : 0,
2735
+ codec: frame.codec || '',
2736
+ h264Format: frame.h264Format || '',
2737
+ isKeyFrame: frame.isKeyFrame === true,
2738
+ chunkType: frame.chunkType || '',
2739
+ timestampUs: Number.isFinite(Number(frame.timestampUs)) ? Number(frame.timestampUs) : 0,
2740
+ durationUs: Number.isFinite(Number(frame.durationUs)) ? Number(frame.durationUs) : 0,
2741
+ streamFrameSeq: Number.isFinite(Number(frame.streamFrameSeq)) ? Number(frame.streamFrameSeq) : 0,
2742
+ commandId: frame.commandId || ''
2720
2743
  };
2721
2744
  const metaBuffer = Buffer.from(JSON.stringify(metadata), 'utf8');
2722
2745
  const header = Buffer.allocUnsafe(4);
@@ -12803,9 +12826,11 @@ app.get('/api/remote/devices/:deviceId/live/frame', (req, res) => {
12803
12826
  });
12804
12827
 
12805
12828
  app.post('/api/remote/devices/:deviceId/live/start', (req, res) => {
12829
+ const streamPurpose = String(req.body?.streamPurpose || '').trim().toLowerCase();
12806
12830
  res.json(remoteHub.startLiveStream(req.params.deviceId, {
12807
12831
  streamId: req.body?.streamId,
12808
- mode: req.body?.mode,
12832
+ mode: req.body?.frameMode || req.body?.mode || (streamPurpose === 'control' ? 'mode3-h264-hw' : 'mode2-lzo'),
12833
+ streamPurpose,
12809
12834
  fps: req.body?.fps,
12810
12835
  maxWidth: req.body?.maxWidth,
12811
12836
  maxHeight: req.body?.maxHeight,
@@ -14891,9 +14891,9 @@
14891
14891
  const REMOTE_FLEET_MONITOR_REFRESH_MS = 10000;
14892
14892
  const REMOTE_FLEET_EMPTY_MONITOR_REFRESH_MS = 2500;
14893
14893
  const REMOTE_FLEET_LIVE_REFRESH_MS = 30000;
14894
- const REMOTE_FLEET_MONITOR_LIVE_FPS = 12;
14894
+ const REMOTE_FLEET_MONITOR_LIVE_FPS = 20;
14895
14895
  const REMOTE_FLEET_LIVE_FRAME_REFRESH_MS = Math.round(1000 / REMOTE_FLEET_MONITOR_LIVE_FPS);
14896
- const REMOTE_FLEET_CONTROL_LIVE_FPS = 20;
14896
+ const REMOTE_FLEET_CONTROL_LIVE_FPS = 30;
14897
14897
  const REMOTE_FLEET_CONTROL_FRAME_REFRESH_MS = Math.round(1000 / REMOTE_FLEET_CONTROL_LIVE_FPS);
14898
14898
  const REMOTE_FLEET_CONTROL_INPUT_MOVE_MS = 16;
14899
14899
  const REMOTE_FLEET_CONTROL_INPUT_QUEUE_LIMIT = 64;
@@ -15667,7 +15667,8 @@
15667
15667
  Number(liveOptions.maxWidth || 0) || 0,
15668
15668
  Number(liveOptions.maxHeight || 0) || 0,
15669
15669
  Number(liveOptions.quality || 0) || 0,
15670
- String(liveOptions.mode || '')
15670
+ String(liveOptions.mode || ''),
15671
+ String(liveOptions.streamPurpose || 'wall')
15671
15672
  ].join('|');
15672
15673
  const key = `${deviceIds.join('\n')}::${optionKey}`;
15673
15674
  const now = getRemoteFleetFrameNow();
@@ -15692,7 +15693,9 @@
15692
15693
  maxWidth: liveOptions.maxWidth,
15693
15694
  maxHeight: liveOptions.maxHeight,
15694
15695
  quality: liveOptions.quality,
15695
- mode: liveOptions.mode
15696
+ mode: liveOptions.mode,
15697
+ frameMode: liveOptions.mode,
15698
+ streamPurpose: liveOptions.streamPurpose || 'wall'
15696
15699
  }));
15697
15700
  return true;
15698
15701
  }
@@ -15952,7 +15955,8 @@
15952
15955
  maxWidth: Number(options.maxWidth || 960) || 960,
15953
15956
  maxHeight: Number(options.maxHeight || 540) || 540,
15954
15957
  quality: Number(options.quality || 60) || 60,
15955
- mode: String(options.mode || 'remote-fast')
15958
+ mode: String(options.mode || 'mode2-lzo'),
15959
+ streamPurpose: String(options.streamPurpose || 'wall')
15956
15960
  };
15957
15961
  bodyView._remoteFleetBinaryFrameSession = session;
15958
15962
  primeRemoteFleetRenderedFrameSurfaces(bodyView, 'ws-start');
@@ -17186,6 +17190,22 @@
17186
17190
  }
17187
17191
 
17188
17192
  function applyRemoteFleetFramePatchToPreview(preview, frame) {
17193
+ if (frame?._remoteFleetBinaryFrame === true
17194
+ && frame?._remoteFleetPayloadBlob
17195
+ && (String(frame.codec || '').toLowerCase().includes('h264')
17196
+ || (String(frame.frameMode || frame.mode || '').toLowerCase() === 'mode2-lzo'
17197
+ && String(frame.compression || '').toLowerCase() === 'lzo1x'))
17198
+ && window.MindExecRemoteCodecs?.decodeFrame) {
17199
+ const canvas = ensureRemoteFleetFrameCanvas(preview);
17200
+ if (canvas) {
17201
+ canvas.style.display = 'block';
17202
+ preview.querySelector?.('img[data-remote-fleet-frame-image="true"]')?.style.setProperty('display', 'none');
17203
+ window.MindExecRemoteCodecs.decodeFrame(canvas, frame).catch?.(() => undefined);
17204
+ preview.dataset.remoteFleetFrameKind = String(frame.kind || 'live').toLowerCase();
17205
+ preview.dataset.remoteFleetFrameSeq = String(frame.frameSeq || 0);
17206
+ return true;
17207
+ }
17208
+ }
17189
17209
  if (frame?._remoteFleetBinaryFrame === true && frame?._remoteFleetPayloadBlob) {
17190
17210
  preview._remoteFleetPendingImageFrame = null;
17191
17211
  delete preview.dataset.remoteFleetPendingImageKind;
@@ -17415,7 +17435,8 @@
17415
17435
  maxWidth: 1280,
17416
17436
  maxHeight: 720,
17417
17437
  quality: 65,
17418
- mode: 'remote-fast-control'
17438
+ mode: 'mode3-h264-hw',
17439
+ streamPurpose: 'control'
17419
17440
  })) {
17420
17441
  return false;
17421
17442
  }
@@ -17438,7 +17459,8 @@
17438
17459
  maxWidth: 1280,
17439
17460
  maxHeight: 720,
17440
17461
  quality: 65,
17441
- mode: 'remote-fast-control'
17462
+ mode: 'mode3-h264-hw',
17463
+ streamPurpose: 'control'
17442
17464
  };
17443
17465
  controlSession.binaryFrameSession = binarySession;
17444
17466
  controlSession.binaryFramePreferred = true;
@@ -17514,6 +17536,24 @@
17514
17536
  session.lastControlFrameSeq = frameSeq;
17515
17537
  }
17516
17538
 
17539
+ if (frame._remoteFleetPayloadBlob
17540
+ && (String(frame.codec || '').toLowerCase().includes('h264')
17541
+ || (String(frame.frameMode || frame.mode || '').toLowerCase() === 'mode2-lzo'
17542
+ && String(frame.compression || '').toLowerCase() === 'lzo1x'))
17543
+ && window.MindExecRemoteCodecs?.decodeFrame) {
17544
+ const painted = await window.MindExecRemoteCodecs.decodeFrame(session.canvas, frame);
17545
+ if (painted && session.active) {
17546
+ session.canvas.dataset.remoteFleetFrameKind = 'live';
17547
+ session.canvas.dataset.remoteFleetFrameSeq = String(frameSeq || 0);
17548
+ session.canvas.style.display = 'block';
17549
+ session.lastControlFrameAt = Date.now();
17550
+ session.status.textContent = `Control ${REMOTE_FLEET_CONTROL_LIVE_FPS}fps`;
17551
+ session.placeholder?.remove?.();
17552
+ session.placeholder = null;
17553
+ }
17554
+ return painted;
17555
+ }
17556
+
17517
17557
  let bitmap = null;
17518
17558
  try {
17519
17559
  if (frame._remoteFleetPayloadBlob && typeof createImageBitmap === 'function') {
@@ -17784,11 +17824,16 @@
17784
17824
  }
17785
17825
 
17786
17826
  const input = createRemoteFleetControlInput(session, payload);
17827
+ const inputSeq = Number(session.inputSeq || 0) + 1;
17828
+ session.inputSeq = inputSeq;
17829
+ input.inputSeq = inputSeq;
17830
+ input.requestAck = String(input.type || '').toLowerCase() !== 'pointermove' || inputSeq % 6 === 0;
17787
17831
  const envelope = {
17788
17832
  type: 'input',
17789
17833
  nodeId: session.nodeId,
17790
17834
  deviceId: session.deviceId,
17791
17835
  requestId: `input-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`,
17836
+ fireAndForget: input.requestAck !== true,
17792
17837
  input
17793
17838
  };
17794
17839
 
@@ -18315,7 +18360,7 @@
18315
18360
  maxWidth: 1280,
18316
18361
  maxHeight: 720,
18317
18362
  quality: 65,
18318
- mode: 'remote-fast-control-node'
18363
+ mode: 'mode3-h264-hw'
18319
18364
  });
18320
18365
  attachRemoteFleetControlBinaryFrameSession(session, bodyView);
18321
18366
  stage.focus?.({ preventScroll: true });
@@ -20676,7 +20721,8 @@
20676
20721
  maxWidth: 960,
20677
20722
  maxHeight: 540,
20678
20723
  quality: 60,
20679
- mode: 'remote-fast'
20724
+ mode: 'mode2-lzo',
20725
+ streamPurpose: 'wall'
20680
20726
  });
20681
20727
  if (!binaryFrameSocketStarted) {
20682
20728
  window.RuntimeTrace?.emit?.('remote.frame.wsUnavailable', {
@@ -0,0 +1,199 @@
1
+ (function () {
2
+ 'use strict';
3
+
4
+ const decoderByCanvas = new WeakMap();
5
+ const MAX_DECODE_QUEUE = 3;
6
+ const rawFrameByCanvas = new WeakMap();
7
+
8
+ function emit(type, data) {
9
+ window.RuntimeTrace?.emit?.(type, data);
10
+ }
11
+
12
+ function getDecoderState(canvas) {
13
+ let state = decoderByCanvas.get(canvas);
14
+ if (state) return state;
15
+ state = {
16
+ decoder: null,
17
+ generation: 0,
18
+ width: 0,
19
+ height: 0,
20
+ pending: 0,
21
+ lastSeq: 0,
22
+ lastPaintAt: 0
23
+ };
24
+ decoderByCanvas.set(canvas, state);
25
+ return state;
26
+ }
27
+
28
+ function closeDecoder(state) {
29
+ try { state.decoder?.close?.(); } catch { /* stale decoder */ }
30
+ state.decoder = null;
31
+ state.pending = 0;
32
+ }
33
+
34
+ // LiveDesk Mode 2 payloads are LZO1X-compressed little-endian RGB565.
35
+ // Keep this decoder local to the wall path so H.264 control surfaces remain
36
+ // fully independent.
37
+ function decodeLzo1x(input, outputLength) {
38
+ if (!(input instanceof Uint8Array) || input.length < 3) throw new Error('Invalid LZO1X block');
39
+ const output = new Uint8Array(outputLength);
40
+ const s = { i: 0, o: 0 };
41
+ const need = (n) => { if (s.i + n > input.length) throw new Error('LZO input overrun'); };
42
+ const literals = (n) => {
43
+ need(n);
44
+ if (s.o + n > output.length) throw new Error('LZO output overrun');
45
+ output.set(input.subarray(s.i, s.i + n), s.o); s.i += n; s.o += n;
46
+ };
47
+ const ext = (basis) => { let zeros = 0; while (true) { need(1); if (input[s.i] !== 0) break; zeros++; s.i++; } return zeros * 255 + basis + input[s.i++]; };
48
+ const match = (at, length) => {
49
+ const distance = s.o - at;
50
+ if (distance <= 0 || s.o + length > output.length) throw new Error('LZO match overrun');
51
+ for (let n = 0; n < length; n++) output[s.o++] = output[at + (n % distance)];
52
+ };
53
+ let state = 0; let matchLength = 0;
54
+ if (input[0] >= 22) { s.i++; literals(input[0] - 17); state = 4; }
55
+ else if (input[0] >= 18) { s.i++; state = input[0] - 17; literals(state); }
56
+ while (true) {
57
+ need(1); const instruction = input[s.i++]; let nextState; let at;
58
+ if ((instruction & 0xc0) !== 0) {
59
+ need(1); at = s.o - ((input[s.i++] << 3) + ((instruction >> 2) & 7) + 1); matchLength = (instruction >> 5) + 1; nextState = instruction & 3;
60
+ } else if ((instruction & 0x20) !== 0) {
61
+ matchLength = (instruction & 0x1f) + 2; if (matchLength === 2) matchLength += ext(31); need(2); const encoded = input[s.i++] | (input[s.i++] << 8); at = s.o - ((encoded >> 2) + 1); nextState = encoded & 3;
62
+ } else if ((instruction & 0x10) !== 0) {
63
+ matchLength = (instruction & 7) + 2; if (matchLength === 2) matchLength += ext(7); need(2); const encoded = input[s.i++] | (input[s.i++] << 8); at = s.o - (((instruction & 8) << 11) + (encoded >> 2)); nextState = encoded & 3; if (at === s.o) break; at -= 0x4000;
64
+ } else if (state === 0) {
65
+ let length = instruction + 3; if (length === 3) length += ext(15); literals(length); state = 4; continue;
66
+ } else {
67
+ need(1); nextState = instruction & 3; at = s.o - ((instruction >> 2) + (input[s.i++] << 2) + (state === 4 ? 2049 : 1)); matchLength = state === 4 ? 3 : 2;
68
+ }
69
+ if (at < 0 || s.o + matchLength + nextState > output.length) throw new Error('LZO lookbehind overrun');
70
+ match(at, matchLength); state = nextState; literals(nextState);
71
+ }
72
+ if (matchLength !== 3 || s.i !== input.length || s.o !== output.length) throw new Error('Incomplete LZO block');
73
+ return output;
74
+ }
75
+
76
+ async function decodeMode2Frame(canvas, frame) {
77
+ const payload = frame?._remoteFleetPayloadBlob;
78
+ if (!canvas || !payload) return false;
79
+ const width = Math.max(1, Number(frame.width || 0) | 0);
80
+ const height = Math.max(1, Number(frame.height || 0) | 0);
81
+ const expected = width * height * 2;
82
+ if (Number(frame.bytesPerPixel || 2) !== 2 || (Number(frame.uncompressedByteLength || expected) !== expected)) return false;
83
+ const state = rawFrameByCanvas.get(canvas) || { lastSeq: 0 };
84
+ const seq = Number(frame.streamFrameSeq || frame.frameSeq || 0) || 0;
85
+ if (seq > 0 && seq <= state.lastSeq) return true;
86
+ const compressed = new Uint8Array(await payload.arrayBuffer());
87
+ const rgb565 = decodeLzo1x(compressed, expected);
88
+ const rgba = new Uint8ClampedArray(width * height * 4);
89
+ for (let source = 0, target = 0; source < rgb565.length; source += 2, target += 4) {
90
+ const pixel = rgb565[source] | (rgb565[source + 1] << 8);
91
+ const r = (pixel >> 11) & 31; const g = (pixel >> 5) & 63; const b = pixel & 31;
92
+ rgba[target] = (r << 3) | (r >> 2); rgba[target + 1] = (g << 2) | (g >> 4); rgba[target + 2] = (b << 3) | (b >> 2); rgba[target + 3] = 255;
93
+ }
94
+ canvas.width = width; canvas.height = height;
95
+ canvas.getContext('2d', { alpha: false, desynchronized: true })?.putImageData(new ImageData(rgba, width, height), 0, 0);
96
+ state.lastSeq = seq; rawFrameByCanvas.set(canvas, state);
97
+ emit('remote.mode2.paint', { frameSeq: seq, width, height });
98
+ return true;
99
+ }
100
+
101
+ function ensureDecoder(canvas, frame, state) {
102
+ if (typeof VideoDecoder !== 'function' || typeof EncodedVideoChunk !== 'function') {
103
+ return null;
104
+ }
105
+
106
+ const width = Number(frame.width || 0) || canvas.width || 1920;
107
+ const height = Number(frame.height || 0) || canvas.height || 1080;
108
+ const key = `${width}x${height}`;
109
+ if (state.decoder && state.width === width && state.height === height) {
110
+ return state.decoder;
111
+ }
112
+
113
+ closeDecoder(state);
114
+ state.width = width;
115
+ state.height = height;
116
+ const generation = ++state.generation;
117
+ const decoder = new VideoDecoder({
118
+ output(videoFrame) {
119
+ if (generation !== state.generation) {
120
+ videoFrame.close?.();
121
+ return;
122
+ }
123
+ try {
124
+ canvas.width = videoFrame.displayWidth || width;
125
+ canvas.height = videoFrame.displayHeight || height;
126
+ const context = canvas.getContext('2d', { alpha: false, desynchronized: true });
127
+ context?.drawImage(videoFrame, 0, 0, canvas.width, canvas.height);
128
+ state.lastPaintAt = performance.now();
129
+ emit('remote.h264.paint', { frameSeq: state.lastSeq, width: canvas.width, height: canvas.height });
130
+ } finally {
131
+ videoFrame.close?.();
132
+ }
133
+ },
134
+ error(error) {
135
+ emit('remote.h264.decodeFailed', { error: error?.message || String(error || ''), frameSeq: state.lastSeq });
136
+ closeDecoder(state);
137
+ }
138
+ });
139
+ try {
140
+ decoder.configure({
141
+ codec: String(frame.codec || 'avc1.42E01E'),
142
+ codedWidth: width,
143
+ codedHeight: height,
144
+ hardwareAcceleration: 'prefer-software',
145
+ optimizeForLatency: true,
146
+ avc: { format: String(frame.h264Format || 'annexb').toLowerCase() === 'avc' ? 'avc' : 'annexb' }
147
+ });
148
+ } catch (error) {
149
+ emit('remote.h264.configureFailed', { key, error: error?.message || String(error || '') });
150
+ try { decoder.close(); } catch { /* ignore */ }
151
+ return null;
152
+ }
153
+ state.decoder = decoder;
154
+ return decoder;
155
+ }
156
+
157
+ async function decode(canvas, frame) {
158
+ const payload = frame?._remoteFleetPayloadBlob;
159
+ if (!canvas || !payload) {
160
+ return false;
161
+ }
162
+ const mode = String(frame?.frameMode || frame?.mode || '').toLowerCase();
163
+ if (mode === 'mode2-lzo' || String(frame?.compression || '').toLowerCase() === 'lzo1x' || String(frame?.mimeType || '').toLowerCase() === 'application/vnd.livedesk.lzo-rgb565') {
164
+ try { return await decodeMode2Frame(canvas, frame); } catch (error) { emit('remote.mode2.decodeFailed', { error: error?.message || String(error || '') }); return false; }
165
+ }
166
+ if (!String(frame?.codec || '').toLowerCase().includes('h264')) return false;
167
+ const state = getDecoderState(canvas);
168
+ const seq = Number(frame.streamFrameSeq || frame.frameSeq || 0) || 0;
169
+ if (seq > 0 && seq <= state.lastSeq) return true;
170
+ state.lastSeq = seq;
171
+ const decoder = ensureDecoder(canvas, frame, state);
172
+ if (!decoder || decoder.state === 'closed') return false;
173
+ if (state.pending >= MAX_DECODE_QUEUE) {
174
+ emit('remote.h264.drop', { reason: 'decode-queue', frameSeq: seq });
175
+ return true;
176
+ }
177
+ state.pending += 1;
178
+ try {
179
+ const bytes = new Uint8Array(await payload.arrayBuffer());
180
+ if (!bytes.length) return false;
181
+ const timestamp = Number(frame.timestampUs || 0) || Math.round(performance.now() * 1000);
182
+ decoder.decode(new EncodedVideoChunk({
183
+ type: frame.isKeyFrame === true || String(frame.chunkType || '').toLowerCase() === 'key' ? 'key' : 'delta',
184
+ timestamp,
185
+ duration: Number(frame.durationUs || 0) || undefined,
186
+ data: bytes
187
+ }));
188
+ return true;
189
+ } catch (error) {
190
+ emit('remote.h264.decodeSubmitFailed', { error: error?.message || String(error || ''), frameSeq: seq });
191
+ closeDecoder(state);
192
+ return false;
193
+ } finally {
194
+ state.pending = Math.max(0, state.pending - 1);
195
+ }
196
+ }
197
+
198
+ window.MindExecRemoteCodecs = Object.freeze({ decodeH264Frame: decode, decodeFrame: decode });
199
+ })();
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "mainAssemblyName": "MindExecution.Web",
3
3
  "resources": {
4
- "hash": "sha256-cyYstxxu9/Yn3zgm26aHsm55DzzVHsZnB734jEONmCw=",
4
+ "hash": "sha256-vyIwPs5NXG0WvUn1crlwB/OCRyxH6tUNE8CXfOaHuOI=",
5
5
  "fingerprinting": {
6
6
  "Google.Protobuf.9h59ukbel7.dll": "Google.Protobuf.dll",
7
7
  "Markdig.d1j7v41cl1.dll": "Markdig.dll",
@@ -122,16 +122,16 @@
122
122
  "System.brmz7yk5qh.dll": "System.dll",
123
123
  "netstandard.b50t77veor.dll": "netstandard.dll",
124
124
  "System.Private.CoreLib.g6ztz7cmo2.dll": "System.Private.CoreLib.dll",
125
- "MindExecution.Core.808jj176e1.dll": "MindExecution.Core.dll",
126
- "MindExecution.Kernel.75hxk08tt0.dll": "MindExecution.Kernel.dll",
127
- "MindExecution.Plugins.Admin.0zkmk8wahq.dll": "MindExecution.Plugins.Admin.dll",
128
- "MindExecution.Plugins.Business.vyw3769hrw.dll": "MindExecution.Plugins.Business.dll",
129
- "MindExecution.Plugins.Concept.cvmglrxsjb.dll": "MindExecution.Plugins.Concept.dll",
130
- "MindExecution.Plugins.Directory.jtw9q1dm9n.dll": "MindExecution.Plugins.Directory.dll",
131
- "MindExecution.Plugins.PlanMaster.8hmc6ps1ux.dll": "MindExecution.Plugins.PlanMaster.dll",
132
- "MindExecution.Plugins.YouTube.xb9sou9ox0.dll": "MindExecution.Plugins.YouTube.dll",
133
- "MindExecution.Shared.pqab76cjb6.dll": "MindExecution.Shared.dll",
134
- "MindExecution.Web.mc24u4bzol.dll": "MindExecution.Web.dll",
125
+ "MindExecution.Core.4moacskf64.dll": "MindExecution.Core.dll",
126
+ "MindExecution.Kernel.pa251cfsz4.dll": "MindExecution.Kernel.dll",
127
+ "MindExecution.Plugins.Admin.dxyuwmxv1s.dll": "MindExecution.Plugins.Admin.dll",
128
+ "MindExecution.Plugins.Business.7uj5erqhhn.dll": "MindExecution.Plugins.Business.dll",
129
+ "MindExecution.Plugins.Concept.108rmsxc96.dll": "MindExecution.Plugins.Concept.dll",
130
+ "MindExecution.Plugins.Directory.ccsy3g0fe5.dll": "MindExecution.Plugins.Directory.dll",
131
+ "MindExecution.Plugins.PlanMaster.1vjpuoe9ff.dll": "MindExecution.Plugins.PlanMaster.dll",
132
+ "MindExecution.Plugins.YouTube.q8ml98phj9.dll": "MindExecution.Plugins.YouTube.dll",
133
+ "MindExecution.Shared.2pywq19zjy.dll": "MindExecution.Shared.dll",
134
+ "MindExecution.Web.qucbls1wfr.dll": "MindExecution.Web.dll",
135
135
  "dotnet.native.566r55w3xu.js": "dotnet.native.js",
136
136
  "dotnet.native.x6q5aixc38.wasm": "dotnet.native.wasm",
137
137
  "dotnet.js": "dotnet.js",
@@ -276,18 +276,18 @@
276
276
  "System.Xml.XDocument.sn51jas17n.dll": "sha256-GNI2kFgFmPTwzuzwUn8gxK+AzGLUWRJFdg9JzIbrybQ=",
277
277
  "System.brmz7yk5qh.dll": "sha256-CfM2miyj1KHApFmqMdLYWio3S/jrdON2pW9Xr2nTwlo=",
278
278
  "netstandard.b50t77veor.dll": "sha256-//jQGOXjb8ET8WtXgOJrAxLx6E7zDJ5RjRRutwkvmxo=",
279
- "MindExecution.Core.808jj176e1.dll": "sha256-uMmP6rEgsbuwnsZ6Cnxrpmzio4usBtoJERfkOvz25iY=",
280
- "MindExecution.Kernel.75hxk08tt0.dll": "sha256-9db04cSFp4z4iblswVb0UWgpjeluVqZUa7g27Oj3p40=",
281
- "MindExecution.Plugins.Business.vyw3769hrw.dll": "sha256-WSc1w7WNOhnmzD3DcIgg4PCYzHeeU5rc7KK7eLgsu+M=",
282
- "MindExecution.Plugins.Concept.cvmglrxsjb.dll": "sha256-yGhEvwMzCTsmRB6D80lOSfOUWCegs7b/GRvXEdIss5s=",
283
- "MindExecution.Plugins.PlanMaster.8hmc6ps1ux.dll": "sha256-NDlttv/8WOvjy9hud+07v5ul3ZJhf2n/cf2CgMfhBnA=",
284
- "MindExecution.Shared.pqab76cjb6.dll": "sha256-3zUucQiJHN3pl4KBqsG0D0j054ojYss5D69/xCNTngY=",
285
- "MindExecution.Web.mc24u4bzol.dll": "sha256-5sJydtlQZKVkPUzMIYPO5q2iWWpstxPNVn6Kyk3fBrk="
279
+ "MindExecution.Core.4moacskf64.dll": "sha256-5OiBWkHcOvL4NsaHtQ7O3z5N1Ba7nTRi3xkehUMMgkE=",
280
+ "MindExecution.Kernel.pa251cfsz4.dll": "sha256-4dswyE6zmKAS+CnExpbXK871UMxIp+a7SPMIMwmZ+2Q=",
281
+ "MindExecution.Plugins.Business.7uj5erqhhn.dll": "sha256-URKvk2etEOiEa/URXJpkYx7aJcPQd1Xs0Yxn3Uqg/ok=",
282
+ "MindExecution.Plugins.Concept.108rmsxc96.dll": "sha256-QTd+zvSVcfwz3gYaKZ3pP0wgxrj9R1aP6qQKsByDRR0=",
283
+ "MindExecution.Plugins.PlanMaster.1vjpuoe9ff.dll": "sha256-M3Fvm8WU5xbx24cTyACzH1IuZXuIY06dkeCfNCgeUT4=",
284
+ "MindExecution.Shared.2pywq19zjy.dll": "sha256-Wjp+pPwb4TDj0YtYTzvNQGIzQI7xAg9DeyO0g/jxyxU=",
285
+ "MindExecution.Web.qucbls1wfr.dll": "sha256-0kpuM4z2XvRReo2Eiy7cJ/SAfoF/dVnn6WChaz//lGc="
286
286
  },
287
287
  "lazyAssembly": {
288
- "MindExecution.Plugins.Admin.0zkmk8wahq.dll": "sha256-VLiwzLIr+tjKr6+yQfhMVQHq2Yx26QenAkC092+fEdw=",
289
- "MindExecution.Plugins.Directory.jtw9q1dm9n.dll": "sha256-Z1x+H7sTj3w9XjWxfqGsd3Jv+qlzwQxAur6pJIP4l20=",
290
- "MindExecution.Plugins.YouTube.xb9sou9ox0.dll": "sha256-Pf4IWNwd62loUPGvRnJ8ZgJ1X/h87tNDeBwS8ajlwyk="
288
+ "MindExecution.Plugins.Admin.dxyuwmxv1s.dll": "sha256-URTQOP1nUuBC2leUgGdGWb+rc/1blCxbpbhRGE1MW/I=",
289
+ "MindExecution.Plugins.Directory.ccsy3g0fe5.dll": "sha256-BFk4mut2rsioBC9unD8+BoxnoJqTJlS5uZV7uXr8i5E=",
290
+ "MindExecution.Plugins.YouTube.q8ml98phj9.dll": "sha256-2vzs6nizBsYO1JjXPxdSi6O7uyZLpqFblwE0q09mvfw="
291
291
  }
292
292
  },
293
293
  "cacheBootResources": true,
@@ -579,7 +579,7 @@
579
579
  }
580
580
 
581
581
  const base = '_content/MindExecution.Shared/js/';
582
- const scriptVersion = '20260713-selection-video-playback-v935';
582
+ const scriptVersion = '20260717-livedesk-wall-lzo-control-h264-v937';
583
583
  const scriptUrl = (script) => `${base}${script}?v=${scriptVersion}`;
584
584
  console.log(`[Script Loader] Shared JS version: ${scriptVersion}`);
585
585
  const criticalScripts = [
@@ -594,6 +594,7 @@
594
594
  'mind-map-texture-factory.js',
595
595
  'mind-map-glow-shader.js', // ??SDF Glow (no textures, GPU only)
596
596
  'mind-map-video-playback-controls.js',
597
+ 'mind-map-remote-codecs.js',
597
598
  'mind-map-css3d-manager.js',
598
599
  'mind-map-object-manager.js',
599
600
  'mind-map-pipeline.js',
@@ -1,5 +1,5 @@
1
1
  self.assetsManifest = {
2
- "version": "VUZJrplE",
2
+ "version": "rJ2/x4YC",
3
3
  "assets": [
4
4
  {
5
5
  "hash": "sha256-+CSYMcqLNTsq3VnH11jgYyOCCdxvHzL74CBmo4sCmMU=",
@@ -86,7 +86,7 @@
86
86
  "url": "_content/MindExecution.Shared/js/mind-map-core.js.backup"
87
87
  },
88
88
  {
89
- "hash": "sha256-V3om7yYRGnEVFwXSaNqT+tzvnLAFzHpQN5+M0RahIxU=",
89
+ "hash": "sha256-UG57W/xx2is6r0blcR4M4YYFG2zpW7oRyflGw5UE6yQ=",
90
90
  "url": "_content/MindExecution.Shared/js/mind-map-css3d-manager.js"
91
91
  },
92
92
  {
@@ -153,6 +153,10 @@
153
153
  "hash": "sha256-QvC3R24/3hjEyEkuxhKD2yA47gscsPoysFuaQJ6hhLQ=",
154
154
  "url": "_content/MindExecution.Shared/js/mind-map-pipeline.js"
155
155
  },
156
+ {
157
+ "hash": "sha256-sSOS0P5WQJR45J7JqcTrit9KCONG59fFYCgUfYgA/+c=",
158
+ "url": "_content/MindExecution.Shared/js/mind-map-remote-codecs.js"
159
+ },
156
160
  {
157
161
  "hash": "sha256-cLpfBu1xGaz6r3erSnxPGrqPlfldqcMbV/taYkFtnlE=",
158
162
  "url": "_content/MindExecution.Shared/js/mind-map-render-plan.js"
@@ -418,44 +422,44 @@
418
422
  "url": "_framework/MimeMapping.og9ys58ylm.dll"
419
423
  },
420
424
  {
421
- "hash": "sha256-uMmP6rEgsbuwnsZ6Cnxrpmzio4usBtoJERfkOvz25iY=",
422
- "url": "_framework/MindExecution.Core.808jj176e1.dll"
425
+ "hash": "sha256-5OiBWkHcOvL4NsaHtQ7O3z5N1Ba7nTRi3xkehUMMgkE=",
426
+ "url": "_framework/MindExecution.Core.4moacskf64.dll"
423
427
  },
424
428
  {
425
- "hash": "sha256-9db04cSFp4z4iblswVb0UWgpjeluVqZUa7g27Oj3p40=",
426
- "url": "_framework/MindExecution.Kernel.75hxk08tt0.dll"
429
+ "hash": "sha256-4dswyE6zmKAS+CnExpbXK871UMxIp+a7SPMIMwmZ+2Q=",
430
+ "url": "_framework/MindExecution.Kernel.pa251cfsz4.dll"
427
431
  },
428
432
  {
429
- "hash": "sha256-VLiwzLIr+tjKr6+yQfhMVQHq2Yx26QenAkC092+fEdw=",
430
- "url": "_framework/MindExecution.Plugins.Admin.0zkmk8wahq.dll"
433
+ "hash": "sha256-URTQOP1nUuBC2leUgGdGWb+rc/1blCxbpbhRGE1MW/I=",
434
+ "url": "_framework/MindExecution.Plugins.Admin.dxyuwmxv1s.dll"
431
435
  },
432
436
  {
433
- "hash": "sha256-WSc1w7WNOhnmzD3DcIgg4PCYzHeeU5rc7KK7eLgsu+M=",
434
- "url": "_framework/MindExecution.Plugins.Business.vyw3769hrw.dll"
437
+ "hash": "sha256-URKvk2etEOiEa/URXJpkYx7aJcPQd1Xs0Yxn3Uqg/ok=",
438
+ "url": "_framework/MindExecution.Plugins.Business.7uj5erqhhn.dll"
435
439
  },
436
440
  {
437
- "hash": "sha256-yGhEvwMzCTsmRB6D80lOSfOUWCegs7b/GRvXEdIss5s=",
438
- "url": "_framework/MindExecution.Plugins.Concept.cvmglrxsjb.dll"
441
+ "hash": "sha256-QTd+zvSVcfwz3gYaKZ3pP0wgxrj9R1aP6qQKsByDRR0=",
442
+ "url": "_framework/MindExecution.Plugins.Concept.108rmsxc96.dll"
439
443
  },
440
444
  {
441
- "hash": "sha256-Z1x+H7sTj3w9XjWxfqGsd3Jv+qlzwQxAur6pJIP4l20=",
442
- "url": "_framework/MindExecution.Plugins.Directory.jtw9q1dm9n.dll"
445
+ "hash": "sha256-BFk4mut2rsioBC9unD8+BoxnoJqTJlS5uZV7uXr8i5E=",
446
+ "url": "_framework/MindExecution.Plugins.Directory.ccsy3g0fe5.dll"
443
447
  },
444
448
  {
445
- "hash": "sha256-NDlttv/8WOvjy9hud+07v5ul3ZJhf2n/cf2CgMfhBnA=",
446
- "url": "_framework/MindExecution.Plugins.PlanMaster.8hmc6ps1ux.dll"
449
+ "hash": "sha256-M3Fvm8WU5xbx24cTyACzH1IuZXuIY06dkeCfNCgeUT4=",
450
+ "url": "_framework/MindExecution.Plugins.PlanMaster.1vjpuoe9ff.dll"
447
451
  },
448
452
  {
449
- "hash": "sha256-Pf4IWNwd62loUPGvRnJ8ZgJ1X/h87tNDeBwS8ajlwyk=",
450
- "url": "_framework/MindExecution.Plugins.YouTube.xb9sou9ox0.dll"
453
+ "hash": "sha256-2vzs6nizBsYO1JjXPxdSi6O7uyZLpqFblwE0q09mvfw=",
454
+ "url": "_framework/MindExecution.Plugins.YouTube.q8ml98phj9.dll"
451
455
  },
452
456
  {
453
- "hash": "sha256-3zUucQiJHN3pl4KBqsG0D0j054ojYss5D69/xCNTngY=",
454
- "url": "_framework/MindExecution.Shared.pqab76cjb6.dll"
457
+ "hash": "sha256-Wjp+pPwb4TDj0YtYTzvNQGIzQI7xAg9DeyO0g/jxyxU=",
458
+ "url": "_framework/MindExecution.Shared.2pywq19zjy.dll"
455
459
  },
456
460
  {
457
- "hash": "sha256-5sJydtlQZKVkPUzMIYPO5q2iWWpstxPNVn6Kyk3fBrk=",
458
- "url": "_framework/MindExecution.Web.mc24u4bzol.dll"
461
+ "hash": "sha256-0kpuM4z2XvRReo2Eiy7cJ/SAfoF/dVnn6WChaz//lGc=",
462
+ "url": "_framework/MindExecution.Web.qucbls1wfr.dll"
459
463
  },
460
464
  {
461
465
  "hash": "sha256-IsZJ91/OW+fHzNqIgEc7Y072ns8z9dGritiSyvR9Wgc=",
@@ -774,7 +778,7 @@
774
778
  "url": "_framework/Websocket.Client.vapounvmnl.dll"
775
779
  },
776
780
  {
777
- "hash": "sha256-BhRb0qMTAHsNxt77FQUjETyjbzdhjkbZN5P0GDBi7vU=",
781
+ "hash": "sha256-SodYBsgd8t15/lAV4kw0t8S8pVMaovSwrWPF2PO4ZeM=",
778
782
  "url": "_framework/blazor.boot.json"
779
783
  },
780
784
  {
@@ -834,7 +838,7 @@
834
838
  "url": "icon-512.png"
835
839
  },
836
840
  {
837
- "hash": "sha256-ofd66howCQblx2Uy6MHTwD8Hwb1zYJZ0E9NtIBUxi3o=",
841
+ "hash": "sha256-APqqcB+gM4o0ey/YKw0z/i3QKVnlJxEV9xJ4Uu+UF7I=",
838
842
  "url": "index.html"
839
843
  },
840
844
  {