@voltras/node-sdk 0.1.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.
- package/LICENSE +21 -0
- package/README.md +272 -0
- package/dist/cjs/bluetooth/adapters/base.js +116 -0
- package/dist/cjs/bluetooth/adapters/base.js.map +1 -0
- package/dist/cjs/bluetooth/adapters/index.js +58 -0
- package/dist/cjs/bluetooth/adapters/index.js.map +1 -0
- package/dist/cjs/bluetooth/adapters/native.js +473 -0
- package/dist/cjs/bluetooth/adapters/native.js.map +1 -0
- package/dist/cjs/bluetooth/adapters/node.js +228 -0
- package/dist/cjs/bluetooth/adapters/node.js.map +1 -0
- package/dist/cjs/bluetooth/adapters/types.js +11 -0
- package/dist/cjs/bluetooth/adapters/types.js.map +1 -0
- package/dist/cjs/bluetooth/adapters/web-bluetooth-base.js +187 -0
- package/dist/cjs/bluetooth/adapters/web-bluetooth-base.js.map +1 -0
- package/dist/cjs/bluetooth/adapters/web.js +112 -0
- package/dist/cjs/bluetooth/adapters/web.js.map +1 -0
- package/dist/cjs/bluetooth/controllers/scanner-controller.js +145 -0
- package/dist/cjs/bluetooth/controllers/scanner-controller.js.map +1 -0
- package/dist/cjs/bluetooth/index.js +27 -0
- package/dist/cjs/bluetooth/index.js.map +1 -0
- package/dist/cjs/bluetooth/models/connection.js +68 -0
- package/dist/cjs/bluetooth/models/connection.js.map +1 -0
- package/dist/cjs/bluetooth/models/device.js +26 -0
- package/dist/cjs/bluetooth/models/device.js.map +1 -0
- package/dist/cjs/bluetooth/models/environment.js +106 -0
- package/dist/cjs/bluetooth/models/environment.js.map +1 -0
- package/dist/cjs/errors.js +167 -0
- package/dist/cjs/errors.js.map +1 -0
- package/dist/cjs/index.js +116 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/react/hooks.js +262 -0
- package/dist/cjs/react/hooks.js.map +1 -0
- package/dist/cjs/react/index.js +18 -0
- package/dist/cjs/react/index.js.map +1 -0
- package/dist/cjs/sdk/index.js +14 -0
- package/dist/cjs/sdk/index.js.map +1 -0
- package/dist/cjs/sdk/types.js +8 -0
- package/dist/cjs/sdk/types.js.map +1 -0
- package/dist/cjs/sdk/voltra-client.js +632 -0
- package/dist/cjs/sdk/voltra-client.js.map +1 -0
- package/dist/cjs/sdk/voltra-manager.js +419 -0
- package/dist/cjs/sdk/voltra-manager.js.map +1 -0
- package/dist/cjs/shared/index.js +12 -0
- package/dist/cjs/shared/index.js.map +1 -0
- package/dist/cjs/shared/utils.js +51 -0
- package/dist/cjs/shared/utils.js.map +1 -0
- package/dist/cjs/voltra/index.js +56 -0
- package/dist/cjs/voltra/index.js.map +1 -0
- package/dist/cjs/voltra/models/connection.js +68 -0
- package/dist/cjs/voltra/models/connection.js.map +1 -0
- package/dist/cjs/voltra/models/device-filter.js +28 -0
- package/dist/cjs/voltra/models/device-filter.js.map +1 -0
- package/dist/cjs/voltra/models/device.js +152 -0
- package/dist/cjs/voltra/models/device.js.map +1 -0
- package/dist/cjs/voltra/models/telemetry/frame.js +46 -0
- package/dist/cjs/voltra/models/telemetry/frame.js.map +1 -0
- package/dist/cjs/voltra/models/telemetry/index.js +14 -0
- package/dist/cjs/voltra/models/telemetry/index.js.map +1 -0
- package/dist/cjs/voltra/protocol/commands.js +230 -0
- package/dist/cjs/voltra/protocol/commands.js.map +1 -0
- package/dist/cjs/voltra/protocol/constants.js +136 -0
- package/dist/cjs/voltra/protocol/constants.js.map +1 -0
- package/dist/cjs/voltra/protocol/data/chains.json +830 -0
- package/dist/cjs/voltra/protocol/data/eccentric.json +1598 -0
- package/dist/cjs/voltra/protocol/data/protocol.json +54 -0
- package/dist/cjs/voltra/protocol/data/weights.json +62 -0
- package/dist/cjs/voltra/protocol/index.js +25 -0
- package/dist/cjs/voltra/protocol/index.js.map +1 -0
- package/dist/cjs/voltra/protocol/telemetry-decoder.js +146 -0
- package/dist/cjs/voltra/protocol/telemetry-decoder.js.map +1 -0
- package/dist/esm/bluetooth/adapters/base.js +112 -0
- package/dist/esm/bluetooth/adapters/base.js.map +1 -0
- package/dist/esm/bluetooth/adapters/index.js +51 -0
- package/dist/esm/bluetooth/adapters/index.js.map +1 -0
- package/dist/esm/bluetooth/adapters/native.js +469 -0
- package/dist/esm/bluetooth/adapters/native.js.map +1 -0
- package/dist/esm/bluetooth/adapters/node.js +191 -0
- package/dist/esm/bluetooth/adapters/node.js.map +1 -0
- package/dist/esm/bluetooth/adapters/types.js +10 -0
- package/dist/esm/bluetooth/adapters/types.js.map +1 -0
- package/dist/esm/bluetooth/adapters/web-bluetooth-base.js +183 -0
- package/dist/esm/bluetooth/adapters/web-bluetooth-base.js.map +1 -0
- package/dist/esm/bluetooth/adapters/web.js +108 -0
- package/dist/esm/bluetooth/adapters/web.js.map +1 -0
- package/dist/esm/bluetooth/controllers/scanner-controller.js +141 -0
- package/dist/esm/bluetooth/controllers/scanner-controller.js.map +1 -0
- package/dist/esm/bluetooth/index.js +17 -0
- package/dist/esm/bluetooth/index.js.map +1 -0
- package/dist/esm/bluetooth/models/connection.js +63 -0
- package/dist/esm/bluetooth/models/connection.js.map +1 -0
- package/dist/esm/bluetooth/models/device.js +22 -0
- package/dist/esm/bluetooth/models/device.js.map +1 -0
- package/dist/esm/bluetooth/models/environment.js +101 -0
- package/dist/esm/bluetooth/models/environment.js.map +1 -0
- package/dist/esm/errors.js +155 -0
- package/dist/esm/errors.js.map +1 -0
- package/dist/esm/index.js +72 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/react/hooks.js +257 -0
- package/dist/esm/react/hooks.js.map +1 -0
- package/dist/esm/react/index.js +12 -0
- package/dist/esm/react/index.js.map +1 -0
- package/dist/esm/sdk/index.js +9 -0
- package/dist/esm/sdk/index.js.map +1 -0
- package/dist/esm/sdk/types.js +7 -0
- package/dist/esm/sdk/types.js.map +1 -0
- package/dist/esm/sdk/voltra-client.js +628 -0
- package/dist/esm/sdk/voltra-client.js.map +1 -0
- package/dist/esm/sdk/voltra-manager.js +415 -0
- package/dist/esm/sdk/voltra-manager.js.map +1 -0
- package/dist/esm/shared/index.js +5 -0
- package/dist/esm/shared/index.js.map +1 -0
- package/dist/esm/shared/utils.js +45 -0
- package/dist/esm/shared/utils.js.map +1 -0
- package/dist/esm/voltra/index.js +26 -0
- package/dist/esm/voltra/index.js.map +1 -0
- package/dist/esm/voltra/models/connection.js +63 -0
- package/dist/esm/voltra/models/connection.js.map +1 -0
- package/dist/esm/voltra/models/device-filter.js +23 -0
- package/dist/esm/voltra/models/device-filter.js.map +1 -0
- package/dist/esm/voltra/models/device.js +148 -0
- package/dist/esm/voltra/models/device.js.map +1 -0
- package/dist/esm/voltra/models/telemetry/frame.js +40 -0
- package/dist/esm/voltra/models/telemetry/frame.js.map +1 -0
- package/dist/esm/voltra/models/telemetry/index.js +7 -0
- package/dist/esm/voltra/models/telemetry/index.js.map +1 -0
- package/dist/esm/voltra/protocol/commands.js +224 -0
- package/dist/esm/voltra/protocol/commands.js.map +1 -0
- package/dist/esm/voltra/protocol/constants.js +130 -0
- package/dist/esm/voltra/protocol/constants.js.map +1 -0
- package/dist/esm/voltra/protocol/data/chains.json +830 -0
- package/dist/esm/voltra/protocol/data/eccentric.json +1598 -0
- package/dist/esm/voltra/protocol/data/protocol.json +54 -0
- package/dist/esm/voltra/protocol/data/weights.json +62 -0
- package/dist/esm/voltra/protocol/index.js +9 -0
- package/dist/esm/voltra/protocol/index.js.map +1 -0
- package/dist/esm/voltra/protocol/telemetry-decoder.js +140 -0
- package/dist/esm/voltra/protocol/telemetry-decoder.js.map +1 -0
- package/dist/types/bluetooth/adapters/base.d.ts +85 -0
- package/dist/types/bluetooth/adapters/base.d.ts.map +1 -0
- package/dist/types/bluetooth/adapters/index.d.ts +35 -0
- package/dist/types/bluetooth/adapters/index.d.ts.map +1 -0
- package/dist/types/bluetooth/adapters/native.d.ts +109 -0
- package/dist/types/bluetooth/adapters/native.d.ts.map +1 -0
- package/dist/types/bluetooth/adapters/node.d.ts +91 -0
- package/dist/types/bluetooth/adapters/node.d.ts.map +1 -0
- package/dist/types/bluetooth/adapters/types.d.ts +102 -0
- package/dist/types/bluetooth/adapters/types.d.ts.map +1 -0
- package/dist/types/bluetooth/adapters/web-bluetooth-base.d.ts +90 -0
- package/dist/types/bluetooth/adapters/web-bluetooth-base.d.ts.map +1 -0
- package/dist/types/bluetooth/adapters/web.d.ts +57 -0
- package/dist/types/bluetooth/adapters/web.d.ts.map +1 -0
- package/dist/types/bluetooth/controllers/scanner-controller.d.ts +93 -0
- package/dist/types/bluetooth/controllers/scanner-controller.d.ts.map +1 -0
- package/dist/types/bluetooth/index.d.ts +14 -0
- package/dist/types/bluetooth/index.d.ts.map +1 -0
- package/dist/types/bluetooth/models/connection.d.ts +37 -0
- package/dist/types/bluetooth/models/connection.d.ts.map +1 -0
- package/dist/types/bluetooth/models/device.d.ts +25 -0
- package/dist/types/bluetooth/models/device.d.ts.map +1 -0
- package/dist/types/bluetooth/models/environment.d.ts +45 -0
- package/dist/types/bluetooth/models/environment.d.ts.map +1 -0
- package/dist/types/errors.d.ts +113 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/index.d.ts +55 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/react/hooks.d.ts +130 -0
- package/dist/types/react/hooks.d.ts.map +1 -0
- package/dist/types/react/index.d.ts +12 -0
- package/dist/types/react/index.d.ts.map +1 -0
- package/dist/types/sdk/index.d.ts +11 -0
- package/dist/types/sdk/index.d.ts.map +1 -0
- package/dist/types/sdk/types.d.ts +104 -0
- package/dist/types/sdk/types.d.ts.map +1 -0
- package/dist/types/sdk/voltra-client.d.ts +221 -0
- package/dist/types/sdk/voltra-client.d.ts.map +1 -0
- package/dist/types/sdk/voltra-manager.d.ts +226 -0
- package/dist/types/sdk/voltra-manager.d.ts.map +1 -0
- package/dist/types/shared/index.d.ts +5 -0
- package/dist/types/shared/index.d.ts.map +1 -0
- package/dist/types/shared/utils.d.ts +25 -0
- package/dist/types/shared/utils.d.ts.map +1 -0
- package/dist/types/voltra/index.d.ts +13 -0
- package/dist/types/voltra/index.d.ts.map +1 -0
- package/dist/types/voltra/models/connection.d.ts +37 -0
- package/dist/types/voltra/models/connection.d.ts.map +1 -0
- package/dist/types/voltra/models/device-filter.d.ts +19 -0
- package/dist/types/voltra/models/device-filter.d.ts.map +1 -0
- package/dist/types/voltra/models/device.d.ts +105 -0
- package/dist/types/voltra/models/device.d.ts.map +1 -0
- package/dist/types/voltra/models/telemetry/frame.d.ts +41 -0
- package/dist/types/voltra/models/telemetry/frame.d.ts.map +1 -0
- package/dist/types/voltra/models/telemetry/index.d.ts +8 -0
- package/dist/types/voltra/models/telemetry/index.d.ts.map +1 -0
- package/dist/types/voltra/protocol/commands.d.ts +99 -0
- package/dist/types/voltra/protocol/commands.d.ts.map +1 -0
- package/dist/types/voltra/protocol/constants.d.ts +103 -0
- package/dist/types/voltra/protocol/constants.d.ts.map +1 -0
- package/dist/types/voltra/protocol/index.d.ts +9 -0
- package/dist/types/voltra/protocol/index.d.ts.map +1 -0
- package/dist/types/voltra/protocol/telemetry-decoder.d.ts +45 -0
- package/dist/types/voltra/protocol/telemetry-decoder.d.ts.map +1 -0
- package/package.json +111 -0
|
@@ -0,0 +1,473 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Native BLE Adapter
|
|
4
|
+
*
|
|
5
|
+
* Uses react-native-ble-plx for direct BLE communication on iOS/Android.
|
|
6
|
+
* Includes auto-reconnect functionality for seamless app resume.
|
|
7
|
+
*
|
|
8
|
+
* This adapter is generic and can be configured for any BLE device by
|
|
9
|
+
* providing the appropriate service/characteristic UUIDs.
|
|
10
|
+
*
|
|
11
|
+
* IMPORTANT: This adapter requires react-native-ble-plx as a peer dependency.
|
|
12
|
+
* Install it in your React Native project: npm install react-native-ble-plx
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.NativeBLEAdapter = void 0;
|
|
16
|
+
const react_native_ble_plx_1 = require("react-native-ble-plx");
|
|
17
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
18
|
+
// @ts-ignore - React Native imports may not be available in all environments
|
|
19
|
+
const react_native_1 = require("react-native");
|
|
20
|
+
const base_1 = require("./base");
|
|
21
|
+
/**
|
|
22
|
+
* Request Android Bluetooth permissions at runtime.
|
|
23
|
+
* Android 12+ requires BLUETOOTH_SCAN and BLUETOOTH_CONNECT.
|
|
24
|
+
* Android 11 and below require ACCESS_FINE_LOCATION for BLE scanning.
|
|
25
|
+
*/
|
|
26
|
+
async function requestAndroidBLEPermissions() {
|
|
27
|
+
if (react_native_1.Platform.OS !== 'android') {
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
const apiLevel = react_native_1.Platform.Version;
|
|
31
|
+
console.log('[NativeBLE] Android API level:', apiLevel);
|
|
32
|
+
try {
|
|
33
|
+
if (typeof apiLevel === 'number' && apiLevel >= 31) {
|
|
34
|
+
// Android 12+ (API 31+)
|
|
35
|
+
const results = await react_native_1.PermissionsAndroid.requestMultiple([
|
|
36
|
+
react_native_1.PermissionsAndroid.PERMISSIONS.BLUETOOTH_SCAN,
|
|
37
|
+
react_native_1.PermissionsAndroid.PERMISSIONS.BLUETOOTH_CONNECT,
|
|
38
|
+
react_native_1.PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
|
|
39
|
+
]);
|
|
40
|
+
const allGranted = Object.values(results).every((result) => result === react_native_1.PermissionsAndroid.RESULTS.GRANTED);
|
|
41
|
+
if (!allGranted) {
|
|
42
|
+
console.warn('[NativeBLE] Not all permissions granted:', results);
|
|
43
|
+
}
|
|
44
|
+
return allGranted;
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
// Android 11 and below
|
|
48
|
+
const granted = await react_native_1.PermissionsAndroid.request(react_native_1.PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION, {
|
|
49
|
+
title: 'Bluetooth Permission',
|
|
50
|
+
message: 'This app needs access to your location to scan for Bluetooth devices.',
|
|
51
|
+
buttonPositive: 'OK',
|
|
52
|
+
});
|
|
53
|
+
return granted === react_native_1.PermissionsAndroid.RESULTS.GRANTED;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
console.error('[NativeBLE] Permission request error:', error);
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// Base64 encoding/decoding for BLE data
|
|
62
|
+
function base64ToBytes(base64) {
|
|
63
|
+
const binary = atob(base64);
|
|
64
|
+
const bytes = new Uint8Array(binary.length);
|
|
65
|
+
for (let i = 0; i < binary.length; i++) {
|
|
66
|
+
bytes[i] = binary.charCodeAt(i);
|
|
67
|
+
}
|
|
68
|
+
return bytes;
|
|
69
|
+
}
|
|
70
|
+
function bytesToBase64(bytes) {
|
|
71
|
+
let binary = '';
|
|
72
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
73
|
+
binary += String.fromCharCode(bytes[i]);
|
|
74
|
+
}
|
|
75
|
+
return btoa(binary);
|
|
76
|
+
}
|
|
77
|
+
const DEFAULT_RECONNECT_CONFIG = {
|
|
78
|
+
autoReconnect: true,
|
|
79
|
+
maxReconnectAttempts: 3,
|
|
80
|
+
reconnectDelayMs: 1000,
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* BLE adapter using react-native-ble-plx for native device communication.
|
|
84
|
+
* Supports auto-reconnect when app resumes from background.
|
|
85
|
+
*/
|
|
86
|
+
class NativeBLEAdapter extends base_1.BaseBLEAdapter {
|
|
87
|
+
constructor(config) {
|
|
88
|
+
super();
|
|
89
|
+
this.device = null;
|
|
90
|
+
this.notifySubscription = null;
|
|
91
|
+
this.writeSubscription = null;
|
|
92
|
+
// Auto-reconnect state
|
|
93
|
+
this.lastConnectedDeviceId = null;
|
|
94
|
+
this.lastConnectedDeviceName = null;
|
|
95
|
+
this.isReconnecting = false;
|
|
96
|
+
this.reconnectAttempts = 0;
|
|
97
|
+
this.appStateSubscription = null;
|
|
98
|
+
// Disconnect handling - prevents crash when subscriptions error during disconnect
|
|
99
|
+
this.isDisconnecting = false;
|
|
100
|
+
this.disconnectSubscription = null;
|
|
101
|
+
this.bleConfig = config.ble;
|
|
102
|
+
this.autoReconnect = config.autoReconnect ?? DEFAULT_RECONNECT_CONFIG.autoReconnect;
|
|
103
|
+
this.maxReconnectAttempts =
|
|
104
|
+
config.maxReconnectAttempts ?? DEFAULT_RECONNECT_CONFIG.maxReconnectAttempts;
|
|
105
|
+
this.reconnectDelayMs = config.reconnectDelayMs ?? DEFAULT_RECONNECT_CONFIG.reconnectDelayMs;
|
|
106
|
+
this.manager = new react_native_ble_plx_1.BleManager();
|
|
107
|
+
// Set up app state listener for auto-reconnect
|
|
108
|
+
if (this.autoReconnect) {
|
|
109
|
+
this.setupAppStateListener();
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Set up listener for app state changes (background/foreground).
|
|
114
|
+
*/
|
|
115
|
+
setupAppStateListener() {
|
|
116
|
+
this.appStateSubscription = react_native_1.AppState.addEventListener('change', this.handleAppStateChange.bind(this));
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Handle app state changes for auto-reconnect.
|
|
120
|
+
*/
|
|
121
|
+
async handleAppStateChange(nextAppState) {
|
|
122
|
+
if (nextAppState === 'active') {
|
|
123
|
+
// App came to foreground
|
|
124
|
+
console.log('[NativeBLE] App became active');
|
|
125
|
+
// Check if we were connected and got disconnected
|
|
126
|
+
if (this.lastConnectedDeviceId &&
|
|
127
|
+
this.connectionState === 'disconnected' &&
|
|
128
|
+
!this.isReconnecting) {
|
|
129
|
+
console.log('[NativeBLE] Was connected before, attempting auto-reconnect...');
|
|
130
|
+
await this.attemptReconnect();
|
|
131
|
+
}
|
|
132
|
+
else if (this.device) {
|
|
133
|
+
// Check if device is still connected
|
|
134
|
+
const isConnected = await this.device.isConnected();
|
|
135
|
+
if (!isConnected) {
|
|
136
|
+
console.log('[NativeBLE] Device disconnected while in background, attempting reconnect...');
|
|
137
|
+
this.setConnectionState('disconnected');
|
|
138
|
+
await this.attemptReconnect();
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Attempt to reconnect to the last known device.
|
|
145
|
+
*/
|
|
146
|
+
async attemptReconnect() {
|
|
147
|
+
if (!this.lastConnectedDeviceId || this.isReconnecting) {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
this.isReconnecting = true;
|
|
151
|
+
this.reconnectAttempts = 0;
|
|
152
|
+
this.onReconnectStart?.();
|
|
153
|
+
while (this.reconnectAttempts < this.maxReconnectAttempts) {
|
|
154
|
+
this.reconnectAttempts++;
|
|
155
|
+
console.log(`[NativeBLE] Reconnect attempt ${this.reconnectAttempts}/${this.maxReconnectAttempts}`);
|
|
156
|
+
try {
|
|
157
|
+
await this.connect(this.lastConnectedDeviceId);
|
|
158
|
+
console.log('[NativeBLE] Reconnect successful');
|
|
159
|
+
this.isReconnecting = false;
|
|
160
|
+
this.reconnectAttempts = 0;
|
|
161
|
+
this.onReconnectSuccess?.();
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
console.warn(`[NativeBLE] Reconnect attempt ${this.reconnectAttempts} failed:`, error);
|
|
166
|
+
if (this.reconnectAttempts < this.maxReconnectAttempts) {
|
|
167
|
+
await new Promise((resolve) => setTimeout(resolve, this.reconnectDelayMs));
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
// All attempts failed
|
|
172
|
+
console.error('[NativeBLE] Auto-reconnect failed after all attempts');
|
|
173
|
+
this.isReconnecting = false;
|
|
174
|
+
this.onReconnectFailed?.(new Error('Auto-reconnect failed'));
|
|
175
|
+
}
|
|
176
|
+
async waitForPoweredOn() {
|
|
177
|
+
return new Promise((resolve, reject) => {
|
|
178
|
+
const subscription = this.manager.onStateChange((state) => {
|
|
179
|
+
console.log('[NativeBLE] Bluetooth state:', state);
|
|
180
|
+
if (state === react_native_ble_plx_1.State.PoweredOn) {
|
|
181
|
+
subscription.remove();
|
|
182
|
+
resolve();
|
|
183
|
+
}
|
|
184
|
+
else if (state === react_native_ble_plx_1.State.Unauthorized) {
|
|
185
|
+
subscription.remove();
|
|
186
|
+
reject(new Error('Bluetooth permission denied. Please enable in Settings.'));
|
|
187
|
+
}
|
|
188
|
+
else if (state === react_native_ble_plx_1.State.Unsupported) {
|
|
189
|
+
subscription.remove();
|
|
190
|
+
reject(new Error('Bluetooth is not supported on this device.'));
|
|
191
|
+
}
|
|
192
|
+
else if (state === react_native_ble_plx_1.State.PoweredOff) {
|
|
193
|
+
// Don't reject yet - user might turn it on
|
|
194
|
+
console.log('[NativeBLE] Bluetooth is off - waiting for user to enable');
|
|
195
|
+
}
|
|
196
|
+
}, true);
|
|
197
|
+
// Timeout after 10 seconds
|
|
198
|
+
setTimeout(() => {
|
|
199
|
+
subscription.remove();
|
|
200
|
+
reject(new Error('Timeout waiting for Bluetooth. Please ensure Bluetooth is enabled.'));
|
|
201
|
+
}, 10000);
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
async scan(timeout) {
|
|
205
|
+
console.log('[NativeBLE] Starting scan...');
|
|
206
|
+
console.log('[NativeBLE] Looking for service:', this.bleConfig.serviceUUID);
|
|
207
|
+
if (this.bleConfig.deviceNamePrefix) {
|
|
208
|
+
console.log('[NativeBLE] Device name prefix:', this.bleConfig.deviceNamePrefix);
|
|
209
|
+
}
|
|
210
|
+
// Request Android permissions first
|
|
211
|
+
const hasPermissions = await requestAndroidBLEPermissions();
|
|
212
|
+
if (!hasPermissions) {
|
|
213
|
+
throw new Error('Bluetooth permissions not granted. Please enable in Settings.');
|
|
214
|
+
}
|
|
215
|
+
console.log('[NativeBLE] Permissions granted');
|
|
216
|
+
await this.waitForPoweredOn();
|
|
217
|
+
console.log('[NativeBLE] Bluetooth is powered on');
|
|
218
|
+
const devices = [];
|
|
219
|
+
const seen = new Set();
|
|
220
|
+
const prefix = this.bleConfig.deviceNamePrefix;
|
|
221
|
+
return new Promise((resolve, _reject) => {
|
|
222
|
+
// Scan for all devices (filtering is done by name prefix if configured)
|
|
223
|
+
this.manager.startDeviceScan(null, // No service filter - scan for all devices
|
|
224
|
+
{ allowDuplicates: false }, (error, device) => {
|
|
225
|
+
if (error) {
|
|
226
|
+
console.error('[NativeBLE] Scan error:', error);
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
if (device) {
|
|
230
|
+
// Log all devices with names for debugging
|
|
231
|
+
if (device.name) {
|
|
232
|
+
console.log(`[NativeBLE] Found device: ${device.name} (${device.id})`);
|
|
233
|
+
}
|
|
234
|
+
// Check if device matches filter (if prefix is configured)
|
|
235
|
+
const matchesFilter = !prefix || device.name?.startsWith(prefix) || device.localName?.startsWith(prefix);
|
|
236
|
+
if (matchesFilter && !seen.has(device.id) && (device.name || device.localName)) {
|
|
237
|
+
console.log(`[NativeBLE] ✓ Found matching device: ${device.name || device.localName}`);
|
|
238
|
+
seen.add(device.id);
|
|
239
|
+
devices.push({
|
|
240
|
+
id: device.id,
|
|
241
|
+
name: device.name || device.localName || 'Unknown Device',
|
|
242
|
+
rssi: device.rssi,
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
// Stop scan after timeout
|
|
248
|
+
setTimeout(() => {
|
|
249
|
+
this.manager.stopDeviceScan();
|
|
250
|
+
console.log(`[NativeBLE] Scan complete. Found ${devices.length} device(s)`);
|
|
251
|
+
resolve(devices);
|
|
252
|
+
}, timeout * 1000);
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
async connect(deviceId, options) {
|
|
256
|
+
// Request Android permissions first
|
|
257
|
+
const hasPermissions = await requestAndroidBLEPermissions();
|
|
258
|
+
if (!hasPermissions) {
|
|
259
|
+
throw new Error('Bluetooth permissions not granted. Please enable in Settings.');
|
|
260
|
+
}
|
|
261
|
+
await this.waitForPoweredOn();
|
|
262
|
+
this.setConnectionState('connecting');
|
|
263
|
+
try {
|
|
264
|
+
// Connect to device - don't request MTU yet, we need to authenticate first
|
|
265
|
+
const device = await this.manager.connectToDevice(deviceId, {
|
|
266
|
+
autoConnect: false, // Use direct connection for faster connect on Android
|
|
267
|
+
});
|
|
268
|
+
this.device = device;
|
|
269
|
+
this.lastConnectedDeviceId = deviceId;
|
|
270
|
+
this.lastConnectedDeviceName = device.name;
|
|
271
|
+
// Discover services and characteristics FIRST (needed for immediate write)
|
|
272
|
+
await device.discoverAllServicesAndCharacteristics();
|
|
273
|
+
// If immediate write is provided, send it NOW before anything else
|
|
274
|
+
// This is critical for devices that require fast authentication
|
|
275
|
+
if (options?.immediateWrite) {
|
|
276
|
+
console.log('[NativeBLE] Sending immediate auth write...');
|
|
277
|
+
const base64 = bytesToBase64(options.immediateWrite);
|
|
278
|
+
await device.writeCharacteristicWithResponseForService(this.bleConfig.serviceUUID, this.bleConfig.writeCharUUID, base64);
|
|
279
|
+
console.log('[NativeBLE] Immediate auth write sent');
|
|
280
|
+
}
|
|
281
|
+
// Now request MTU (optional, may fail on some devices)
|
|
282
|
+
try {
|
|
283
|
+
await device.requestMTU(512);
|
|
284
|
+
}
|
|
285
|
+
catch (mtuError) {
|
|
286
|
+
console.log('[NativeBLE] MTU request failed (non-fatal):', mtuError);
|
|
287
|
+
}
|
|
288
|
+
// Set up disconnect listener BEFORE setting up characteristic monitors
|
|
289
|
+
// This ensures we can clean up subscriptions before the error propagates
|
|
290
|
+
this.disconnectSubscription = device.onDisconnected((error, _disconnectedDevice) => {
|
|
291
|
+
console.log('[NativeBLE] Device disconnected', error ? `(error: ${error.message})` : '');
|
|
292
|
+
// Mark as disconnecting to prevent monitor errors from crashing
|
|
293
|
+
this.isDisconnecting = true;
|
|
294
|
+
// Clean up subscriptions IMMEDIATELY to prevent RxJava crash
|
|
295
|
+
this.cleanupSubscriptions();
|
|
296
|
+
this.setConnectionState('disconnected');
|
|
297
|
+
this.device = null;
|
|
298
|
+
this.isDisconnecting = false;
|
|
299
|
+
// Don't clear lastConnectedDeviceId - we want to try reconnecting
|
|
300
|
+
});
|
|
301
|
+
// Subscribe to notifications on notify characteristic
|
|
302
|
+
// Error callback must handle disconnect gracefully to avoid Android crash
|
|
303
|
+
this.notifySubscription = device.monitorCharacteristicForService(this.bleConfig.serviceUUID, this.bleConfig.notifyCharUUID, (error, characteristic) => {
|
|
304
|
+
if (error) {
|
|
305
|
+
// Ignore errors if we're disconnecting - this prevents the Android crash
|
|
306
|
+
if (this.isDisconnecting || !this.device) {
|
|
307
|
+
console.log('[NativeBLE] Notification error during disconnect (ignored):', error.message);
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
console.error('[NativeBLE] Notification error:', error);
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
if (characteristic?.value) {
|
|
314
|
+
const bytes = base64ToBytes(characteristic.value);
|
|
315
|
+
this.emitNotification(bytes);
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
// Also subscribe to write characteristic (it also sends notifications)
|
|
319
|
+
// Error callback must handle disconnect gracefully to avoid Android crash
|
|
320
|
+
this.writeSubscription = device.monitorCharacteristicForService(this.bleConfig.serviceUUID, this.bleConfig.writeCharUUID, (error, characteristic) => {
|
|
321
|
+
if (error) {
|
|
322
|
+
// Ignore errors if we're disconnecting - this prevents the Android crash
|
|
323
|
+
if (this.isDisconnecting || !this.device) {
|
|
324
|
+
console.log('[NativeBLE] Write char error during disconnect (ignored):', error.message);
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
console.error('[NativeBLE] Write char notification error:', error);
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
if (characteristic?.value) {
|
|
331
|
+
const bytes = base64ToBytes(characteristic.value);
|
|
332
|
+
this.emitNotification(bytes);
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
this.setConnectionState('connected');
|
|
336
|
+
}
|
|
337
|
+
catch (error) {
|
|
338
|
+
console.error('[NativeBLE] Connect error:', error);
|
|
339
|
+
this.setConnectionState('disconnected');
|
|
340
|
+
throw error;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
cleanupSubscriptions() {
|
|
344
|
+
// Clean up characteristic monitor subscriptions
|
|
345
|
+
// Must be done synchronously to prevent RxJava crash on Android
|
|
346
|
+
if (this.notifySubscription) {
|
|
347
|
+
try {
|
|
348
|
+
this.notifySubscription.remove();
|
|
349
|
+
}
|
|
350
|
+
catch (e) {
|
|
351
|
+
console.log('[NativeBLE] Error removing notify subscription:', e);
|
|
352
|
+
}
|
|
353
|
+
this.notifySubscription = null;
|
|
354
|
+
}
|
|
355
|
+
if (this.writeSubscription) {
|
|
356
|
+
try {
|
|
357
|
+
this.writeSubscription.remove();
|
|
358
|
+
}
|
|
359
|
+
catch (e) {
|
|
360
|
+
console.log('[NativeBLE] Error removing write subscription:', e);
|
|
361
|
+
}
|
|
362
|
+
this.writeSubscription = null;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
cleanupAllSubscriptions() {
|
|
366
|
+
this.cleanupSubscriptions();
|
|
367
|
+
if (this.disconnectSubscription) {
|
|
368
|
+
try {
|
|
369
|
+
this.disconnectSubscription.remove();
|
|
370
|
+
}
|
|
371
|
+
catch (e) {
|
|
372
|
+
console.log('[NativeBLE] Error removing disconnect subscription:', e);
|
|
373
|
+
}
|
|
374
|
+
this.disconnectSubscription = null;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
async disconnect() {
|
|
378
|
+
this.setConnectionState('disconnecting');
|
|
379
|
+
// Mark as disconnecting to prevent monitor errors from crashing
|
|
380
|
+
this.isDisconnecting = true;
|
|
381
|
+
// Clean up all subscriptions BEFORE canceling connection
|
|
382
|
+
// This prevents the RxJava crash on Android
|
|
383
|
+
this.cleanupAllSubscriptions();
|
|
384
|
+
if (this.device) {
|
|
385
|
+
try {
|
|
386
|
+
await this.device.cancelConnection();
|
|
387
|
+
}
|
|
388
|
+
catch (error) {
|
|
389
|
+
console.error('[NativeBLE] Disconnect error:', error);
|
|
390
|
+
}
|
|
391
|
+
this.device = null;
|
|
392
|
+
}
|
|
393
|
+
// Clear last device so we don't auto-reconnect after intentional disconnect
|
|
394
|
+
this.lastConnectedDeviceId = null;
|
|
395
|
+
this.lastConnectedDeviceName = null;
|
|
396
|
+
this.isDisconnecting = false;
|
|
397
|
+
this.setConnectionState('disconnected');
|
|
398
|
+
}
|
|
399
|
+
async write(data) {
|
|
400
|
+
if (!this.device) {
|
|
401
|
+
throw new Error('Not connected to device');
|
|
402
|
+
}
|
|
403
|
+
const base64 = bytesToBase64(data);
|
|
404
|
+
await this.device.writeCharacteristicWithResponseForService(this.bleConfig.serviceUUID, this.bleConfig.writeCharUUID, base64);
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Override isConnected to also check if device exists.
|
|
408
|
+
*/
|
|
409
|
+
isConnected() {
|
|
410
|
+
return super.isConnected() && this.device !== null;
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* Get info about the currently connected device.
|
|
414
|
+
*/
|
|
415
|
+
getConnectedDevice() {
|
|
416
|
+
if (!this.device)
|
|
417
|
+
return null;
|
|
418
|
+
return {
|
|
419
|
+
id: this.device.id,
|
|
420
|
+
name: this.device.name,
|
|
421
|
+
rssi: null, // Not available after connection
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* Get the last connected device ID (for reconnection).
|
|
426
|
+
*/
|
|
427
|
+
getLastConnectedDeviceId() {
|
|
428
|
+
return this.lastConnectedDeviceId;
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* Set callbacks for reconnect events.
|
|
432
|
+
*/
|
|
433
|
+
setReconnectCallbacks(callbacks) {
|
|
434
|
+
this.onReconnectStart = callbacks.onStart;
|
|
435
|
+
this.onReconnectSuccess = callbacks.onSuccess;
|
|
436
|
+
this.onReconnectFailed = callbacks.onFailed;
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* Manually trigger a reconnect attempt.
|
|
440
|
+
*/
|
|
441
|
+
async reconnect() {
|
|
442
|
+
if (this.lastConnectedDeviceId) {
|
|
443
|
+
await this.connect(this.lastConnectedDeviceId);
|
|
444
|
+
}
|
|
445
|
+
else {
|
|
446
|
+
throw new Error('No previous device to reconnect to');
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* Set the last connected device (for restoring from storage).
|
|
451
|
+
*/
|
|
452
|
+
setLastConnectedDevice(deviceId, deviceName) {
|
|
453
|
+
this.lastConnectedDeviceId = deviceId;
|
|
454
|
+
this.lastConnectedDeviceName = deviceName ?? null;
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* Check if auto-reconnect is in progress.
|
|
458
|
+
*/
|
|
459
|
+
isAutoReconnecting() {
|
|
460
|
+
return this.isReconnecting;
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Destroy the BLE manager (call when app is closing).
|
|
464
|
+
*/
|
|
465
|
+
destroy() {
|
|
466
|
+
this.isDisconnecting = true;
|
|
467
|
+
this.appStateSubscription?.remove();
|
|
468
|
+
this.cleanupAllSubscriptions();
|
|
469
|
+
this.manager.destroy();
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
exports.NativeBLEAdapter = NativeBLEAdapter;
|
|
473
|
+
//# sourceMappingURL=native.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native.js","sourceRoot":"","sources":["../../../../src/bluetooth/adapters/native.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;;AAEH,+DAAmF;AACnF,6DAA6D;AAC7D,6EAA6E;AAC7E,+CAA2F;AAC3F,iCAAwC;AAMxC;;;;GAIG;AACH,KAAK,UAAU,4BAA4B;IACzC,IAAI,uBAAQ,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,QAAQ,GAAG,uBAAQ,CAAC,OAAO,CAAC;IAClC,OAAO,CAAC,GAAG,CAAC,gCAAgC,EAAE,QAAQ,CAAC,CAAC;IAExD,IAAI,CAAC;QACH,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,IAAI,EAAE,EAAE,CAAC;YACnD,wBAAwB;YACxB,MAAM,OAAO,GAAG,MAAM,iCAAkB,CAAC,eAAe,CAAC;gBACvD,iCAAkB,CAAC,WAAW,CAAC,cAAc;gBAC7C,iCAAkB,CAAC,WAAW,CAAC,iBAAiB;gBAChD,iCAAkB,CAAC,WAAW,CAAC,oBAAoB;aACpD,CAAC,CAAC;YAEH,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,CAC7C,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,KAAK,iCAAkB,CAAC,OAAO,CAAC,OAAO,CAC1D,CAAC;YAEF,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,OAAO,CAAC,IAAI,CAAC,0CAA0C,EAAE,OAAO,CAAC,CAAC;YACpE,CAAC;YAED,OAAO,UAAU,CAAC;QACpB,CAAC;aAAM,CAAC;YACN,uBAAuB;YACvB,MAAM,OAAO,GAAG,MAAM,iCAAkB,CAAC,OAAO,CAC9C,iCAAkB,CAAC,WAAW,CAAC,oBAAoB,EACnD;gBACE,KAAK,EAAE,sBAAsB;gBAC7B,OAAO,EAAE,uEAAuE;gBAChF,cAAc,EAAE,IAAI;aACrB,CACF,CAAC;YAEF,OAAO,OAAO,KAAK,iCAAkB,CAAC,OAAO,CAAC,OAAO,CAAC;QACxD,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,uCAAuC,EAAE,KAAK,CAAC,CAAC;QAC9D,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,wCAAwC;AACxC,SAAS,aAAa,CAAC,MAAc;IACnC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5B,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,aAAa,CAAC,KAAiB;IACtC,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC;AACtB,CAAC;AAgBD,MAAM,wBAAwB,GAAG;IAC/B,aAAa,EAAE,IAAI;IACnB,oBAAoB,EAAE,CAAC;IACvB,gBAAgB,EAAE,IAAI;CACvB,CAAC;AAEF;;;GAGG;AACH,MAAa,gBAAiB,SAAQ,qBAAc;IA0BlD,YAAY,MAA2B;QACrC,KAAK,EAAE,CAAC;QAzBF,WAAM,GAAqB,IAAI,CAAC;QAChC,uBAAkB,GAAkC,IAAI,CAAC;QACzD,sBAAiB,GAAkC,IAAI,CAAC;QAMhE,uBAAuB;QACf,0BAAqB,GAAkB,IAAI,CAAC;QAC5C,4BAAuB,GAAkB,IAAI,CAAC;QAC9C,mBAAc,GAAY,KAAK,CAAC;QAChC,sBAAiB,GAAW,CAAC,CAAC;QAC9B,yBAAoB,GAAkC,IAAI,CAAC;QAEnE,kFAAkF;QAC1E,oBAAe,GAAY,KAAK,CAAC;QACjC,2BAAsB,GAAkC,IAAI,CAAC;QASnE,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC;QAC5B,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC,aAAa,IAAI,wBAAwB,CAAC,aAAa,CAAC;QACpF,IAAI,CAAC,oBAAoB;YACvB,MAAM,CAAC,oBAAoB,IAAI,wBAAwB,CAAC,oBAAoB,CAAC;QAC/E,IAAI,CAAC,gBAAgB,GAAG,MAAM,CAAC,gBAAgB,IAAI,wBAAwB,CAAC,gBAAgB,CAAC;QAC7F,IAAI,CAAC,OAAO,GAAG,IAAI,iCAAU,EAAE,CAAC;QAEhC,+CAA+C;QAC/C,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC/B,CAAC;IACH,CAAC;IAED;;OAEG;IACK,qBAAqB;QAC3B,IAAI,CAAC,oBAAoB,GAAG,uBAAQ,CAAC,gBAAgB,CACnD,QAAQ,EACR,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,CACrC,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,oBAAoB,CAAC,YAA4B;QAC7D,IAAI,YAAY,KAAK,QAAQ,EAAE,CAAC;YAC9B,yBAAyB;YACzB,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;YAE7C,kDAAkD;YAClD,IACE,IAAI,CAAC,qBAAqB;gBAC1B,IAAI,CAAC,eAAe,KAAK,cAAc;gBACvC,CAAC,IAAI,CAAC,cAAc,EACpB,CAAC;gBACD,OAAO,CAAC,GAAG,CAAC,gEAAgE,CAAC,CAAC;gBAC9E,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAChC,CAAC;iBAAM,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBACvB,qCAAqC;gBACrC,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;gBACpD,IAAI,CAAC,WAAW,EAAE,CAAC;oBACjB,OAAO,CAAC,GAAG,CACT,8EAA8E,CAC/E,CAAC;oBACF,IAAI,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAC;oBACxC,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBAChC,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,gBAAgB;QAC5B,IAAI,CAAC,IAAI,CAAC,qBAAqB,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACvD,OAAO;QACT,CAAC;QAED,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC3B,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC;QAC3B,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC;QAE1B,OAAO,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC1D,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACzB,OAAO,CAAC,GAAG,CACT,iCAAiC,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAC,oBAAoB,EAAE,CACvF,CAAC;YAEF,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;gBAC/C,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;gBAChD,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;gBAC5B,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC;gBAC3B,IAAI,CAAC,kBAAkB,EAAE,EAAE,CAAC;gBAC5B,OAAO;YACT,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,IAAI,CAAC,iCAAiC,IAAI,CAAC,iBAAiB,UAAU,EAAE,KAAK,CAAC,CAAC;gBAEvF,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC;oBACvD,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;gBAC7E,CAAC;YACH,CAAC;QACH,CAAC;QAED,sBAAsB;QACtB,OAAO,CAAC,KAAK,CAAC,sDAAsD,CAAC,CAAC;QACtE,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;QAC5B,IAAI,CAAC,iBAAiB,EAAE,CAAC,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC,CAAC;IAC/D,CAAC;IAEO,KAAK,CAAC,gBAAgB;QAC5B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,KAAK,EAAE,EAAE;gBACxD,OAAO,CAAC,GAAG,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;gBACnD,IAAI,KAAK,KAAK,4BAAK,CAAC,SAAS,EAAE,CAAC;oBAC9B,YAAY,CAAC,MAAM,EAAE,CAAC;oBACtB,OAAO,EAAE,CAAC;gBACZ,CAAC;qBAAM,IAAI,KAAK,KAAK,4BAAK,CAAC,YAAY,EAAE,CAAC;oBACxC,YAAY,CAAC,MAAM,EAAE,CAAC;oBACtB,MAAM,CAAC,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC,CAAC;gBAC/E,CAAC;qBAAM,IAAI,KAAK,KAAK,4BAAK,CAAC,WAAW,EAAE,CAAC;oBACvC,YAAY,CAAC,MAAM,EAAE,CAAC;oBACtB,MAAM,CAAC,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC,CAAC;gBAClE,CAAC;qBAAM,IAAI,KAAK,KAAK,4BAAK,CAAC,UAAU,EAAE,CAAC;oBACtC,2CAA2C;oBAC3C,OAAO,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAC;gBAC3E,CAAC;YACH,CAAC,EAAE,IAAI,CAAC,CAAC;YAET,2BAA2B;YAC3B,UAAU,CAAC,GAAG,EAAE;gBACd,YAAY,CAAC,MAAM,EAAE,CAAC;gBACtB,MAAM,CAAC,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC,CAAC;YAC1F,CAAC,EAAE,KAAK,CAAC,CAAC;QACZ,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,OAAe;QACxB,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;QAC5C,OAAO,CAAC,GAAG,CAAC,kCAAkC,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAC5E,IAAI,IAAI,CAAC,SAAS,CAAC,gBAAgB,EAAE,CAAC;YACpC,OAAO,CAAC,GAAG,CAAC,iCAAiC,EAAE,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;QAClF,CAAC;QAED,oCAAoC;QACpC,MAAM,cAAc,GAAG,MAAM,4BAA4B,EAAE,CAAC;QAC5D,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;QACnF,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;QAE/C,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;QAEnD,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC;QAE/C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE;YACtC,wEAAwE;YACxE,IAAI,CAAC,OAAO,CAAC,eAAe,CAC1B,IAAI,EAAE,2CAA2C;YACjD,EAAE,eAAe,EAAE,KAAK,EAAE,EAC1B,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;gBAChB,IAAI,KAAK,EAAE,CAAC;oBACV,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;oBAChD,OAAO;gBACT,CAAC;gBAED,IAAI,MAAM,EAAE,CAAC;oBACX,2CAA2C;oBAC3C,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;wBAChB,OAAO,CAAC,GAAG,CAAC,6BAA6B,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,EAAE,GAAG,CAAC,CAAC;oBACzE,CAAC;oBAED,2DAA2D;oBAC3D,MAAM,aAAa,GACjB,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,SAAS,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;oBAErF,IAAI,aAAa,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;wBAC/E,OAAO,CAAC,GAAG,CACT,wCAAwC,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,SAAS,EAAE,CAC1E,CAAC;wBACF,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;wBACpB,OAAO,CAAC,IAAI,CAAC;4BACX,EAAE,EAAE,MAAM,CAAC,EAAE;4BACb,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,SAAS,IAAI,gBAAgB;4BACzD,IAAI,EAAE,MAAM,CAAC,IAAI;yBAClB,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;YACH,CAAC,CACF,CAAC;YAEF,0BAA0B;YAC1B,UAAU,CAAC,GAAG,EAAE;gBACd,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;gBAC9B,OAAO,CAAC,GAAG,CAAC,oCAAoC,OAAO,CAAC,MAAM,YAAY,CAAC,CAAC;gBAC5E,OAAO,CAAC,OAAO,CAAC,CAAC;YACnB,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC,CAAC;QACrB,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,QAAgB,EAAE,OAAwB;QACtD,oCAAoC;QACpC,MAAM,cAAc,GAAG,MAAM,4BAA4B,EAAE,CAAC;QAC5D,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;QACnF,CAAC;QAED,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAE9B,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC;QAEtC,IAAI,CAAC;YACH,2EAA2E;YAC3E,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,QAAQ,EAAE;gBAC1D,WAAW,EAAE,KAAK,EAAE,sDAAsD;aAC3E,CAAC,CAAC;YAEH,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;YACrB,IAAI,CAAC,qBAAqB,GAAG,QAAQ,CAAC;YACtC,IAAI,CAAC,uBAAuB,GAAG,MAAM,CAAC,IAAI,CAAC;YAE3C,2EAA2E;YAC3E,MAAM,MAAM,CAAC,qCAAqC,EAAE,CAAC;YAErD,mEAAmE;YACnE,gEAAgE;YAChE,IAAI,OAAO,EAAE,cAAc,EAAE,CAAC;gBAC5B,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;gBAC3D,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;gBACrD,MAAM,MAAM,CAAC,yCAAyC,CACpD,IAAI,CAAC,SAAS,CAAC,WAAW,EAC1B,IAAI,CAAC,SAAS,CAAC,aAAa,EAC5B,MAAM,CACP,CAAC;gBACF,OAAO,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC;YACvD,CAAC;YAED,uDAAuD;YACvD,IAAI,CAAC;gBACH,MAAM,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;YAC/B,CAAC;YAAC,OAAO,QAAQ,EAAE,CAAC;gBAClB,OAAO,CAAC,GAAG,CAAC,6CAA6C,EAAE,QAAQ,CAAC,CAAC;YACvE,CAAC;YAED,uEAAuE;YACvE,yEAAyE;YACzE,IAAI,CAAC,sBAAsB,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC,KAAK,EAAE,mBAAmB,EAAE,EAAE;gBACjF,OAAO,CAAC,GAAG,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAC,CAAC,WAAW,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBAEzF,gEAAgE;gBAChE,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;gBAE5B,6DAA6D;gBAC7D,IAAI,CAAC,oBAAoB,EAAE,CAAC;gBAE5B,IAAI,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAC;gBACxC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;gBACnB,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;gBAE7B,kEAAkE;YACpE,CAAC,CAAC,CAAC;YAEH,sDAAsD;YACtD,0EAA0E;YAC1E,IAAI,CAAC,kBAAkB,GAAG,MAAM,CAAC,+BAA+B,CAC9D,IAAI,CAAC,SAAS,CAAC,WAAW,EAC1B,IAAI,CAAC,SAAS,CAAC,cAAc,EAC7B,CAAC,KAAK,EAAE,cAAc,EAAE,EAAE;gBACxB,IAAI,KAAK,EAAE,CAAC;oBACV,yEAAyE;oBACzE,IAAI,IAAI,CAAC,eAAe,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;wBACzC,OAAO,CAAC,GAAG,CACT,6DAA6D,EAC7D,KAAK,CAAC,OAAO,CACd,CAAC;wBACF,OAAO;oBACT,CAAC;oBACD,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAC;oBACxD,OAAO;gBACT,CAAC;gBACD,IAAI,cAAc,EAAE,KAAK,EAAE,CAAC;oBAC1B,MAAM,KAAK,GAAG,aAAa,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;oBAClD,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;gBAC/B,CAAC;YACH,CAAC,CACF,CAAC;YAEF,uEAAuE;YACvE,0EAA0E;YAC1E,IAAI,CAAC,iBAAiB,GAAG,MAAM,CAAC,+BAA+B,CAC7D,IAAI,CAAC,SAAS,CAAC,WAAW,EAC1B,IAAI,CAAC,SAAS,CAAC,aAAa,EAC5B,CAAC,KAAK,EAAE,cAAc,EAAE,EAAE;gBACxB,IAAI,KAAK,EAAE,CAAC;oBACV,yEAAyE;oBACzE,IAAI,IAAI,CAAC,eAAe,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;wBACzC,OAAO,CAAC,GAAG,CACT,2DAA2D,EAC3D,KAAK,CAAC,OAAO,CACd,CAAC;wBACF,OAAO;oBACT,CAAC;oBACD,OAAO,CAAC,KAAK,CAAC,4CAA4C,EAAE,KAAK,CAAC,CAAC;oBACnE,OAAO;gBACT,CAAC;gBACD,IAAI,cAAc,EAAE,KAAK,EAAE,CAAC;oBAC1B,MAAM,KAAK,GAAG,aAAa,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;oBAClD,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;gBAC/B,CAAC;YACH,CAAC,CACF,CAAC;YAEF,IAAI,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAC;QACvC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,KAAK,CAAC,CAAC;YACnD,IAAI,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAC;YACxC,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAEO,oBAAoB;QAC1B,gDAAgD;QAChD,gEAAgE;QAChE,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC5B,IAAI,CAAC;gBACH,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE,CAAC;YACnC,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,OAAO,CAAC,GAAG,CAAC,iDAAiD,EAAE,CAAC,CAAC,CAAC;YACpE,CAAC;YACD,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;QACjC,CAAC;QACD,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC3B,IAAI,CAAC;gBACH,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE,CAAC;YAClC,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,OAAO,CAAC,GAAG,CAAC,gDAAgD,EAAE,CAAC,CAAC,CAAC;YACnE,CAAC;YACD,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAChC,CAAC;IACH,CAAC;IAEO,uBAAuB;QAC7B,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC5B,IAAI,IAAI,CAAC,sBAAsB,EAAE,CAAC;YAChC,IAAI,CAAC;gBACH,IAAI,CAAC,sBAAsB,CAAC,MAAM,EAAE,CAAC;YACvC,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,OAAO,CAAC,GAAG,CAAC,qDAAqD,EAAE,CAAC,CAAC,CAAC;YACxE,CAAC;YACD,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC;QACrC,CAAC;IACH,CAAC;IAED,KAAK,CAAC,UAAU;QACd,IAAI,CAAC,kBAAkB,CAAC,eAAe,CAAC,CAAC;QAEzC,gEAAgE;QAChE,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QAE5B,yDAAyD;QACzD,4CAA4C;QAC5C,IAAI,CAAC,uBAAuB,EAAE,CAAC;QAE/B,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,MAAM,CAAC,gBAAgB,EAAE,CAAC;YACvC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,KAAK,CAAC,CAAC;YACxD,CAAC;YACD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACrB,CAAC;QAED,4EAA4E;QAC5E,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC;QAClC,IAAI,CAAC,uBAAuB,GAAG,IAAI,CAAC;QACpC,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;QAE7B,IAAI,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,IAAgB;QAC1B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;QAC7C,CAAC;QAED,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;QAEnC,MAAM,IAAI,CAAC,MAAM,CAAC,yCAAyC,CACzD,IAAI,CAAC,SAAS,CAAC,WAAW,EAC1B,IAAI,CAAC,SAAS,CAAC,aAAa,EAC5B,MAAM,CACP,CAAC;IACJ,CAAC;IAED;;OAEG;IACM,WAAW;QAClB,OAAO,KAAK,CAAC,WAAW,EAAE,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC;IACrD,CAAC;IAED;;OAEG;IACH,kBAAkB;QAChB,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QAC9B,OAAO;YACL,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE;YAClB,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI;YACtB,IAAI,EAAE,IAAI,EAAE,iCAAiC;SAC9C,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,wBAAwB;QACtB,OAAO,IAAI,CAAC,qBAAqB,CAAC;IACpC,CAAC;IAED;;OAEG;IACH,qBAAqB,CAAC,SAIrB;QACC,IAAI,CAAC,gBAAgB,GAAG,SAAS,CAAC,OAAO,CAAC;QAC1C,IAAI,CAAC,kBAAkB,GAAG,SAAS,CAAC,SAAS,CAAC;QAC9C,IAAI,CAAC,iBAAiB,GAAG,SAAS,CAAC,QAAQ,CAAC;IAC9C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,SAAS;QACb,IAAI,IAAI,CAAC,qBAAqB,EAAE,CAAC;YAC/B,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;QACjD,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACxD,CAAC;IACH,CAAC;IAED;;OAEG;IACH,sBAAsB,CAAC,QAAgB,EAAE,UAAmB;QAC1D,IAAI,CAAC,qBAAqB,GAAG,QAAQ,CAAC;QACtC,IAAI,CAAC,uBAAuB,GAAG,UAAU,IAAI,IAAI,CAAC;IACpD,CAAC;IAED;;OAEG;IACH,kBAAkB;QAChB,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,OAAO;QACL,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QAC5B,IAAI,CAAC,oBAAoB,EAAE,MAAM,EAAE,CAAC;QACpC,IAAI,CAAC,uBAAuB,EAAE,CAAC;QAC/B,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;IACzB,CAAC;CACF;AAleD,4CAkeC"}
|