qlsdk2 0.3.0a3__py3-none-any.whl → 0.4.0__py3-none-any.whl

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.
qlsdk/rsc/paradigm.py ADDED
@@ -0,0 +1,313 @@
1
+ from enum import Enum
2
+ from abc import ABC, abstractmethod
3
+ from loguru import logger
4
+ import struct
5
+
6
+ from qlsdk.core import to_bytes, to_channels
7
+
8
+ class C64Channel(Enum):
9
+ CH0 = 0
10
+ CH1 = 1
11
+ CH2 = 2
12
+ CH3 = 3
13
+ CH4 = 4
14
+ CH5 = 5
15
+ CH6 = 6
16
+ CH7 = 7
17
+ CH8 = 8
18
+ CH9 = 9
19
+ CH10 = 10
20
+ CH11 = 11
21
+ CH12 = 12
22
+ CH13 = 13
23
+ CH14 = 14
24
+ CH15 = 15
25
+
26
+ class WaveForm(Enum):
27
+ DC = 0
28
+ PULSE = 1
29
+ AC = 2
30
+ SQUARE = 3
31
+
32
+ class StimulationChannel(ABC):
33
+ def __init__(self, channel_id: int, wave_form: int, current: float, duration: float, ramp_up: float = None, ramp_down: float = None,):
34
+ self.channel_id = channel_id
35
+ self.wave_form = wave_form
36
+ self.current_max = current
37
+ self.current_min = 0
38
+ self.duration = duration
39
+ self.ramp_up = ramp_up
40
+ self.ramp_down = ramp_down
41
+ self.delay_time = 0
42
+ self.frequency = 0
43
+ self.phase_position = 0
44
+ # 预留值,用作占位
45
+ self.reserved = 0
46
+
47
+ def to_bytes(self):
48
+ result = self.channel_id.to_bytes(1, 'little')
49
+ result += self.wave_form.to_bytes(1, 'little')
50
+ result += int(self.current_max * 1000 ).to_bytes(2, 'little', signed = True)
51
+ result += int(self.current_min * 1000 ).to_bytes(2, 'little', signed = True)
52
+ result += struct.pack('<f', self.frequency)
53
+ result += struct.pack('<f', self.phase_position)
54
+
55
+ result += self._ext_bytes()
56
+
57
+ result += int(self.delay_time).to_bytes(4, 'little')
58
+ result += int(self.ramp_up * 1000).to_bytes(4, 'little')
59
+ result += int((self.duration + self.ramp_up) * 1000).to_bytes(4, 'little')
60
+ result += int(self.ramp_down * 1000).to_bytes(4, 'little')
61
+
62
+ return result
63
+
64
+ def _ext_bytes(self):
65
+ return bytes.fromhex("00000000000000000000000000000000")
66
+
67
+ def to_json(self):
68
+ pass
69
+
70
+ def from_json(self, param):
71
+ pass
72
+
73
+ def __str__(self):
74
+ return f"ACStimulation(channel_id={self.channel_id}, waveform={self.waveform}, current={self.current_max}, duration={self.duration}, ramp_up={self.ramp_up}, ramp_down={self.ramp_down}, frequency={self.frequency}, phase_position={self.phase_position}, duration_delay={self.duration_delay})"
75
+
76
+
77
+
78
+ # 刺激模式-直流
79
+ class DCStimulation(StimulationChannel):
80
+ '''
81
+ channel_id: int, 通道编号,从0开始
82
+ current: float, 电流值,单位为mA
83
+ duration: float, 刺激时间,单位为秒
84
+ ramp_up: float, 上升时间,单位为秒
85
+ ramp_down: float, 下降时间,单位为秒
86
+ '''
87
+ def __init__(self, channel_id: int, current: float, duration: float, ramp_up: float = 0, ramp_down: float = 0):
88
+ super().__init__(channel_id, WaveForm.DC.value, current, duration, ramp_up, ramp_down)
89
+ def to_json(self):
90
+ return {
91
+ "channel_id": self.channel_id,
92
+ "waveform": self.wave_form,
93
+ "current_max": self.current_max,
94
+ "duration": self.duration,
95
+ "ramp_up": self.ramp_up,
96
+ "ramp_down": self.ramp_down,
97
+ "frequency": self.frequency,
98
+ "phase_position": self.phase_position,
99
+ "delay_time": self.delay_time
100
+ }
101
+
102
+ def from_json(self, param):
103
+ pass
104
+ def __str__(self):
105
+ return f"ACStimulation(channel_id={self.channel_id}, waveform={self.waveform}, current={self.current_max}, duration={self.duration}, ramp_up={self.ramp_up}, ramp_down={self.ramp_down}, frequency={self.frequency}, phase_position={self.phase_position}, duration_delay={self.duration_delay})"
106
+
107
+
108
+ # 刺激模式-方波
109
+ class SquareWaveStimulation(StimulationChannel):
110
+ '''
111
+ channel_id: int, 通道编号,从0开始
112
+ current: float, 电流值,单位为mA
113
+ duration: float, 刺激时间,单位为秒
114
+ ramp_up: float, 上升时间,单位为秒
115
+ ramp_down: float, 下降时间,单位为秒
116
+ frequency: float, 频率,单位为Hz
117
+ duty_cycle: float, 占空比,高电平时间/周期,范围(0, 100)
118
+ '''
119
+ def __init__(self, channel_id: int, current: float, duration: float, ramp_up: float = 0, ramp_down: float = 0,
120
+ frequency: float = None, duty_cycle: float = 0.5):
121
+ super().__init__(channel_id, WaveForm.SQUARE.value, current, duration, ramp_up, ramp_down)
122
+ self.frequency = frequency
123
+ self.duty_cycle = duty_cycle
124
+
125
+
126
+ def to_bytes(self):
127
+ # Convert the object to bytes for transmission
128
+ result = self.channel_id.to_bytes(1, 'little')
129
+ result += self.wave_form.to_bytes(1, 'little')
130
+ result += int(self.current_max * 1000 * 1000).to_bytes(4, 'little', signed = True)
131
+ # result += int(self.current_min * 1000).to_bytes(2, 'little')
132
+ result += int(self.frequency).to_bytes(2, 'little')
133
+ result += int(self.reserved).to_bytes(2, 'little')
134
+ result += struct.pack('<f', self.duty_cycle)
135
+
136
+ result += self._ext_bytes()
137
+
138
+ result += int(self.delay_time).to_bytes(4, 'little')
139
+ result += int(self.ramp_up * 1000).to_bytes(4, 'little')
140
+ result += int((self.duration + self.ramp_up) * 1000).to_bytes(4, 'little')
141
+ result += int(self.ramp_down * 1000).to_bytes(4, 'little')
142
+
143
+ return result
144
+
145
+ # 刺激模式-交流
146
+ class ACStimulation(StimulationChannel):
147
+ '''
148
+ channel_id: int, 通道编号,从0开始
149
+ current: float, 电流值,单位为mA
150
+ duration: float, 刺激时间,单位为秒
151
+ ramp_up: float, 上升时间,单位为秒
152
+ ramp_down: float, 下降时间,单位为秒
153
+ frequency: float, 频率,单位为Hz
154
+ phase_position: int, 相位位置,单位为度
155
+ '''
156
+
157
+ def __init__(self, channel_id: int, current: float, duration: float, ramp_up: float = 0, ramp_down: float = 0,
158
+ frequency: float = None, phase_position: int = 0):
159
+ super().__init__(channel_id, WaveForm.AC.value, current, duration, ramp_up, ramp_down)
160
+ self.current_max = abs(current)
161
+ self.current_min = -abs(current)
162
+ self.frequency = frequency
163
+ # self.frequency = frequency
164
+ self.phase_position = phase_position
165
+
166
+ def to_json(self):
167
+ return {
168
+ "channel_id": self.channel_id,
169
+ "waveform": self.wave_form,
170
+ "current_max": self.current_max,
171
+ "duration": self.duration,
172
+ "ramp_up": self.ramp_up,
173
+ "ramp_down": self.ramp_down,
174
+ "frequency": self.frequency,
175
+ "phase_position": self.phase_position
176
+ }
177
+
178
+ def from_json(self, param):
179
+ pass
180
+ def __str__(self):
181
+ return f"ACStimulation(channel_id={self.channel_id}, waveform={self.waveform}, current={self.current_max}, duration={self.duration}, ramp_up={self.ramp_up}, ramp_down={self.ramp_down}, frequency={self.frequency}, phase_position={self.phase_position}, duration_delay={self.duration_delay})"
182
+
183
+ # 刺激模式-脉冲
184
+ class PulseStimulation(StimulationChannel):
185
+ '''
186
+ channel_id: int, 通道编号,从0开始
187
+ current: float, 电流值,单位为mA
188
+ duration: float, 刺激时间,单位为秒
189
+ frequency: float, 频率,单位为Hz
190
+ pulse_width: int, 脉冲宽度,单位为uS
191
+ pulse_width_ratio: float, 脉冲宽度比,范围(0, 1)
192
+ pulse_interval: int 脉冲间隔,单位为uS
193
+ ramp_up: float, 上升时间,单位为秒
194
+ ramp_down: float, 下降时间,单位为秒
195
+ delay_time: float, 延迟启动时间,单位为秒(暂未启用)
196
+ '''
197
+ def __init__(self, channel_id: int, current: float, duration: float, frequency: float, pulse_width: int,
198
+ pulse_width_ratio: float = 1, pulse_interval = 0, ramp_up: float = 0, ramp_down: float = 0, delay_time = 0):
199
+ super().__init__(channel_id, WaveForm.PULSE.value, current, duration, ramp_up, ramp_down)
200
+ self.frequency = frequency
201
+ self.delay_time = delay_time
202
+ self.pulse_width = pulse_width
203
+ self.pulse_width_ratio = pulse_width_ratio
204
+ self.pulse_interval = pulse_interval
205
+ self.with_group_repeats = 1
206
+ self.pulse_time_f = 0
207
+ self.pulse_time_out = 0
208
+ self.pulse_time_idle = 0
209
+
210
+ def to_bytes(self):
211
+ # Convert the object to bytes for transmission
212
+ result = self.channel_id.to_bytes(1, 'little')
213
+ result += self.wave_form.to_bytes(1, 'little')
214
+ result += int(self.current_max * 1000 * 1000).to_bytes(4, 'little', signed = True)
215
+ # result += int(self.current_min * 1000).to_bytes(2, 'little')
216
+ result += int(self.frequency).to_bytes(2, 'little')
217
+ result += int(self.pulse_width).to_bytes(2, 'little')
218
+ result += struct.pack('<f', self.pulse_width_ratio)
219
+
220
+ result += int(self.pulse_interval).to_bytes(2, 'little')
221
+ result += int(self.with_group_repeats).to_bytes(2, 'little')
222
+ result += int(self.pulse_time_f).to_bytes(4, 'little')
223
+ result += int(self.pulse_time_out).to_bytes(4, 'little')
224
+ result += int(self.pulse_time_idle).to_bytes(4, 'little')
225
+
226
+ result += int(self.delay_time).to_bytes(4, 'little')
227
+ result += int(self.ramp_up * 1000).to_bytes(4, 'little')
228
+ result += int((self.duration + self.ramp_up) * 1000).to_bytes(4, 'little')
229
+ result += int(self.ramp_down * 1000).to_bytes(4, 'little')
230
+
231
+ return result
232
+
233
+ def to_json(self):
234
+ return {
235
+ "channel_id": self.channel_id,
236
+ "wave_form": self.wave_form,
237
+ "current_max": self.current_max,
238
+ "current_min": self.current_min,
239
+ "duration": self.duration,
240
+ "ramp_up": self.ramp_up,
241
+ "ramp_down": self.ramp_down,
242
+ "frequency": self.frequency,
243
+ "phase_position": self.phase_position,
244
+ "duration_delay": self.duration_delay,
245
+ "pulse_width": self.pulse_width,
246
+ "delay_time": self.delay_time,
247
+ "pulse_interval": self.pulse_interval,
248
+ "with_group_repeats": self.with_group_repeats
249
+ }
250
+
251
+
252
+ # 刺激范式
253
+ class StimulationParadigm(object):
254
+ def __init__(self):
255
+ self.channels = None
256
+ self.duration = None
257
+ self.interval_time = 0
258
+ self.characteristic = 1
259
+ self.mode = 0
260
+ self.repeats = 0
261
+
262
+ def add_channel(self, channel: StimulationChannel, update=False):
263
+ if self.channels is None:
264
+ self.channels = {}
265
+ channel_id = channel.channel_id + 1
266
+ if channel_id in self.channels.keys():
267
+ logger.warning(f"Channel {channel_id} already exists")
268
+ if update:
269
+ self.channels[channel_id] = channel
270
+ else:
271
+ self.channels[channel_id] = channel
272
+
273
+ # 计算刺激时间
274
+ duration = channel.duration + channel.ramp_up + channel.ramp_down
275
+ if self.duration is None or duration > self.duration:
276
+ self.duration = duration
277
+
278
+
279
+ def to_bytes(self):
280
+ result = to_bytes(list(self.channels.keys()), 64)
281
+ result += int(self.duration * 1000).to_bytes(4, 'little')
282
+ result += int(self.interval_time).to_bytes(4, 'little')
283
+ result += int(self.characteristic).to_bytes(4, 'little')
284
+ result += int(self.mode).to_bytes(1, 'little')
285
+ result += int(self.repeats).to_bytes(4, 'little')
286
+ for channel in self.channels.values():
287
+ result += channel.to_bytes()
288
+ return result
289
+
290
+ def to_json(self):
291
+ # Convert the object to JSON for transmission
292
+ return {
293
+ "channels": list(self.channels.keys()),
294
+ "duration": self.duration,
295
+ "interval_time": self.interval_time,
296
+ "characteristic": self.characteristic,
297
+ "mode": self.mode,
298
+ "repeats": self.repeats,
299
+ "stim": [channel.to_json() for channel in self.channels.values()]
300
+ }
301
+
302
+ # @staticmethod
303
+ # def from_json(param: Dict[str, Any]):
304
+ # pass
305
+
306
+ def clear(self):
307
+ self.channels = None
308
+ self.duration = None
309
+ self.interval_time = 0
310
+ self.characteristic = 1
311
+ self.mode = 0
312
+ self.repeats = 0
313
+
qlsdk/rsc/proxy.py ADDED
@@ -0,0 +1,76 @@
1
+ from loguru import logger
2
+ from threading import Thread, Lock
3
+ import socket
4
+
5
+ class DeviceProxy(object):
6
+ def __init__(self, client_socket):
7
+ self.client_socket = client_socket
8
+ self.server_socket = None
9
+ # 客户端设备
10
+ # self.device = QLDevice(client_socket)
11
+ # self.parser = DeviceParser(self.device)
12
+
13
+ self._init_server()
14
+
15
+ def _init_server(self):
16
+ # 连接目标服务(桌面端运行在本地的18125端口)
17
+ self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
18
+ self.server_socket.connect(('localhost', 18125))
19
+
20
+ def start(self):
21
+ logger.info("DeviceProxy连接已建立")
22
+
23
+ try:
24
+ # 创建双向转发线程
25
+ client_thread = Thread(
26
+ target=self.data_forward,
27
+ args=(self.client_socket, self.server_socket, "设备->软件")
28
+ )
29
+ server_thread = Thread(
30
+ target=self.data_forward,
31
+ args=(self.server_socket, self.client_socket, "软件->设备")
32
+ )
33
+
34
+ # 启动线程
35
+ client_thread.start()
36
+ server_thread.start()
37
+
38
+ # 等待线程结束
39
+ client_thread.join()
40
+ server_thread.join()
41
+
42
+ except Exception as e:
43
+ logger.error(f"连接异常: {str(e)}")
44
+ self.client_socket.close()
45
+ finally:
46
+ logger.error(f"连接已结束")
47
+ self.client_socket.close()
48
+
49
+ def data_forward(self, src, dest, direction, callback=None):
50
+ """
51
+ 数据转发函数
52
+ :param src: 源socket连接
53
+ :param dest: 目标socket连接
54
+ :param direction: 转发方向描述
55
+ """
56
+ try:
57
+ logger.debug(f"[{direction}] 转发开始")
58
+ while True:
59
+ data = src.recv(4096*1024) # 接收数据缓冲区设为4KB
60
+ if not data:
61
+ break
62
+ logger.info(f"[{direction}] 转发指令: {hex(int.from_bytes(data[12:14], 'little'))} ")
63
+ logger.debug(f"[{direction}] 转发 {data.hex()} ")
64
+ if callback:
65
+ callback(data)
66
+ dest.sendall(data)
67
+ logger.debug(f"[{direction}] 转发 {len(data)} 字节")
68
+ except ConnectionResetError:
69
+ logger.error(f"[{direction}] 连接已关闭")
70
+ finally:
71
+ src.close()
72
+ dest.close()
73
+
74
+ # def device_message(self, data):
75
+ # # 解析数据包
76
+ # self.parser.append(data)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: qlsdk2
3
- Version: 0.3.0a3
3
+ Version: 0.4.0
4
4
  Summary: SDK for quanlan device
5
5
  Home-page: https://github.com/hehuajun/qlsdk
6
6
  Author: hehuajun
@@ -12,7 +12,7 @@ Requires-Python: >=3.9
12
12
  Description-Content-Type: text/markdown
13
13
  Requires-Dist: loguru>=0.6.0
14
14
  Requires-Dist: numpy>=1.23.5
15
- Requires-Dist: pyedflib>=0.1.40
15
+ Requires-Dist: bitarray>=1.5.3
16
16
  Provides-Extra: dev
17
17
  Requires-Dist: pytest>=6.0; extra == "dev"
18
18
  Requires-Dist: twine>=3.0; extra == "dev"
@@ -0,0 +1,42 @@
1
+ qlsdk/__init__.py,sha256=mjjFQ8LEHgwMmud5ie2Tgl2aOafnz53gkcAju0q7T0c,446
2
+ qlsdk/ar4/__init__.py,sha256=iR0bFanDwqSxSEM1nCcge1l-GSIWjwnMeRQa47wGrds,4752
3
+ qlsdk/ar4m/__init__.py,sha256=Z13X53WKmKp6MW_fA1FUPdQgJxhxxuyzemJWPS_CEHA,639
4
+ qlsdk/core/__init__.py,sha256=WMjvdiSD3BWAsebktWJU3dt71wOML44xe_EAZ5WJZQY,159
5
+ qlsdk/core/device.py,sha256=dPoQUwd78-Ieef6ZcBI7isVm0W8aYarqBy6UHP7Yjoc,587
6
+ qlsdk/core/exception.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ qlsdk/core/local.py,sha256=vbison4XZtS4SNYLJ9CqBhetEcukdviTWmvtdA1efkQ,811
8
+ qlsdk/core/utils.py,sha256=Dcpor6CGjkIhaZbUzVGFQMdCY54PDJ_etdZ68WD1q8g,4071
9
+ qlsdk/core/crc/__init__.py,sha256=kaYSr6KN5g4U49xlxAvT2lnEeGtwX4Dz1ArwKDvUIIY,143
10
+ qlsdk/core/crc/crctools.py,sha256=sDeE6CMccQX2cRAyMQK0SZUk1fa50XMuwqXau5UX5C8,4242
11
+ qlsdk/core/entity/__init__.py,sha256=THJpYIO-rDfK_UMU6qgraIKft7KfRZ_1dcBQliLT6AM,3291
12
+ qlsdk/core/filter/__init__.py,sha256=YIWIzDUKN30mq2JTr53ZGblggZfC_rLUp2FSRrsQFgU,36
13
+ qlsdk/core/filter/norch.py,sha256=5RdIBX5eqs5w5nmVAnCB3ESSuAT_vVBZ2g-dg6HMZdY,1858
14
+ qlsdk/core/message/__init__.py,sha256=sHuavOyHf4bhH6VdDpTA1EsCh7Q-XsPHcFiItpVz3Rs,51
15
+ qlsdk/core/message/command.py,sha256=Q4NPHEXkWKU266XHb3sbFK9aYpS_U0e64THgBcbBfs8,11959
16
+ qlsdk/core/message/tcp.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
+ qlsdk/core/message/udp.py,sha256=KS_pKZcCEFhNGABCOZTOHiVFkfPNZl_0K5RXppwMIvA,3085
18
+ qlsdk/core/network/__init__.py,sha256=9Ww0cGgBEU_TVrwmgiDz20zA2fMFgepI_kOF4ggHcS0,1111
19
+ qlsdk/core/network/monitor.py,sha256=QqjjPwSr1kgqDTTySp5bpalZmsBQTaAWSxrfPLdROZo,1810
20
+ qlsdk/persist/__init__.py,sha256=OR8mnPTsktxw67G-z0VsPWJXInkKircMTHQdibmmz3M,63
21
+ qlsdk/persist/edf.py,sha256=usgFjZJVcfAUwSy6cJtRdgjdqMgOS4viLCDGcwAGMZE,7106
22
+ qlsdk/persist/rsc_edf.py,sha256=mhSW02N2LYvOebCXdeXvO5k8HsEYjyWKPWz12p39P1c,11568
23
+ qlsdk/rsc/__init__.py,sha256=bR678DilIIK7tFP65tscPUI7Bp4VN0ndVQWt6bnQKGg,197
24
+ qlsdk/rsc/device_manager.py,sha256=1ucd-lzHkNeQPKPzXV6OBkAMqPp_vOcsLyS-9TJ7wRc,4448
25
+ qlsdk/rsc/discover.py,sha256=ONXN6YWY-OMU0sBoLqqKUyb-8drtAp1g_MvnpzaFvHQ,3124
26
+ qlsdk/rsc/eegion.py,sha256=lxrktO-3Z_MYdFIwc4NxvgLM5AL5kU3UItjH6tsKmHY,11670
27
+ qlsdk/rsc/entity.py,sha256=vZv8-M9DWYBgJYa3UxNzSi9zFSO3uTujl63kWQVkskg,16744
28
+ qlsdk/rsc/paradigm.py,sha256=qwBkTRglEGMeLYBhE7AQmZoxXfHiDyATqBARF4IjPA8,12835
29
+ qlsdk/rsc/proxy.py,sha256=9CPdGNGWremwBUh4GvlXAykYB-x_BEPPLqsNvwuwIDE,2736
30
+ qlsdk/rsc/command/__init__.py,sha256=D5pBE2leqFG-IPU2pDAGuLsqHmc0wRPrBOXR0-K8d6k,8117
31
+ qlsdk/rsc/command/message.py,sha256=bcuUDJj0CMekcZMNhKrzIpkHtDC-QBCs3dJG6Bx_PHc,8723
32
+ qlsdk/sdk/__init__.py,sha256=v9LKP-5qXCqnAsCkiRE9LDb5Tagvl_Qd_fqrw7y9yd4,68
33
+ qlsdk/sdk/ar4sdk.py,sha256=ZILuUVgUZN7-LNQm4xdItxmZWGwvFt4oWUKGez1BCLI,27101
34
+ qlsdk/sdk/hub.py,sha256=uEOGZBZtMDCWlV8G2TZe6FAo6eTPcwHAW8zdqr1eq_0,1571
35
+ qlsdk/sdk/libs/libAr4SDK.dll,sha256=kZp9_DRwPdAJ5OgTFQSqS8tEETxUs7YmmETuBP2g60U,15402132
36
+ qlsdk/sdk/libs/libwinpthread-1.dll,sha256=W77ySaDQDi0yxpnQu-ifcU6-uHKzmQpcvsyx2J9j5eg,52224
37
+ qlsdk/x8/__init__.py,sha256=XlQn3Af_HA7bGrxhv3RZKWMob_SnmissXiso7OH1UgI,4750
38
+ qlsdk/x8m/__init__.py,sha256=cLeUqEEj65qXw4Qa4REyxoLh6T24anSqPaKe9_lR340,634
39
+ qlsdk2-0.4.0.dist-info/METADATA,sha256=kBH6NH04cR9pxOAEZG4I4cf42f0F1wWCkZuylX3lzYM,7063
40
+ qlsdk2-0.4.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
41
+ qlsdk2-0.4.0.dist-info/top_level.txt,sha256=2CHzn0SY-NIBVyBl07Suh-Eo8oBAQfyNPtqQ_aDatBg,6
42
+ qlsdk2-0.4.0.dist-info/RECORD,,
@@ -1,16 +0,0 @@
1
- qlsdk/__init__.py,sha256=w0UCnZJekAq4orDahQXRL8s5JJGrWMz0De5LVIf4X_c,426
2
- qlsdk/ar4/__init__.py,sha256=iR0bFanDwqSxSEM1nCcge1l-GSIWjwnMeRQa47wGrds,4752
3
- qlsdk/ar4m/__init__.py,sha256=Z13X53WKmKp6MW_fA1FUPdQgJxhxxuyzemJWPS_CEHA,639
4
- qlsdk/persist/__init__.py,sha256=UYaNL_RSczIZL_YrBWAifoAnNxpgZHEeSp-goHqyqv4,27
5
- qlsdk/persist/edf.py,sha256=usgFjZJVcfAUwSy6cJtRdgjdqMgOS4viLCDGcwAGMZE,7106
6
- qlsdk/sdk/__init__.py,sha256=v9LKP-5qXCqnAsCkiRE9LDb5Tagvl_Qd_fqrw7y9yd4,68
7
- qlsdk/sdk/ar4sdk.py,sha256=ZILuUVgUZN7-LNQm4xdItxmZWGwvFt4oWUKGez1BCLI,27101
8
- qlsdk/sdk/hub.py,sha256=uEOGZBZtMDCWlV8G2TZe6FAo6eTPcwHAW8zdqr1eq_0,1571
9
- qlsdk/sdk/libs/libAr4SDK.dll,sha256=kZp9_DRwPdAJ5OgTFQSqS8tEETxUs7YmmETuBP2g60U,15402132
10
- qlsdk/sdk/libs/libwinpthread-1.dll,sha256=W77ySaDQDi0yxpnQu-ifcU6-uHKzmQpcvsyx2J9j5eg,52224
11
- qlsdk/x8/__init__.py,sha256=XlQn3Af_HA7bGrxhv3RZKWMob_SnmissXiso7OH1UgI,4750
12
- qlsdk/x8m/__init__.py,sha256=cLeUqEEj65qXw4Qa4REyxoLh6T24anSqPaKe9_lR340,634
13
- qlsdk2-0.3.0a3.dist-info/METADATA,sha256=FE9C1YckDtBRsYXY6VInPhcf_WT5X1D-t_FO7WL-MUc,7066
14
- qlsdk2-0.3.0a3.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
15
- qlsdk2-0.3.0a3.dist-info/top_level.txt,sha256=2CHzn0SY-NIBVyBl07Suh-Eo8oBAQfyNPtqQ_aDatBg,6
16
- qlsdk2-0.3.0a3.dist-info/RECORD,,