manim-web 0.30.0 → 0.32.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,273 @@
1
+ import { StateMachineInputSink, ValueSink, Unsubscribe, BindValueOptions } from './KeyboardInput';
2
+ /**
3
+ * The subset of a `GamepadButton` the controller reads. A real `GamepadButton`
4
+ * satisfies this, and a test stub implements only these two fields.
5
+ */
6
+ export interface GamepadButtonLike {
7
+ /** Whether the button is pressed. */
8
+ readonly pressed: boolean;
9
+ /** The analog value in `[0, 1]` (triggers), or `0` / `1` for a plain button. */
10
+ readonly value: number;
11
+ }
12
+ /**
13
+ * The subset of a `Gamepad` the controller reads. A real `Gamepad` satisfies
14
+ * this shape, so `navigator.getGamepads()` feeds the controller directly, and a
15
+ * test injects a plain object with the same fields.
16
+ */
17
+ export interface GamepadLike {
18
+ /** The pad's index in the snapshot array. */
19
+ readonly index: number;
20
+ /** The device id, when the pad exposes one. */
21
+ readonly id?: string;
22
+ /** Whether the pad is connected. Absent is treated as connected. */
23
+ readonly connected?: boolean;
24
+ /** The W3C mapping name, typically `'standard'`. */
25
+ readonly mapping?: string;
26
+ /** The button states, indexed by the standard-mapping order. */
27
+ readonly buttons: ReadonlyArray<GamepadButtonLike>;
28
+ /** The axis values in `[-1, 1]`, indexed by the standard-mapping order. */
29
+ readonly axes: ReadonlyArray<number>;
30
+ }
31
+ /**
32
+ * The snapshot source. Returns one entry per pad slot; a slot is `null` when no
33
+ * pad is connected there. `navigator.getGamepads()` matches this signature.
34
+ */
35
+ export type GamepadSource = () => ReadonlyArray<GamepadLike | null>;
36
+ /** A gamepad button callback. `button` is the resolved button index. */
37
+ export type GamepadButtonCallback = (button: number, gamepad: GamepadLike | null) => void;
38
+ /**
39
+ * The W3C standard-gamepad button name → index map. Use a name
40
+ * (`'A'`, `'dpadUp'`, `'LT'`) in any query instead of a raw index.
41
+ * @see https://www.w3.org/TR/gamepad/#remapping
42
+ */
43
+ export declare const STANDARD_BUTTONS: {
44
+ readonly A: 0;
45
+ readonly B: 1;
46
+ readonly X: 2;
47
+ readonly Y: 3;
48
+ readonly LB: 4;
49
+ readonly RB: 5;
50
+ readonly LT: 6;
51
+ readonly RT: 7;
52
+ readonly select: 8;
53
+ readonly start: 9;
54
+ readonly L3: 10;
55
+ readonly R3: 11;
56
+ readonly dpadUp: 12;
57
+ readonly dpadDown: 13;
58
+ readonly dpadLeft: 14;
59
+ readonly dpadRight: 15;
60
+ readonly guide: 16;
61
+ };
62
+ /** The standard-mapping axis indices for the two sticks. */
63
+ export declare const STANDARD_AXES: {
64
+ readonly leftX: 0;
65
+ readonly leftY: 1;
66
+ readonly rightX: 2;
67
+ readonly rightY: 3;
68
+ };
69
+ /**
70
+ * Resolve a button name or index to a standard-mapping index.
71
+ * @param button - A button index, or a name in any common spelling.
72
+ * @returns The index, or `-1` when the name is unknown.
73
+ */
74
+ export declare function resolveButton(button: number | string): number;
75
+ /** Options for a {@link GamepadInput}. */
76
+ export interface GamepadInputOptions {
77
+ /**
78
+ * Which pad slot to read. By default the first connected pad in the snapshot
79
+ * is used, so a single controller just works.
80
+ */
81
+ gamepadIndex?: number;
82
+ /**
83
+ * Stick deadzone in `[0, 1]`. An axis whose magnitude is below this reads as
84
+ * `0`, so a resting stick does not drift. Default `0.1`.
85
+ */
86
+ deadzone?: number;
87
+ /**
88
+ * Attach the connection listeners immediately on construction. Set `false` to
89
+ * attach later with {@link GamepadInput.enable}. Default `true`.
90
+ */
91
+ autoEnable?: boolean;
92
+ }
93
+ /** Whether the Web Gamepad API is available in this environment. */
94
+ export declare function isGamepadSupported(): boolean;
95
+ /**
96
+ * Reads live gamepad state for interactive apps and games. Mirrors
97
+ * {@link KeyboardInput}: construct, then
98
+ * {@link enable} / {@link disable} / {@link dispose}, and {@link poll} once a
99
+ * frame.
100
+ */
101
+ export declare class GamepadInput {
102
+ private readonly _getGamepads;
103
+ private readonly _eventTarget;
104
+ private readonly _gamepadIndex?;
105
+ private readonly _deadzone;
106
+ private readonly _down;
107
+ private readonly _pressed;
108
+ private readonly _released;
109
+ private _axes;
110
+ private _buttonValues;
111
+ private readonly _downCallbacks;
112
+ private readonly _upCallbacks;
113
+ private _enabled;
114
+ private readonly _onConnect;
115
+ private readonly _onDisconnect;
116
+ /**
117
+ * Create a GamepadInput.
118
+ * @param options - Behavior options.
119
+ * @param getGamepads - Snapshot source. Defaults to `navigator.getGamepads`,
120
+ * or `null` when no Gamepad API is present. Tests inject a fake here.
121
+ * @param eventTarget - Target for connection events. Defaults to `window`.
122
+ */
123
+ constructor(options?: GamepadInputOptions, getGamepads?: GamepadSource | null, eventTarget?: EventTarget | null);
124
+ /** Whether the controller is enabled (connection listeners attached). */
125
+ get isEnabled(): boolean;
126
+ /** Whether a Gamepad API snapshot source is available. */
127
+ get hasSource(): boolean;
128
+ /** Whether a DOM target for connection events is available. */
129
+ get hasTarget(): boolean;
130
+ /**
131
+ * Attach the `gamepadconnected` / `gamepaddisconnected` listeners. A no-op
132
+ * when already enabled. Polling works even without a DOM target.
133
+ */
134
+ enable(): void;
135
+ /**
136
+ * Detach the connection listeners and clear all held and edge state, so no
137
+ * button stays stuck. Reads return defaults until {@link enable} is called.
138
+ */
139
+ disable(): void;
140
+ /**
141
+ * Detach listeners and drop every registered callback. Use when the
142
+ * controller is no longer needed.
143
+ */
144
+ dispose(): void;
145
+ /** Clear held buttons, both edge sets, and the cached axes and values. */
146
+ clear(): void;
147
+ /**
148
+ * Read the live gamepad snapshot and compute the press / release edges. Call
149
+ * once per frame before reading state. The edges stay readable until the next
150
+ * {@link poll}, so {@link wasButtonPressed} is true for exactly one frame.
151
+ *
152
+ * When no pad is present, any held button is released and the state resets,
153
+ * so a disconnect never leaves a button stuck.
154
+ */
155
+ poll(): void;
156
+ /**
157
+ * Alias of {@link poll} for render-loop compatibility with
158
+ * {@link KeyboardInput}.
159
+ * @param _dt - Delta time (seconds), accepted but not used.
160
+ */
161
+ update(_dt?: number): void;
162
+ /**
163
+ * Whether the button is held right now (as of the last {@link poll}).
164
+ * @param button - A button index, or a name (`'A'`, `'dpadUp'`, `'LT'`).
165
+ */
166
+ isButtonDown(button: number | string): boolean;
167
+ /** Whether any button is held right now. */
168
+ anyButtonDown(): boolean;
169
+ /**
170
+ * Whether the button went down on the last {@link poll}. True for exactly one
171
+ * frame after a 0→1 transition.
172
+ * @param button - A button index or name.
173
+ */
174
+ wasButtonPressed(button: number | string): boolean;
175
+ /**
176
+ * Whether the button came up on the last {@link poll}. True for exactly one
177
+ * frame after a 1→0 transition.
178
+ * @param button - A button index or name.
179
+ */
180
+ wasButtonReleased(button: number | string): boolean;
181
+ /**
182
+ * The analog value `[0, 1]` of a button (triggers vary; plain buttons read
183
+ * `0` or `1`).
184
+ * @param button - A button index or name.
185
+ */
186
+ getButtonValue(button: number | string): number;
187
+ /**
188
+ * The raw value `[-1, 1]` of an axis, with the deadzone applied so a resting
189
+ * stick reads `0`. The API convention is used verbatim: for the vertical
190
+ * stick axes, up is negative.
191
+ * @param index - The axis index (see {@link STANDARD_AXES}).
192
+ * @param deadzone - Override the instance deadzone for this read.
193
+ */
194
+ getAxis(index: number, deadzone?: number): number;
195
+ /**
196
+ * The left stick as `[x, y]`, deadzone applied, with up as `+y` (the API's
197
+ * downward vertical axis is flipped to match {@link KeyboardInput}).
198
+ */
199
+ getLeftStick(): [number, number];
200
+ /** The right stick as `[x, y]`, deadzone applied, with up as `+y`. */
201
+ getRightStick(): [number, number];
202
+ /**
203
+ * A normalized movement direction `[x, y]`, up is `+y`. The d-pad wins when
204
+ * any d-pad button is held; otherwise the left stick is used. A neutral input
205
+ * stays `[0, 0]`.
206
+ */
207
+ getDirectionVector(): [number, number];
208
+ /** The connected pads in the current snapshot (empty when headless). */
209
+ getConnectedGamepads(): GamepadLike[];
210
+ /**
211
+ * Register a button-down callback, fired by {@link poll} on a 0→1 edge.
212
+ * @param button - A button index or name, or `'any'` for every button.
213
+ * @param callback - Called with the button index and the pad.
214
+ * @returns An unsubscribe function.
215
+ */
216
+ onButtonDown(button: number | string, callback: GamepadButtonCallback): Unsubscribe;
217
+ /**
218
+ * Register a button-up callback, fired by {@link poll} on a 1→0 edge.
219
+ * @param button - A button index or name, or `'any'` for every button.
220
+ * @param callback - Called with the button index and the pad.
221
+ * @returns An unsubscribe function.
222
+ */
223
+ onButtonUp(button: number | string, callback: GamepadButtonCallback): Unsubscribe;
224
+ /**
225
+ * Hold a `StateMachine` bool input to match a button: `true` while held,
226
+ * `false` on release.
227
+ * @param machine - The `StateMachine` (or any {@link StateMachineInputSink}).
228
+ * @param inputName - The bool input name.
229
+ * @param button - The button to track.
230
+ * @returns An unsubscribe function.
231
+ */
232
+ bindBool(machine: StateMachineInputSink, inputName: string, button: number | string): Unsubscribe;
233
+ /**
234
+ * Fire a `StateMachine` trigger input on each button-down.
235
+ * @param machine - The `StateMachine` (or any {@link StateMachineInputSink}).
236
+ * @param triggerName - The trigger input name.
237
+ * @param button - The button to track.
238
+ * @returns An unsubscribe function.
239
+ */
240
+ bindTrigger(machine: StateMachineInputSink, triggerName: string, button: number | string): Unsubscribe;
241
+ /**
242
+ * Drive a `ValueTracker` from a button: `heldValue` while held,
243
+ * `releasedValue` on release.
244
+ * @param tracker - The `ValueTracker` (or any {@link ValueSink}).
245
+ * @param button - The button to track.
246
+ * @param options - The held and released values.
247
+ * @returns An unsubscribe function.
248
+ */
249
+ bindValue(tracker: ValueSink, button: number | string, options: BindValueOptions): Unsubscribe;
250
+ /** Read the active pad from the snapshot, honoring the `gamepadIndex` option. */
251
+ private _readActivePad;
252
+ /** Release every held button, emitting up callbacks, on a disconnect. */
253
+ private _releaseAll;
254
+ /** Apply the deadzone: magnitudes below `deadzone` read as `0`. */
255
+ private _applyDeadzone;
256
+ private _addCallback;
257
+ /** Resolve a callback registration key, warning on an unknown button name. */
258
+ private _callbackKey;
259
+ private _emit;
260
+ /** Log a connected pad. The snapshot is still read fresh each {@link poll}. */
261
+ private _handleConnect;
262
+ /** Log a disconnected pad. {@link poll} releases its held buttons. */
263
+ private _handleDisconnect;
264
+ }
265
+ /**
266
+ * Factory for a {@link GamepadInput}.
267
+ * @param options - Behavior options.
268
+ * @param getGamepads - Snapshot source.
269
+ * @param eventTarget - Target for connection events.
270
+ * @returns A new GamepadInput.
271
+ */
272
+ export declare function makeGamepadInput(options?: GamepadInputOptions, getGamepads?: GamepadSource | null, eventTarget?: EventTarget | null): GamepadInput;
273
+ //# sourceMappingURL=GamepadInput.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GamepadInput.d.ts","sourceRoot":"","sources":["../../src/interaction/GamepadInput.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,210 @@
1
+ /**
2
+ * KeyboardInput — a general-purpose keyboard controller for interactive apps
3
+ * and games.
4
+ *
5
+ * manim-web already has pointer interaction (`Clickable` / `Draggable` /
6
+ * `Hoverable`) and a `StateMachine`, but no general keyboard primitive. This
7
+ * controller tracks held keys, exposes per-frame edge queries (`wasPressed` /
8
+ * `wasReleased`), derives a movement vector from arrow keys and WASD, and binds
9
+ * a key to a `StateMachine` input or a `ValueTracker`. It makes the kind of
10
+ * interactive software and games that plain Manim cannot do first-class in the
11
+ * browser.
12
+ *
13
+ * All DOM access is feature-detected, so the controller is safe to construct
14
+ * in Node, jsdom, or a headless render. Without a window the reads return
15
+ * `false` or zero and never throw.
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * const keys = new KeyboardInput({ preventDefault: true });
20
+ * // In the render loop, each frame:
21
+ * function frame(dt: number): void {
22
+ * const [dx, dy] = keys.getDirectionVector();
23
+ * player.shift([dx * speed * dt, dy * speed * dt, 0]);
24
+ * if (keys.wasPressed('Space')) player.jump();
25
+ * keys.endFrame(); // clear the per-frame pressed/released edges
26
+ * }
27
+ * ```
28
+ */
29
+ /** A per-key or wildcard callback. `key` is the normalized key name. */
30
+ export type KeyCallback = (key: string, event: KeyboardEvent) => void;
31
+ /** Unsubscribe from a callback registration. */
32
+ export type Unsubscribe = () => void;
33
+ /**
34
+ * Minimal view of a `StateMachine` for binding. Both `StateMachine.setInput`
35
+ * and `StateMachine.fire` match this, so no import of the class is needed.
36
+ */
37
+ export interface StateMachineInputSink {
38
+ setInput(name: string, value: boolean | number): unknown;
39
+ fire(name: string): unknown;
40
+ }
41
+ /** Minimal view of a `ValueTracker` for binding. */
42
+ export interface ValueSink {
43
+ setValue(value: number): unknown;
44
+ }
45
+ /** Options for a {@link KeyboardInput}. */
46
+ export interface KeyboardInputOptions {
47
+ /**
48
+ * Call `preventDefault()` on handled key events. `true` applies to every
49
+ * key; an array restricts it to the listed (normalized) keys. Use it so game
50
+ * keys such as the arrows and Space do not scroll the page. Default `false`.
51
+ */
52
+ preventDefault?: boolean | string[];
53
+ /**
54
+ * Attach the listeners immediately on construction. Set `false` to attach
55
+ * later with {@link KeyboardInput.enable}. Default `true`.
56
+ */
57
+ autoEnable?: boolean;
58
+ }
59
+ /** Options for {@link KeyboardInput.bindValue}. */
60
+ export interface BindValueOptions {
61
+ /** Value written to the tracker while the key is held. */
62
+ heldValue: number;
63
+ /** Value written when the key is released. Default `0`. */
64
+ releasedValue?: number;
65
+ }
66
+ /**
67
+ * Normalize a raw `KeyboardEvent.key` or a user query to a canonical,
68
+ * lowercase name. `'ArrowUp'`, `'W'`, and `' '` become `'arrowup'`, `'w'`, and
69
+ * `'space'`, so a held key reads back under any common spelling.
70
+ * @param key - A raw key name.
71
+ * @returns The canonical key name.
72
+ */
73
+ export declare function normalizeKey(key: string): string;
74
+ /**
75
+ * Tracks keyboard state for interactive apps and games. Mirrors the
76
+ * `Clickable` / `OrbitControls` lifecycle: construct, then
77
+ * {@link enable} / {@link disable} / {@link dispose}.
78
+ */
79
+ export declare class KeyboardInput {
80
+ private readonly _target;
81
+ private readonly _preventDefault;
82
+ private readonly _down;
83
+ private readonly _pressed;
84
+ private readonly _released;
85
+ private readonly _downCallbacks;
86
+ private readonly _upCallbacks;
87
+ private _enabled;
88
+ private readonly _onKeyDown;
89
+ private readonly _onKeyUp;
90
+ /**
91
+ * Create a KeyboardInput.
92
+ * @param options - Behavior options.
93
+ * @param domTarget - Event target for key events. Defaults to `window` (or
94
+ * `document`), or `null` when no DOM is present.
95
+ */
96
+ constructor(options?: KeyboardInputOptions, domTarget?: EventTarget | null);
97
+ /** Whether the listeners are attached. */
98
+ get isEnabled(): boolean;
99
+ /** Whether a DOM target is available. `false` in a headless environment. */
100
+ get hasTarget(): boolean;
101
+ /**
102
+ * Attach the key listeners. A no-op when already enabled or headless.
103
+ */
104
+ enable(): void;
105
+ /**
106
+ * Detach the key listeners and clear all held and edge state, so no key stays
107
+ * stuck. Reads return defaults until {@link enable} is called again.
108
+ */
109
+ disable(): void;
110
+ /**
111
+ * Detach listeners and drop every registered callback. Use when the
112
+ * controller is no longer needed.
113
+ */
114
+ dispose(): void;
115
+ /** Clear held keys and both per-frame edge sets. */
116
+ clear(): void;
117
+ /**
118
+ * Whether the key is held right now.
119
+ * @param key - A key name in any common spelling (`'ArrowUp'`, `'w'`, `' '`).
120
+ */
121
+ isKeyDown(key: string): boolean;
122
+ /** Whether any key is held right now. */
123
+ anyKeyDown(): boolean;
124
+ /**
125
+ * Whether the key went down during the current frame. Cleared by
126
+ * {@link update} / {@link endFrame}. Key auto-repeat does not re-fire it.
127
+ * @param key - A key name in any common spelling.
128
+ */
129
+ wasPressed(key: string): boolean;
130
+ /**
131
+ * Whether the key came up during the current frame. Cleared by
132
+ * {@link update} / {@link endFrame}.
133
+ * @param key - A key name in any common spelling.
134
+ */
135
+ wasReleased(key: string): boolean;
136
+ /**
137
+ * The raw movement axes from the arrow keys and WASD, each component in
138
+ * `{-1, 0, 1}`. Up is +y and right is +x; opposite keys cancel.
139
+ * @returns `[x, y]`.
140
+ */
141
+ getAxis(): [number, number];
142
+ /**
143
+ * The movement vector from {@link getAxis}, normalized to unit length so a
144
+ * diagonal is not faster than a straight line. A zero axis stays `[0, 0]`.
145
+ * @returns `[x, y]`.
146
+ */
147
+ getDirectionVector(): [number, number];
148
+ /**
149
+ * Register a key-down callback. Repeated auto-repeat events do not re-fire it.
150
+ * @param key - A key name, or `'any'` for every key.
151
+ * @param callback - Called with the normalized key and the event.
152
+ * @returns An unsubscribe function.
153
+ */
154
+ onKeyDown(key: string, callback: KeyCallback): Unsubscribe;
155
+ /**
156
+ * Register a key-up callback.
157
+ * @param key - A key name, or `'any'` for every key.
158
+ * @param callback - Called with the normalized key and the event.
159
+ * @returns An unsubscribe function.
160
+ */
161
+ onKeyUp(key: string, callback: KeyCallback): Unsubscribe;
162
+ /**
163
+ * Hold a `StateMachine` bool input to match a key: `true` while held, `false`
164
+ * on release.
165
+ * @param machine - The `StateMachine` (or any {@link StateMachineInputSink}).
166
+ * @param inputName - The bool input name.
167
+ * @param key - The key to track.
168
+ * @returns An unsubscribe function.
169
+ */
170
+ bindBool(machine: StateMachineInputSink, inputName: string, key: string): Unsubscribe;
171
+ /**
172
+ * Fire a `StateMachine` trigger input on each key-down.
173
+ * @param machine - The `StateMachine` (or any {@link StateMachineInputSink}).
174
+ * @param triggerName - The trigger input name.
175
+ * @param key - The key to track.
176
+ * @returns An unsubscribe function.
177
+ */
178
+ bindTrigger(machine: StateMachineInputSink, triggerName: string, key: string): Unsubscribe;
179
+ /**
180
+ * Drive a `ValueTracker` from a key: `heldValue` while held, `releasedValue`
181
+ * on release.
182
+ * @param tracker - The `ValueTracker` (or any {@link ValueSink}).
183
+ * @param key - The key to track.
184
+ * @param options - The held and released values.
185
+ * @returns An unsubscribe function.
186
+ */
187
+ bindValue(tracker: ValueSink, key: string, options: BindValueOptions): Unsubscribe;
188
+ /**
189
+ * Clear the per-frame pressed and released edge sets. Call once per frame
190
+ * after reading {@link wasPressed} / {@link wasReleased}.
191
+ * @param _dt - Delta time (seconds), accepted for render-loop compatibility.
192
+ */
193
+ update(_dt?: number): void;
194
+ /** Alias of {@link update} that clears the per-frame edge sets. */
195
+ endFrame(): void;
196
+ private _anyDown;
197
+ private _handleKeyDown;
198
+ private _handleKeyUp;
199
+ private _maybePreventDefault;
200
+ private _addCallback;
201
+ private _emit;
202
+ }
203
+ /**
204
+ * Factory for a {@link KeyboardInput}.
205
+ * @param options - Behavior options.
206
+ * @param domTarget - Event target for key events.
207
+ * @returns A new KeyboardInput.
208
+ */
209
+ export declare function makeKeyboardInput(options?: KeyboardInputOptions, domTarget?: EventTarget | null): KeyboardInput;
210
+ //# sourceMappingURL=KeyboardInput.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"KeyboardInput.d.ts","sourceRoot":"","sources":["../../src/interaction/KeyboardInput.ts"],"names":[],"mappings":"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"}
@@ -12,6 +12,8 @@ export { Slider, makeSlider, type SliderOptions } from './Slider';
12
12
  export { MatrixTracker, makeMatrixTracker, applyMatrixLive, type Matrix2x2, type MatrixSource, type BasisVectorSource, type DependentPoint, type DynamicMatrixOptions, type LiveMatrixBinding, } from './DynamicMatrix';
13
13
  export { SelectionManager, type SelectionManagerOptions } from './SelectionManager';
14
14
  export { StateMachine, GuardBuilder, when, allOf, anyOf, type InputValue, type InputKind, type InputsSnapshot, type Guard, type StateContext, type StateAction, type StateConfig, type TransitionConfig, type StateMachineOptions, } from './StateMachine';
15
+ export { KeyboardInput, makeKeyboardInput, normalizeKey, type KeyboardInputOptions, type KeyCallback, type Unsubscribe, type StateMachineInputSink, type ValueSink, type BindValueOptions, } from './KeyboardInput';
16
+ export { GamepadInput, makeGamepadInput, resolveButton, isGamepadSupported, STANDARD_BUTTONS, STANDARD_AXES, type GamepadInputOptions, type GamepadButtonLike, type GamepadLike, type GamepadSource, type GamepadButtonCallback, } from './GamepadInput';
15
17
  export { OrbitControls, type OrbitControlsOptions } from './OrbitControls';
16
18
  export { PanZoomControls, makePanZoomControls, type PanZoomControlsOptions, type PanZoomCamera, type PanZoomBounds, } from './PanZoomControls';
17
19
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/interaction/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,QAAQ,EACR,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,iBAAiB,GACvB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,gBAAgB,EAChB,KAAK,uBAAuB,EAC5B,KAAK,kBAAkB,GACxB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAG9E,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,KAAK,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAC1F,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAC;AAGlE,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,GACvB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAGpF,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,IAAI,EACJ,KAAK,EACL,KAAK,EACL,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,KAAK,EACV,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,GACzB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAC3E,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,KAAK,sBAAsB,EAC3B,KAAK,aAAa,EAClB,KAAK,aAAa,GACnB,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/interaction/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,QAAQ,EACR,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,iBAAiB,GACvB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,gBAAgB,EAChB,KAAK,uBAAuB,EAC5B,KAAK,kBAAkB,GACxB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAG9E,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,KAAK,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAC1F,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAC;AAGlE,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,GACvB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAGpF,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,IAAI,EACJ,KAAK,EACL,KAAK,EACL,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,KAAK,EACV,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,GACzB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,KAAK,oBAAoB,EACzB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,qBAAqB,EAC1B,KAAK,SAAS,EACd,KAAK,gBAAgB,GACtB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EAClB,gBAAgB,EAChB,aAAa,EACb,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,qBAAqB,GAC3B,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAC3E,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,KAAK,sBAAsB,EAC3B,KAAK,aAAa,EAClB,KAAK,aAAa,GACnB,MAAM,mBAAmB,CAAC"}