@kelnishi/satmouse-client 0.17.1 → 0.18.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/index.cjs +31 -5
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.js +31 -5
- package/dist/core/index.js.map +1 -1
- package/dist/elements/index.cjs +81 -36
- package/dist/elements/index.cjs.map +1 -1
- package/dist/elements/index.d.cts +32 -1
- package/dist/elements/index.d.ts +32 -1
- package/dist/elements/index.js +79 -37
- package/dist/elements/index.js.map +1 -1
- package/dist/react/index.cjs +31 -5
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.js +31 -5
- package/dist/react/index.js.map +1 -1
- package/package.json +1 -1
package/dist/elements/index.js
CHANGED
|
@@ -17,6 +17,44 @@ function onManager(fn) {
|
|
|
17
17
|
return () => listeners.delete(fn);
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
// src/elements/locale.ts
|
|
21
|
+
var DEFAULT_LOCALE = {
|
|
22
|
+
// satmouse-status
|
|
23
|
+
connected: "Connected",
|
|
24
|
+
connecting: "Connecting...",
|
|
25
|
+
disconnected: "Disconnected",
|
|
26
|
+
notRunning: "Not running",
|
|
27
|
+
extensionRequired: "Extension required",
|
|
28
|
+
launchSatMouse: "Launch SatMouse",
|
|
29
|
+
downloadSatMouse: "Download SatMouse",
|
|
30
|
+
enableExtension: "Enable Extension",
|
|
31
|
+
// satmouse-devices
|
|
32
|
+
noDevices: "No devices",
|
|
33
|
+
flip: "Flip",
|
|
34
|
+
translateScale: "Trans",
|
|
35
|
+
rotateScale: "Rot",
|
|
36
|
+
wScale: "W",
|
|
37
|
+
buttonMappings: "Button Mappings",
|
|
38
|
+
remapKey: "Remap key",
|
|
39
|
+
pressAKey: "Press a key...",
|
|
40
|
+
remove: "Remove",
|
|
41
|
+
addButtonMapping: "+ Add Button Mapping",
|
|
42
|
+
pressDeviceButton: "Press a device button...",
|
|
43
|
+
restoreDefaults: "Restore Defaults",
|
|
44
|
+
// satmouse-debug
|
|
45
|
+
fps: "fps"
|
|
46
|
+
};
|
|
47
|
+
var current = { ...DEFAULT_LOCALE };
|
|
48
|
+
function setLocale(overrides) {
|
|
49
|
+
current = { ...current, ...overrides };
|
|
50
|
+
}
|
|
51
|
+
function getLocale() {
|
|
52
|
+
return current;
|
|
53
|
+
}
|
|
54
|
+
function t(key) {
|
|
55
|
+
return current[key];
|
|
56
|
+
}
|
|
57
|
+
|
|
20
58
|
// src/elements/satmouse-status.ts
|
|
21
59
|
var TEMPLATE = `
|
|
22
60
|
<style>
|
|
@@ -32,9 +70,9 @@ var TEMPLATE = `
|
|
|
32
70
|
|
|
33
71
|
</style>
|
|
34
72
|
<span class="dot"></span>
|
|
35
|
-
<span class="text"
|
|
73
|
+
<span class="text"></span>
|
|
36
74
|
<span class="protocol"></span>
|
|
37
|
-
<button class="launch"
|
|
75
|
+
<button class="launch"></button>
|
|
38
76
|
`;
|
|
39
77
|
var SatMouseStatus = class extends HTMLElement {
|
|
40
78
|
dot;
|
|
@@ -53,6 +91,8 @@ var SatMouseStatus = class extends HTMLElement {
|
|
|
53
91
|
this.text = shadow.querySelector(".text");
|
|
54
92
|
this.proto = shadow.querySelector(".protocol");
|
|
55
93
|
this.launch = shadow.querySelector(".launch");
|
|
94
|
+
this.text.textContent = t("disconnected");
|
|
95
|
+
this.launch.textContent = t("launchSatMouse");
|
|
56
96
|
this.launch.addEventListener("click", () => {
|
|
57
97
|
this.startLaunchFlow();
|
|
58
98
|
});
|
|
@@ -61,7 +101,7 @@ var SatMouseStatus = class extends HTMLElement {
|
|
|
61
101
|
this.unsub = onManager((mgr) => this.bind(mgr));
|
|
62
102
|
this.stopPoll();
|
|
63
103
|
this.launch.disabled = false;
|
|
64
|
-
this.launch.textContent = "
|
|
104
|
+
this.launch.textContent = t("launchSatMouse");
|
|
65
105
|
}
|
|
66
106
|
disconnectedCallback() {
|
|
67
107
|
this.stopPoll();
|
|
@@ -84,30 +124,30 @@ var SatMouseStatus = class extends HTMLElement {
|
|
|
84
124
|
if (state === "connected") {
|
|
85
125
|
this.stopPoll();
|
|
86
126
|
this.showDownload = false;
|
|
87
|
-
this.text.textContent = "
|
|
127
|
+
this.text.textContent = t("connected");
|
|
88
128
|
this.launch.style.display = "none";
|
|
89
129
|
} else if (state === "connecting") {
|
|
90
|
-
this.text.textContent = "
|
|
130
|
+
this.text.textContent = t("connecting");
|
|
91
131
|
this.launch.style.display = "none";
|
|
92
132
|
} else if (state === "failed") {
|
|
93
133
|
const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
|
|
94
134
|
const hasExtension = !!globalThis.__satmouseExtensionAvailable;
|
|
95
135
|
if (isSafari && !hasExtension) {
|
|
96
|
-
this.text.textContent = "
|
|
136
|
+
this.text.textContent = t("extensionRequired");
|
|
97
137
|
this.launch.style.display = "inline-block";
|
|
98
138
|
this.launch.disabled = false;
|
|
99
|
-
this.launch.textContent = "
|
|
139
|
+
this.launch.textContent = t("enableExtension");
|
|
100
140
|
this.showDownload = false;
|
|
101
141
|
this.needsExtension = true;
|
|
102
142
|
} else {
|
|
103
|
-
this.text.textContent = "
|
|
143
|
+
this.text.textContent = t("notRunning");
|
|
104
144
|
this.launch.style.display = "inline-block";
|
|
105
145
|
this.launch.disabled = false;
|
|
106
|
-
this.launch.textContent = this.showDownload ? "
|
|
146
|
+
this.launch.textContent = this.showDownload ? t("downloadSatMouse") : t("launchSatMouse");
|
|
107
147
|
this.needsExtension = false;
|
|
108
148
|
}
|
|
109
149
|
} else {
|
|
110
|
-
this.text.textContent = "
|
|
150
|
+
this.text.textContent = t("disconnected");
|
|
111
151
|
this.launch.style.display = "none";
|
|
112
152
|
}
|
|
113
153
|
}
|
|
@@ -116,7 +156,7 @@ var SatMouseStatus = class extends HTMLElement {
|
|
|
116
156
|
startLaunchFlow() {
|
|
117
157
|
if (this.needsExtension) {
|
|
118
158
|
window.location.href = "satmouse://enable-extension";
|
|
119
|
-
this.launch.textContent = "
|
|
159
|
+
this.launch.textContent = t("connecting");
|
|
120
160
|
this.launch.disabled = true;
|
|
121
161
|
this.stopPoll();
|
|
122
162
|
this.pollTimer = setInterval(() => {
|
|
@@ -129,7 +169,7 @@ var SatMouseStatus = class extends HTMLElement {
|
|
|
129
169
|
setTimeout(() => {
|
|
130
170
|
this.stopPoll();
|
|
131
171
|
this.launch.disabled = false;
|
|
132
|
-
this.launch.textContent = "
|
|
172
|
+
this.launch.textContent = t("enableExtension");
|
|
133
173
|
}, 3e4);
|
|
134
174
|
return;
|
|
135
175
|
}
|
|
@@ -137,7 +177,7 @@ var SatMouseStatus = class extends HTMLElement {
|
|
|
137
177
|
window.location.href = "https://github.com/kelnishi/SatMouse/releases/latest";
|
|
138
178
|
return;
|
|
139
179
|
}
|
|
140
|
-
this.launch.textContent = "
|
|
180
|
+
this.launch.textContent = t("connecting");
|
|
141
181
|
this.launch.disabled = true;
|
|
142
182
|
this.manager?.retry();
|
|
143
183
|
window.location.href = "satmouse://launch";
|
|
@@ -154,7 +194,7 @@ var SatMouseStatus = class extends HTMLElement {
|
|
|
154
194
|
this.stopPoll();
|
|
155
195
|
this.showDownload = true;
|
|
156
196
|
this.launch.disabled = false;
|
|
157
|
-
this.launch.textContent = "
|
|
197
|
+
this.launch.textContent = t("downloadSatMouse");
|
|
158
198
|
return;
|
|
159
199
|
}
|
|
160
200
|
this.manager?.retry();
|
|
@@ -237,7 +277,7 @@ var SatMouseDevices = class extends HTMLElement {
|
|
|
237
277
|
disconnectedCallback() {
|
|
238
278
|
this.unsub?.();
|
|
239
279
|
this.unbind();
|
|
240
|
-
this.container.innerHTML = `<span class="empty"
|
|
280
|
+
this.container.innerHTML = `<span class="empty">${t("noDevices")}</span>`;
|
|
241
281
|
}
|
|
242
282
|
bind(mgr) {
|
|
243
283
|
this.unbind();
|
|
@@ -291,7 +331,7 @@ var SatMouseDevices = class extends HTMLElement {
|
|
|
291
331
|
const cb = document.createElement("input");
|
|
292
332
|
cb.type = "checkbox";
|
|
293
333
|
cb.checked = route.flip ?? false;
|
|
294
|
-
cb.title = "
|
|
334
|
+
cb.title = t("flip");
|
|
295
335
|
const routeIndex = i;
|
|
296
336
|
cb.addEventListener("change", () => {
|
|
297
337
|
this.updateRoute(device.id, routeIndex, deviceAxes, { flip: cb.checked });
|
|
@@ -316,9 +356,9 @@ var SatMouseDevices = class extends HTMLElement {
|
|
|
316
356
|
}
|
|
317
357
|
controls.appendChild(routeGroup);
|
|
318
358
|
for (const [label, key, globalKey] of [
|
|
319
|
-
["
|
|
320
|
-
["
|
|
321
|
-
["
|
|
359
|
+
[t("translateScale"), "translateScale", "translateScale"],
|
|
360
|
+
[t("rotateScale"), "rotateScale", "rotateScale"],
|
|
361
|
+
[t("wScale"), "wScale", "wScale"]
|
|
322
362
|
]) {
|
|
323
363
|
const row = document.createElement("div");
|
|
324
364
|
row.className = "slider-row";
|
|
@@ -337,7 +377,7 @@ var SatMouseDevices = class extends HTMLElement {
|
|
|
337
377
|
btnSection.className = "btn-section";
|
|
338
378
|
const btnLabel = document.createElement("div");
|
|
339
379
|
btnLabel.className = "btn-section-label";
|
|
340
|
-
btnLabel.textContent = "
|
|
380
|
+
btnLabel.textContent = t("buttonMappings");
|
|
341
381
|
btnSection.appendChild(btnLabel);
|
|
342
382
|
const buttonRoutes = cfg.buttonRoutes ?? [];
|
|
343
383
|
const labels = device.buttonLabels ?? [];
|
|
@@ -361,17 +401,17 @@ var SatMouseDevices = class extends HTMLElement {
|
|
|
361
401
|
const editBtn = document.createElement("button");
|
|
362
402
|
editBtn.className = "btn-remove";
|
|
363
403
|
editBtn.textContent = "\u270E";
|
|
364
|
-
editBtn.title = "
|
|
404
|
+
editBtn.title = t("remapKey");
|
|
365
405
|
const routeIdx = i;
|
|
366
406
|
editBtn.addEventListener("click", () => {
|
|
367
|
-
keySpan.textContent = "
|
|
407
|
+
keySpan.textContent = t("pressAKey");
|
|
368
408
|
keySpan.style.color = "#f39c12";
|
|
369
409
|
const onKey = (e) => {
|
|
370
410
|
e.preventDefault();
|
|
371
411
|
e.stopPropagation();
|
|
372
412
|
document.removeEventListener("keydown", onKey, true);
|
|
373
|
-
const
|
|
374
|
-
const updated =
|
|
413
|
+
const current2 = mgr.getDeviceConfig(device.id).buttonRoutes ?? [];
|
|
414
|
+
const updated = current2.map(
|
|
375
415
|
(r, j) => j === routeIdx ? { ...r, key: e.key, code: e.code } : r
|
|
376
416
|
);
|
|
377
417
|
mgr.updateDeviceConfig(device.id, { buttonRoutes: updated });
|
|
@@ -383,10 +423,10 @@ var SatMouseDevices = class extends HTMLElement {
|
|
|
383
423
|
const removeBtn = document.createElement("button");
|
|
384
424
|
removeBtn.className = "btn-remove";
|
|
385
425
|
removeBtn.textContent = "\xD7";
|
|
386
|
-
removeBtn.title = "
|
|
426
|
+
removeBtn.title = t("remove");
|
|
387
427
|
removeBtn.addEventListener("click", () => {
|
|
388
|
-
const
|
|
389
|
-
const updated =
|
|
428
|
+
const current2 = mgr.getDeviceConfig(device.id).buttonRoutes ?? [];
|
|
429
|
+
const updated = current2.filter((_, j) => j !== routeIdx);
|
|
390
430
|
mgr.updateDeviceConfig(device.id, { buttonRoutes: updated });
|
|
391
431
|
this.refreshControls(panel, device);
|
|
392
432
|
});
|
|
@@ -395,7 +435,7 @@ var SatMouseDevices = class extends HTMLElement {
|
|
|
395
435
|
}
|
|
396
436
|
const addBtn = document.createElement("button");
|
|
397
437
|
addBtn.className = "btn-add";
|
|
398
|
-
addBtn.textContent = "
|
|
438
|
+
addBtn.textContent = t("addButtonMapping");
|
|
399
439
|
addBtn.addEventListener("click", () => {
|
|
400
440
|
if (addBtn.classList.contains("listening")) return;
|
|
401
441
|
this.startButtonListen(addBtn, mgr, device, panel);
|
|
@@ -404,7 +444,7 @@ var SatMouseDevices = class extends HTMLElement {
|
|
|
404
444
|
controls.appendChild(btnSection);
|
|
405
445
|
const resetBtn = document.createElement("button");
|
|
406
446
|
resetBtn.className = "reset-btn";
|
|
407
|
-
resetBtn.textContent = "
|
|
447
|
+
resetBtn.textContent = t("restoreDefaults");
|
|
408
448
|
resetBtn.addEventListener("click", () => {
|
|
409
449
|
mgr.resetDeviceConfig(device.id);
|
|
410
450
|
this.refreshControls(panel, device);
|
|
@@ -435,12 +475,12 @@ var SatMouseDevices = class extends HTMLElement {
|
|
|
435
475
|
}
|
|
436
476
|
startButtonListen(btn, mgr, device, panel) {
|
|
437
477
|
btn.classList.add("listening");
|
|
438
|
-
btn.textContent = "
|
|
478
|
+
btn.textContent = t("pressDeviceButton");
|
|
439
479
|
const onButton = (event) => {
|
|
440
480
|
if (!event.pressed) return;
|
|
441
481
|
mgr.off("buttonEvent", onButton);
|
|
442
482
|
const capturedButton = event.button;
|
|
443
|
-
btn.textContent = `Btn ${capturedButton} \u2192
|
|
483
|
+
btn.textContent = `Btn ${capturedButton} \u2192 ${t("pressAKey")}`;
|
|
444
484
|
const onKey = (e) => {
|
|
445
485
|
e.preventDefault();
|
|
446
486
|
e.stopPropagation();
|
|
@@ -450,8 +490,8 @@ var SatMouseDevices = class extends HTMLElement {
|
|
|
450
490
|
key: e.key,
|
|
451
491
|
code: e.code
|
|
452
492
|
};
|
|
453
|
-
const
|
|
454
|
-
const updated =
|
|
493
|
+
const current2 = mgr.getDeviceConfig(device.id).buttonRoutes ?? [];
|
|
494
|
+
const updated = current2.filter((r) => r.button !== capturedButton);
|
|
455
495
|
updated.push(route);
|
|
456
496
|
mgr.updateDeviceConfig(device.id, { buttonRoutes: updated });
|
|
457
497
|
this.refreshControls(panel, device);
|
|
@@ -464,7 +504,7 @@ var SatMouseDevices = class extends HTMLElement {
|
|
|
464
504
|
mgr.off("buttonEvent", onButton);
|
|
465
505
|
document.removeEventListener("keydown", onCancel, true);
|
|
466
506
|
btn.classList.remove("listening");
|
|
467
|
-
btn.textContent = "
|
|
507
|
+
btn.textContent = t("addButtonMapping");
|
|
468
508
|
}
|
|
469
509
|
};
|
|
470
510
|
document.addEventListener("keydown", onCancel, true);
|
|
@@ -472,7 +512,7 @@ var SatMouseDevices = class extends HTMLElement {
|
|
|
472
512
|
removeDevice(device) {
|
|
473
513
|
this.shadowRoot.getElementById(`dev-${device.id}`)?.remove();
|
|
474
514
|
if (this.container.children.length === 0) {
|
|
475
|
-
this.container.innerHTML = `<span class="empty"
|
|
515
|
+
this.container.innerHTML = `<span class="empty">${t("noDevices")}</span>`;
|
|
476
516
|
}
|
|
477
517
|
}
|
|
478
518
|
};
|
|
@@ -487,7 +527,7 @@ var TEMPLATE2 = `
|
|
|
487
527
|
.value { color: #3498db; text-align: right; min-width: 50px; }
|
|
488
528
|
.meta { color: #7f8c8d; font-size: 11px; padding: 2px 0; }
|
|
489
529
|
</style>
|
|
490
|
-
<div class="meta"><span class="state"
|
|
530
|
+
<div class="meta"><span class="state"></span> \xB7 <span class="protocol"></span> \xB7 <span class="fps">0</span> <span class="fps-label"></span></div>
|
|
491
531
|
<div class="row"><span class="label">TX</span><span class="value" id="tx">0</span></div>
|
|
492
532
|
<div class="row"><span class="label">TY</span><span class="value" id="ty">0</span></div>
|
|
493
533
|
<div class="row"><span class="label">TZ</span><span class="value" id="tz">0</span></div>
|
|
@@ -524,6 +564,8 @@ var SatMouseDebug = class extends HTMLElement {
|
|
|
524
564
|
this.els.state = shadow.querySelector(".state");
|
|
525
565
|
this.els.protocol = shadow.querySelector(".protocol");
|
|
526
566
|
this.els.fps = shadow.querySelector(".fps");
|
|
567
|
+
this.els.state.textContent = t("disconnected");
|
|
568
|
+
shadow.querySelector(".fps-label").textContent = t("fps");
|
|
527
569
|
}
|
|
528
570
|
connectedCallback() {
|
|
529
571
|
this.unsub = onManager((mgr) => this.bind(mgr));
|
|
@@ -558,6 +600,6 @@ var SatMouseDebug = class extends HTMLElement {
|
|
|
558
600
|
};
|
|
559
601
|
customElements.define("satmouse-debug", SatMouseDebug);
|
|
560
602
|
|
|
561
|
-
export { SatMouseDebug, SatMouseDevices, SatMouseStatus, getManager, registerSatMouse };
|
|
603
|
+
export { DEFAULT_LOCALE, SatMouseDebug, SatMouseDevices, SatMouseStatus, getLocale, getManager, registerSatMouse, setLocale };
|
|
562
604
|
//# sourceMappingURL=index.js.map
|
|
563
605
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/elements/registry.ts","../../src/elements/satmouse-status.ts","../../src/elements/satmouse-devices.ts","../../src/elements/satmouse-debug.ts"],"names":["TEMPLATE"],"mappings":"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","file":"index.js","sourcesContent":["import type { InputManager } from \"../utils/input-manager.js\";\n\n/**\n * Global registry for SatMouse Web Components.\n *\n * Usage:\n * import { registerSatMouse } from \"@kelnishi/satmouse-client/elements\";\n * registerSatMouse(manager);\n * // All <satmouse-*> elements auto-connect to this manager\n */\n\nlet globalManager: InputManager | null = null;\nconst listeners = new Set<(m: InputManager) => void>();\n\nexport function registerSatMouse(manager: InputManager): void {\n globalManager = manager;\n for (const fn of listeners) fn(manager);\n listeners.clear();\n}\n\nexport function getManager(): InputManager | null {\n return globalManager;\n}\n\nexport function onManagerReady(fn: (m: InputManager) => void): void {\n if (globalManager) fn(globalManager);\n else listeners.add(fn);\n}\n\n/** Subscribe to manager availability. Calls fn immediately if already available.\n * Returns an unsubscribe function (for disconnectedCallback). */\nexport function onManager(fn: (m: InputManager) => void): () => void {\n if (globalManager) fn(globalManager);\n else listeners.add(fn);\n return () => listeners.delete(fn);\n}\n","import { onManager } from \"./registry.js\";\nimport type { InputManager } from \"../utils/input-manager.js\";\nimport type { ConnectionState, TransportProtocol } from \"../core/types.js\";\n\nconst TEMPLATE = `\n<style>\n :host { display: inline-flex; align-items: center; gap: 8px; font-family: inherit; font-size: 13px; }\n .dot { width: 8px; height: 8px; border-radius: 50%; background: #e74c3c; transition: background 0.3s; }\n .dot[data-state=\"connected\"] { background: #2ecc71; }\n .dot[data-state=\"connecting\"] { background: #f39c12; }\n .dot[data-state=\"failed\"] { background: #e74c3c; }\n .protocol { color: #7f8c8d; font-size: 11px; text-transform: uppercase; letter-spacing: 1px; }\n .launch { padding: 4px 12px; background: #2980b9; color: #fff; border-radius: 4px; font-size: 11px;\n text-decoration: none; cursor: pointer; border: none; font-family: inherit; display: none; }\n .launch:hover { background: #3498db; }\n\n</style>\n<span class=\"dot\"></span>\n<span class=\"text\">Disconnected</span>\n<span class=\"protocol\"></span>\n<button class=\"launch\">Launch SatMouse</button>\n`;\n\nexport class SatMouseStatus extends HTMLElement {\n private dot!: HTMLElement;\n private text!: HTMLElement;\n private proto!: HTMLElement;\n private launch!: HTMLButtonElement;\n private manager: InputManager | null = null;\n private unsub: (() => void) | null = null;\n private pollTimer: ReturnType<typeof setInterval> | null = null;\n\n private stateHandler = (state: ConnectionState, protocol: TransportProtocol) => this.update(state, protocol);\n\n constructor() {\n super();\n const shadow = this.attachShadow({ mode: \"open\" });\n shadow.innerHTML = TEMPLATE;\n this.dot = shadow.querySelector(\".dot\")!;\n this.text = shadow.querySelector(\".text\")!;\n this.proto = shadow.querySelector(\".protocol\")!;\n this.launch = shadow.querySelector(\".launch\")!;\n\n this.launch.addEventListener(\"click\", () => {\n this.startLaunchFlow();\n });\n }\n\n connectedCallback() {\n this.unsub = onManager((mgr) => this.bind(mgr));\n // Reset button state on remount\n this.stopPoll();\n this.launch.disabled = false;\n this.launch.textContent = \"Launch SatMouse\";\n }\n\n disconnectedCallback() {\n this.stopPoll();\n this.unsub?.();\n this.unbind();\n }\n\n private bind(mgr: InputManager): void {\n this.unbind();\n this.manager = mgr;\n mgr.on(\"stateChange\", this.stateHandler);\n this.update(mgr.state, mgr.protocol);\n }\n\n private unbind(): void {\n this.manager?.off(\"stateChange\", this.stateHandler);\n this.manager = null;\n }\n\n private update(state: ConnectionState, protocol: TransportProtocol): void {\n this.dot.dataset.state = state;\n this.proto.textContent = protocol !== \"none\" ? protocol : \"\";\n\n if (state === \"connected\") {\n this.stopPoll();\n this.showDownload = false;\n this.text.textContent = \"Connected\";\n this.launch.style.display = \"none\";\n } else if (state === \"connecting\") {\n this.text.textContent = \"Connecting...\";\n this.launch.style.display = \"none\";\n } else if (state === \"failed\") {\n // Detect Safari without extension — suggest enabling it\n const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);\n const hasExtension = !!(globalThis as any).__satmouseExtensionAvailable;\n if (isSafari && !hasExtension) {\n this.text.textContent = \"Extension required\";\n this.launch.style.display = \"inline-block\";\n this.launch.disabled = false;\n this.launch.textContent = \"Enable Extension\";\n this.showDownload = false;\n this.needsExtension = true;\n } else {\n this.text.textContent = \"Not running\";\n this.launch.style.display = \"inline-block\";\n this.launch.disabled = false;\n this.launch.textContent = this.showDownload ? \"Download SatMouse\" : \"Launch SatMouse\";\n this.needsExtension = false;\n }\n } else {\n this.text.textContent = \"Disconnected\";\n this.launch.style.display = \"none\";\n }\n }\n\n private showDownload = false;\n private needsExtension = false;\n\n private startLaunchFlow(): void {\n if (this.needsExtension) {\n // Open Safari extension preferences via the bridge's URL scheme\n window.location.href = \"satmouse://enable-extension\";\n // Retry connection after user enables the extension\n this.launch.textContent = \"Connecting...\";\n this.launch.disabled = true;\n this.stopPoll();\n this.pollTimer = setInterval(() => {\n if (this.manager?.state === \"connected\") { this.stopPoll(); return; }\n this.manager?.retry();\n }, 2000);\n // Give up after 30s\n setTimeout(() => { this.stopPoll(); this.launch.disabled = false; this.launch.textContent = \"Enable Extension\"; }, 30000);\n return;\n }\n\n if (this.showDownload) {\n window.location.href = \"https://github.com/kelnishi/SatMouse/releases/latest\";\n return;\n }\n\n this.launch.textContent = \"Connecting...\";\n this.launch.disabled = true;\n\n this.manager?.retry();\n window.location.href = \"satmouse://launch\";\n\n let attempts = 0;\n this.stopPoll();\n this.pollTimer = setInterval(() => {\n attempts++;\n if (this.manager?.state === \"connected\") {\n this.stopPoll();\n this.showDownload = false;\n return;\n }\n if (attempts >= 5) {\n this.stopPoll();\n this.showDownload = true;\n this.launch.disabled = false;\n this.launch.textContent = \"Download SatMouse\";\n return;\n }\n this.manager?.retry();\n }, 1500);\n }\n\n private stopPoll(): void {\n if (this.pollTimer) {\n clearInterval(this.pollTimer);\n this.pollTimer = null;\n }\n }\n}\n\ncustomElements.define(\"satmouse-status\", SatMouseStatus);\n","import { onManager } from \"./registry.js\";\nimport type { InputManager } from \"../utils/input-manager.js\";\nimport type { DeviceInfo } from \"../core/types.js\";\nimport type { InputAxis, AxisRoute } from \"../utils/action-map.js\";\nimport type { ButtonRoute } from \"../utils/config.js\";\nimport type { ButtonEvent } from \"../core/types.js\";\nimport { FULL_AXES, buildRoutes, DEFAULT_ROUTES } from \"../utils/action-map.js\";\n\nconst STYLES = `\n<style>\n :host { display: block; font-family: inherit; font-size: 12px; }\n .panel { background: #0f3460; border: 1px solid #1a4a8a; border-radius: 6px; padding: 10px; margin-bottom: 8px; }\n summary { cursor: pointer; font-weight: 600; color: #e0e0e0; font-size: 13px; }\n .type { font-size: 10px; color: #7f8c8d; text-transform: uppercase; margin-left: 6px; }\n .controls { margin-top: 8px; display: flex; flex-direction: column; gap: 6px; }\n .slider-row { display: flex; align-items: center; gap: 6px; }\n .slider-row label { color: #7f8c8d; font-weight: 600; width: 38px; flex-shrink: 0; }\n .slider-row input[type=\"range\"] { flex: 1; min-width: 0; height: 4px; accent-color: #3498db; }\n .slider-row span { color: #7f8c8d; font-family: monospace; font-size: 10px; min-width: 44px; text-align: right; }\n .route-group { display: flex; flex-wrap: wrap; gap: 4px 12px; }\n .route-row { display: flex; gap: 4px; align-items: center; }\n .route-row label { color: #7f8c8d; white-space: nowrap; }\n .route-row select { background: #16213e; color: #e0e0e0; border: 1px solid #1a4a8a; border-radius: 3px;\n font-size: 11px; padding: 1px 4px; }\n .route-row input[type=\"checkbox\"] { accent-color: #e74c3c; margin: 0; }\n .empty { color: #7f8c8d; font-style: italic; }\n .reset-btn { background: none; border: 1px solid #1a4a8a; border-radius: 3px; color: #7f8c8d;\n font-size: 11px; padding: 3px 8px; cursor: pointer; margin-top: 4px; }\n .reset-btn:hover { color: #e0e0e0; border-color: #e74c3c; }\n .btn-section { display: flex; flex-direction: column; gap: 4px; }\n .btn-section-label { color: #7f8c8d; font-weight: 600; font-size: 10px; text-transform: uppercase; letter-spacing: 0.5px; }\n .btn-route { display: flex; gap: 6px; align-items: center; font-size: 11px; }\n .btn-route .btn-idx { color: #7f8c8d; font-family: monospace; min-width: 32px; }\n .btn-route .btn-arrow { color: #7f8c8d; }\n .btn-route .btn-key { color: #3498db; font-family: monospace; }\n .btn-route .btn-remove { cursor: pointer; color: #e74c3c; background: none; border: none;\n font-size: 11px; padding: 0 2px; font-family: inherit; }\n .btn-route .btn-remove:hover { color: #ff6b6b; }\n .btn-add { background: none; border: 1px dashed #1a4a8a; border-radius: 3px; color: #7f8c8d;\n font-size: 11px; padding: 4px 8px; cursor: pointer; font-family: inherit; }\n .btn-add:hover { color: #e0e0e0; border-color: #3498db; }\n .btn-add.listening { color: #f39c12; border-color: #f39c12; border-style: solid; cursor: default; }\n</style>\n`;\n\nfunction mapSlider(v: number): number { return 0.0001 * Math.pow(500, v / 100); }\nfunction unmapSlider(v: number): number { return (100 * Math.log(v / 0.0001)) / Math.log(500); }\n\nexport class SatMouseDevices extends HTMLElement {\n private manager: InputManager | null = null;\n private container!: HTMLElement;\n\n constructor() {\n super();\n const shadow = this.attachShadow({ mode: \"open\" });\n shadow.innerHTML = STYLES + `<div class=\"container\"><span class=\"empty\">No devices</span></div>`;\n this.container = shadow.querySelector(\".container\")!;\n }\n\n private unsub: (() => void) | null = null;\n\n private deviceStatusHandler = (event: \"connected\" | \"disconnected\", device: DeviceInfo) => {\n if (event === \"connected\") this.addDevice(device);\n else this.removeDevice(device);\n };\n\n private stateHandler = (state: string) => {\n if (state === \"connected\") {\n this.manager?.fetchDeviceInfo().then((devices) => devices.forEach((d) => this.addDevice(d)));\n }\n };\n\n connectedCallback() {\n this.unsub = onManager((mgr) => this.bind(mgr));\n }\n\n disconnectedCallback() {\n this.unsub?.();\n this.unbind();\n this.container.innerHTML = `<span class=\"empty\">No devices</span>`;\n }\n\n private bind(mgr: InputManager): void {\n this.unbind();\n this.manager = mgr;\n mgr.on(\"deviceStatus\", this.deviceStatusHandler);\n mgr.on(\"stateChange\", this.stateHandler);\n if (mgr.state === \"connected\") {\n mgr.fetchDeviceInfo().then((devices) => devices.forEach((d) => this.addDevice(d)));\n }\n }\n\n private unbind(): void {\n if (this.manager) {\n this.manager.off(\"deviceStatus\", this.deviceStatusHandler);\n this.manager.off(\"stateChange\", this.stateHandler);\n this.manager = null;\n }\n }\n\n private addDevice(device: DeviceInfo): void {\n const existing = this.shadowRoot!.getElementById(`dev-${device.id}`);\n if (existing) {\n this.refreshControls(existing as HTMLDetailsElement, device);\n return;\n }\n const empty = this.container.querySelector(\".empty\");\n if (empty) empty.remove();\n\n const panel = document.createElement(\"details\");\n panel.className = \"panel\";\n panel.id = `dev-${device.id}`;\n panel.open = true;\n\n const summary = document.createElement(\"summary\");\n summary.innerHTML = `${device.model ?? device.name}<span class=\"type\">${device.connectionType ?? \"\"}</span>`;\n panel.appendChild(summary);\n\n this.refreshControls(panel, device);\n this.container.appendChild(panel);\n }\n\n private refreshControls(panel: HTMLDetailsElement, device: DeviceInfo): void {\n const old = panel.querySelector(\".controls\");\n if (old) old.remove();\n\n const mgr = this.manager!;\n const cfg = mgr.getDeviceConfig(device.id);\n\n const controls = document.createElement(\"div\");\n controls.className = \"controls\";\n\n // Axis routes — one row per device input: [flip] [label] → [target dropdown] [scale slider]\n const routeGroup = document.createElement(\"div\");\n routeGroup.className = \"route-group\";\n const deviceAxes = device.axes ?? [\"tx\", \"ty\", \"tz\", \"rx\", \"ry\", \"rz\"];\n const routes = this.getRoutes(device, deviceAxes);\n\n for (let i = 0; i < deviceAxes.length; i++) {\n const route = routes[i] ?? { source: deviceAxes[i] as InputAxis, target: deviceAxes[i].replace(/[+-]$/, \"\") as InputAxis };\n const row = document.createElement(\"div\");\n row.className = \"route-row\";\n\n // Flip checkbox\n const cb = document.createElement(\"input\");\n cb.type = \"checkbox\";\n cb.checked = route.flip ?? false;\n cb.title = \"Flip\";\n const routeIndex = i;\n cb.addEventListener(\"change\", () => {\n this.updateRoute(device.id, routeIndex, deviceAxes, { flip: cb.checked });\n });\n row.appendChild(cb);\n\n // Label (device input name)\n const label = document.createElement(\"label\");\n label.textContent = device.axisLabels?.[i] ?? deviceAxes[i].toUpperCase();\n row.appendChild(label);\n\n // Target dropdown\n const sel = document.createElement(\"select\");\n for (const target of FULL_AXES) {\n const opt = document.createElement(\"option\");\n opt.value = target;\n opt.textContent = target.toUpperCase();\n if (target === route.target) opt.selected = true;\n sel.appendChild(opt);\n }\n sel.addEventListener(\"change\", () => {\n this.updateRoute(device.id, routeIndex, deviceAxes, { target: sel.value as InputAxis });\n });\n row.appendChild(sel);\n\n routeGroup.appendChild(row);\n }\n controls.appendChild(routeGroup);\n\n // Scale sliders\n for (const [label, key, globalKey] of [\n [\"Trans\", \"translateScale\", \"translateScale\"],\n [\"Rot\", \"rotateScale\", \"rotateScale\"],\n [\"W\", \"wScale\", \"wScale\"],\n ] as const) {\n const row = document.createElement(\"div\");\n row.className = \"slider-row\";\n const val = (cfg as any)[key] ?? (mgr.config as any)[globalKey];\n row.innerHTML = `<label>${label}</label>` +\n `<input type=\"range\" min=\"0\" max=\"100\" value=\"${Math.round(unmapSlider(val))}\">` +\n `<span>${val.toFixed(4)}</span>`;\n const sl = row.querySelector(\"input\")! as HTMLInputElement;\n const sp = row.querySelector(\"span\")!;\n sl.addEventListener(\"input\", () => {\n const v = mapSlider(+sl.value);\n sp.textContent = v.toFixed(4);\n mgr.updateDeviceConfig(device.id, { [key]: v });\n });\n controls.appendChild(row);\n }\n\n // Button mappings\n const btnSection = document.createElement(\"div\");\n btnSection.className = \"btn-section\";\n const btnLabel = document.createElement(\"div\");\n btnLabel.className = \"btn-section-label\";\n btnLabel.textContent = \"Button Mappings\";\n btnSection.appendChild(btnLabel);\n\n const buttonRoutes: ButtonRoute[] = cfg.buttonRoutes ?? [];\n const labels = device.buttonLabels ?? [];\n for (let i = 0; i < buttonRoutes.length; i++) {\n const route = buttonRoutes[i];\n const btnName = labels[route.button] ?? `Btn ${route.button}`;\n const row = document.createElement(\"div\");\n row.className = \"btn-route\";\n\n const idxSpan = document.createElement(\"span\");\n idxSpan.className = \"btn-idx\";\n idxSpan.textContent = btnName;\n row.appendChild(idxSpan);\n\n const arrow = document.createElement(\"span\");\n arrow.className = \"btn-arrow\";\n arrow.textContent = \"\\u2192\";\n row.appendChild(arrow);\n\n const keySpan = document.createElement(\"span\");\n keySpan.className = \"btn-key\";\n keySpan.textContent = route.key;\n row.appendChild(keySpan);\n\n // Edit — re-listen for a new key\n const editBtn = document.createElement(\"button\");\n editBtn.className = \"btn-remove\";\n editBtn.textContent = \"\\u270E\";\n editBtn.title = \"Remap key\";\n const routeIdx = i;\n editBtn.addEventListener(\"click\", () => {\n keySpan.textContent = \"Press a key...\";\n keySpan.style.color = \"#f39c12\";\n const onKey = (e: KeyboardEvent) => {\n e.preventDefault();\n e.stopPropagation();\n document.removeEventListener(\"keydown\", onKey, true);\n const current = mgr.getDeviceConfig(device.id).buttonRoutes ?? [];\n const updated = current.map((r: ButtonRoute, j: number) =>\n j === routeIdx ? { ...r, key: e.key, code: e.code } : r\n );\n mgr.updateDeviceConfig(device.id, { buttonRoutes: updated });\n this.refreshControls(panel, device);\n };\n document.addEventListener(\"keydown\", onKey, true);\n });\n row.appendChild(editBtn);\n\n // Delete\n const removeBtn = document.createElement(\"button\");\n removeBtn.className = \"btn-remove\";\n removeBtn.textContent = \"\\u00d7\";\n removeBtn.title = \"Remove\";\n removeBtn.addEventListener(\"click\", () => {\n const current = mgr.getDeviceConfig(device.id).buttonRoutes ?? [];\n const updated = current.filter((_: ButtonRoute, j: number) => j !== routeIdx);\n mgr.updateDeviceConfig(device.id, { buttonRoutes: updated });\n this.refreshControls(panel, device);\n });\n row.appendChild(removeBtn);\n btnSection.appendChild(row);\n }\n\n // Add mapping button with listen flow\n const addBtn = document.createElement(\"button\");\n addBtn.className = \"btn-add\";\n addBtn.textContent = \"+ Add Button Mapping\";\n addBtn.addEventListener(\"click\", () => {\n if (addBtn.classList.contains(\"listening\")) return;\n this.startButtonListen(addBtn, mgr, device, panel);\n });\n btnSection.appendChild(addBtn);\n controls.appendChild(btnSection);\n\n // Reset button\n const resetBtn = document.createElement(\"button\");\n resetBtn.className = \"reset-btn\";\n resetBtn.textContent = \"Restore Defaults\";\n resetBtn.addEventListener(\"click\", () => {\n mgr.resetDeviceConfig(device.id);\n this.refreshControls(panel, device);\n });\n controls.appendChild(resetBtn);\n\n panel.appendChild(controls);\n }\n\n private getRoutes(device: DeviceInfo, deviceAxes: string[]): AxisRoute[] {\n const mgr = this.manager!;\n\n // 1. Exact device ID\n const devCfg = mgr.config.devices[device.id];\n if (devCfg?.routes && Array.isArray(devCfg.routes)) return devCfg.routes;\n\n // 2. Pattern match\n for (const [pattern, cfg] of Object.entries(mgr.config.devices)) {\n if (pattern.endsWith(\"*\") && device.id.startsWith(pattern.slice(0, -1))) {\n if (cfg.routes && Array.isArray(cfg.routes)) return cfg.routes;\n }\n }\n\n // 3. Device class defaults\n if (device.deviceClass && mgr.config.deviceClasses) {\n const classCfg = mgr.config.deviceClasses[device.deviceClass];\n if (classCfg?.routes && Array.isArray(classCfg.routes)) return classCfg.routes;\n }\n\n // 4. Build from device axes metadata\n return buildRoutes(deviceAxes);\n }\n\n private updateRoute(deviceId: string, index: number, deviceAxes: string[], patch: Partial<AxisRoute>): void {\n const device = Array.from(this.manager!.getDevicesWithConfig()).find(d => d.device.id === deviceId)?.device;\n const base = this.getRoutes(device ?? { id: deviceId } as DeviceInfo, deviceAxes);\n const updated = base.map((r, j) => j === index ? { ...r, ...patch } : { ...r });\n this.manager!.updateDeviceConfig(deviceId, { routes: updated });\n }\n\n private startButtonListen(\n btn: HTMLButtonElement,\n mgr: InputManager,\n device: DeviceInfo,\n panel: HTMLDetailsElement,\n ): void {\n btn.classList.add(\"listening\");\n btn.textContent = \"Press a device button...\";\n\n // Step 1: Listen for device button\n const onButton = (event: ButtonEvent) => {\n if (!event.pressed) return; // only on press, not release\n mgr.off(\"buttonEvent\", onButton);\n\n const capturedButton = event.button;\n btn.textContent = `Btn ${capturedButton} \\u2192 Press a key...`;\n\n // Step 2: Listen for keyboard key\n const onKey = (e: KeyboardEvent) => {\n e.preventDefault();\n e.stopPropagation();\n document.removeEventListener(\"keydown\", onKey, true);\n\n const route: ButtonRoute = {\n button: capturedButton,\n key: e.key,\n code: e.code,\n };\n\n const current = mgr.getDeviceConfig(device.id).buttonRoutes ?? [];\n // Replace existing mapping for the same button, or add new\n const updated = current.filter((r: ButtonRoute) => r.button !== capturedButton);\n updated.push(route);\n mgr.updateDeviceConfig(device.id, { buttonRoutes: updated });\n this.refreshControls(panel, device);\n };\n document.addEventListener(\"keydown\", onKey, true);\n };\n mgr.on(\"buttonEvent\", onButton);\n\n // Cancel on Escape (before a button is pressed)\n const onCancel = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n mgr.off(\"buttonEvent\", onButton);\n document.removeEventListener(\"keydown\", onCancel, true);\n btn.classList.remove(\"listening\");\n btn.textContent = \"+ Add Button Mapping\";\n }\n };\n document.addEventListener(\"keydown\", onCancel, true);\n }\n\n private removeDevice(device: DeviceInfo): void {\n this.shadowRoot!.getElementById(`dev-${device.id}`)?.remove();\n if (this.container.children.length === 0) {\n this.container.innerHTML = `<span class=\"empty\">No devices</span>`;\n }\n }\n}\n\ncustomElements.define(\"satmouse-devices\", SatMouseDevices);\n","import { onManager } from \"./registry.js\";\nimport type { InputManager } from \"../utils/input-manager.js\";\nimport type { SpatialData, ConnectionState, TransportProtocol } from \"../core/types.js\";\n\nconst TEMPLATE = `\n<style>\n :host { display: block; font-family: monospace; font-size: 12px; }\n .row { display: flex; justify-content: space-between; padding: 2px 0; }\n .label { color: #7f8c8d; font-weight: 600; width: 28px; }\n .value { color: #3498db; text-align: right; min-width: 50px; }\n .meta { color: #7f8c8d; font-size: 11px; padding: 2px 0; }\n</style>\n<div class=\"meta\"><span class=\"state\">Disconnected</span> · <span class=\"protocol\"></span> · <span class=\"fps\">0</span> fps</div>\n<div class=\"row\"><span class=\"label\">TX</span><span class=\"value\" id=\"tx\">0</span></div>\n<div class=\"row\"><span class=\"label\">TY</span><span class=\"value\" id=\"ty\">0</span></div>\n<div class=\"row\"><span class=\"label\">TZ</span><span class=\"value\" id=\"tz\">0</span></div>\n<div class=\"row\"><span class=\"label\">RX</span><span class=\"value\" id=\"rx\">0</span></div>\n<div class=\"row\"><span class=\"label\">RY</span><span class=\"value\" id=\"ry\">0</span></div>\n<div class=\"row\"><span class=\"label\">RZ</span><span class=\"value\" id=\"rz\">0</span></div>\n`;\n\nexport class SatMouseDebug extends HTMLElement {\n private els: Record<string, HTMLElement> = {};\n private frameCount = 0;\n private fpsInterval: ReturnType<typeof setInterval> | null = null;\n private manager: InputManager | null = null;\n private unsub: (() => void) | null = null;\n\n private spatialHandler = (data: SpatialData) => {\n this.frameCount++;\n this.els.tx.textContent = String(Math.round(data.translation.x));\n this.els.ty.textContent = String(Math.round(data.translation.y));\n this.els.tz.textContent = String(Math.round(data.translation.z));\n this.els.rx.textContent = String(Math.round(data.rotation.x));\n this.els.ry.textContent = String(Math.round(data.rotation.y));\n this.els.rz.textContent = String(Math.round(data.rotation.z));\n };\n\n private stateHandler = (state: ConnectionState, protocol: TransportProtocol) => {\n this.els.state.textContent = state;\n this.els.protocol.textContent = protocol !== \"none\" ? protocol : \"\";\n };\n\n constructor() {\n super();\n const shadow = this.attachShadow({ mode: \"open\" });\n shadow.innerHTML = TEMPLATE;\n for (const id of [\"tx\", \"ty\", \"tz\", \"rx\", \"ry\", \"rz\"]) {\n this.els[id] = shadow.getElementById(id)!;\n }\n this.els.state = shadow.querySelector(\".state\")!;\n this.els.protocol = shadow.querySelector(\".protocol\")!;\n this.els.fps = shadow.querySelector(\".fps\")!;\n }\n\n connectedCallback() {\n this.unsub = onManager((mgr) => this.bind(mgr));\n this.fpsInterval = setInterval(() => {\n this.els.fps.textContent = String(this.frameCount);\n this.frameCount = 0;\n }, 1000);\n }\n\n disconnectedCallback() {\n this.unsub?.();\n this.unbind();\n if (this.fpsInterval) {\n clearInterval(this.fpsInterval);\n this.fpsInterval = null;\n }\n }\n\n private bind(mgr: InputManager): void {\n this.unbind();\n this.manager = mgr;\n mgr.on(\"rawSpatialData\", this.spatialHandler);\n mgr.on(\"stateChange\", this.stateHandler);\n this.els.state.textContent = mgr.state;\n this.els.protocol.textContent = mgr.protocol !== \"none\" ? mgr.protocol : \"\";\n }\n\n private unbind(): void {\n if (this.manager) {\n this.manager.off(\"rawSpatialData\", this.spatialHandler);\n this.manager.off(\"stateChange\", this.stateHandler);\n this.manager = null;\n }\n }\n}\n\ncustomElements.define(\"satmouse-debug\", SatMouseDebug);\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/elements/registry.ts","../../src/elements/locale.ts","../../src/elements/satmouse-status.ts","../../src/elements/satmouse-devices.ts","../../src/elements/satmouse-debug.ts"],"names":["current","TEMPLATE"],"mappings":"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","file":"index.js","sourcesContent":["import type { InputManager } from \"../utils/input-manager.js\";\n\n/**\n * Global registry for SatMouse Web Components.\n *\n * Usage:\n * import { registerSatMouse } from \"@kelnishi/satmouse-client/elements\";\n * registerSatMouse(manager);\n * // All <satmouse-*> elements auto-connect to this manager\n */\n\nlet globalManager: InputManager | null = null;\nconst listeners = new Set<(m: InputManager) => void>();\n\nexport function registerSatMouse(manager: InputManager): void {\n globalManager = manager;\n for (const fn of listeners) fn(manager);\n listeners.clear();\n}\n\nexport function getManager(): InputManager | null {\n return globalManager;\n}\n\nexport function onManagerReady(fn: (m: InputManager) => void): void {\n if (globalManager) fn(globalManager);\n else listeners.add(fn);\n}\n\n/** Subscribe to manager availability. Calls fn immediately if already available.\n * Returns an unsubscribe function (for disconnectedCallback). */\nexport function onManager(fn: (m: InputManager) => void): () => void {\n if (globalManager) fn(globalManager);\n else listeners.add(fn);\n return () => listeners.delete(fn);\n}\n","/** All localizable strings used by SatMouse Web Components. */\nexport interface SatMouseLocale {\n // satmouse-status\n connected: string;\n connecting: string;\n disconnected: string;\n notRunning: string;\n extensionRequired: string;\n launchSatMouse: string;\n downloadSatMouse: string;\n enableExtension: string;\n\n // satmouse-devices\n noDevices: string;\n flip: string;\n translateScale: string;\n rotateScale: string;\n wScale: string;\n buttonMappings: string;\n remapKey: string;\n pressAKey: string;\n remove: string;\n addButtonMapping: string;\n pressDeviceButton: string;\n restoreDefaults: string;\n\n // satmouse-debug\n fps: string;\n}\n\n/** Default English strings. Exported so implementors can iterate keys for translation tooling. */\nexport const DEFAULT_LOCALE: Readonly<SatMouseLocale> = {\n // satmouse-status\n connected: \"Connected\",\n connecting: \"Connecting...\",\n disconnected: \"Disconnected\",\n notRunning: \"Not running\",\n extensionRequired: \"Extension required\",\n launchSatMouse: \"Launch SatMouse\",\n downloadSatMouse: \"Download SatMouse\",\n enableExtension: \"Enable Extension\",\n\n // satmouse-devices\n noDevices: \"No devices\",\n flip: \"Flip\",\n translateScale: \"Trans\",\n rotateScale: \"Rot\",\n wScale: \"W\",\n buttonMappings: \"Button Mappings\",\n remapKey: \"Remap key\",\n pressAKey: \"Press a key...\",\n remove: \"Remove\",\n addButtonMapping: \"+ Add Button Mapping\",\n pressDeviceButton: \"Press a device button...\",\n restoreDefaults: \"Restore Defaults\",\n\n // satmouse-debug\n fps: \"fps\",\n};\n\nlet current: SatMouseLocale = { ...DEFAULT_LOCALE };\n\n/** Override some or all UI strings. Partial updates merge with the current locale. */\nexport function setLocale(overrides: Partial<SatMouseLocale>): void {\n current = { ...current, ...overrides };\n}\n\n/** Get the current locale strings. */\nexport function getLocale(): Readonly<SatMouseLocale> {\n return current;\n}\n\n/** Read a single string by key. Used internally by components. */\nexport function t(key: keyof SatMouseLocale): string {\n return current[key];\n}\n","import { onManager } from \"./registry.js\";\nimport { t } from \"./locale.js\";\nimport type { InputManager } from \"../utils/input-manager.js\";\nimport type { ConnectionState, TransportProtocol } from \"../core/types.js\";\n\nconst TEMPLATE = `\n<style>\n :host { display: inline-flex; align-items: center; gap: 8px; font-family: inherit; font-size: 13px; }\n .dot { width: 8px; height: 8px; border-radius: 50%; background: #e74c3c; transition: background 0.3s; }\n .dot[data-state=\"connected\"] { background: #2ecc71; }\n .dot[data-state=\"connecting\"] { background: #f39c12; }\n .dot[data-state=\"failed\"] { background: #e74c3c; }\n .protocol { color: #7f8c8d; font-size: 11px; text-transform: uppercase; letter-spacing: 1px; }\n .launch { padding: 4px 12px; background: #2980b9; color: #fff; border-radius: 4px; font-size: 11px;\n text-decoration: none; cursor: pointer; border: none; font-family: inherit; display: none; }\n .launch:hover { background: #3498db; }\n\n</style>\n<span class=\"dot\"></span>\n<span class=\"text\"></span>\n<span class=\"protocol\"></span>\n<button class=\"launch\"></button>\n`;\n\nexport class SatMouseStatus extends HTMLElement {\n private dot!: HTMLElement;\n private text!: HTMLElement;\n private proto!: HTMLElement;\n private launch!: HTMLButtonElement;\n private manager: InputManager | null = null;\n private unsub: (() => void) | null = null;\n private pollTimer: ReturnType<typeof setInterval> | null = null;\n\n private stateHandler = (state: ConnectionState, protocol: TransportProtocol) => this.update(state, protocol);\n\n constructor() {\n super();\n const shadow = this.attachShadow({ mode: \"open\" });\n shadow.innerHTML = TEMPLATE;\n this.dot = shadow.querySelector(\".dot\")!;\n this.text = shadow.querySelector(\".text\")!;\n this.proto = shadow.querySelector(\".protocol\")!;\n this.launch = shadow.querySelector(\".launch\")!;\n this.text.textContent = t(\"disconnected\");\n this.launch.textContent = t(\"launchSatMouse\");\n\n this.launch.addEventListener(\"click\", () => {\n this.startLaunchFlow();\n });\n }\n\n connectedCallback() {\n this.unsub = onManager((mgr) => this.bind(mgr));\n // Reset button state on remount\n this.stopPoll();\n this.launch.disabled = false;\n this.launch.textContent = t(\"launchSatMouse\");\n }\n\n disconnectedCallback() {\n this.stopPoll();\n this.unsub?.();\n this.unbind();\n }\n\n private bind(mgr: InputManager): void {\n this.unbind();\n this.manager = mgr;\n mgr.on(\"stateChange\", this.stateHandler);\n this.update(mgr.state, mgr.protocol);\n }\n\n private unbind(): void {\n this.manager?.off(\"stateChange\", this.stateHandler);\n this.manager = null;\n }\n\n private update(state: ConnectionState, protocol: TransportProtocol): void {\n this.dot.dataset.state = state;\n this.proto.textContent = protocol !== \"none\" ? protocol : \"\";\n\n if (state === \"connected\") {\n this.stopPoll();\n this.showDownload = false;\n this.text.textContent = t(\"connected\");\n this.launch.style.display = \"none\";\n } else if (state === \"connecting\") {\n this.text.textContent = t(\"connecting\");\n this.launch.style.display = \"none\";\n } else if (state === \"failed\") {\n // Detect Safari without extension — suggest enabling it\n const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);\n const hasExtension = !!(globalThis as any).__satmouseExtensionAvailable;\n if (isSafari && !hasExtension) {\n this.text.textContent = t(\"extensionRequired\");\n this.launch.style.display = \"inline-block\";\n this.launch.disabled = false;\n this.launch.textContent = t(\"enableExtension\");\n this.showDownload = false;\n this.needsExtension = true;\n } else {\n this.text.textContent = t(\"notRunning\");\n this.launch.style.display = \"inline-block\";\n this.launch.disabled = false;\n this.launch.textContent = this.showDownload ? t(\"downloadSatMouse\") : t(\"launchSatMouse\");\n this.needsExtension = false;\n }\n } else {\n this.text.textContent = t(\"disconnected\");\n this.launch.style.display = \"none\";\n }\n }\n\n private showDownload = false;\n private needsExtension = false;\n\n private startLaunchFlow(): void {\n if (this.needsExtension) {\n // Open Safari extension preferences via the bridge's URL scheme\n window.location.href = \"satmouse://enable-extension\";\n // Retry connection after user enables the extension\n this.launch.textContent = t(\"connecting\");\n this.launch.disabled = true;\n this.stopPoll();\n this.pollTimer = setInterval(() => {\n if (this.manager?.state === \"connected\") { this.stopPoll(); return; }\n this.manager?.retry();\n }, 2000);\n // Give up after 30s\n setTimeout(() => { this.stopPoll(); this.launch.disabled = false; this.launch.textContent = t(\"enableExtension\"); }, 30000);\n return;\n }\n\n if (this.showDownload) {\n window.location.href = \"https://github.com/kelnishi/SatMouse/releases/latest\";\n return;\n }\n\n this.launch.textContent = t(\"connecting\");\n this.launch.disabled = true;\n\n this.manager?.retry();\n window.location.href = \"satmouse://launch\";\n\n let attempts = 0;\n this.stopPoll();\n this.pollTimer = setInterval(() => {\n attempts++;\n if (this.manager?.state === \"connected\") {\n this.stopPoll();\n this.showDownload = false;\n return;\n }\n if (attempts >= 5) {\n this.stopPoll();\n this.showDownload = true;\n this.launch.disabled = false;\n this.launch.textContent = t(\"downloadSatMouse\");\n return;\n }\n this.manager?.retry();\n }, 1500);\n }\n\n private stopPoll(): void {\n if (this.pollTimer) {\n clearInterval(this.pollTimer);\n this.pollTimer = null;\n }\n }\n}\n\ncustomElements.define(\"satmouse-status\", SatMouseStatus);\n","import { onManager } from \"./registry.js\";\nimport { t } from \"./locale.js\";\nimport type { InputManager } from \"../utils/input-manager.js\";\nimport type { DeviceInfo } from \"../core/types.js\";\nimport type { InputAxis, AxisRoute } from \"../utils/action-map.js\";\nimport type { ButtonRoute } from \"../utils/config.js\";\nimport type { ButtonEvent } from \"../core/types.js\";\nimport { FULL_AXES, buildRoutes, DEFAULT_ROUTES } from \"../utils/action-map.js\";\n\nconst STYLES = `\n<style>\n :host { display: block; font-family: inherit; font-size: 12px; }\n .panel { background: #0f3460; border: 1px solid #1a4a8a; border-radius: 6px; padding: 10px; margin-bottom: 8px; }\n summary { cursor: pointer; font-weight: 600; color: #e0e0e0; font-size: 13px; }\n .type { font-size: 10px; color: #7f8c8d; text-transform: uppercase; margin-left: 6px; }\n .controls { margin-top: 8px; display: flex; flex-direction: column; gap: 6px; }\n .slider-row { display: flex; align-items: center; gap: 6px; }\n .slider-row label { color: #7f8c8d; font-weight: 600; width: 38px; flex-shrink: 0; }\n .slider-row input[type=\"range\"] { flex: 1; min-width: 0; height: 4px; accent-color: #3498db; }\n .slider-row span { color: #7f8c8d; font-family: monospace; font-size: 10px; min-width: 44px; text-align: right; }\n .route-group { display: flex; flex-wrap: wrap; gap: 4px 12px; }\n .route-row { display: flex; gap: 4px; align-items: center; }\n .route-row label { color: #7f8c8d; white-space: nowrap; }\n .route-row select { background: #16213e; color: #e0e0e0; border: 1px solid #1a4a8a; border-radius: 3px;\n font-size: 11px; padding: 1px 4px; }\n .route-row input[type=\"checkbox\"] { accent-color: #e74c3c; margin: 0; }\n .empty { color: #7f8c8d; font-style: italic; }\n .reset-btn { background: none; border: 1px solid #1a4a8a; border-radius: 3px; color: #7f8c8d;\n font-size: 11px; padding: 3px 8px; cursor: pointer; margin-top: 4px; }\n .reset-btn:hover { color: #e0e0e0; border-color: #e74c3c; }\n .btn-section { display: flex; flex-direction: column; gap: 4px; }\n .btn-section-label { color: #7f8c8d; font-weight: 600; font-size: 10px; text-transform: uppercase; letter-spacing: 0.5px; }\n .btn-route { display: flex; gap: 6px; align-items: center; font-size: 11px; }\n .btn-route .btn-idx { color: #7f8c8d; font-family: monospace; min-width: 32px; }\n .btn-route .btn-arrow { color: #7f8c8d; }\n .btn-route .btn-key { color: #3498db; font-family: monospace; }\n .btn-route .btn-remove { cursor: pointer; color: #e74c3c; background: none; border: none;\n font-size: 11px; padding: 0 2px; font-family: inherit; }\n .btn-route .btn-remove:hover { color: #ff6b6b; }\n .btn-add { background: none; border: 1px dashed #1a4a8a; border-radius: 3px; color: #7f8c8d;\n font-size: 11px; padding: 4px 8px; cursor: pointer; font-family: inherit; }\n .btn-add:hover { color: #e0e0e0; border-color: #3498db; }\n .btn-add.listening { color: #f39c12; border-color: #f39c12; border-style: solid; cursor: default; }\n</style>\n`;\n\nfunction mapSlider(v: number): number { return 0.0001 * Math.pow(500, v / 100); }\nfunction unmapSlider(v: number): number { return (100 * Math.log(v / 0.0001)) / Math.log(500); }\n\nexport class SatMouseDevices extends HTMLElement {\n private manager: InputManager | null = null;\n private container!: HTMLElement;\n\n constructor() {\n super();\n const shadow = this.attachShadow({ mode: \"open\" });\n shadow.innerHTML = STYLES + `<div class=\"container\"><span class=\"empty\">No devices</span></div>`;\n this.container = shadow.querySelector(\".container\")!;\n }\n\n private unsub: (() => void) | null = null;\n\n private deviceStatusHandler = (event: \"connected\" | \"disconnected\", device: DeviceInfo) => {\n if (event === \"connected\") this.addDevice(device);\n else this.removeDevice(device);\n };\n\n private stateHandler = (state: string) => {\n if (state === \"connected\") {\n this.manager?.fetchDeviceInfo().then((devices) => devices.forEach((d) => this.addDevice(d)));\n }\n };\n\n connectedCallback() {\n this.unsub = onManager((mgr) => this.bind(mgr));\n }\n\n disconnectedCallback() {\n this.unsub?.();\n this.unbind();\n this.container.innerHTML = `<span class=\"empty\">${t(\"noDevices\")}</span>`;\n }\n\n private bind(mgr: InputManager): void {\n this.unbind();\n this.manager = mgr;\n mgr.on(\"deviceStatus\", this.deviceStatusHandler);\n mgr.on(\"stateChange\", this.stateHandler);\n if (mgr.state === \"connected\") {\n mgr.fetchDeviceInfo().then((devices) => devices.forEach((d) => this.addDevice(d)));\n }\n }\n\n private unbind(): void {\n if (this.manager) {\n this.manager.off(\"deviceStatus\", this.deviceStatusHandler);\n this.manager.off(\"stateChange\", this.stateHandler);\n this.manager = null;\n }\n }\n\n private addDevice(device: DeviceInfo): void {\n const existing = this.shadowRoot!.getElementById(`dev-${device.id}`);\n if (existing) {\n this.refreshControls(existing as HTMLDetailsElement, device);\n return;\n }\n const empty = this.container.querySelector(\".empty\");\n if (empty) empty.remove();\n\n const panel = document.createElement(\"details\");\n panel.className = \"panel\";\n panel.id = `dev-${device.id}`;\n panel.open = true;\n\n const summary = document.createElement(\"summary\");\n summary.innerHTML = `${device.model ?? device.name}<span class=\"type\">${device.connectionType ?? \"\"}</span>`;\n panel.appendChild(summary);\n\n this.refreshControls(panel, device);\n this.container.appendChild(panel);\n }\n\n private refreshControls(panel: HTMLDetailsElement, device: DeviceInfo): void {\n const old = panel.querySelector(\".controls\");\n if (old) old.remove();\n\n const mgr = this.manager!;\n const cfg = mgr.getDeviceConfig(device.id);\n\n const controls = document.createElement(\"div\");\n controls.className = \"controls\";\n\n // Axis routes — one row per device input: [flip] [label] → [target dropdown] [scale slider]\n const routeGroup = document.createElement(\"div\");\n routeGroup.className = \"route-group\";\n const deviceAxes = device.axes ?? [\"tx\", \"ty\", \"tz\", \"rx\", \"ry\", \"rz\"];\n const routes = this.getRoutes(device, deviceAxes);\n\n for (let i = 0; i < deviceAxes.length; i++) {\n const route = routes[i] ?? { source: deviceAxes[i] as InputAxis, target: deviceAxes[i].replace(/[+-]$/, \"\") as InputAxis };\n const row = document.createElement(\"div\");\n row.className = \"route-row\";\n\n // Flip checkbox\n const cb = document.createElement(\"input\");\n cb.type = \"checkbox\";\n cb.checked = route.flip ?? false;\n cb.title = t(\"flip\");\n const routeIndex = i;\n cb.addEventListener(\"change\", () => {\n this.updateRoute(device.id, routeIndex, deviceAxes, { flip: cb.checked });\n });\n row.appendChild(cb);\n\n // Label (device input name)\n const label = document.createElement(\"label\");\n label.textContent = device.axisLabels?.[i] ?? deviceAxes[i].toUpperCase();\n row.appendChild(label);\n\n // Target dropdown\n const sel = document.createElement(\"select\");\n for (const target of FULL_AXES) {\n const opt = document.createElement(\"option\");\n opt.value = target;\n opt.textContent = target.toUpperCase();\n if (target === route.target) opt.selected = true;\n sel.appendChild(opt);\n }\n sel.addEventListener(\"change\", () => {\n this.updateRoute(device.id, routeIndex, deviceAxes, { target: sel.value as InputAxis });\n });\n row.appendChild(sel);\n\n routeGroup.appendChild(row);\n }\n controls.appendChild(routeGroup);\n\n // Scale sliders\n for (const [label, key, globalKey] of [\n [t(\"translateScale\"), \"translateScale\", \"translateScale\"],\n [t(\"rotateScale\"), \"rotateScale\", \"rotateScale\"],\n [t(\"wScale\"), \"wScale\", \"wScale\"],\n ] as const) {\n const row = document.createElement(\"div\");\n row.className = \"slider-row\";\n const val = (cfg as any)[key] ?? (mgr.config as any)[globalKey];\n row.innerHTML = `<label>${label}</label>` +\n `<input type=\"range\" min=\"0\" max=\"100\" value=\"${Math.round(unmapSlider(val))}\">` +\n `<span>${val.toFixed(4)}</span>`;\n const sl = row.querySelector(\"input\")! as HTMLInputElement;\n const sp = row.querySelector(\"span\")!;\n sl.addEventListener(\"input\", () => {\n const v = mapSlider(+sl.value);\n sp.textContent = v.toFixed(4);\n mgr.updateDeviceConfig(device.id, { [key]: v });\n });\n controls.appendChild(row);\n }\n\n // Button mappings\n const btnSection = document.createElement(\"div\");\n btnSection.className = \"btn-section\";\n const btnLabel = document.createElement(\"div\");\n btnLabel.className = \"btn-section-label\";\n btnLabel.textContent = t(\"buttonMappings\");\n btnSection.appendChild(btnLabel);\n\n const buttonRoutes: ButtonRoute[] = cfg.buttonRoutes ?? [];\n const labels = device.buttonLabels ?? [];\n for (let i = 0; i < buttonRoutes.length; i++) {\n const route = buttonRoutes[i];\n const btnName = labels[route.button] ?? `Btn ${route.button}`;\n const row = document.createElement(\"div\");\n row.className = \"btn-route\";\n\n const idxSpan = document.createElement(\"span\");\n idxSpan.className = \"btn-idx\";\n idxSpan.textContent = btnName;\n row.appendChild(idxSpan);\n\n const arrow = document.createElement(\"span\");\n arrow.className = \"btn-arrow\";\n arrow.textContent = \"\\u2192\";\n row.appendChild(arrow);\n\n const keySpan = document.createElement(\"span\");\n keySpan.className = \"btn-key\";\n keySpan.textContent = route.key;\n row.appendChild(keySpan);\n\n // Edit — re-listen for a new key\n const editBtn = document.createElement(\"button\");\n editBtn.className = \"btn-remove\";\n editBtn.textContent = \"\\u270E\";\n editBtn.title = t(\"remapKey\");\n const routeIdx = i;\n editBtn.addEventListener(\"click\", () => {\n keySpan.textContent = t(\"pressAKey\");\n keySpan.style.color = \"#f39c12\";\n const onKey = (e: KeyboardEvent) => {\n e.preventDefault();\n e.stopPropagation();\n document.removeEventListener(\"keydown\", onKey, true);\n const current = mgr.getDeviceConfig(device.id).buttonRoutes ?? [];\n const updated = current.map((r: ButtonRoute, j: number) =>\n j === routeIdx ? { ...r, key: e.key, code: e.code } : r\n );\n mgr.updateDeviceConfig(device.id, { buttonRoutes: updated });\n this.refreshControls(panel, device);\n };\n document.addEventListener(\"keydown\", onKey, true);\n });\n row.appendChild(editBtn);\n\n // Delete\n const removeBtn = document.createElement(\"button\");\n removeBtn.className = \"btn-remove\";\n removeBtn.textContent = \"\\u00d7\";\n removeBtn.title = t(\"remove\");\n removeBtn.addEventListener(\"click\", () => {\n const current = mgr.getDeviceConfig(device.id).buttonRoutes ?? [];\n const updated = current.filter((_: ButtonRoute, j: number) => j !== routeIdx);\n mgr.updateDeviceConfig(device.id, { buttonRoutes: updated });\n this.refreshControls(panel, device);\n });\n row.appendChild(removeBtn);\n btnSection.appendChild(row);\n }\n\n // Add mapping button with listen flow\n const addBtn = document.createElement(\"button\");\n addBtn.className = \"btn-add\";\n addBtn.textContent = t(\"addButtonMapping\");\n addBtn.addEventListener(\"click\", () => {\n if (addBtn.classList.contains(\"listening\")) return;\n this.startButtonListen(addBtn, mgr, device, panel);\n });\n btnSection.appendChild(addBtn);\n controls.appendChild(btnSection);\n\n // Reset button\n const resetBtn = document.createElement(\"button\");\n resetBtn.className = \"reset-btn\";\n resetBtn.textContent = t(\"restoreDefaults\");\n resetBtn.addEventListener(\"click\", () => {\n mgr.resetDeviceConfig(device.id);\n this.refreshControls(panel, device);\n });\n controls.appendChild(resetBtn);\n\n panel.appendChild(controls);\n }\n\n private getRoutes(device: DeviceInfo, deviceAxes: string[]): AxisRoute[] {\n const mgr = this.manager!;\n\n // 1. Exact device ID\n const devCfg = mgr.config.devices[device.id];\n if (devCfg?.routes && Array.isArray(devCfg.routes)) return devCfg.routes;\n\n // 2. Pattern match\n for (const [pattern, cfg] of Object.entries(mgr.config.devices)) {\n if (pattern.endsWith(\"*\") && device.id.startsWith(pattern.slice(0, -1))) {\n if (cfg.routes && Array.isArray(cfg.routes)) return cfg.routes;\n }\n }\n\n // 3. Device class defaults\n if (device.deviceClass && mgr.config.deviceClasses) {\n const classCfg = mgr.config.deviceClasses[device.deviceClass];\n if (classCfg?.routes && Array.isArray(classCfg.routes)) return classCfg.routes;\n }\n\n // 4. Build from device axes metadata\n return buildRoutes(deviceAxes);\n }\n\n private updateRoute(deviceId: string, index: number, deviceAxes: string[], patch: Partial<AxisRoute>): void {\n const device = Array.from(this.manager!.getDevicesWithConfig()).find(d => d.device.id === deviceId)?.device;\n const base = this.getRoutes(device ?? { id: deviceId } as DeviceInfo, deviceAxes);\n const updated = base.map((r, j) => j === index ? { ...r, ...patch } : { ...r });\n this.manager!.updateDeviceConfig(deviceId, { routes: updated });\n }\n\n private startButtonListen(\n btn: HTMLButtonElement,\n mgr: InputManager,\n device: DeviceInfo,\n panel: HTMLDetailsElement,\n ): void {\n btn.classList.add(\"listening\");\n btn.textContent = t(\"pressDeviceButton\");\n\n // Step 1: Listen for device button\n const onButton = (event: ButtonEvent) => {\n if (!event.pressed) return; // only on press, not release\n mgr.off(\"buttonEvent\", onButton);\n\n const capturedButton = event.button;\n btn.textContent = `Btn ${capturedButton} \\u2192 ${t(\"pressAKey\")}`;\n\n // Step 2: Listen for keyboard key\n const onKey = (e: KeyboardEvent) => {\n e.preventDefault();\n e.stopPropagation();\n document.removeEventListener(\"keydown\", onKey, true);\n\n const route: ButtonRoute = {\n button: capturedButton,\n key: e.key,\n code: e.code,\n };\n\n const current = mgr.getDeviceConfig(device.id).buttonRoutes ?? [];\n // Replace existing mapping for the same button, or add new\n const updated = current.filter((r: ButtonRoute) => r.button !== capturedButton);\n updated.push(route);\n mgr.updateDeviceConfig(device.id, { buttonRoutes: updated });\n this.refreshControls(panel, device);\n };\n document.addEventListener(\"keydown\", onKey, true);\n };\n mgr.on(\"buttonEvent\", onButton);\n\n // Cancel on Escape (before a button is pressed)\n const onCancel = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") {\n mgr.off(\"buttonEvent\", onButton);\n document.removeEventListener(\"keydown\", onCancel, true);\n btn.classList.remove(\"listening\");\n btn.textContent = t(\"addButtonMapping\");\n }\n };\n document.addEventListener(\"keydown\", onCancel, true);\n }\n\n private removeDevice(device: DeviceInfo): void {\n this.shadowRoot!.getElementById(`dev-${device.id}`)?.remove();\n if (this.container.children.length === 0) {\n this.container.innerHTML = `<span class=\"empty\">${t(\"noDevices\")}</span>`;\n }\n }\n}\n\ncustomElements.define(\"satmouse-devices\", SatMouseDevices);\n","import { onManager } from \"./registry.js\";\nimport { t } from \"./locale.js\";\nimport type { InputManager } from \"../utils/input-manager.js\";\nimport type { SpatialData, ConnectionState, TransportProtocol } from \"../core/types.js\";\n\nconst TEMPLATE = `\n<style>\n :host { display: block; font-family: monospace; font-size: 12px; }\n .row { display: flex; justify-content: space-between; padding: 2px 0; }\n .label { color: #7f8c8d; font-weight: 600; width: 28px; }\n .value { color: #3498db; text-align: right; min-width: 50px; }\n .meta { color: #7f8c8d; font-size: 11px; padding: 2px 0; }\n</style>\n<div class=\"meta\"><span class=\"state\"></span> · <span class=\"protocol\"></span> · <span class=\"fps\">0</span> <span class=\"fps-label\"></span></div>\n<div class=\"row\"><span class=\"label\">TX</span><span class=\"value\" id=\"tx\">0</span></div>\n<div class=\"row\"><span class=\"label\">TY</span><span class=\"value\" id=\"ty\">0</span></div>\n<div class=\"row\"><span class=\"label\">TZ</span><span class=\"value\" id=\"tz\">0</span></div>\n<div class=\"row\"><span class=\"label\">RX</span><span class=\"value\" id=\"rx\">0</span></div>\n<div class=\"row\"><span class=\"label\">RY</span><span class=\"value\" id=\"ry\">0</span></div>\n<div class=\"row\"><span class=\"label\">RZ</span><span class=\"value\" id=\"rz\">0</span></div>\n`;\n\nexport class SatMouseDebug extends HTMLElement {\n private els: Record<string, HTMLElement> = {};\n private frameCount = 0;\n private fpsInterval: ReturnType<typeof setInterval> | null = null;\n private manager: InputManager | null = null;\n private unsub: (() => void) | null = null;\n\n private spatialHandler = (data: SpatialData) => {\n this.frameCount++;\n this.els.tx.textContent = String(Math.round(data.translation.x));\n this.els.ty.textContent = String(Math.round(data.translation.y));\n this.els.tz.textContent = String(Math.round(data.translation.z));\n this.els.rx.textContent = String(Math.round(data.rotation.x));\n this.els.ry.textContent = String(Math.round(data.rotation.y));\n this.els.rz.textContent = String(Math.round(data.rotation.z));\n };\n\n private stateHandler = (state: ConnectionState, protocol: TransportProtocol) => {\n this.els.state.textContent = state;\n this.els.protocol.textContent = protocol !== \"none\" ? protocol : \"\";\n };\n\n constructor() {\n super();\n const shadow = this.attachShadow({ mode: \"open\" });\n shadow.innerHTML = TEMPLATE;\n for (const id of [\"tx\", \"ty\", \"tz\", \"rx\", \"ry\", \"rz\"]) {\n this.els[id] = shadow.getElementById(id)!;\n }\n this.els.state = shadow.querySelector(\".state\")!;\n this.els.protocol = shadow.querySelector(\".protocol\")!;\n this.els.fps = shadow.querySelector(\".fps\")!;\n this.els.state.textContent = t(\"disconnected\");\n shadow.querySelector(\".fps-label\")!.textContent = t(\"fps\");\n }\n\n connectedCallback() {\n this.unsub = onManager((mgr) => this.bind(mgr));\n this.fpsInterval = setInterval(() => {\n this.els.fps.textContent = String(this.frameCount);\n this.frameCount = 0;\n }, 1000);\n }\n\n disconnectedCallback() {\n this.unsub?.();\n this.unbind();\n if (this.fpsInterval) {\n clearInterval(this.fpsInterval);\n this.fpsInterval = null;\n }\n }\n\n private bind(mgr: InputManager): void {\n this.unbind();\n this.manager = mgr;\n mgr.on(\"rawSpatialData\", this.spatialHandler);\n mgr.on(\"stateChange\", this.stateHandler);\n this.els.state.textContent = mgr.state;\n this.els.protocol.textContent = mgr.protocol !== \"none\" ? mgr.protocol : \"\";\n }\n\n private unbind(): void {\n if (this.manager) {\n this.manager.off(\"rawSpatialData\", this.spatialHandler);\n this.manager.off(\"stateChange\", this.stateHandler);\n this.manager = null;\n }\n }\n}\n\ncustomElements.define(\"satmouse-debug\", SatMouseDebug);\n"]}
|
package/dist/react/index.cjs
CHANGED
|
@@ -263,6 +263,7 @@ var ExtensionAdapter = class {
|
|
|
263
263
|
onClose = null;
|
|
264
264
|
onError = null;
|
|
265
265
|
messageHandler = null;
|
|
266
|
+
pendingDeviceFetch = null;
|
|
266
267
|
static isAvailable() {
|
|
267
268
|
return !!globalThis.__satmouseExtensionAvailable;
|
|
268
269
|
}
|
|
@@ -294,11 +295,27 @@ var ExtensionAdapter = class {
|
|
|
294
295
|
if (msg.type === "deviceStatus" && msg.data) {
|
|
295
296
|
this.onDeviceStatus?.(msg.data.event, msg.data.device);
|
|
296
297
|
}
|
|
298
|
+
if (msg.type === "deviceList" && this.pendingDeviceFetch) {
|
|
299
|
+
this.pendingDeviceFetch(Array.isArray(msg.data) ? msg.data : []);
|
|
300
|
+
this.pendingDeviceFetch = null;
|
|
301
|
+
}
|
|
297
302
|
};
|
|
298
303
|
globalThis.addEventListener("message", this.messageHandler);
|
|
299
304
|
globalThis.postMessage({ target: "satmouse-extension", action: "connect" }, "*");
|
|
300
305
|
});
|
|
301
306
|
}
|
|
307
|
+
fetchDeviceInfo() {
|
|
308
|
+
return new Promise((resolve) => {
|
|
309
|
+
this.pendingDeviceFetch = resolve;
|
|
310
|
+
globalThis.postMessage({ target: "satmouse-extension", action: "fetchDevices" }, "*");
|
|
311
|
+
setTimeout(() => {
|
|
312
|
+
if (this.pendingDeviceFetch) {
|
|
313
|
+
this.pendingDeviceFetch = null;
|
|
314
|
+
resolve([]);
|
|
315
|
+
}
|
|
316
|
+
}, 3e3);
|
|
317
|
+
});
|
|
318
|
+
}
|
|
302
319
|
close() {
|
|
303
320
|
if (this.messageHandler) {
|
|
304
321
|
globalThis.removeEventListener("message", this.messageHandler);
|
|
@@ -428,11 +445,20 @@ var SatMouseConnection = class extends TypedEmitter {
|
|
|
428
445
|
this.setState("disconnected", "none");
|
|
429
446
|
}
|
|
430
447
|
async fetchDeviceInfo() {
|
|
431
|
-
if (
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
448
|
+
if (this.deviceInfoUrl) {
|
|
449
|
+
try {
|
|
450
|
+
const res = await globalThis.fetch(this.deviceInfoUrl);
|
|
451
|
+
if (res.ok) {
|
|
452
|
+
const data = await res.json();
|
|
453
|
+
return data.devices ?? [];
|
|
454
|
+
}
|
|
455
|
+
} catch {
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
if (this.transport && "fetchDeviceInfo" in this.transport) {
|
|
459
|
+
return this.transport.fetchDeviceInfo();
|
|
460
|
+
}
|
|
461
|
+
return [];
|
|
436
462
|
}
|
|
437
463
|
async tryTransport(adapter) {
|
|
438
464
|
adapter.onSpatialData = (data) => this.emit("spatialData", data);
|