@kelnishi/satmouse-client 0.10.9 → 0.12.3
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/{chunk-RNM322RZ.js → chunk-RE4PNORY.js} +18 -11
- package/dist/chunk-RE4PNORY.js.map +1 -0
- package/dist/{chunk-JTG5GEIB.cjs → chunk-Y75556IA.cjs} +18 -11
- package/dist/chunk-Y75556IA.cjs.map +1 -0
- package/dist/{connection-DQxI5qib.d.cts → connection-iUlge6Er.d.cts} +9 -1
- package/dist/{connection-DQxI5qib.d.ts → connection-iUlge6Er.d.ts} +9 -1
- package/dist/core/index.d.cts +2 -2
- package/dist/core/index.d.ts +2 -2
- package/dist/elements/index.cjs +138 -14
- package/dist/elements/index.cjs.map +1 -1
- package/dist/elements/index.d.cts +2 -1
- package/dist/elements/index.d.ts +2 -1
- package/dist/elements/index.js +136 -12
- package/dist/elements/index.js.map +1 -1
- package/dist/react/index.cjs +59 -15
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.js +59 -15
- package/dist/react/index.js.map +1 -1
- package/dist/utils/index.cjs +52 -15
- package/dist/utils/index.cjs.map +1 -1
- package/dist/utils/index.d.cts +35 -11
- package/dist/utils/index.d.ts +35 -11
- package/dist/utils/index.js +46 -9
- package/dist/utils/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-JTG5GEIB.cjs.map +0 -1
- package/dist/chunk-RNM322RZ.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/utils/action-map.ts
|
|
2
|
-
var FULL_AXES = ["tx", "ty", "tz", "rx", "ry", "rz"];
|
|
2
|
+
var FULL_AXES = ["tx", "ty", "tz", "rx", "ry", "rz", "w"];
|
|
3
3
|
var DEFAULT_ROUTES = [
|
|
4
4
|
{ source: "tx", target: "tx" },
|
|
5
5
|
{ source: "ty", target: "ty" },
|
|
@@ -30,31 +30,38 @@ function readAxis(data, axis) {
|
|
|
30
30
|
return data.rotation.y;
|
|
31
31
|
case "rz":
|
|
32
32
|
return data.rotation.z;
|
|
33
|
+
case "w":
|
|
34
|
+
return data.w ?? 0;
|
|
33
35
|
default:
|
|
34
36
|
return 0;
|
|
35
37
|
}
|
|
36
38
|
}
|
|
37
|
-
function writeAxis(
|
|
39
|
+
function writeAxis(acc, axis, value) {
|
|
38
40
|
const isNeg = axis.endsWith("-");
|
|
39
41
|
const base = axis.replace(/[+-]$/, "");
|
|
40
42
|
const sign = isNeg ? -1 : 1;
|
|
43
|
+
if (base === "w") {
|
|
44
|
+
acc.w += value * sign;
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
41
47
|
const group = base[0];
|
|
42
48
|
const key = base[1];
|
|
43
|
-
if (group === "t") t[key] += value * sign;
|
|
44
|
-
else r[key] += value * sign;
|
|
49
|
+
if (group === "t") acc.t[key] += value * sign;
|
|
50
|
+
else acc.r[key] += value * sign;
|
|
45
51
|
}
|
|
46
|
-
function applyRoutes(data, routes,
|
|
47
|
-
const
|
|
48
|
-
const r = { x: 0, y: 0, z: 0 };
|
|
52
|
+
function applyRoutes(data, routes, translateScale = 1, rotateScale = 1, wScale = 1) {
|
|
53
|
+
const acc = { t: { x: 0, y: 0, z: 0 }, r: { x: 0, y: 0, z: 0 }, w: 0 };
|
|
49
54
|
for (const route of routes) {
|
|
50
55
|
let value = readAxis(data, route.source);
|
|
51
56
|
if (route.flip) value = -value;
|
|
57
|
+
const targetBase = route.target.replace(/[+-]$/, "");
|
|
58
|
+
const scale = targetBase === "w" ? wScale : targetBase[0] === "t" ? translateScale : rotateScale;
|
|
52
59
|
value *= scale;
|
|
53
|
-
writeAxis(
|
|
60
|
+
writeAxis(acc, route.target, value);
|
|
54
61
|
}
|
|
55
|
-
return { translation: t, rotation: r, timestamp: data.timestamp, deviceId: data.deviceId };
|
|
62
|
+
return { translation: acc.t, rotation: acc.r, w: acc.w || void 0, timestamp: data.timestamp, deviceId: data.deviceId };
|
|
56
63
|
}
|
|
57
64
|
|
|
58
65
|
export { DEFAULT_ROUTES, FULL_AXES, applyRoutes, buildRoutes };
|
|
59
|
-
//# sourceMappingURL=chunk-
|
|
60
|
-
//# sourceMappingURL=chunk-
|
|
66
|
+
//# sourceMappingURL=chunk-RE4PNORY.js.map
|
|
67
|
+
//# sourceMappingURL=chunk-RE4PNORY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/action-map.ts"],"names":[],"mappings":"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","file":"chunk-RE4PNORY.js","sourcesContent":["import type { SpatialData } from \"../core/types.js\";\n\n/** Axis identifier — full or half */\nexport type InputAxis =\n | \"tx\" | \"ty\" | \"tz\" | \"rx\" | \"ry\" | \"rz\" | \"w\"\n | \"tx+\" | \"ty+\" | \"tz+\" | \"rx+\" | \"ry+\" | \"rz+\" | \"w+\"\n | \"tx-\" | \"ty-\" | \"tz-\" | \"rx-\" | \"ry-\" | \"rz-\" | \"w-\";\n\n/** The 7 full output axes (6DOF + W) */\nexport const FULL_AXES: InputAxis[] = [\"tx\", \"ty\", \"tz\", \"rx\", \"ry\", \"rz\", \"w\"];\n\n/** A single axis route — reads from source, writes to target */\nexport interface AxisRoute {\n source: InputAxis;\n target: InputAxis;\n /** Negate the value (default: false) */\n flip?: boolean;\n}\n\n/** Default 6DOF passthrough */\nexport const DEFAULT_ROUTES: AxisRoute[] = [\n { source: \"tx\", target: \"tx\" },\n { source: \"ty\", target: \"ty\" },\n { source: \"tz\", target: \"tz\" },\n { source: \"rx\", target: \"rx\" },\n { source: \"ry\", target: \"ry\" },\n { source: \"rz\", target: \"rz\" },\n];\n\n/** Build passthrough routes from a device's axis list. Half-axes target their base axis.\n * Negative half-axes (e.g., \"ty-\") get flip: true. */\nexport function buildRoutes(axes: string[]): AxisRoute[] {\n return axes.map((axis) => {\n const base = axis.replace(/[+-]$/, \"\");\n const flip = axis.endsWith(\"-\");\n return { source: axis as InputAxis, target: base as InputAxis, ...(flip && { flip: true }) };\n });\n}\n\n/** Read a value from SpatialData by axis name. Half-axes read the same as the full axis. */\nfunction readAxis(data: SpatialData, axis: InputAxis): number {\n const base = axis.replace(/[+-]$/, \"\");\n switch (base) {\n case \"tx\": return data.translation.x;\n case \"ty\": return data.translation.y;\n case \"tz\": return data.translation.z;\n case \"rx\": return data.rotation.x;\n case \"ry\": return data.rotation.y;\n case \"rz\": return data.rotation.z;\n case \"w\": return data.w ?? 0;\n default: return 0;\n }\n}\n\n/** Accumulator for applyRoutes */\ninterface RouteAccum {\n t: { x: number; y: number; z: number };\n r: { x: number; y: number; z: number };\n w: number;\n}\n\n/** Write a value to accumulators. Half-axis targets: \"tz+\" adds, \"tz-\" subtracts. */\nfunction writeAxis(acc: RouteAccum, axis: InputAxis, value: number): void {\n const isNeg = axis.endsWith(\"-\");\n const base = axis.replace(/[+-]$/, \"\");\n const sign = isNeg ? -1 : 1;\n if (base === \"w\") { acc.w += value * sign; return; }\n const group = base[0] as \"t\" | \"r\";\n const key = base[1] as \"x\" | \"y\" | \"z\";\n if (group === \"t\") acc.t[key] += value * sign;\n else acc.r[key] += value * sign;\n}\n\n/** Apply routes to SpatialData. Multiple routes targeting the same axis accumulate. */\nexport function applyRoutes(data: SpatialData, routes: AxisRoute[], translateScale = 1, rotateScale = 1, wScale = 1): SpatialData {\n const acc: RouteAccum = { t: { x: 0, y: 0, z: 0 }, r: { x: 0, y: 0, z: 0 }, w: 0 };\n\n for (const route of routes) {\n let value = readAxis(data, route.source);\n if (route.flip) value = -value;\n const targetBase = route.target.replace(/[+-]$/, \"\");\n const scale = targetBase === \"w\" ? wScale : targetBase[0] === \"t\" ? translateScale : rotateScale;\n value *= scale;\n writeAxis(acc, route.target, value);\n }\n\n return { translation: acc.t, rotation: acc.r, w: acc.w || undefined, timestamp: data.timestamp, deviceId: data.deviceId };\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
// src/utils/action-map.ts
|
|
4
|
-
var FULL_AXES = ["tx", "ty", "tz", "rx", "ry", "rz"];
|
|
4
|
+
var FULL_AXES = ["tx", "ty", "tz", "rx", "ry", "rz", "w"];
|
|
5
5
|
var DEFAULT_ROUTES = [
|
|
6
6
|
{ source: "tx", target: "tx" },
|
|
7
7
|
{ source: "ty", target: "ty" },
|
|
@@ -32,34 +32,41 @@ function readAxis(data, axis) {
|
|
|
32
32
|
return data.rotation.y;
|
|
33
33
|
case "rz":
|
|
34
34
|
return data.rotation.z;
|
|
35
|
+
case "w":
|
|
36
|
+
return data.w ?? 0;
|
|
35
37
|
default:
|
|
36
38
|
return 0;
|
|
37
39
|
}
|
|
38
40
|
}
|
|
39
|
-
function writeAxis(
|
|
41
|
+
function writeAxis(acc, axis, value) {
|
|
40
42
|
const isNeg = axis.endsWith("-");
|
|
41
43
|
const base = axis.replace(/[+-]$/, "");
|
|
42
44
|
const sign = isNeg ? -1 : 1;
|
|
45
|
+
if (base === "w") {
|
|
46
|
+
acc.w += value * sign;
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
43
49
|
const group = base[0];
|
|
44
50
|
const key = base[1];
|
|
45
|
-
if (group === "t") t[key] += value * sign;
|
|
46
|
-
else r[key] += value * sign;
|
|
51
|
+
if (group === "t") acc.t[key] += value * sign;
|
|
52
|
+
else acc.r[key] += value * sign;
|
|
47
53
|
}
|
|
48
|
-
function applyRoutes(data, routes,
|
|
49
|
-
const
|
|
50
|
-
const r = { x: 0, y: 0, z: 0 };
|
|
54
|
+
function applyRoutes(data, routes, translateScale = 1, rotateScale = 1, wScale = 1) {
|
|
55
|
+
const acc = { t: { x: 0, y: 0, z: 0 }, r: { x: 0, y: 0, z: 0 }, w: 0 };
|
|
51
56
|
for (const route of routes) {
|
|
52
57
|
let value = readAxis(data, route.source);
|
|
53
58
|
if (route.flip) value = -value;
|
|
59
|
+
const targetBase = route.target.replace(/[+-]$/, "");
|
|
60
|
+
const scale = targetBase === "w" ? wScale : targetBase[0] === "t" ? translateScale : rotateScale;
|
|
54
61
|
value *= scale;
|
|
55
|
-
writeAxis(
|
|
62
|
+
writeAxis(acc, route.target, value);
|
|
56
63
|
}
|
|
57
|
-
return { translation: t, rotation: r, timestamp: data.timestamp, deviceId: data.deviceId };
|
|
64
|
+
return { translation: acc.t, rotation: acc.r, w: acc.w || void 0, timestamp: data.timestamp, deviceId: data.deviceId };
|
|
58
65
|
}
|
|
59
66
|
|
|
60
67
|
exports.DEFAULT_ROUTES = DEFAULT_ROUTES;
|
|
61
68
|
exports.FULL_AXES = FULL_AXES;
|
|
62
69
|
exports.applyRoutes = applyRoutes;
|
|
63
70
|
exports.buildRoutes = buildRoutes;
|
|
64
|
-
//# sourceMappingURL=chunk-
|
|
65
|
-
//# sourceMappingURL=chunk-
|
|
71
|
+
//# sourceMappingURL=chunk-Y75556IA.cjs.map
|
|
72
|
+
//# sourceMappingURL=chunk-Y75556IA.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/action-map.ts"],"names":[],"mappings":"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","file":"chunk-Y75556IA.cjs","sourcesContent":["import type { SpatialData } from \"../core/types.js\";\n\n/** Axis identifier — full or half */\nexport type InputAxis =\n | \"tx\" | \"ty\" | \"tz\" | \"rx\" | \"ry\" | \"rz\" | \"w\"\n | \"tx+\" | \"ty+\" | \"tz+\" | \"rx+\" | \"ry+\" | \"rz+\" | \"w+\"\n | \"tx-\" | \"ty-\" | \"tz-\" | \"rx-\" | \"ry-\" | \"rz-\" | \"w-\";\n\n/** The 7 full output axes (6DOF + W) */\nexport const FULL_AXES: InputAxis[] = [\"tx\", \"ty\", \"tz\", \"rx\", \"ry\", \"rz\", \"w\"];\n\n/** A single axis route — reads from source, writes to target */\nexport interface AxisRoute {\n source: InputAxis;\n target: InputAxis;\n /** Negate the value (default: false) */\n flip?: boolean;\n}\n\n/** Default 6DOF passthrough */\nexport const DEFAULT_ROUTES: AxisRoute[] = [\n { source: \"tx\", target: \"tx\" },\n { source: \"ty\", target: \"ty\" },\n { source: \"tz\", target: \"tz\" },\n { source: \"rx\", target: \"rx\" },\n { source: \"ry\", target: \"ry\" },\n { source: \"rz\", target: \"rz\" },\n];\n\n/** Build passthrough routes from a device's axis list. Half-axes target their base axis.\n * Negative half-axes (e.g., \"ty-\") get flip: true. */\nexport function buildRoutes(axes: string[]): AxisRoute[] {\n return axes.map((axis) => {\n const base = axis.replace(/[+-]$/, \"\");\n const flip = axis.endsWith(\"-\");\n return { source: axis as InputAxis, target: base as InputAxis, ...(flip && { flip: true }) };\n });\n}\n\n/** Read a value from SpatialData by axis name. Half-axes read the same as the full axis. */\nfunction readAxis(data: SpatialData, axis: InputAxis): number {\n const base = axis.replace(/[+-]$/, \"\");\n switch (base) {\n case \"tx\": return data.translation.x;\n case \"ty\": return data.translation.y;\n case \"tz\": return data.translation.z;\n case \"rx\": return data.rotation.x;\n case \"ry\": return data.rotation.y;\n case \"rz\": return data.rotation.z;\n case \"w\": return data.w ?? 0;\n default: return 0;\n }\n}\n\n/** Accumulator for applyRoutes */\ninterface RouteAccum {\n t: { x: number; y: number; z: number };\n r: { x: number; y: number; z: number };\n w: number;\n}\n\n/** Write a value to accumulators. Half-axis targets: \"tz+\" adds, \"tz-\" subtracts. */\nfunction writeAxis(acc: RouteAccum, axis: InputAxis, value: number): void {\n const isNeg = axis.endsWith(\"-\");\n const base = axis.replace(/[+-]$/, \"\");\n const sign = isNeg ? -1 : 1;\n if (base === \"w\") { acc.w += value * sign; return; }\n const group = base[0] as \"t\" | \"r\";\n const key = base[1] as \"x\" | \"y\" | \"z\";\n if (group === \"t\") acc.t[key] += value * sign;\n else acc.r[key] += value * sign;\n}\n\n/** Apply routes to SpatialData. Multiple routes targeting the same axis accumulate. */\nexport function applyRoutes(data: SpatialData, routes: AxisRoute[], translateScale = 1, rotateScale = 1, wScale = 1): SpatialData {\n const acc: RouteAccum = { t: { x: 0, y: 0, z: 0 }, r: { x: 0, y: 0, z: 0 }, w: 0 };\n\n for (const route of routes) {\n let value = readAxis(data, route.source);\n if (route.flip) value = -value;\n const targetBase = route.target.replace(/[+-]$/, \"\");\n const scale = targetBase === \"w\" ? wScale : targetBase[0] === \"t\" ? translateScale : rotateScale;\n value *= scale;\n writeAxis(acc, route.target, value);\n }\n\n return { translation: acc.t, rotation: acc.r, w: acc.w || undefined, timestamp: data.timestamp, deviceId: data.deviceId };\n}\n"]}
|
|
@@ -12,10 +12,12 @@ interface Vec3 {
|
|
|
12
12
|
y: number;
|
|
13
13
|
z: number;
|
|
14
14
|
}
|
|
15
|
-
/** 6DOF spatial input frame
|
|
15
|
+
/** 6DOF+W spatial input frame */
|
|
16
16
|
interface SpatialData {
|
|
17
17
|
translation: Vec3;
|
|
18
18
|
rotation: Vec3;
|
|
19
|
+
/** Virtual W axis — application-defined (e.g., zoom, scroll, tool size) */
|
|
20
|
+
w?: number;
|
|
19
21
|
timestamp: number;
|
|
20
22
|
/** Source device ID (e.g., "cnx-c635", "hid-054c-5c4") */
|
|
21
23
|
deviceId?: string;
|
|
@@ -26,6 +28,8 @@ interface ButtonEvent {
|
|
|
26
28
|
pressed: boolean;
|
|
27
29
|
timestamp: number;
|
|
28
30
|
}
|
|
31
|
+
/** Device form factor */
|
|
32
|
+
type DeviceClass = "spacemouse" | "gamepad" | "dial" | "joystick" | "6dof" | "other";
|
|
29
33
|
/** Device metadata from the bridge */
|
|
30
34
|
interface DeviceInfo {
|
|
31
35
|
id: string;
|
|
@@ -35,6 +39,8 @@ interface DeviceInfo {
|
|
|
35
39
|
vendorId?: number;
|
|
36
40
|
productId?: number;
|
|
37
41
|
connectionType?: "usb" | "wireless" | "bluetooth" | "unknown";
|
|
42
|
+
/** General form factor */
|
|
43
|
+
deviceClass?: DeviceClass;
|
|
38
44
|
connected?: boolean;
|
|
39
45
|
/** Axes this device provides (e.g., ["tx","ty","tz","rx","ry","rz"] or ["tx","ty","rx","ry","tz+","rz+"]) */
|
|
40
46
|
axes?: string[];
|
|
@@ -42,6 +48,8 @@ interface DeviceInfo {
|
|
|
42
48
|
axisLabels?: string[];
|
|
43
49
|
/** Number of buttons this device provides */
|
|
44
50
|
buttonCount?: number;
|
|
51
|
+
/** Human-readable labels for buttons (indexed by targetButton) */
|
|
52
|
+
buttonLabels?: string[];
|
|
45
53
|
}
|
|
46
54
|
type ConnectionState = "disconnected" | "connecting" | "connected" | "failed";
|
|
47
55
|
type TransportProtocol = "webtransport" | "websocket" | "none";
|
|
@@ -12,10 +12,12 @@ interface Vec3 {
|
|
|
12
12
|
y: number;
|
|
13
13
|
z: number;
|
|
14
14
|
}
|
|
15
|
-
/** 6DOF spatial input frame
|
|
15
|
+
/** 6DOF+W spatial input frame */
|
|
16
16
|
interface SpatialData {
|
|
17
17
|
translation: Vec3;
|
|
18
18
|
rotation: Vec3;
|
|
19
|
+
/** Virtual W axis — application-defined (e.g., zoom, scroll, tool size) */
|
|
20
|
+
w?: number;
|
|
19
21
|
timestamp: number;
|
|
20
22
|
/** Source device ID (e.g., "cnx-c635", "hid-054c-5c4") */
|
|
21
23
|
deviceId?: string;
|
|
@@ -26,6 +28,8 @@ interface ButtonEvent {
|
|
|
26
28
|
pressed: boolean;
|
|
27
29
|
timestamp: number;
|
|
28
30
|
}
|
|
31
|
+
/** Device form factor */
|
|
32
|
+
type DeviceClass = "spacemouse" | "gamepad" | "dial" | "joystick" | "6dof" | "other";
|
|
29
33
|
/** Device metadata from the bridge */
|
|
30
34
|
interface DeviceInfo {
|
|
31
35
|
id: string;
|
|
@@ -35,6 +39,8 @@ interface DeviceInfo {
|
|
|
35
39
|
vendorId?: number;
|
|
36
40
|
productId?: number;
|
|
37
41
|
connectionType?: "usb" | "wireless" | "bluetooth" | "unknown";
|
|
42
|
+
/** General form factor */
|
|
43
|
+
deviceClass?: DeviceClass;
|
|
38
44
|
connected?: boolean;
|
|
39
45
|
/** Axes this device provides (e.g., ["tx","ty","tz","rx","ry","rz"] or ["tx","ty","rx","ry","tz+","rz+"]) */
|
|
40
46
|
axes?: string[];
|
|
@@ -42,6 +48,8 @@ interface DeviceInfo {
|
|
|
42
48
|
axisLabels?: string[];
|
|
43
49
|
/** Number of buttons this device provides */
|
|
44
50
|
buttonCount?: number;
|
|
51
|
+
/** Human-readable labels for buttons (indexed by targetButton) */
|
|
52
|
+
buttonLabels?: string[];
|
|
45
53
|
}
|
|
46
54
|
type ConnectionState = "disconnected" | "connecting" | "connected" | "failed";
|
|
47
55
|
type TransportProtocol = "webtransport" | "websocket" | "none";
|
package/dist/core/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { T as ThingDescription, S as SpatialData, B as ButtonEvent } from '../connection-
|
|
2
|
-
export { C as ConnectOptions, a as ConnectionState, D as DeviceInfo, b as SatMouseConnection, c as SatMouseEvents, d as TransportProtocol, e as TypedEmitter, V as Vec3, f as buildSatMouseUri, p as parseSatMouseUri } from '../connection-
|
|
1
|
+
import { T as ThingDescription, S as SpatialData, B as ButtonEvent } from '../connection-iUlge6Er.cjs';
|
|
2
|
+
export { C as ConnectOptions, a as ConnectionState, D as DeviceInfo, b as SatMouseConnection, c as SatMouseEvents, d as TransportProtocol, e as TypedEmitter, V as Vec3, f as buildSatMouseUri, p as parseSatMouseUri } from '../connection-iUlge6Er.cjs';
|
|
3
3
|
|
|
4
4
|
interface ResolvedEndpoints {
|
|
5
5
|
webtransport?: {
|
package/dist/core/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { T as ThingDescription, S as SpatialData, B as ButtonEvent } from '../connection-
|
|
2
|
-
export { C as ConnectOptions, a as ConnectionState, D as DeviceInfo, b as SatMouseConnection, c as SatMouseEvents, d as TransportProtocol, e as TypedEmitter, V as Vec3, f as buildSatMouseUri, p as parseSatMouseUri } from '../connection-
|
|
1
|
+
import { T as ThingDescription, S as SpatialData, B as ButtonEvent } from '../connection-iUlge6Er.js';
|
|
2
|
+
export { C as ConnectOptions, a as ConnectionState, D as DeviceInfo, b as SatMouseConnection, c as SatMouseEvents, d as TransportProtocol, e as TypedEmitter, V as Vec3, f as buildSatMouseUri, p as parseSatMouseUri } from '../connection-iUlge6Er.js';
|
|
3
3
|
|
|
4
4
|
interface ResolvedEndpoints {
|
|
5
5
|
webtransport?: {
|
package/dist/elements/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkY75556IA_cjs = require('../chunk-Y75556IA.cjs');
|
|
4
4
|
|
|
5
5
|
// src/elements/registry.ts
|
|
6
6
|
var globalManager = null;
|
|
@@ -161,6 +161,19 @@ var STYLES = `
|
|
|
161
161
|
.reset-btn { background: none; border: 1px solid #1a4a8a; border-radius: 3px; color: #7f8c8d;
|
|
162
162
|
font-size: 11px; padding: 3px 8px; cursor: pointer; margin-top: 4px; }
|
|
163
163
|
.reset-btn:hover { color: #e0e0e0; border-color: #e74c3c; }
|
|
164
|
+
.btn-section { display: flex; flex-direction: column; gap: 4px; }
|
|
165
|
+
.btn-section-label { color: #7f8c8d; font-weight: 600; font-size: 10px; text-transform: uppercase; letter-spacing: 0.5px; }
|
|
166
|
+
.btn-route { display: flex; gap: 6px; align-items: center; font-size: 11px; }
|
|
167
|
+
.btn-route .btn-idx { color: #7f8c8d; font-family: monospace; min-width: 32px; }
|
|
168
|
+
.btn-route .btn-arrow { color: #7f8c8d; }
|
|
169
|
+
.btn-route .btn-key { color: #3498db; font-family: monospace; }
|
|
170
|
+
.btn-route .btn-remove { cursor: pointer; color: #e74c3c; background: none; border: none;
|
|
171
|
+
font-size: 11px; padding: 0 2px; font-family: inherit; }
|
|
172
|
+
.btn-route .btn-remove:hover { color: #ff6b6b; }
|
|
173
|
+
.btn-add { background: none; border: 1px dashed #1a4a8a; border-radius: 3px; color: #7f8c8d;
|
|
174
|
+
font-size: 11px; padding: 4px 8px; cursor: pointer; font-family: inherit; }
|
|
175
|
+
.btn-add:hover { color: #e0e0e0; border-color: #3498db; }
|
|
176
|
+
.btn-add.listening { color: #f39c12; border-color: #f39c12; border-style: solid; cursor: default; }
|
|
164
177
|
</style>
|
|
165
178
|
`;
|
|
166
179
|
function mapSlider(v) {
|
|
@@ -258,7 +271,7 @@ var SatMouseDevices = class extends HTMLElement {
|
|
|
258
271
|
label.textContent = device.axisLabels?.[i] ?? deviceAxes[i].toUpperCase();
|
|
259
272
|
row.appendChild(label);
|
|
260
273
|
const sel = document.createElement("select");
|
|
261
|
-
for (const target of
|
|
274
|
+
for (const target of chunkY75556IA_cjs.FULL_AXES) {
|
|
262
275
|
const opt = document.createElement("option");
|
|
263
276
|
opt.value = target;
|
|
264
277
|
opt.textContent = target.toUpperCase();
|
|
@@ -272,18 +285,93 @@ var SatMouseDevices = class extends HTMLElement {
|
|
|
272
285
|
routeGroup.appendChild(row);
|
|
273
286
|
}
|
|
274
287
|
controls.appendChild(routeGroup);
|
|
275
|
-
const
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
const
|
|
283
|
-
|
|
284
|
-
|
|
288
|
+
for (const [label, key, globalKey] of [
|
|
289
|
+
["Trans", "translateScale", "translateScale"],
|
|
290
|
+
["Rot", "rotateScale", "rotateScale"],
|
|
291
|
+
["W", "wScale", "wScale"]
|
|
292
|
+
]) {
|
|
293
|
+
const row = document.createElement("div");
|
|
294
|
+
row.className = "slider-row";
|
|
295
|
+
const val = cfg[key] ?? mgr.config[globalKey];
|
|
296
|
+
row.innerHTML = `<label>${label}</label><input type="range" min="0" max="100" value="${Math.round(unmapSlider(val))}"><span>${val.toFixed(4)}</span>`;
|
|
297
|
+
const sl = row.querySelector("input");
|
|
298
|
+
const sp = row.querySelector("span");
|
|
299
|
+
sl.addEventListener("input", () => {
|
|
300
|
+
const v = mapSlider(+sl.value);
|
|
301
|
+
sp.textContent = v.toFixed(4);
|
|
302
|
+
mgr.updateDeviceConfig(device.id, { [key]: v });
|
|
303
|
+
});
|
|
304
|
+
controls.appendChild(row);
|
|
305
|
+
}
|
|
306
|
+
const btnSection = document.createElement("div");
|
|
307
|
+
btnSection.className = "btn-section";
|
|
308
|
+
const btnLabel = document.createElement("div");
|
|
309
|
+
btnLabel.className = "btn-section-label";
|
|
310
|
+
btnLabel.textContent = "Button Mappings";
|
|
311
|
+
btnSection.appendChild(btnLabel);
|
|
312
|
+
const buttonRoutes = cfg.buttonRoutes ?? [];
|
|
313
|
+
const labels = device.buttonLabels ?? [];
|
|
314
|
+
for (let i = 0; i < buttonRoutes.length; i++) {
|
|
315
|
+
const route = buttonRoutes[i];
|
|
316
|
+
const btnName = labels[route.button] ?? `Btn ${route.button}`;
|
|
317
|
+
const row = document.createElement("div");
|
|
318
|
+
row.className = "btn-route";
|
|
319
|
+
const idxSpan = document.createElement("span");
|
|
320
|
+
idxSpan.className = "btn-idx";
|
|
321
|
+
idxSpan.textContent = btnName;
|
|
322
|
+
row.appendChild(idxSpan);
|
|
323
|
+
const arrow = document.createElement("span");
|
|
324
|
+
arrow.className = "btn-arrow";
|
|
325
|
+
arrow.textContent = "\u2192";
|
|
326
|
+
row.appendChild(arrow);
|
|
327
|
+
const keySpan = document.createElement("span");
|
|
328
|
+
keySpan.className = "btn-key";
|
|
329
|
+
keySpan.textContent = route.key;
|
|
330
|
+
row.appendChild(keySpan);
|
|
331
|
+
const editBtn = document.createElement("button");
|
|
332
|
+
editBtn.className = "btn-remove";
|
|
333
|
+
editBtn.textContent = "\u270E";
|
|
334
|
+
editBtn.title = "Remap key";
|
|
335
|
+
const routeIdx = i;
|
|
336
|
+
editBtn.addEventListener("click", () => {
|
|
337
|
+
keySpan.textContent = "Press a key...";
|
|
338
|
+
keySpan.style.color = "#f39c12";
|
|
339
|
+
const onKey = (e) => {
|
|
340
|
+
e.preventDefault();
|
|
341
|
+
e.stopPropagation();
|
|
342
|
+
document.removeEventListener("keydown", onKey, true);
|
|
343
|
+
const current = mgr.getDeviceConfig(device.id).buttonRoutes ?? [];
|
|
344
|
+
const updated = current.map(
|
|
345
|
+
(r, j) => j === routeIdx ? { ...r, key: e.key, code: e.code } : r
|
|
346
|
+
);
|
|
347
|
+
mgr.updateDeviceConfig(device.id, { buttonRoutes: updated });
|
|
348
|
+
this.refreshControls(panel, device);
|
|
349
|
+
};
|
|
350
|
+
document.addEventListener("keydown", onKey, true);
|
|
351
|
+
});
|
|
352
|
+
row.appendChild(editBtn);
|
|
353
|
+
const removeBtn = document.createElement("button");
|
|
354
|
+
removeBtn.className = "btn-remove";
|
|
355
|
+
removeBtn.textContent = "\xD7";
|
|
356
|
+
removeBtn.title = "Remove";
|
|
357
|
+
removeBtn.addEventListener("click", () => {
|
|
358
|
+
const current = mgr.getDeviceConfig(device.id).buttonRoutes ?? [];
|
|
359
|
+
const updated = current.filter((_, j) => j !== routeIdx);
|
|
360
|
+
mgr.updateDeviceConfig(device.id, { buttonRoutes: updated });
|
|
361
|
+
this.refreshControls(panel, device);
|
|
362
|
+
});
|
|
363
|
+
row.appendChild(removeBtn);
|
|
364
|
+
btnSection.appendChild(row);
|
|
365
|
+
}
|
|
366
|
+
const addBtn = document.createElement("button");
|
|
367
|
+
addBtn.className = "btn-add";
|
|
368
|
+
addBtn.textContent = "+ Add Button Mapping";
|
|
369
|
+
addBtn.addEventListener("click", () => {
|
|
370
|
+
if (addBtn.classList.contains("listening")) return;
|
|
371
|
+
this.startButtonListen(addBtn, mgr, device, panel);
|
|
285
372
|
});
|
|
286
|
-
|
|
373
|
+
btnSection.appendChild(addBtn);
|
|
374
|
+
controls.appendChild(btnSection);
|
|
287
375
|
const resetBtn = document.createElement("button");
|
|
288
376
|
resetBtn.className = "reset-btn";
|
|
289
377
|
resetBtn.textContent = "Restore Defaults";
|
|
@@ -303,13 +391,49 @@ var SatMouseDevices = class extends HTMLElement {
|
|
|
303
391
|
if (cfg.routes && Array.isArray(cfg.routes)) return cfg.routes;
|
|
304
392
|
}
|
|
305
393
|
}
|
|
306
|
-
return
|
|
394
|
+
return chunkY75556IA_cjs.buildRoutes(deviceAxes);
|
|
307
395
|
}
|
|
308
396
|
updateRoute(deviceId, index, deviceAxes, patch) {
|
|
309
397
|
const base = this.getRoutes(deviceId, deviceAxes);
|
|
310
398
|
const updated = base.map((r, j) => j === index ? { ...r, ...patch } : { ...r });
|
|
311
399
|
this.manager.updateDeviceConfig(deviceId, { routes: updated });
|
|
312
400
|
}
|
|
401
|
+
startButtonListen(btn, mgr, device, panel) {
|
|
402
|
+
btn.classList.add("listening");
|
|
403
|
+
btn.textContent = "Press a device button...";
|
|
404
|
+
const onButton = (event) => {
|
|
405
|
+
if (!event.pressed) return;
|
|
406
|
+
mgr.off("buttonEvent", onButton);
|
|
407
|
+
const capturedButton = event.button;
|
|
408
|
+
btn.textContent = `Btn ${capturedButton} \u2192 Press a key...`;
|
|
409
|
+
const onKey = (e) => {
|
|
410
|
+
e.preventDefault();
|
|
411
|
+
e.stopPropagation();
|
|
412
|
+
document.removeEventListener("keydown", onKey, true);
|
|
413
|
+
const route = {
|
|
414
|
+
button: capturedButton,
|
|
415
|
+
key: e.key,
|
|
416
|
+
code: e.code
|
|
417
|
+
};
|
|
418
|
+
const current = mgr.getDeviceConfig(device.id).buttonRoutes ?? [];
|
|
419
|
+
const updated = current.filter((r) => r.button !== capturedButton);
|
|
420
|
+
updated.push(route);
|
|
421
|
+
mgr.updateDeviceConfig(device.id, { buttonRoutes: updated });
|
|
422
|
+
this.refreshControls(panel, device);
|
|
423
|
+
};
|
|
424
|
+
document.addEventListener("keydown", onKey, true);
|
|
425
|
+
};
|
|
426
|
+
mgr.on("buttonEvent", onButton);
|
|
427
|
+
const onCancel = (e) => {
|
|
428
|
+
if (e.key === "Escape") {
|
|
429
|
+
mgr.off("buttonEvent", onButton);
|
|
430
|
+
document.removeEventListener("keydown", onCancel, true);
|
|
431
|
+
btn.classList.remove("listening");
|
|
432
|
+
btn.textContent = "+ Add Button Mapping";
|
|
433
|
+
}
|
|
434
|
+
};
|
|
435
|
+
document.addEventListener("keydown", onCancel, true);
|
|
436
|
+
}
|
|
313
437
|
removeDevice(device) {
|
|
314
438
|
this.shadowRoot.getElementById(`dev-${device.id}`)?.remove();
|
|
315
439
|
if (this.container.children.length === 0) {
|