@myerscarpenter/quest-dev 1.4.0 → 2.0.0

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 (151) hide show
  1. package/.claude/settings.local.json +7 -0
  2. package/.github/workflows/docs.yml +45 -0
  3. package/.github/workflows/publish.yml +11 -1
  4. package/README.md +27 -0
  5. package/build/cast/decoder.d.ts +48 -0
  6. package/build/cast/decoder.d.ts.map +1 -0
  7. package/build/cast/decoder.js +152 -0
  8. package/build/cast/decoder.js.map +1 -0
  9. package/build/cast/session.d.ts +87 -0
  10. package/build/cast/session.d.ts.map +1 -0
  11. package/build/cast/session.js +565 -0
  12. package/build/cast/session.js.map +1 -0
  13. package/build/commands/logcat.d.ts.map +1 -1
  14. package/build/commands/logcat.js +7 -6
  15. package/build/commands/logcat.js.map +1 -1
  16. package/build/commands/open.d.ts.map +1 -1
  17. package/build/commands/open.js +9 -4
  18. package/build/commands/open.js.map +1 -1
  19. package/build/commands/screenshot.d.ts.map +1 -1
  20. package/build/commands/screenshot.js +17 -20
  21. package/build/commands/screenshot.js.map +1 -1
  22. package/build/commands/stay-awake.d.ts +2 -15
  23. package/build/commands/stay-awake.d.ts.map +1 -1
  24. package/build/commands/stay-awake.js +14 -77
  25. package/build/commands/stay-awake.js.map +1 -1
  26. package/build/daemon/cast-manager.d.ts +42 -0
  27. package/build/daemon/cast-manager.d.ts.map +1 -0
  28. package/build/daemon/cast-manager.js +243 -0
  29. package/build/daemon/cast-manager.js.map +1 -0
  30. package/build/daemon/client.d.ts +40 -0
  31. package/build/daemon/client.d.ts.map +1 -0
  32. package/build/daemon/client.js +133 -0
  33. package/build/daemon/client.js.map +1 -0
  34. package/build/daemon/daemon.d.ts +20 -0
  35. package/build/daemon/daemon.d.ts.map +1 -0
  36. package/build/daemon/daemon.js +130 -0
  37. package/build/daemon/daemon.js.map +1 -0
  38. package/build/daemon/deploy.d.ts +44 -0
  39. package/build/daemon/deploy.d.ts.map +1 -0
  40. package/build/daemon/deploy.js +230 -0
  41. package/build/daemon/deploy.js.map +1 -0
  42. package/build/daemon/logcat-manager.d.ts +39 -0
  43. package/build/daemon/logcat-manager.d.ts.map +1 -0
  44. package/build/daemon/logcat-manager.js +194 -0
  45. package/build/daemon/logcat-manager.js.map +1 -0
  46. package/build/daemon/server.d.ts +19 -0
  47. package/build/daemon/server.d.ts.map +1 -0
  48. package/build/daemon/server.js +482 -0
  49. package/build/daemon/server.js.map +1 -0
  50. package/build/daemon/stay-awake-manager.d.ts +22 -0
  51. package/build/daemon/stay-awake-manager.d.ts.map +1 -0
  52. package/build/daemon/stay-awake-manager.js +74 -0
  53. package/build/daemon/stay-awake-manager.js.map +1 -0
  54. package/build/index.js +285 -45
  55. package/build/index.js.map +1 -1
  56. package/build/public/dashboard.js +749 -0
  57. package/build/public/index.html +12 -0
  58. package/build/public/style.css +106 -0
  59. package/build/utils/adb.d.ts +12 -0
  60. package/build/utils/adb.d.ts.map +1 -1
  61. package/build/utils/adb.js +116 -51
  62. package/build/utils/adb.js.map +1 -1
  63. package/build/utils/casting-apk.d.ts +40 -0
  64. package/build/utils/casting-apk.d.ts.map +1 -0
  65. package/build/utils/casting-apk.js +252 -0
  66. package/build/utils/casting-apk.js.map +1 -0
  67. package/build/utils/config.d.ts +5 -3
  68. package/build/utils/config.d.ts.map +1 -1
  69. package/build/utils/config.js +18 -38
  70. package/build/utils/config.js.map +1 -1
  71. package/build/utils/exec.d.ts +5 -0
  72. package/build/utils/exec.d.ts.map +1 -1
  73. package/build/utils/exec.js +17 -0
  74. package/build/utils/exec.js.map +1 -1
  75. package/build/utils/filename.d.ts +7 -1
  76. package/build/utils/filename.d.ts.map +1 -1
  77. package/build/utils/filename.js +17 -2
  78. package/build/utils/filename.js.map +1 -1
  79. package/build/utils/filename.test.js +33 -1
  80. package/build/utils/filename.test.js.map +1 -1
  81. package/build/utils/jpeg-comment.d.ts +14 -0
  82. package/build/utils/jpeg-comment.d.ts.map +1 -0
  83. package/build/utils/jpeg-comment.js +28 -0
  84. package/build/utils/jpeg-comment.js.map +1 -0
  85. package/build/utils/test-properties.d.ts +34 -0
  86. package/build/utils/test-properties.d.ts.map +1 -0
  87. package/build/utils/test-properties.js +73 -0
  88. package/build/utils/test-properties.js.map +1 -0
  89. package/build/utils/verbose.d.ts +3 -0
  90. package/build/utils/verbose.d.ts.map +1 -0
  91. package/build/utils/verbose.js +13 -0
  92. package/build/utils/verbose.js.map +1 -0
  93. package/package.json +11 -5
  94. package/packages/cast2-protocol/README.md +86 -0
  95. package/packages/cast2-protocol/docs/_config.yml +4 -0
  96. package/packages/cast2-protocol/docs/feature-flags.md +102 -0
  97. package/packages/cast2-protocol/docs/index.md +24 -0
  98. package/packages/cast2-protocol/docs/open-investigations.md +149 -0
  99. package/packages/cast2-protocol/docs/protocol.md +602 -0
  100. package/packages/cast2-protocol/package.json +46 -0
  101. package/packages/cast2-protocol/src/constants.ts +65 -0
  102. package/packages/cast2-protocol/src/index.ts +7 -0
  103. package/packages/cast2-protocol/src/mgik.ts +69 -0
  104. package/packages/cast2-protocol/src/mud.ts +294 -0
  105. package/packages/cast2-protocol/src/pose.ts +99 -0
  106. package/packages/cast2-protocol/src/resolutions.ts +34 -0
  107. package/packages/cast2-protocol/src/types.ts +64 -0
  108. package/packages/cast2-protocol/src/xrsp.ts +73 -0
  109. package/packages/cast2-protocol/tests/mgik.test.ts +80 -0
  110. package/packages/cast2-protocol/tests/mud.test.ts +295 -0
  111. package/packages/cast2-protocol/tests/pose.test.ts +173 -0
  112. package/packages/cast2-protocol/tests/xrsp.test.ts +90 -0
  113. package/packages/cast2-protocol/tsconfig.json +20 -0
  114. package/pnpm-workspace.yaml +2 -0
  115. package/src/cast/decoder.ts +178 -0
  116. package/src/cast/session.ts +708 -0
  117. package/src/commands/logcat.ts +6 -5
  118. package/src/commands/open.ts +10 -3
  119. package/src/commands/screenshot.ts +19 -13
  120. package/src/commands/stay-awake.ts +22 -91
  121. package/src/daemon/adbkit-apkreader.d.ts +14 -0
  122. package/src/daemon/cast-manager.ts +282 -0
  123. package/src/daemon/client.ts +166 -0
  124. package/src/daemon/daemon.ts +169 -0
  125. package/src/daemon/deploy.ts +307 -0
  126. package/src/daemon/logcat-manager.ts +229 -0
  127. package/src/daemon/server.ts +595 -0
  128. package/src/daemon/stay-awake-manager.ts +83 -0
  129. package/src/index.ts +340 -56
  130. package/src/public/dashboard.js +288 -0
  131. package/src/public/index.html +12 -0
  132. package/src/public/style.css +106 -0
  133. package/src/utils/adb.ts +129 -42
  134. package/src/utils/casting-apk.ts +276 -0
  135. package/src/utils/config.ts +18 -36
  136. package/src/utils/exec.ts +20 -0
  137. package/src/utils/filename.test.ts +41 -1
  138. package/src/utils/filename.ts +18 -2
  139. package/src/utils/jpeg-comment.ts +30 -0
  140. package/src/utils/test-properties.ts +94 -0
  141. package/src/utils/verbose.ts +14 -0
  142. package/tests/cast/auto-layer.test.ts +87 -0
  143. package/tests/cast/decoder.test.ts +82 -0
  144. package/tests/cast/session-restart.test.ts +107 -0
  145. package/tests/config.test.ts +17 -22
  146. package/tests/daemon/api-status.test.ts +82 -0
  147. package/tests/daemon/cast-manager.test.ts +69 -0
  148. package/tests/daemon/mjpeg-stream.test.ts +144 -0
  149. package/tests/daemon/pose-endpoint.test.ts +63 -0
  150. package/tests/daemon/start-guard.test.ts +77 -0
  151. package/vitest.config.ts +10 -0
@@ -0,0 +1,749 @@
1
+ "use strict";
2
+ (() => {
3
+ // node_modules/.pnpm/preact@10.29.0/node_modules/preact/dist/preact.module.js
4
+ var n;
5
+ var l;
6
+ var u;
7
+ var t;
8
+ var i;
9
+ var r;
10
+ var o;
11
+ var e;
12
+ var f;
13
+ var c;
14
+ var s;
15
+ var a;
16
+ var h;
17
+ var p = {};
18
+ var v = [];
19
+ var y = /acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;
20
+ var d = Array.isArray;
21
+ function w(n3, l3) {
22
+ for (var u3 in l3) n3[u3] = l3[u3];
23
+ return n3;
24
+ }
25
+ function g(n3) {
26
+ n3 && n3.parentNode && n3.parentNode.removeChild(n3);
27
+ }
28
+ function _(l3, u3, t4) {
29
+ var i3, r3, o3, e3 = {};
30
+ for (o3 in u3) "key" == o3 ? i3 = u3[o3] : "ref" == o3 ? r3 = u3[o3] : e3[o3] = u3[o3];
31
+ if (arguments.length > 2 && (e3.children = arguments.length > 3 ? n.call(arguments, 2) : t4), "function" == typeof l3 && null != l3.defaultProps) for (o3 in l3.defaultProps) void 0 === e3[o3] && (e3[o3] = l3.defaultProps[o3]);
32
+ return m(l3, e3, i3, r3, null);
33
+ }
34
+ function m(n3, t4, i3, r3, o3) {
35
+ var e3 = { type: n3, props: t4, key: i3, ref: r3, __k: null, __: null, __b: 0, __e: null, __c: null, constructor: void 0, __v: null == o3 ? ++u : o3, __i: -1, __u: 0 };
36
+ return null == o3 && null != l.vnode && l.vnode(e3), e3;
37
+ }
38
+ function k(n3) {
39
+ return n3.children;
40
+ }
41
+ function x(n3, l3) {
42
+ this.props = n3, this.context = l3;
43
+ }
44
+ function S(n3, l3) {
45
+ if (null == l3) return n3.__ ? S(n3.__, n3.__i + 1) : null;
46
+ for (var u3; l3 < n3.__k.length; l3++) if (null != (u3 = n3.__k[l3]) && null != u3.__e) return u3.__e;
47
+ return "function" == typeof n3.type ? S(n3) : null;
48
+ }
49
+ function C(n3) {
50
+ if (n3.__P && n3.__d) {
51
+ var u3 = n3.__v, t4 = u3.__e, i3 = [], r3 = [], o3 = w({}, u3);
52
+ o3.__v = u3.__v + 1, l.vnode && l.vnode(o3), z(n3.__P, o3, u3, n3.__n, n3.__P.namespaceURI, 32 & u3.__u ? [t4] : null, i3, null == t4 ? S(u3) : t4, !!(32 & u3.__u), r3), o3.__v = u3.__v, o3.__.__k[o3.__i] = o3, V(i3, o3, r3), u3.__e = u3.__ = null, o3.__e != t4 && M(o3);
53
+ }
54
+ }
55
+ function M(n3) {
56
+ if (null != (n3 = n3.__) && null != n3.__c) return n3.__e = n3.__c.base = null, n3.__k.some(function(l3) {
57
+ if (null != l3 && null != l3.__e) return n3.__e = n3.__c.base = l3.__e;
58
+ }), M(n3);
59
+ }
60
+ function $(n3) {
61
+ (!n3.__d && (n3.__d = true) && i.push(n3) && !I.__r++ || r != l.debounceRendering) && ((r = l.debounceRendering) || o)(I);
62
+ }
63
+ function I() {
64
+ try {
65
+ for (var n3, l3 = 1; i.length; ) i.length > l3 && i.sort(e), n3 = i.shift(), l3 = i.length, C(n3);
66
+ } finally {
67
+ i.length = I.__r = 0;
68
+ }
69
+ }
70
+ function P(n3, l3, u3, t4, i3, r3, o3, e3, f3, c3, s3) {
71
+ var a3, h3, y3, d3, w3, g2, _2, m3 = t4 && t4.__k || v, b = l3.length;
72
+ for (f3 = A(u3, l3, m3, f3, b), a3 = 0; a3 < b; a3++) null != (y3 = u3.__k[a3]) && (h3 = -1 != y3.__i && m3[y3.__i] || p, y3.__i = a3, g2 = z(n3, y3, h3, i3, r3, o3, e3, f3, c3, s3), d3 = y3.__e, y3.ref && h3.ref != y3.ref && (h3.ref && D(h3.ref, null, y3), s3.push(y3.ref, y3.__c || d3, y3)), null == w3 && null != d3 && (w3 = d3), (_2 = !!(4 & y3.__u)) || h3.__k === y3.__k ? f3 = H(y3, f3, n3, _2) : "function" == typeof y3.type && void 0 !== g2 ? f3 = g2 : d3 && (f3 = d3.nextSibling), y3.__u &= -7);
73
+ return u3.__e = w3, f3;
74
+ }
75
+ function A(n3, l3, u3, t4, i3) {
76
+ var r3, o3, e3, f3, c3, s3 = u3.length, a3 = s3, h3 = 0;
77
+ for (n3.__k = new Array(i3), r3 = 0; r3 < i3; r3++) null != (o3 = l3[r3]) && "boolean" != typeof o3 && "function" != typeof o3 ? ("string" == typeof o3 || "number" == typeof o3 || "bigint" == typeof o3 || o3.constructor == String ? o3 = n3.__k[r3] = m(null, o3, null, null, null) : d(o3) ? o3 = n3.__k[r3] = m(k, { children: o3 }, null, null, null) : void 0 === o3.constructor && o3.__b > 0 ? o3 = n3.__k[r3] = m(o3.type, o3.props, o3.key, o3.ref ? o3.ref : null, o3.__v) : n3.__k[r3] = o3, f3 = r3 + h3, o3.__ = n3, o3.__b = n3.__b + 1, e3 = null, -1 != (c3 = o3.__i = T(o3, u3, f3, a3)) && (a3--, (e3 = u3[c3]) && (e3.__u |= 2)), null == e3 || null == e3.__v ? (-1 == c3 && (i3 > s3 ? h3-- : i3 < s3 && h3++), "function" != typeof o3.type && (o3.__u |= 4)) : c3 != f3 && (c3 == f3 - 1 ? h3-- : c3 == f3 + 1 ? h3++ : (c3 > f3 ? h3-- : h3++, o3.__u |= 4))) : n3.__k[r3] = null;
78
+ if (a3) for (r3 = 0; r3 < s3; r3++) null != (e3 = u3[r3]) && 0 == (2 & e3.__u) && (e3.__e == t4 && (t4 = S(e3)), E(e3, e3));
79
+ return t4;
80
+ }
81
+ function H(n3, l3, u3, t4) {
82
+ var i3, r3;
83
+ if ("function" == typeof n3.type) {
84
+ for (i3 = n3.__k, r3 = 0; i3 && r3 < i3.length; r3++) i3[r3] && (i3[r3].__ = n3, l3 = H(i3[r3], l3, u3, t4));
85
+ return l3;
86
+ }
87
+ n3.__e != l3 && (t4 && (l3 && n3.type && !l3.parentNode && (l3 = S(n3)), u3.insertBefore(n3.__e, l3 || null)), l3 = n3.__e);
88
+ do {
89
+ l3 = l3 && l3.nextSibling;
90
+ } while (null != l3 && 8 == l3.nodeType);
91
+ return l3;
92
+ }
93
+ function T(n3, l3, u3, t4) {
94
+ var i3, r3, o3, e3 = n3.key, f3 = n3.type, c3 = l3[u3], s3 = null != c3 && 0 == (2 & c3.__u);
95
+ if (null === c3 && null == e3 || s3 && e3 == c3.key && f3 == c3.type) return u3;
96
+ if (t4 > (s3 ? 1 : 0)) {
97
+ for (i3 = u3 - 1, r3 = u3 + 1; i3 >= 0 || r3 < l3.length; ) if (null != (c3 = l3[o3 = i3 >= 0 ? i3-- : r3++]) && 0 == (2 & c3.__u) && e3 == c3.key && f3 == c3.type) return o3;
98
+ }
99
+ return -1;
100
+ }
101
+ function j(n3, l3, u3) {
102
+ "-" == l3[0] ? n3.setProperty(l3, null == u3 ? "" : u3) : n3[l3] = null == u3 ? "" : "number" != typeof u3 || y.test(l3) ? u3 : u3 + "px";
103
+ }
104
+ function F(n3, l3, u3, t4, i3) {
105
+ var r3, o3;
106
+ n: if ("style" == l3) if ("string" == typeof u3) n3.style.cssText = u3;
107
+ else {
108
+ if ("string" == typeof t4 && (n3.style.cssText = t4 = ""), t4) for (l3 in t4) u3 && l3 in u3 || j(n3.style, l3, "");
109
+ if (u3) for (l3 in u3) t4 && u3[l3] == t4[l3] || j(n3.style, l3, u3[l3]);
110
+ }
111
+ else if ("o" == l3[0] && "n" == l3[1]) r3 = l3 != (l3 = l3.replace(f, "$1")), o3 = l3.toLowerCase(), l3 = o3 in n3 || "onFocusOut" == l3 || "onFocusIn" == l3 ? o3.slice(2) : l3.slice(2), n3.l || (n3.l = {}), n3.l[l3 + r3] = u3, u3 ? t4 ? u3.u = t4.u : (u3.u = c, n3.addEventListener(l3, r3 ? a : s, r3)) : n3.removeEventListener(l3, r3 ? a : s, r3);
112
+ else {
113
+ if ("http://www.w3.org/2000/svg" == i3) l3 = l3.replace(/xlink(H|:h)/, "h").replace(/sName$/, "s");
114
+ else if ("width" != l3 && "height" != l3 && "href" != l3 && "list" != l3 && "form" != l3 && "tabIndex" != l3 && "download" != l3 && "rowSpan" != l3 && "colSpan" != l3 && "role" != l3 && "popover" != l3 && l3 in n3) try {
115
+ n3[l3] = null == u3 ? "" : u3;
116
+ break n;
117
+ } catch (n4) {
118
+ }
119
+ "function" == typeof u3 || (null == u3 || false === u3 && "-" != l3[4] ? n3.removeAttribute(l3) : n3.setAttribute(l3, "popover" == l3 && 1 == u3 ? "" : u3));
120
+ }
121
+ }
122
+ function O(n3) {
123
+ return function(u3) {
124
+ if (this.l) {
125
+ var t4 = this.l[u3.type + n3];
126
+ if (null == u3.t) u3.t = c++;
127
+ else if (u3.t < t4.u) return;
128
+ return t4(l.event ? l.event(u3) : u3);
129
+ }
130
+ };
131
+ }
132
+ function z(n3, u3, t4, i3, r3, o3, e3, f3, c3, s3) {
133
+ var a3, h3, p3, y3, _2, m3, b, S2, C3, M2, $2, I2, A3, H2, L, T3 = u3.type;
134
+ if (void 0 !== u3.constructor) return null;
135
+ 128 & t4.__u && (c3 = !!(32 & t4.__u), o3 = [f3 = u3.__e = t4.__e]), (a3 = l.__b) && a3(u3);
136
+ n: if ("function" == typeof T3) try {
137
+ if (S2 = u3.props, C3 = T3.prototype && T3.prototype.render, M2 = (a3 = T3.contextType) && i3[a3.__c], $2 = a3 ? M2 ? M2.props.value : a3.__ : i3, t4.__c ? b = (h3 = u3.__c = t4.__c).__ = h3.__E : (C3 ? u3.__c = h3 = new T3(S2, $2) : (u3.__c = h3 = new x(S2, $2), h3.constructor = T3, h3.render = G), M2 && M2.sub(h3), h3.state || (h3.state = {}), h3.__n = i3, p3 = h3.__d = true, h3.__h = [], h3._sb = []), C3 && null == h3.__s && (h3.__s = h3.state), C3 && null != T3.getDerivedStateFromProps && (h3.__s == h3.state && (h3.__s = w({}, h3.__s)), w(h3.__s, T3.getDerivedStateFromProps(S2, h3.__s))), y3 = h3.props, _2 = h3.state, h3.__v = u3, p3) C3 && null == T3.getDerivedStateFromProps && null != h3.componentWillMount && h3.componentWillMount(), C3 && null != h3.componentDidMount && h3.__h.push(h3.componentDidMount);
138
+ else {
139
+ if (C3 && null == T3.getDerivedStateFromProps && S2 !== y3 && null != h3.componentWillReceiveProps && h3.componentWillReceiveProps(S2, $2), u3.__v == t4.__v || !h3.__e && null != h3.shouldComponentUpdate && false === h3.shouldComponentUpdate(S2, h3.__s, $2)) {
140
+ u3.__v != t4.__v && (h3.props = S2, h3.state = h3.__s, h3.__d = false), u3.__e = t4.__e, u3.__k = t4.__k, u3.__k.some(function(n4) {
141
+ n4 && (n4.__ = u3);
142
+ }), v.push.apply(h3.__h, h3._sb), h3._sb = [], h3.__h.length && e3.push(h3);
143
+ break n;
144
+ }
145
+ null != h3.componentWillUpdate && h3.componentWillUpdate(S2, h3.__s, $2), C3 && null != h3.componentDidUpdate && h3.__h.push(function() {
146
+ h3.componentDidUpdate(y3, _2, m3);
147
+ });
148
+ }
149
+ if (h3.context = $2, h3.props = S2, h3.__P = n3, h3.__e = false, I2 = l.__r, A3 = 0, C3) h3.state = h3.__s, h3.__d = false, I2 && I2(u3), a3 = h3.render(h3.props, h3.state, h3.context), v.push.apply(h3.__h, h3._sb), h3._sb = [];
150
+ else do {
151
+ h3.__d = false, I2 && I2(u3), a3 = h3.render(h3.props, h3.state, h3.context), h3.state = h3.__s;
152
+ } while (h3.__d && ++A3 < 25);
153
+ h3.state = h3.__s, null != h3.getChildContext && (i3 = w(w({}, i3), h3.getChildContext())), C3 && !p3 && null != h3.getSnapshotBeforeUpdate && (m3 = h3.getSnapshotBeforeUpdate(y3, _2)), H2 = null != a3 && a3.type === k && null == a3.key ? q(a3.props.children) : a3, f3 = P(n3, d(H2) ? H2 : [H2], u3, t4, i3, r3, o3, e3, f3, c3, s3), h3.base = u3.__e, u3.__u &= -161, h3.__h.length && e3.push(h3), b && (h3.__E = h3.__ = null);
154
+ } catch (n4) {
155
+ if (u3.__v = null, c3 || null != o3) if (n4.then) {
156
+ for (u3.__u |= c3 ? 160 : 128; f3 && 8 == f3.nodeType && f3.nextSibling; ) f3 = f3.nextSibling;
157
+ o3[o3.indexOf(f3)] = null, u3.__e = f3;
158
+ } else {
159
+ for (L = o3.length; L--; ) g(o3[L]);
160
+ N(u3);
161
+ }
162
+ else u3.__e = t4.__e, u3.__k = t4.__k, n4.then || N(u3);
163
+ l.__e(n4, u3, t4);
164
+ }
165
+ else null == o3 && u3.__v == t4.__v ? (u3.__k = t4.__k, u3.__e = t4.__e) : f3 = u3.__e = B(t4.__e, u3, t4, i3, r3, o3, e3, c3, s3);
166
+ return (a3 = l.diffed) && a3(u3), 128 & u3.__u ? void 0 : f3;
167
+ }
168
+ function N(n3) {
169
+ n3 && (n3.__c && (n3.__c.__e = true), n3.__k && n3.__k.some(N));
170
+ }
171
+ function V(n3, u3, t4) {
172
+ for (var i3 = 0; i3 < t4.length; i3++) D(t4[i3], t4[++i3], t4[++i3]);
173
+ l.__c && l.__c(u3, n3), n3.some(function(u4) {
174
+ try {
175
+ n3 = u4.__h, u4.__h = [], n3.some(function(n4) {
176
+ n4.call(u4);
177
+ });
178
+ } catch (n4) {
179
+ l.__e(n4, u4.__v);
180
+ }
181
+ });
182
+ }
183
+ function q(n3) {
184
+ return "object" != typeof n3 || null == n3 || n3.__b > 0 ? n3 : d(n3) ? n3.map(q) : w({}, n3);
185
+ }
186
+ function B(u3, t4, i3, r3, o3, e3, f3, c3, s3) {
187
+ var a3, h3, v3, y3, w3, _2, m3, b = i3.props || p, k3 = t4.props, x2 = t4.type;
188
+ if ("svg" == x2 ? o3 = "http://www.w3.org/2000/svg" : "math" == x2 ? o3 = "http://www.w3.org/1998/Math/MathML" : o3 || (o3 = "http://www.w3.org/1999/xhtml"), null != e3) {
189
+ for (a3 = 0; a3 < e3.length; a3++) if ((w3 = e3[a3]) && "setAttribute" in w3 == !!x2 && (x2 ? w3.localName == x2 : 3 == w3.nodeType)) {
190
+ u3 = w3, e3[a3] = null;
191
+ break;
192
+ }
193
+ }
194
+ if (null == u3) {
195
+ if (null == x2) return document.createTextNode(k3);
196
+ u3 = document.createElementNS(o3, x2, k3.is && k3), c3 && (l.__m && l.__m(t4, e3), c3 = false), e3 = null;
197
+ }
198
+ if (null == x2) b === k3 || c3 && u3.data == k3 || (u3.data = k3);
199
+ else {
200
+ if (e3 = e3 && n.call(u3.childNodes), !c3 && null != e3) for (b = {}, a3 = 0; a3 < u3.attributes.length; a3++) b[(w3 = u3.attributes[a3]).name] = w3.value;
201
+ for (a3 in b) w3 = b[a3], "dangerouslySetInnerHTML" == a3 ? v3 = w3 : "children" == a3 || a3 in k3 || "value" == a3 && "defaultValue" in k3 || "checked" == a3 && "defaultChecked" in k3 || F(u3, a3, null, w3, o3);
202
+ for (a3 in k3) w3 = k3[a3], "children" == a3 ? y3 = w3 : "dangerouslySetInnerHTML" == a3 ? h3 = w3 : "value" == a3 ? _2 = w3 : "checked" == a3 ? m3 = w3 : c3 && "function" != typeof w3 || b[a3] === w3 || F(u3, a3, w3, b[a3], o3);
203
+ if (h3) c3 || v3 && (h3.__html == v3.__html || h3.__html == u3.innerHTML) || (u3.innerHTML = h3.__html), t4.__k = [];
204
+ else if (v3 && (u3.innerHTML = ""), P("template" == t4.type ? u3.content : u3, d(y3) ? y3 : [y3], t4, i3, r3, "foreignObject" == x2 ? "http://www.w3.org/1999/xhtml" : o3, e3, f3, e3 ? e3[0] : i3.__k && S(i3, 0), c3, s3), null != e3) for (a3 = e3.length; a3--; ) g(e3[a3]);
205
+ c3 || (a3 = "value", "progress" == x2 && null == _2 ? u3.removeAttribute("value") : null != _2 && (_2 !== u3[a3] || "progress" == x2 && !_2 || "option" == x2 && _2 != b[a3]) && F(u3, a3, _2, b[a3], o3), a3 = "checked", null != m3 && m3 != u3[a3] && F(u3, a3, m3, b[a3], o3));
206
+ }
207
+ return u3;
208
+ }
209
+ function D(n3, u3, t4) {
210
+ try {
211
+ if ("function" == typeof n3) {
212
+ var i3 = "function" == typeof n3.__u;
213
+ i3 && n3.__u(), i3 && null == u3 || (n3.__u = n3(u3));
214
+ } else n3.current = u3;
215
+ } catch (n4) {
216
+ l.__e(n4, t4);
217
+ }
218
+ }
219
+ function E(n3, u3, t4) {
220
+ var i3, r3;
221
+ if (l.unmount && l.unmount(n3), (i3 = n3.ref) && (i3.current && i3.current != n3.__e || D(i3, null, u3)), null != (i3 = n3.__c)) {
222
+ if (i3.componentWillUnmount) try {
223
+ i3.componentWillUnmount();
224
+ } catch (n4) {
225
+ l.__e(n4, u3);
226
+ }
227
+ i3.base = i3.__P = null;
228
+ }
229
+ if (i3 = n3.__k) for (r3 = 0; r3 < i3.length; r3++) i3[r3] && E(i3[r3], u3, t4 || "function" != typeof n3.type);
230
+ t4 || g(n3.__e), n3.__c = n3.__ = n3.__e = void 0;
231
+ }
232
+ function G(n3, l3, u3) {
233
+ return this.constructor(n3, u3);
234
+ }
235
+ function J(u3, t4, i3) {
236
+ var r3, o3, e3, f3;
237
+ t4 == document && (t4 = document.documentElement), l.__ && l.__(u3, t4), o3 = (r3 = "function" == typeof i3) ? null : i3 && i3.__k || t4.__k, e3 = [], f3 = [], z(t4, u3 = (!r3 && i3 || t4).__k = _(k, null, [u3]), o3 || p, p, t4.namespaceURI, !r3 && i3 ? [i3] : o3 ? null : t4.firstChild ? n.call(t4.childNodes) : null, e3, !r3 && i3 ? i3 : o3 ? o3.__e : t4.firstChild, r3, f3), V(e3, u3, f3);
238
+ }
239
+ n = v.slice, l = { __e: function(n3, l3, u3, t4) {
240
+ for (var i3, r3, o3; l3 = l3.__; ) if ((i3 = l3.__c) && !i3.__) try {
241
+ if ((r3 = i3.constructor) && null != r3.getDerivedStateFromError && (i3.setState(r3.getDerivedStateFromError(n3)), o3 = i3.__d), null != i3.componentDidCatch && (i3.componentDidCatch(n3, t4 || {}), o3 = i3.__d), o3) return i3.__E = i3;
242
+ } catch (l4) {
243
+ n3 = l4;
244
+ }
245
+ throw n3;
246
+ } }, u = 0, t = function(n3) {
247
+ return null != n3 && void 0 === n3.constructor;
248
+ }, x.prototype.setState = function(n3, l3) {
249
+ var u3;
250
+ u3 = null != this.__s && this.__s != this.state ? this.__s : this.__s = w({}, this.state), "function" == typeof n3 && (n3 = n3(w({}, u3), this.props)), n3 && w(u3, n3), null != n3 && this.__v && (l3 && this._sb.push(l3), $(this));
251
+ }, x.prototype.forceUpdate = function(n3) {
252
+ this.__v && (this.__e = true, n3 && this.__h.push(n3), $(this));
253
+ }, x.prototype.render = k, i = [], o = "function" == typeof Promise ? Promise.prototype.then.bind(Promise.resolve()) : setTimeout, e = function(n3, l3) {
254
+ return n3.__v.__b - l3.__v.__b;
255
+ }, I.__r = 0, f = /(PointerCapture)$|Capture$/i, c = 0, s = O(false), a = O(true), h = 0;
256
+
257
+ // node_modules/.pnpm/preact@10.29.0/node_modules/preact/hooks/dist/hooks.module.js
258
+ var t2;
259
+ var r2;
260
+ var u2;
261
+ var i2;
262
+ var o2 = 0;
263
+ var f2 = [];
264
+ var c2 = l;
265
+ var e2 = c2.__b;
266
+ var a2 = c2.__r;
267
+ var v2 = c2.diffed;
268
+ var l2 = c2.__c;
269
+ var m2 = c2.unmount;
270
+ var s2 = c2.__;
271
+ function p2(n3, t4) {
272
+ c2.__h && c2.__h(r2, n3, o2 || t4), o2 = 0;
273
+ var u3 = r2.__H || (r2.__H = { __: [], __h: [] });
274
+ return n3 >= u3.__.length && u3.__.push({}), u3.__[n3];
275
+ }
276
+ function d2(n3) {
277
+ return o2 = 1, h2(D2, n3);
278
+ }
279
+ function h2(n3, u3, i3) {
280
+ var o3 = p2(t2++, 2);
281
+ if (o3.t = n3, !o3.__c && (o3.__ = [i3 ? i3(u3) : D2(void 0, u3), function(n4) {
282
+ var t4 = o3.__N ? o3.__N[0] : o3.__[0], r3 = o3.t(t4, n4);
283
+ t4 !== r3 && (o3.__N = [r3, o3.__[1]], o3.__c.setState({}));
284
+ }], o3.__c = r2, !r2.__f)) {
285
+ var f3 = function(n4, t4, r3) {
286
+ if (!o3.__c.__H) return true;
287
+ var u4 = o3.__c.__H.__.filter(function(n5) {
288
+ return n5.__c;
289
+ });
290
+ if (u4.every(function(n5) {
291
+ return !n5.__N;
292
+ })) return !c3 || c3.call(this, n4, t4, r3);
293
+ var i4 = o3.__c.props !== n4;
294
+ return u4.some(function(n5) {
295
+ if (n5.__N) {
296
+ var t5 = n5.__[0];
297
+ n5.__ = n5.__N, n5.__N = void 0, t5 !== n5.__[0] && (i4 = true);
298
+ }
299
+ }), c3 && c3.call(this, n4, t4, r3) || i4;
300
+ };
301
+ r2.__f = true;
302
+ var c3 = r2.shouldComponentUpdate, e3 = r2.componentWillUpdate;
303
+ r2.componentWillUpdate = function(n4, t4, r3) {
304
+ if (this.__e) {
305
+ var u4 = c3;
306
+ c3 = void 0, f3(n4, t4, r3), c3 = u4;
307
+ }
308
+ e3 && e3.call(this, n4, t4, r3);
309
+ }, r2.shouldComponentUpdate = f3;
310
+ }
311
+ return o3.__N || o3.__;
312
+ }
313
+ function y2(n3, u3) {
314
+ var i3 = p2(t2++, 3);
315
+ !c2.__s && C2(i3.__H, u3) && (i3.__ = n3, i3.u = u3, r2.__H.__h.push(i3));
316
+ }
317
+ function A2(n3) {
318
+ return o2 = 5, T2(function() {
319
+ return { current: n3 };
320
+ }, []);
321
+ }
322
+ function T2(n3, r3) {
323
+ var u3 = p2(t2++, 7);
324
+ return C2(u3.__H, r3) && (u3.__ = n3(), u3.__H = r3, u3.__h = n3), u3.__;
325
+ }
326
+ function q2(n3, t4) {
327
+ return o2 = 8, T2(function() {
328
+ return n3;
329
+ }, t4);
330
+ }
331
+ function j2() {
332
+ for (var n3; n3 = f2.shift(); ) {
333
+ var t4 = n3.__H;
334
+ if (n3.__P && t4) try {
335
+ t4.__h.some(z2), t4.__h.some(B2), t4.__h = [];
336
+ } catch (r3) {
337
+ t4.__h = [], c2.__e(r3, n3.__v);
338
+ }
339
+ }
340
+ }
341
+ c2.__b = function(n3) {
342
+ r2 = null, e2 && e2(n3);
343
+ }, c2.__ = function(n3, t4) {
344
+ n3 && t4.__k && t4.__k.__m && (n3.__m = t4.__k.__m), s2 && s2(n3, t4);
345
+ }, c2.__r = function(n3) {
346
+ a2 && a2(n3), t2 = 0;
347
+ var i3 = (r2 = n3.__c).__H;
348
+ i3 && (u2 === r2 ? (i3.__h = [], r2.__h = [], i3.__.some(function(n4) {
349
+ n4.__N && (n4.__ = n4.__N), n4.u = n4.__N = void 0;
350
+ })) : (i3.__h.some(z2), i3.__h.some(B2), i3.__h = [], t2 = 0)), u2 = r2;
351
+ }, c2.diffed = function(n3) {
352
+ v2 && v2(n3);
353
+ var t4 = n3.__c;
354
+ t4 && t4.__H && (t4.__H.__h.length && (1 !== f2.push(t4) && i2 === c2.requestAnimationFrame || ((i2 = c2.requestAnimationFrame) || w2)(j2)), t4.__H.__.some(function(n4) {
355
+ n4.u && (n4.__H = n4.u), n4.u = void 0;
356
+ })), u2 = r2 = null;
357
+ }, c2.__c = function(n3, t4) {
358
+ t4.some(function(n4) {
359
+ try {
360
+ n4.__h.some(z2), n4.__h = n4.__h.filter(function(n5) {
361
+ return !n5.__ || B2(n5);
362
+ });
363
+ } catch (r3) {
364
+ t4.some(function(n5) {
365
+ n5.__h && (n5.__h = []);
366
+ }), t4 = [], c2.__e(r3, n4.__v);
367
+ }
368
+ }), l2 && l2(n3, t4);
369
+ }, c2.unmount = function(n3) {
370
+ m2 && m2(n3);
371
+ var t4, r3 = n3.__c;
372
+ r3 && r3.__H && (r3.__H.__.some(function(n4) {
373
+ try {
374
+ z2(n4);
375
+ } catch (n5) {
376
+ t4 = n5;
377
+ }
378
+ }), r3.__H = void 0, t4 && c2.__e(t4, r3.__v));
379
+ };
380
+ var k2 = "function" == typeof requestAnimationFrame;
381
+ function w2(n3) {
382
+ var t4, r3 = function() {
383
+ clearTimeout(u3), k2 && cancelAnimationFrame(t4), setTimeout(n3);
384
+ }, u3 = setTimeout(r3, 35);
385
+ k2 && (t4 = requestAnimationFrame(r3));
386
+ }
387
+ function z2(n3) {
388
+ var t4 = r2, u3 = n3.__c;
389
+ "function" == typeof u3 && (n3.__c = void 0, u3()), r2 = t4;
390
+ }
391
+ function B2(n3) {
392
+ var t4 = r2;
393
+ n3.__c = n3.__(), r2 = t4;
394
+ }
395
+ function C2(n3, t4) {
396
+ return !n3 || n3.length !== t4.length || t4.some(function(t5, r3) {
397
+ return t5 !== n3[r3];
398
+ });
399
+ }
400
+ function D2(n3, t4) {
401
+ return "function" == typeof t4 ? t4(n3) : t4;
402
+ }
403
+
404
+ // node_modules/.pnpm/htm@3.1.1/node_modules/htm/dist/htm.module.js
405
+ var n2 = function(t4, s3, r3, e3) {
406
+ var u3;
407
+ s3[0] = 0;
408
+ for (var h3 = 1; h3 < s3.length; h3++) {
409
+ var p3 = s3[h3++], a3 = s3[h3] ? (s3[0] |= p3 ? 1 : 2, r3[s3[h3++]]) : s3[++h3];
410
+ 3 === p3 ? e3[0] = a3 : 4 === p3 ? e3[1] = Object.assign(e3[1] || {}, a3) : 5 === p3 ? (e3[1] = e3[1] || {})[s3[++h3]] = a3 : 6 === p3 ? e3[1][s3[++h3]] += a3 + "" : p3 ? (u3 = t4.apply(a3, n2(t4, a3, r3, ["", null])), e3.push(u3), a3[0] ? s3[0] |= 2 : (s3[h3 - 2] = 0, s3[h3] = u3)) : e3.push(a3);
411
+ }
412
+ return e3;
413
+ };
414
+ var t3 = /* @__PURE__ */ new Map();
415
+ function htm_module_default(s3) {
416
+ var r3 = t3.get(this);
417
+ return r3 || (r3 = /* @__PURE__ */ new Map(), t3.set(this, r3)), (r3 = n2(this, r3.get(s3) || (r3.set(s3, r3 = (function(n3) {
418
+ for (var t4, s4, r4 = 1, e3 = "", u3 = "", h3 = [0], p3 = function(n4) {
419
+ 1 === r4 && (n4 || (e3 = e3.replace(/^\s*\n\s*|\s*\n\s*$/g, ""))) ? h3.push(0, n4, e3) : 3 === r4 && (n4 || e3) ? (h3.push(3, n4, e3), r4 = 2) : 2 === r4 && "..." === e3 && n4 ? h3.push(4, n4, 0) : 2 === r4 && e3 && !n4 ? h3.push(5, 0, true, e3) : r4 >= 5 && ((e3 || !n4 && 5 === r4) && (h3.push(r4, 0, e3, s4), r4 = 6), n4 && (h3.push(r4, n4, 0, s4), r4 = 6)), e3 = "";
420
+ }, a3 = 0; a3 < n3.length; a3++) {
421
+ a3 && (1 === r4 && p3(), p3(a3));
422
+ for (var l3 = 0; l3 < n3[a3].length; l3++) t4 = n3[a3][l3], 1 === r4 ? "<" === t4 ? (p3(), h3 = [h3], r4 = 3) : e3 += t4 : 4 === r4 ? "--" === e3 && ">" === t4 ? (r4 = 1, e3 = "") : e3 = t4 + e3[0] : u3 ? t4 === u3 ? u3 = "" : e3 += t4 : '"' === t4 || "'" === t4 ? u3 = t4 : ">" === t4 ? (p3(), r4 = 1) : r4 && ("=" === t4 ? (r4 = 5, s4 = e3, e3 = "") : "/" === t4 && (r4 < 5 || ">" === n3[a3][l3 + 1]) ? (p3(), 3 === r4 && (h3 = h3[0]), r4 = h3, (h3 = h3[0]).push(2, 0, r4), r4 = 0) : " " === t4 || " " === t4 || "\n" === t4 || "\r" === t4 ? (p3(), r4 = 2) : e3 += t4), 3 === r4 && "!--" === e3 && (r4 = 4, h3 = h3[0]);
423
+ }
424
+ return p3(), h3;
425
+ })(s3)), r3), arguments, [])).length > 1 ? r3 : r3[0];
426
+ }
427
+
428
+ // src/public/dashboard.js
429
+ var html = htm_module_default.bind(_);
430
+ async function api(method, path, body) {
431
+ const opts = { method };
432
+ if (body) {
433
+ opts.headers = { "Content-Type": "application/json" };
434
+ opts.body = JSON.stringify(body);
435
+ }
436
+ const r3 = await fetch(path, opts);
437
+ if (!r3.ok) {
438
+ let msg;
439
+ try {
440
+ const j3 = await r3.json();
441
+ msg = j3.error ?? r3.statusText;
442
+ } catch {
443
+ msg = r3.statusText;
444
+ }
445
+ throw new Error(`HTTP ${r3.status}: ${msg}`);
446
+ }
447
+ return r3.json();
448
+ }
449
+ function bc(active) {
450
+ return active ? "" : "secondary";
451
+ }
452
+ function App() {
453
+ const [s3, setS] = d2({ connected: false, running: false });
454
+ const [toast, setToast] = d2(null);
455
+ const toastTimer = A2(null);
456
+ const active = s3.connected && s3.running;
457
+ const pose = s3.pose || {};
458
+ const showToast = q2((msg) => {
459
+ setToast(msg);
460
+ clearTimeout(toastTimer.current);
461
+ toastTimer.current = setTimeout(() => setToast(null), 2e3);
462
+ }, []);
463
+ y2(() => {
464
+ let es;
465
+ function connect() {
466
+ es = new EventSource("/cast/events");
467
+ es.addEventListener("status", (e3) => {
468
+ setS(JSON.parse(e3.data));
469
+ });
470
+ es.addEventListener("toast", (e3) => {
471
+ showToast(JSON.parse(e3.data).message);
472
+ });
473
+ es.onerror = () => {
474
+ setS((prev) => ({ ...prev, connected: false, running: false }));
475
+ es.close();
476
+ setTimeout(connect, 2e3);
477
+ };
478
+ }
479
+ connect();
480
+ return () => es?.close();
481
+ }, [showToast]);
482
+ const imgRef = A2(null);
483
+ y2(() => {
484
+ if (!active) return;
485
+ let run = true;
486
+ const buf = [new Image(), new Image()];
487
+ let idx = 0;
488
+ function fetch_next() {
489
+ if (!run) return;
490
+ const img = buf[idx];
491
+ idx = 1 - idx;
492
+ img.onload = () => {
493
+ if (!run) return;
494
+ if (imgRef.current) imgRef.current.src = img.src;
495
+ requestAnimationFrame(fetch_next);
496
+ };
497
+ img.onerror = () => {
498
+ if (run) setTimeout(fetch_next, 500);
499
+ };
500
+ img.src = "/cast/screenshot?t=" + Date.now();
501
+ }
502
+ fetch_next();
503
+ return () => {
504
+ run = false;
505
+ };
506
+ }, [active]);
507
+ const overlayRef = A2(null);
508
+ const crosshairRef = A2(null);
509
+ y2(() => {
510
+ const keysDown = /* @__PURE__ */ new Set();
511
+ let keyLoop = false, dragging = false, dx0, dy0;
512
+ function spd() {
513
+ return parseFloat(document.getElementById("move-speed")?.value) || 0.3;
514
+ }
515
+ function look() {
516
+ return parseFloat(document.getElementById("look-speed")?.value) || 0.15;
517
+ }
518
+ function tick() {
519
+ if (keysDown.size === 0) {
520
+ keyLoop = false;
521
+ return;
522
+ }
523
+ const m3 = spd(), l3 = look();
524
+ let fwd = 0, str = 0, yaw = 0, pit = 0, up = 0;
525
+ if (keysDown.has("w") || keysDown.has("arrowup")) fwd += m3;
526
+ if (keysDown.has("s") || keysDown.has("arrowdown")) fwd -= m3;
527
+ if (keysDown.has("a") || keysDown.has("arrowleft")) str -= m3;
528
+ if (keysDown.has("d") || keysDown.has("arrowright")) str += m3;
529
+ if (keysDown.has("q")) up -= m3;
530
+ if (keysDown.has("e")) up += m3;
531
+ if (keysDown.has("j")) yaw -= l3;
532
+ if (keysDown.has("l")) yaw += l3;
533
+ if (keysDown.has("i")) pit += l3;
534
+ if (keysDown.has("k")) pit -= l3;
535
+ if (fwd || str || yaw || pit || up)
536
+ api("POST", "/cast/pose", { dz: fwd, dx: str, dy: up, d_yaw: yaw, d_pitch: pit }).catch((e3) => showToast(e3.message));
537
+ setTimeout(tick, 80);
538
+ }
539
+ const kd = (e3) => {
540
+ if (e3.target.tagName === "INPUT") return;
541
+ if (e3.repeat) return;
542
+ keysDown.add(e3.key.toLowerCase());
543
+ if (["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", " "].includes(e3.key)) e3.preventDefault();
544
+ if (e3.key === "p" || e3.key === "P") {
545
+ doScreenshot();
546
+ return;
547
+ }
548
+ if (e3.key === " " || e3.key === "Enter") {
549
+ doClick();
550
+ return;
551
+ }
552
+ if (e3.key === "Escape") {
553
+ doResetPose();
554
+ return;
555
+ }
556
+ if (!keyLoop) {
557
+ keyLoop = true;
558
+ tick();
559
+ }
560
+ };
561
+ const ku = (e3) => {
562
+ if (e3.target.tagName === "INPUT") return;
563
+ keysDown.delete(e3.key.toLowerCase());
564
+ };
565
+ const md = (e3) => {
566
+ if (e3.button !== 0) return;
567
+ dragging = true;
568
+ dx0 = e3.clientX;
569
+ dy0 = e3.clientY;
570
+ if (crosshairRef.current) crosshairRef.current.style.display = "block";
571
+ };
572
+ const mm = (e3) => {
573
+ if (!dragging) return;
574
+ const dx = e3.clientX - dx0, dy = e3.clientY - dy0;
575
+ dx0 = e3.clientX;
576
+ dy0 = e3.clientY;
577
+ const sn = look();
578
+ const yaw = dx * sn * 0.02, pitch = dy * sn * 0.02;
579
+ if (yaw || pitch) api("POST", "/cast/pose", { d_yaw: yaw, d_pitch: pitch }).catch((e4) => showToast(e4.message));
580
+ };
581
+ const mu = () => {
582
+ dragging = false;
583
+ if (crosshairRef.current) crosshairRef.current.style.display = "none";
584
+ };
585
+ const ctx = (e3) => {
586
+ e3.preventDefault();
587
+ doClick();
588
+ };
589
+ document.addEventListener("keydown", kd);
590
+ document.addEventListener("keyup", ku);
591
+ window.addEventListener("mousemove", mm);
592
+ window.addEventListener("mouseup", mu);
593
+ const ov = overlayRef.current;
594
+ if (ov) {
595
+ ov.addEventListener("mousedown", md);
596
+ ov.addEventListener("contextmenu", ctx);
597
+ }
598
+ return () => {
599
+ document.removeEventListener("keydown", kd);
600
+ document.removeEventListener("keyup", ku);
601
+ window.removeEventListener("mousemove", mm);
602
+ window.removeEventListener("mouseup", mu);
603
+ if (ov) {
604
+ ov.removeEventListener("mousedown", md);
605
+ ov.removeEventListener("contextmenu", ctx);
606
+ }
607
+ };
608
+ }, []);
609
+ const doClick = async () => {
610
+ try {
611
+ const r3 = await api("POST", "/cast/click");
612
+ if (r3?.ok) showToast("Click sent");
613
+ } catch (e3) {
614
+ showToast("Click failed: " + e3.message);
615
+ }
616
+ };
617
+ const doScreenshot = () => {
618
+ const a3 = document.createElement("a");
619
+ a3.href = "/cast/screenshot";
620
+ a3.download = "quest-" + (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-") + ".jpg";
621
+ a3.click();
622
+ showToast("Screenshot saved");
623
+ };
624
+ const doResetPose = async () => {
625
+ try {
626
+ await api("POST", "/cast/reset-view");
627
+ showToast("Back to HMD view");
628
+ } catch (e3) {
629
+ showToast("Reset failed: " + e3.message);
630
+ }
631
+ };
632
+ const curRes = s3.width && s3.height ? s3.width + "x" + s3.height : "";
633
+ const curEye = s3.eye || "left";
634
+ return html`
635
+ <header>
636
+ <div id="status-dot" class=${active ? "ok" : ""}></div>
637
+ <h1>Quest Cast</h1>
638
+ ${active ? html`
639
+ <div id="status-bar">
640
+ <span><span class="val">${s3.fps ?? "--"}</span> fps</span>
641
+ <span><span class="val">${s3.width ? s3.width + "\xD7" + s3.height : "--"}</span></span>
642
+ <span><span class="val">${s3.frame_count?.toLocaleString() ?? "--"}</span> frames</span>
643
+ <span><span class="val">${s3.bytes ? (s3.bytes / 1048576).toFixed(1) : "--"}</span> MB</span>
644
+ <button onclick=${() => {
645
+ if (confirm("Stop casting?")) api("POST", "/cast/stop");
646
+ }}>Stop</button>
647
+ </div>
648
+ ` : html`
649
+ <div id="header-cast-btn">
650
+ <button onclick=${() => api("POST", "/cast/start")}>Cast</button>
651
+ </div>
652
+ `}
653
+ </header>
654
+
655
+ <div class="main">
656
+ <div class="video-pane">
657
+ <${VideoPane} active=${active} imgRef=${imgRef} crosshairRef=${crosshairRef} overlayRef=${overlayRef} />
658
+ </div>
659
+
660
+ <div class="sidebar">
661
+ <${Panel} title="Movement">
662
+ <div class="btn-row" style="justify-content:center;">
663
+ <div style="display:grid; grid-template-columns: repeat(3,40px); grid-template-rows: repeat(2,34px); gap:4px;">
664
+ <div></div>
665
+ <button class="secondary" onclick=${() => api("POST", "/cast/pose", { dz: parseFloat(document.getElementById("move-speed")?.value) || 0.3 })}>\u25B2</button>
666
+ <div></div>
667
+ <button class="secondary" onclick=${() => api("POST", "/cast/pose", { dx: -(parseFloat(document.getElementById("move-speed")?.value) || 0.3) })}>\u25C0</button>
668
+ <button class="secondary" onclick=${() => api("POST", "/cast/pose", { dz: -(parseFloat(document.getElementById("move-speed")?.value) || 0.3) })}>\u25BC</button>
669
+ <button class="secondary" onclick=${() => api("POST", "/cast/pose", { dx: parseFloat(document.getElementById("move-speed")?.value) || 0.3 })}>\u25B6</button>
670
+ </div>
671
+ </div>
672
+ <div class="speed-row">
673
+ <label>Speed</label>
674
+ <input type="number" id="move-speed" value="0.3" min="0.01" max="2" step="0.05" />
675
+ <label>Look</label>
676
+ <input type="number" id="look-speed" value="0.15" min="0.01" max="1" step="0.01" />
677
+ </div>
678
+ <//>
679
+
680
+ <${Panel} title="Offset from HMD">
681
+ <div class="pose-readout">
682
+ <span>${pose.x?.toFixed(2) ?? "0"}, ${pose.y?.toFixed(2) ?? "0"}, ${pose.z?.toFixed(2) ?? "0"}</span>
683
+ <span>${pose.yaw_deg?.toFixed(1) ?? "0"}\u00b0 yaw, ${pose.pitch_deg?.toFixed(1) ?? "0"}\u00b0 pitch</span>
684
+ <span>loop: ${s3.pose_loop ? "~27 Hz" : "off"}</span>
685
+ </div>
686
+ <div class="btn-row">
687
+ <button class="secondary" style="flex:1;" onclick=${async () => {
688
+ const r3 = await api("POST", "/cast/pose", { x: 0, y: 0, z: 0, yaw: 0, pitch: 0 });
689
+ if (r3?.ok) showToast("Origin");
690
+ }}>Origin</button>
691
+ <button class=${s3.pose_loop ? "" : "secondary"} style="flex:1;" onclick=${doResetPose}>${s3.pose_loop ? "Back to HMD" : "Reset"}</button>
692
+ </div>
693
+ <//>
694
+
695
+ <${Panel} title="Display">
696
+ <div class="btn-row">
697
+ <button class=${bc(curRes === "2064x1162")} onclick=${() => api("POST", "/cast/config", { resolution: "native" })}>Native</button>
698
+ <button class=${bc(curRes === "1920x1080")} onclick=${() => api("POST", "/cast/config", { resolution: "1080p" })}>1080p</button>
699
+ <button class=${bc(curRes === "1280x720")} onclick=${() => api("POST", "/cast/config", { resolution: "720p" })}>720p</button>
700
+ </div>
701
+ <div class="btn-row" style="margin-top:6px;">
702
+ <button class=${bc(curEye === "left")} onclick=${() => api("POST", "/cast/eye", { mode: "left" })}>L Eye</button>
703
+ <button class=${bc(curEye === "right")} onclick=${() => api("POST", "/cast/eye", { mode: "right" })}>R Eye</button>
704
+ <button class=${bc(curEye === "stereo")} onclick=${() => api("POST", "/cast/eye", { mode: "stereo" })}>Stereo</button>
705
+ </div>
706
+ <//>
707
+
708
+ <${Panel} title="Actions">
709
+ <div class="btn-row">
710
+ <button style="flex:1;" onclick=${doClick}>Click</button>
711
+ <button class="secondary" style="flex:1;" onclick=${() => api("POST", "/cast/home")}>Home</button>
712
+ </div>
713
+ <div class="btn-row" style="margin-top:6px;">
714
+ <button style="flex:1;" onclick=${doScreenshot}>Screenshot</button>
715
+ <button class="secondary" style="flex:1;" onclick=${() => window.open("/cast/stream", "_blank")}>MJPEG</button>
716
+ </div>
717
+ <//>
718
+
719
+ <${Panel} title="Keys">
720
+ <div class="keybind-hint">
721
+ <b>WASD</b> / <b>Arrows</b> move \u00a0 <b>IJKL</b> look \u00a0 <b>QE</b> up/down<br />
722
+ <b>Drag</b> free look \u00a0 <b>Right-click</b> click<br />
723
+ <b>Space</b> click \u00a0 <b>P</b> screenshot \u00a0 <b>Esc</b> back to HMD<br />
724
+ Movement overrides HMD tracking from origin
725
+ </div>
726
+ <//>
727
+ </div>
728
+ </div>
729
+
730
+ ${toast && html`<div class="toast show">${toast}</div>`}
731
+ `;
732
+ }
733
+ function VideoPane({ active, imgRef, crosshairRef, overlayRef }) {
734
+ if (!active) {
735
+ return html`<div class="video-placeholder">
736
+ <button onclick=${() => api("POST", "/cast/start")}>Start Casting</button>
737
+ </div>`;
738
+ }
739
+ return html`
740
+ <img id="live-frame" ref=${imgRef} alt="Quest view" />
741
+ <div id="crosshair" ref=${crosshairRef}></div>
742
+ <div id="drag-overlay" ref=${overlayRef}></div>
743
+ `;
744
+ }
745
+ function Panel({ title, children }) {
746
+ return html`<div class="panel"><h2>${title}</h2>${children}</div>`;
747
+ }
748
+ J(html`<${App} />`, document.body);
749
+ })();