@hotlap.ai/telemetry 1.0.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,288 @@
1
+ // @bun
2
+ var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
3
+ var __require = import.meta.require;
4
+
5
+ // src/constants.ts
6
+ var VERSION = "1.0.0";
7
+ var SIM_STATUS_URL = "http://127.0.0.1:32034/get_sim_status?object=simStatus";
8
+ var DATA_VALID_EVENT_NAME = "LocalIRSDKDataValidEvent";
9
+ var MEMMAPFILE = "LocalIRSDKMemMapFileName";
10
+ var MEMMAPFILESIZE = 1164 * 1024;
11
+ var BROADCASTMSGNAME = "IRSDK_BROADCASTMSG";
12
+ var VAR_TYPE_SIZES = [1, 1, 4, 4, 4, 8];
13
+ var HEADER_SIZE = 112;
14
+ var VAR_HEADER_SIZE = 144;
15
+ var VAR_BUFFER_SIZE = 16;
16
+ var DISK_SUB_HEADER_OFFSET = 112;
17
+ var DISK_SUB_HEADER_SIZE = 32;
18
+ var YAML_CODE_PAGE = "windows-1252";
19
+ var StatusField = {
20
+ STATUS_CONNECTED: 1
21
+ };
22
+ var EngineWarnings = {
23
+ WATER_TEMP_WARNING: 1,
24
+ FUEL_PRESSURE_WARNING: 2,
25
+ OIL_PRESSURE_WARNING: 4,
26
+ ENGINE_STALLED: 8,
27
+ PIT_SPEED_LIMITER: 16,
28
+ REV_LIMITER_ACTIVE: 32,
29
+ OIL_TEMP_WARNING: 64
30
+ };
31
+ var Flags = {
32
+ CHECKERED: 1,
33
+ WHITE: 2,
34
+ GREEN: 4,
35
+ YELLOW: 8,
36
+ RED: 16,
37
+ BLUE: 32,
38
+ DEBRIS: 64,
39
+ CROSSED: 128,
40
+ YELLOW_WAVING: 256,
41
+ ONE_LAP_TO_GREEN: 512,
42
+ GREEN_HELD: 1024,
43
+ TEN_TO_GO: 2048,
44
+ FIVE_TO_GO: 4096,
45
+ RANDOM_WAVING: 8192,
46
+ CAUTION: 16384,
47
+ CAUTION_WAVING: 32768,
48
+ BLACK: 65536,
49
+ DISQUALIFY: 131072,
50
+ SERVICIBLE: 262144,
51
+ FURLED: 524288,
52
+ REPAIR: 1048576,
53
+ START_HIDDEN: 268435456,
54
+ START_READY: 536870912,
55
+ START_SET: 1073741824,
56
+ START_GO: 2147483648
57
+ };
58
+ var TrkLoc = {
59
+ NOT_IN_WORLD: -1,
60
+ OFF_TRACK: 0,
61
+ IN_PIT_STALL: 1,
62
+ APPROACHING_PITS: 2,
63
+ ON_TRACK: 3
64
+ };
65
+ var TrkSurf = {
66
+ NOT_IN_WORLD: -1,
67
+ UNDEFINED: 0,
68
+ ASPHALT_1: 1,
69
+ ASPHALT_2: 2,
70
+ ASPHALT_3: 3,
71
+ ASPHALT_4: 4,
72
+ CONCRETE_1: 5,
73
+ CONCRETE_2: 6,
74
+ RACING_DIRT_1: 7,
75
+ RACING_DIRT_2: 8,
76
+ PAINT_1: 9,
77
+ PAINT_2: 10,
78
+ RUMBLE_1: 11,
79
+ RUMBLE_2: 12,
80
+ RUMBLE_3: 13,
81
+ RUMBLE_4: 14,
82
+ GRASS_1: 15,
83
+ GRASS_2: 16,
84
+ GRASS_3: 17,
85
+ GRASS_4: 18,
86
+ DIRT_1: 19,
87
+ DIRT_2: 20,
88
+ DIRT_3: 21,
89
+ DIRT_4: 22,
90
+ SAND: 23,
91
+ GRAVEL_1: 24,
92
+ GRAVEL_2: 25,
93
+ GRASSCRETE: 26,
94
+ ASTROTURF: 27
95
+ };
96
+ var SessionState = {
97
+ INVALID: 0,
98
+ GET_IN_CAR: 1,
99
+ WARMUP: 2,
100
+ PARADE_LAPS: 3,
101
+ RACING: 4,
102
+ CHECKERED: 5,
103
+ COOL_DOWN: 6
104
+ };
105
+ var CameraState = {
106
+ IS_SESSION_SCREEN: 1,
107
+ IS_SCENIC_ACTIVE: 2,
108
+ CAM_TOOL_ACTIVE: 4,
109
+ UI_HIDDEN: 8,
110
+ USE_AUTO_SHOT_SELECTION: 16,
111
+ USE_TEMPORARY_EDITS: 32,
112
+ USE_KEY_ACCELERATION: 64,
113
+ USE_KEY10X_ACCELERATION: 128,
114
+ USE_MOUSE_AIM_MODE: 256
115
+ };
116
+ var BroadcastMsg = {
117
+ CAM_SWITCH_POS: 0,
118
+ CAM_SWITCH_NUM: 1,
119
+ CAM_SET_STATE: 2,
120
+ REPLAY_SET_PLAY_SPEED: 3,
121
+ REPLAY_SET_PLAY_POSITION: 4,
122
+ REPLAY_SEARCH: 5,
123
+ REPLAY_SET_STATE: 6,
124
+ RELOAD_TEXTURES: 7,
125
+ CHAT_COMMAND: 8,
126
+ PIT_COMMAND: 9,
127
+ TELEM_COMMAND: 10,
128
+ FFB_COMMAND: 11,
129
+ REPLAY_SEARCH_SESSION_TIME: 12,
130
+ VIDEO_CAPTURE: 13
131
+ };
132
+ var ChatCommandMode = {
133
+ MACRO: 0,
134
+ BEGIN_CHAT: 1,
135
+ REPLY: 2,
136
+ CANCEL: 3
137
+ };
138
+ var PitCommandMode = {
139
+ CLEAR: 0,
140
+ WS: 1,
141
+ FUEL: 2,
142
+ LF: 3,
143
+ RF: 4,
144
+ LR: 5,
145
+ RR: 6,
146
+ CLEAR_TIRES: 7,
147
+ FR: 8,
148
+ CLEAR_WS: 9,
149
+ CLEAR_FR: 10,
150
+ CLEAR_FUEL: 11
151
+ };
152
+ var TelemCommandMode = {
153
+ STOP: 0,
154
+ START: 1,
155
+ RESTART: 2
156
+ };
157
+ var RpyStateMode = {
158
+ ERASE_TAPE: 0
159
+ };
160
+ var ReloadTexturesMode = {
161
+ ALL: 0,
162
+ CAR_IDX: 1
163
+ };
164
+ var RpySrchMode = {
165
+ TO_START: 0,
166
+ TO_END: 1,
167
+ PREV_SESSION: 2,
168
+ NEXT_SESSION: 3,
169
+ PREV_LAP: 4,
170
+ NEXT_LAP: 5,
171
+ PREV_FRAME: 6,
172
+ NEXT_FRAME: 7,
173
+ PREV_INCIDENT: 8,
174
+ NEXT_INCIDENT: 9
175
+ };
176
+ var RpyPosMode = {
177
+ BEGIN: 0,
178
+ CURRENT: 1,
179
+ END: 2
180
+ };
181
+ var CsMode = {
182
+ AT_INCIDENT: -3,
183
+ AT_LEADER: -2,
184
+ AT_EXCITING: -1
185
+ };
186
+ var PitSvFlags = {
187
+ LF_TIRE_CHANGE: 1,
188
+ RF_TIRE_CHANGE: 2,
189
+ LR_TIRE_CHANGE: 4,
190
+ RR_TIRE_CHANGE: 8,
191
+ FUEL_FILL: 16,
192
+ WINDSHIELD_TEAROFF: 32,
193
+ FAST_REPAIR: 64
194
+ };
195
+ var PitSvStatus = {
196
+ NONE: 0,
197
+ IN_PROGRESS: 1,
198
+ COMPLETE: 2,
199
+ TOO_FAR_LEFT: 100,
200
+ TOO_FAR_RIGHT: 101,
201
+ TOO_FAR_FORWARD: 102,
202
+ TOO_FAR_BACK: 103,
203
+ BAD_ANGLE: 104,
204
+ CANT_FIX_THAT: 105
205
+ };
206
+ var PaceMode = {
207
+ SINGLE_FILE_START: 0,
208
+ DOUBLE_FILE_START: 1,
209
+ SINGLE_FILE_RESTART: 2,
210
+ DOUBLE_FILE_RESTART: 3,
211
+ NOT_PACING: 4
212
+ };
213
+ var PaceFlags = {
214
+ END_OF_LINE: 1,
215
+ FREE_PASS: 2,
216
+ WAVED_AROUND: 4
217
+ };
218
+ var CarLeftRight = {
219
+ OFF: 0,
220
+ CLEAR: 1,
221
+ CAR_LEFT: 2,
222
+ CAR_RIGHT: 3,
223
+ CAR_LEFT_RIGHT: 4,
224
+ TWO_CARS_LEFT: 5,
225
+ TWO_CARS_RIGHT: 6
226
+ };
227
+ var FFBCommandMode = {
228
+ FFB_COMMAND_MAX_FORCE: 0
229
+ };
230
+ var VideoCaptureMode = {
231
+ TRIGGER_SCREEN_SHOT: 0,
232
+ START_VIDEO_CAPTURE: 1,
233
+ END_VIDEO_CAPTURE: 2,
234
+ TOGGLE_VIDEO_CAPTURE: 3,
235
+ SHOW_VIDEO_TIMER: 4,
236
+ HIDE_VIDEO_TIMER: 5
237
+ };
238
+ var TrackWetness = {
239
+ UNKNOWN: 0,
240
+ DRY: 1,
241
+ MOSTLY_DRY: 2,
242
+ VERY_LIGHTLY_WET: 3,
243
+ LIGHTLY_WET: 4,
244
+ MODERATELY_WET: 5,
245
+ VERY_WET: 6,
246
+ EXTREMELY_WET: 7
247
+ };
248
+ export {
249
+ YAML_CODE_PAGE,
250
+ VideoCaptureMode,
251
+ VERSION,
252
+ VAR_TYPE_SIZES,
253
+ VAR_HEADER_SIZE,
254
+ VAR_BUFFER_SIZE,
255
+ TrkSurf,
256
+ TrkLoc,
257
+ TrackWetness,
258
+ TelemCommandMode,
259
+ StatusField,
260
+ SessionState,
261
+ SIM_STATUS_URL,
262
+ RpyStateMode,
263
+ RpySrchMode,
264
+ RpyPosMode,
265
+ ReloadTexturesMode,
266
+ PitSvStatus,
267
+ PitSvFlags,
268
+ PitCommandMode,
269
+ PaceMode,
270
+ PaceFlags,
271
+ MEMMAPFILESIZE,
272
+ MEMMAPFILE,
273
+ HEADER_SIZE,
274
+ Flags,
275
+ FFBCommandMode,
276
+ EngineWarnings,
277
+ DISK_SUB_HEADER_SIZE,
278
+ DISK_SUB_HEADER_OFFSET,
279
+ DATA_VALID_EVENT_NAME,
280
+ CsMode,
281
+ ChatCommandMode,
282
+ CarLeftRight,
283
+ CameraState,
284
+ BroadcastMsg,
285
+ BROADCASTMSGNAME
286
+ };
287
+
288
+ export { __commonJS, __require, VERSION, SIM_STATUS_URL, DATA_VALID_EVENT_NAME, MEMMAPFILE, MEMMAPFILESIZE, BROADCASTMSGNAME, VAR_TYPE_SIZES, HEADER_SIZE, VAR_HEADER_SIZE, VAR_BUFFER_SIZE, DISK_SUB_HEADER_OFFSET, DISK_SUB_HEADER_SIZE, YAML_CODE_PAGE, StatusField, EngineWarnings, Flags, TrkLoc, TrkSurf, SessionState, CameraState, BroadcastMsg, ChatCommandMode, PitCommandMode, TelemCommandMode, RpyStateMode, ReloadTexturesMode, RpySrchMode, RpyPosMode, CsMode, PitSvFlags, PitSvStatus, PaceMode, PaceFlags, CarLeftRight, FFBCommandMode, VideoCaptureMode, TrackWetness };
package/dist/ibt.d.ts ADDED
@@ -0,0 +1,40 @@
1
+ import type { VarHeader, TelemetryValue } from './types';
2
+ export interface IbtOptions {
3
+ lazyLoad?: boolean;
4
+ preloadVars?: string[];
5
+ }
6
+ export declare class IBT {
7
+ private buffer;
8
+ private view;
9
+ private header;
10
+ private diskHeader;
11
+ private varHeaders;
12
+ private sessionInfoCache;
13
+ private rawSessionInfo;
14
+ private filePath;
15
+ get fileName(): string | null;
16
+ get varHeaderBufferTick(): number | null;
17
+ get varHeaderNames(): string[] | null;
18
+ get recordCount(): number;
19
+ get sessionLapCount(): number;
20
+ get sessionStartTime(): number;
21
+ get sessionEndTime(): number;
22
+ get tickRate(): number;
23
+ get bufLen(): number;
24
+ open(filePath: string): Promise<void>;
25
+ openSync(filePath: string): void;
26
+ static fromBuffer(buffer: ArrayBuffer | Uint8Array): Promise<IBT>;
27
+ close(): void;
28
+ getVarHeader(name: string): VarHeader | undefined;
29
+ get(index: number, key: string): TelemetryValue | null;
30
+ getAll(key: string): TelemetryValue[] | null;
31
+ getAllTyped(key: string): Float32Array | Float64Array | Int32Array | Uint32Array | null;
32
+ getAllMultiple(keys: string[]): Map<string, TelemetryValue[]>;
33
+ iterate(keys: string[]): Generator<Map<string, TelemetryValue>, void, unknown>;
34
+ getRawSessionInfo(): string | null;
35
+ getSessionInfo<T = unknown>(key?: string): T | null;
36
+ private cleanYaml;
37
+ }
38
+ export declare function parseIbt(filePath: string): Promise<IBT>;
39
+ export declare function parseIbtBuffer(buffer: ArrayBuffer | Uint8Array): Promise<IBT>;
40
+ //# sourceMappingURL=ibt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ibt.d.ts","sourceRoot":"","sources":["../src/ibt.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAU,SAAS,EAAiB,cAAc,EAAe,MAAM,SAAS,CAAC;AAY7F,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,qBAAa,GAAG;IACd,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,IAAI,CAAyB;IACrC,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,UAAU,CAA8B;IAChD,OAAO,CAAC,UAAU,CAAuC;IACzD,OAAO,CAAC,gBAAgB,CAAmC;IAC3D,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,QAAQ,CAAuB;IAEvC,IAAI,QAAQ,IAAI,MAAM,GAAG,IAAI,CAE5B;IAED,IAAI,mBAAmB,IAAI,MAAM,GAAG,IAAI,CAEvC;IAED,IAAI,cAAc,IAAI,MAAM,EAAE,GAAG,IAAI,CAGpC;IAED,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,IAAI,eAAe,IAAI,MAAM,CAE5B;IAED,IAAI,gBAAgB,IAAI,MAAM,CAE7B;IAED,IAAI,cAAc,IAAI,MAAM,CAE3B;IAED,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,IAAI,MAAM,IAAI,MAAM,CAEnB;IAEK,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAa3C,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;WAgBnB,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC;IAUvE,KAAK,IAAI,IAAI;IAWb,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAIjD,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI;IAatD,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,EAAE,GAAG,IAAI;IAuB5C,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,GAAG,YAAY,GAAG,UAAU,GAAG,WAAW,GAAG,IAAI;IAmCvF,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,cAAc,EAAE,CAAC;IAgC5D,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC;IA8B/E,iBAAiB,IAAI,MAAM,GAAG,IAAI;IAYlC,cAAc,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI;IAmCnD,OAAO,CAAC,SAAS;CAiBlB;AAED,wBAAsB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAI7D;AAED,wBAAsB,cAAc,CAAC,MAAM,EAAE,WAAW,GAAG,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,CAEnF"}
package/dist/ibt.js ADDED
@@ -0,0 +1,298 @@
1
+ // @bun
2
+ import {
3
+ $parse
4
+ } from "./index-k5bgtn4c.js";
5
+ import {
6
+ parseDiskSubHeader,
7
+ parseHeader,
8
+ parseVarHeaders,
9
+ readString,
10
+ readVarValue,
11
+ readVarValueBatch
12
+ } from "./binary-reader.js";
13
+ import {
14
+ DISK_SUB_HEADER_OFFSET
15
+ } from "./constants.js";
16
+
17
+ // src/ibt.ts
18
+ class IBT {
19
+ buffer = null;
20
+ view = null;
21
+ header = null;
22
+ diskHeader = null;
23
+ varHeaders = null;
24
+ sessionInfoCache = new Map;
25
+ rawSessionInfo = null;
26
+ filePath = null;
27
+ get fileName() {
28
+ return this.filePath;
29
+ }
30
+ get varHeaderBufferTick() {
31
+ return this.header?.varBuf[0]?.tickCount ?? null;
32
+ }
33
+ get varHeaderNames() {
34
+ if (!this.varHeaders)
35
+ return null;
36
+ return Array.from(this.varHeaders.keys());
37
+ }
38
+ get recordCount() {
39
+ return this.diskHeader?.sessionRecordCount ?? 0;
40
+ }
41
+ get sessionLapCount() {
42
+ return this.diskHeader?.sessionLapCount ?? 0;
43
+ }
44
+ get sessionStartTime() {
45
+ return this.diskHeader?.sessionStartTime ?? 0;
46
+ }
47
+ get sessionEndTime() {
48
+ return this.diskHeader?.sessionEndTime ?? 0;
49
+ }
50
+ get tickRate() {
51
+ return this.header?.tickRate ?? 60;
52
+ }
53
+ get bufLen() {
54
+ return this.header?.bufLen ?? 0;
55
+ }
56
+ async open(filePath) {
57
+ this.filePath = filePath;
58
+ const file = Bun.file(filePath);
59
+ const arrayBuffer = await file.arrayBuffer();
60
+ this.buffer = new Uint8Array(arrayBuffer);
61
+ this.view = new DataView(arrayBuffer);
62
+ this.header = parseHeader(this.view);
63
+ this.diskHeader = parseDiskSubHeader(this.view, DISK_SUB_HEADER_OFFSET);
64
+ this.varHeaders = parseVarHeaders(this.view, this.buffer, this.header);
65
+ this.sessionInfoCache.clear();
66
+ this.rawSessionInfo = null;
67
+ }
68
+ openSync(filePath) {
69
+ this.filePath = filePath;
70
+ const file = Bun.file(filePath);
71
+ const arrayBuffer = file.arrayBuffer();
72
+ if (arrayBuffer instanceof Promise) {
73
+ throw new Error("Sync file reading requires Bun.file().bytes() - use open() instead");
74
+ }
75
+ this.buffer = new Uint8Array(arrayBuffer);
76
+ this.view = new DataView(arrayBuffer);
77
+ this.header = parseHeader(this.view);
78
+ this.diskHeader = parseDiskSubHeader(this.view, DISK_SUB_HEADER_OFFSET);
79
+ this.varHeaders = parseVarHeaders(this.view, this.buffer, this.header);
80
+ this.sessionInfoCache.clear();
81
+ this.rawSessionInfo = null;
82
+ }
83
+ static async fromBuffer(buffer) {
84
+ const ibt = new IBT;
85
+ ibt.buffer = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);
86
+ ibt.view = new DataView(ibt.buffer.buffer, ibt.buffer.byteOffset, ibt.buffer.byteLength);
87
+ ibt.header = parseHeader(ibt.view);
88
+ ibt.diskHeader = parseDiskSubHeader(ibt.view, DISK_SUB_HEADER_OFFSET);
89
+ ibt.varHeaders = parseVarHeaders(ibt.view, ibt.buffer, ibt.header);
90
+ return ibt;
91
+ }
92
+ close() {
93
+ this.buffer = null;
94
+ this.view = null;
95
+ this.header = null;
96
+ this.diskHeader = null;
97
+ this.varHeaders = null;
98
+ this.sessionInfoCache.clear();
99
+ this.rawSessionInfo = null;
100
+ this.filePath = null;
101
+ }
102
+ getVarHeader(name) {
103
+ return this.varHeaders?.get(name);
104
+ }
105
+ get(index, key) {
106
+ if (!this.header || !this.view || !this.varHeaders || !this.diskHeader)
107
+ return null;
108
+ if (index < 0 || index >= this.diskHeader.sessionRecordCount)
109
+ return null;
110
+ const varHeader = this.varHeaders.get(key);
111
+ if (!varHeader)
112
+ return null;
113
+ const varBuf = this.header.varBuf[0];
114
+ if (!varBuf)
115
+ return null;
116
+ const varOffset = varHeader.offset + varBuf.bufOffset + index * this.header.bufLen;
117
+ return readVarValue(this.view, varOffset, varHeader.type, varHeader.count);
118
+ }
119
+ getAll(key) {
120
+ if (!this.header || !this.view || !this.varHeaders || !this.diskHeader)
121
+ return null;
122
+ const varHeader = this.varHeaders.get(key);
123
+ if (!varHeader)
124
+ return null;
125
+ const varBuf = this.header.varBuf[0];
126
+ if (!varBuf)
127
+ return null;
128
+ const baseOffset = varBuf.bufOffset;
129
+ const bufLen = this.header.bufLen;
130
+ const recordCount = this.diskHeader.sessionRecordCount;
131
+ const varOffset = varHeader.offset;
132
+ const isArray = varHeader.count > 1;
133
+ const results = new Array(recordCount);
134
+ for (let i = 0;i < recordCount; i++) {
135
+ const offset = baseOffset + i * bufLen + varOffset;
136
+ results[i] = readVarValue(this.view, offset, varHeader.type, varHeader.count);
137
+ }
138
+ return results;
139
+ }
140
+ getAllTyped(key) {
141
+ if (!this.header || !this.view || !this.varHeaders || !this.diskHeader)
142
+ return null;
143
+ const varHeader = this.varHeaders.get(key);
144
+ if (!varHeader || varHeader.count !== 1)
145
+ return null;
146
+ const varBuf = this.header.varBuf[0];
147
+ if (!varBuf)
148
+ return null;
149
+ const baseOffset = varBuf.bufOffset;
150
+ const bufLen = this.header.bufLen;
151
+ const recordCount = this.diskHeader.sessionRecordCount;
152
+ const varOffset = varHeader.offset;
153
+ let output;
154
+ switch (varHeader.type) {
155
+ case 4:
156
+ output = new Float32Array(recordCount);
157
+ break;
158
+ case 5:
159
+ output = new Float64Array(recordCount);
160
+ break;
161
+ case 2:
162
+ output = new Int32Array(recordCount);
163
+ break;
164
+ case 3:
165
+ output = new Uint32Array(recordCount);
166
+ break;
167
+ default:
168
+ return null;
169
+ }
170
+ readVarValueBatch(this.view, baseOffset, varOffset, varHeader.type, bufLen, recordCount, output);
171
+ return output;
172
+ }
173
+ getAllMultiple(keys) {
174
+ const results = new Map;
175
+ if (!this.header || !this.view || !this.varHeaders || !this.diskHeader)
176
+ return results;
177
+ const varBuf = this.header.varBuf[0];
178
+ if (!varBuf)
179
+ return results;
180
+ const baseOffset = varBuf.bufOffset;
181
+ const bufLen = this.header.bufLen;
182
+ const recordCount = this.diskHeader.sessionRecordCount;
183
+ const varInfos = [];
184
+ for (const key of keys) {
185
+ const varHeader = this.varHeaders.get(key);
186
+ if (varHeader) {
187
+ const data = new Array(recordCount);
188
+ varInfos.push({ key, varHeader, data });
189
+ results.set(key, data);
190
+ }
191
+ }
192
+ for (let i = 0;i < recordCount; i++) {
193
+ const recordOffset = baseOffset + i * bufLen;
194
+ for (const { varHeader, data } of varInfos) {
195
+ const offset = recordOffset + varHeader.offset;
196
+ data[i] = readVarValue(this.view, offset, varHeader.type, varHeader.count);
197
+ }
198
+ }
199
+ return results;
200
+ }
201
+ *iterate(keys) {
202
+ if (!this.header || !this.view || !this.varHeaders || !this.diskHeader)
203
+ return;
204
+ const varBuf = this.header.varBuf[0];
205
+ if (!varBuf)
206
+ return;
207
+ const baseOffset = varBuf.bufOffset;
208
+ const bufLen = this.header.bufLen;
209
+ const recordCount = this.diskHeader.sessionRecordCount;
210
+ const varInfos = [];
211
+ for (const key of keys) {
212
+ const varHeader = this.varHeaders.get(key);
213
+ if (varHeader) {
214
+ varInfos.push({ key, varHeader });
215
+ }
216
+ }
217
+ for (let i = 0;i < recordCount; i++) {
218
+ const recordOffset = baseOffset + i * bufLen;
219
+ const record = new Map;
220
+ for (const { key, varHeader } of varInfos) {
221
+ const offset = recordOffset + varHeader.offset;
222
+ record.set(key, readVarValue(this.view, offset, varHeader.type, varHeader.count));
223
+ }
224
+ yield record;
225
+ }
226
+ }
227
+ getRawSessionInfo() {
228
+ if (!this.header || !this.buffer)
229
+ return null;
230
+ if (this.rawSessionInfo === null) {
231
+ const start = this.header.sessionInfoOffset;
232
+ const len = this.header.sessionInfoLen;
233
+ this.rawSessionInfo = readString(this.buffer, start, len);
234
+ }
235
+ return this.rawSessionInfo;
236
+ }
237
+ getSessionInfo(key) {
238
+ const raw = this.getRawSessionInfo();
239
+ if (!raw)
240
+ return null;
241
+ if (!key) {
242
+ if (!this.sessionInfoCache.has("__full__")) {
243
+ try {
244
+ const cleaned = this.cleanYaml(raw);
245
+ this.sessionInfoCache.set("__full__", $parse(cleaned));
246
+ } catch {
247
+ return null;
248
+ }
249
+ }
250
+ return this.sessionInfoCache.get("__full__");
251
+ }
252
+ if (this.sessionInfoCache.has(key)) {
253
+ return this.sessionInfoCache.get(key);
254
+ }
255
+ const sectionMatch = raw.match(new RegExp(`
256
+ ${key}:
257
+ ([\\s\\S]*?)(?=
258
+
259
+ |$)`));
260
+ if (!sectionMatch)
261
+ return null;
262
+ try {
263
+ const sectionYaml = `${key}:
264
+ ${sectionMatch[1]}`;
265
+ const cleaned = this.cleanYaml(sectionYaml);
266
+ const parsed = $parse(cleaned);
267
+ const result = parsed?.[key] ?? null;
268
+ this.sessionInfoCache.set(key, result);
269
+ return result;
270
+ } catch {
271
+ return null;
272
+ }
273
+ }
274
+ cleanYaml(yaml) {
275
+ let cleaned = yaml.replace(/[\x81\x8D\x8F\x90\x9D]/g, " ").replace(/[^\x09\x0A\x0D\x20-\x7E\xA0-\xFF]/g, "");
276
+ cleaned = cleaned.replace(/((?:DriverSetupName|UserName|TeamName|AbbrevName|Initials): )(.*)/g, (_, prefix, value) => {
277
+ const escaped = value.replace(/["\\]/g, "\\$&");
278
+ return `${prefix}"${escaped}"`;
279
+ });
280
+ cleaned = cleaned.replace(/(\w+: )(,.*)/g, '$1"$2"');
281
+ return cleaned;
282
+ }
283
+ }
284
+ async function parseIbt(filePath) {
285
+ const ibt = new IBT;
286
+ await ibt.open(filePath);
287
+ return ibt;
288
+ }
289
+ async function parseIbtBuffer(buffer) {
290
+ return IBT.fromBuffer(buffer);
291
+ }
292
+ export {
293
+ parseIbtBuffer,
294
+ parseIbt,
295
+ IBT
296
+ };
297
+
298
+ export { IBT, parseIbt, parseIbtBuffer };