ts-flp 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.
- package/LICENSE +674 -0
- package/README.md +226 -0
- package/dist/src/api/ProjectApi.d.ts +83 -0
- package/dist/src/api/ProjectApi.d.ts.map +1 -0
- package/dist/src/api/ProjectApi.js +326 -0
- package/dist/src/api/ProjectApi.js.map +1 -0
- package/dist/src/generated/events.generated.d.ts +126 -0
- package/dist/src/generated/events.generated.d.ts.map +1 -0
- package/dist/src/generated/events.generated.js +257 -0
- package/dist/src/generated/events.generated.js.map +1 -0
- package/dist/src/index.d.ts +37 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +41 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/io/BinaryReader.d.ts +94 -0
- package/dist/src/io/BinaryReader.d.ts.map +1 -0
- package/dist/src/io/BinaryReader.js +159 -0
- package/dist/src/io/BinaryReader.js.map +1 -0
- package/dist/src/io/BinaryWriter.d.ts +74 -0
- package/dist/src/io/BinaryWriter.d.ts.map +1 -0
- package/dist/src/io/BinaryWriter.js +124 -0
- package/dist/src/io/BinaryWriter.js.map +1 -0
- package/dist/src/parser/FlpParser.d.ts +90 -0
- package/dist/src/parser/FlpParser.d.ts.map +1 -0
- package/dist/src/parser/FlpParser.js +313 -0
- package/dist/src/parser/FlpParser.js.map +1 -0
- package/package.json +73 -0
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Binary reader for FL Studio .flp files
|
|
3
|
+
* Uses smart-buffer for binary reading and protobufjs for VarInt decoding
|
|
4
|
+
*/
|
|
5
|
+
import * as protobuf from "protobufjs/minimal.js";
|
|
6
|
+
import { SmartBuffer } from "smart-buffer";
|
|
7
|
+
export class BinaryReader {
|
|
8
|
+
sb;
|
|
9
|
+
constructor(buffer) {
|
|
10
|
+
this.sb = SmartBuffer.fromBuffer(buffer);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Returns current read position
|
|
14
|
+
*/
|
|
15
|
+
tell() {
|
|
16
|
+
return this.sb.readOffset;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Seeks to an absolute position
|
|
20
|
+
*/
|
|
21
|
+
seek(pos) {
|
|
22
|
+
this.sb.readOffset = pos;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Seeks relative to current position
|
|
26
|
+
*/
|
|
27
|
+
skip(offset) {
|
|
28
|
+
this.sb.readOffset += offset;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Returns total buffer length
|
|
32
|
+
*/
|
|
33
|
+
length() {
|
|
34
|
+
return this.sb.length;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Returns remaining bytes to read
|
|
38
|
+
*/
|
|
39
|
+
remaining() {
|
|
40
|
+
return this.sb.remaining();
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Returns true if there are more bytes to read
|
|
44
|
+
*/
|
|
45
|
+
hasMore() {
|
|
46
|
+
return this.sb.remaining() > 0;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Reads an unsigned 8-bit integer
|
|
50
|
+
*/
|
|
51
|
+
readU8() {
|
|
52
|
+
return this.sb.readUInt8();
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Reads a signed 8-bit integer
|
|
56
|
+
*/
|
|
57
|
+
readI8() {
|
|
58
|
+
return this.sb.readInt8();
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Reads an unsigned 16-bit integer (little-endian)
|
|
62
|
+
*/
|
|
63
|
+
readU16LE() {
|
|
64
|
+
return this.sb.readUInt16LE();
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Reads a signed 16-bit integer (little-endian)
|
|
68
|
+
*/
|
|
69
|
+
readI16LE() {
|
|
70
|
+
return this.sb.readInt16LE();
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Reads an unsigned 32-bit integer (little-endian)
|
|
74
|
+
*/
|
|
75
|
+
readU32LE() {
|
|
76
|
+
return this.sb.readUInt32LE();
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Reads a signed 32-bit integer (little-endian)
|
|
80
|
+
*/
|
|
81
|
+
readI32LE() {
|
|
82
|
+
return this.sb.readInt32LE();
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Reads a 32-bit float (little-endian)
|
|
86
|
+
*/
|
|
87
|
+
readF32LE() {
|
|
88
|
+
return this.sb.readFloatLE();
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Reads a 64-bit float (little-endian)
|
|
92
|
+
*/
|
|
93
|
+
readF64LE() {
|
|
94
|
+
return this.sb.readDoubleLE();
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Reads raw bytes
|
|
98
|
+
*/
|
|
99
|
+
readBytes(length) {
|
|
100
|
+
return this.sb.readBuffer(length);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Reads a VarInt (variable-length integer) using protobufjs
|
|
104
|
+
* FL Studio uses this encoding for TEXT and DATA event sizes
|
|
105
|
+
*/
|
|
106
|
+
readVarInt() {
|
|
107
|
+
// Get remaining buffer from current position
|
|
108
|
+
const remainingBuffer = this.sb.toBuffer().subarray(this.sb.readOffset);
|
|
109
|
+
const reader = protobuf.Reader.create(remainingBuffer);
|
|
110
|
+
const value = reader.uint32();
|
|
111
|
+
// Advance our position by how many bytes protobufjs consumed
|
|
112
|
+
this.sb.readOffset += reader.pos;
|
|
113
|
+
return value;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Reads an ASCII string (null-terminated)
|
|
117
|
+
*/
|
|
118
|
+
readAsciiString(length) {
|
|
119
|
+
const str = this.sb.readString(length, "ascii");
|
|
120
|
+
// Remove null terminator if present
|
|
121
|
+
const nullPos = str.indexOf("\0");
|
|
122
|
+
return nullPos === -1 ? str : str.substring(0, nullPos);
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Reads a UTF-16LE string (null-terminated)
|
|
126
|
+
*/
|
|
127
|
+
readUtf16LEString(length) {
|
|
128
|
+
const bytes = this.sb.readBuffer(length);
|
|
129
|
+
const str = bytes.toString("utf16le");
|
|
130
|
+
// Remove null terminator if present
|
|
131
|
+
const nullPos = str.indexOf("\0");
|
|
132
|
+
return nullPos === -1 ? str : str.substring(0, nullPos);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Peeks at bytes without advancing position
|
|
136
|
+
*/
|
|
137
|
+
peek(length) {
|
|
138
|
+
const pos = this.sb.readOffset;
|
|
139
|
+
const data = this.sb.readBuffer(length);
|
|
140
|
+
this.sb.readOffset = pos;
|
|
141
|
+
return data;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Peeks at a single byte without advancing position
|
|
145
|
+
*/
|
|
146
|
+
peekU8() {
|
|
147
|
+
const pos = this.sb.readOffset;
|
|
148
|
+
const value = this.sb.readUInt8();
|
|
149
|
+
this.sb.readOffset = pos;
|
|
150
|
+
return value;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Returns the internal buffer
|
|
154
|
+
*/
|
|
155
|
+
toBuffer() {
|
|
156
|
+
return this.sb.toBuffer();
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=BinaryReader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BinaryReader.js","sourceRoot":"","sources":["../../../src/io/BinaryReader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Binary writer for FL Studio .flp files
|
|
3
|
+
* Uses smart-buffer for binary writing and protobufjs for VarInt encoding
|
|
4
|
+
*/
|
|
5
|
+
export declare class BinaryWriter {
|
|
6
|
+
private sb;
|
|
7
|
+
constructor();
|
|
8
|
+
/**
|
|
9
|
+
* Returns current write position (total bytes written)
|
|
10
|
+
*/
|
|
11
|
+
tell(): number;
|
|
12
|
+
/**
|
|
13
|
+
* Writes an unsigned 8-bit integer
|
|
14
|
+
*/
|
|
15
|
+
writeU8(value: number): void;
|
|
16
|
+
/**
|
|
17
|
+
* Writes a signed 8-bit integer
|
|
18
|
+
*/
|
|
19
|
+
writeI8(value: number): void;
|
|
20
|
+
/**
|
|
21
|
+
* Writes an unsigned 16-bit integer (little-endian)
|
|
22
|
+
*/
|
|
23
|
+
writeU16LE(value: number): void;
|
|
24
|
+
/**
|
|
25
|
+
* Writes a signed 16-bit integer (little-endian)
|
|
26
|
+
*/
|
|
27
|
+
writeI16LE(value: number): void;
|
|
28
|
+
/**
|
|
29
|
+
* Writes an unsigned 32-bit integer (little-endian)
|
|
30
|
+
*/
|
|
31
|
+
writeU32LE(value: number): void;
|
|
32
|
+
/**
|
|
33
|
+
* Writes a signed 32-bit integer (little-endian)
|
|
34
|
+
*/
|
|
35
|
+
writeI32LE(value: number): void;
|
|
36
|
+
/**
|
|
37
|
+
* Writes a 32-bit float (little-endian)
|
|
38
|
+
*/
|
|
39
|
+
writeF32LE(value: number): void;
|
|
40
|
+
/**
|
|
41
|
+
* Writes a 64-bit float (little-endian)
|
|
42
|
+
*/
|
|
43
|
+
writeF64LE(value: number): void;
|
|
44
|
+
/**
|
|
45
|
+
* Writes raw bytes
|
|
46
|
+
*/
|
|
47
|
+
writeBytes(data: Buffer): void;
|
|
48
|
+
/**
|
|
49
|
+
* Writes a VarInt (variable-length integer) using protobufjs
|
|
50
|
+
* FL Studio uses this encoding for TEXT and DATA event sizes
|
|
51
|
+
*/
|
|
52
|
+
writeVarInt(value: number): void;
|
|
53
|
+
/**
|
|
54
|
+
* Writes an ASCII string (null-terminated)
|
|
55
|
+
*/
|
|
56
|
+
writeAsciiString(str: string): void;
|
|
57
|
+
/**
|
|
58
|
+
* Writes a UTF-16LE string (null-terminated)
|
|
59
|
+
*/
|
|
60
|
+
writeUtf16LEString(str: string): void;
|
|
61
|
+
/**
|
|
62
|
+
* Gets the final buffer
|
|
63
|
+
*/
|
|
64
|
+
toBuffer(): Buffer;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Encodes a VarInt to a Buffer using protobufjs (standalone utility)
|
|
68
|
+
*/
|
|
69
|
+
export declare function encodeVarInt(value: number): Buffer;
|
|
70
|
+
/**
|
|
71
|
+
* Calculates the byte size needed for a VarInt
|
|
72
|
+
*/
|
|
73
|
+
export declare function varIntSize(value: number): number;
|
|
74
|
+
//# sourceMappingURL=BinaryWriter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BinaryWriter.d.ts","sourceRoot":"","sources":["../../../src/io/BinaryWriter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,qBAAa,YAAY;IACvB,OAAO,CAAC,EAAE,CAAc;;IAMxB;;OAEG;IACH,IAAI,IAAI,MAAM;IAId;;OAEG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI5B;;OAEG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI5B;;OAEG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI/B;;OAEG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI/B;;OAEG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI/B;;OAEG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI/B;;OAEG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI/B;;OAEG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI/B;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI9B;;;OAGG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAOhC;;OAEG;IACH,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAInC;;OAEG;IACH,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAKrC;;OAEG;IACH,QAAQ,IAAI,MAAM;CAGnB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIlD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMhD"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Binary writer for FL Studio .flp files
|
|
3
|
+
* Uses smart-buffer for binary writing and protobufjs for VarInt encoding
|
|
4
|
+
*/
|
|
5
|
+
import { SmartBuffer } from "smart-buffer";
|
|
6
|
+
import * as protobuf from "protobufjs/minimal.js";
|
|
7
|
+
export class BinaryWriter {
|
|
8
|
+
sb;
|
|
9
|
+
constructor() {
|
|
10
|
+
this.sb = new SmartBuffer();
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Returns current write position (total bytes written)
|
|
14
|
+
*/
|
|
15
|
+
tell() {
|
|
16
|
+
return this.sb.writeOffset;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Writes an unsigned 8-bit integer
|
|
20
|
+
*/
|
|
21
|
+
writeU8(value) {
|
|
22
|
+
this.sb.writeUInt8(value & 0xff);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Writes a signed 8-bit integer
|
|
26
|
+
*/
|
|
27
|
+
writeI8(value) {
|
|
28
|
+
this.sb.writeInt8(value);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Writes an unsigned 16-bit integer (little-endian)
|
|
32
|
+
*/
|
|
33
|
+
writeU16LE(value) {
|
|
34
|
+
this.sb.writeUInt16LE(value & 0xffff);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Writes a signed 16-bit integer (little-endian)
|
|
38
|
+
*/
|
|
39
|
+
writeI16LE(value) {
|
|
40
|
+
this.sb.writeInt16LE(value);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Writes an unsigned 32-bit integer (little-endian)
|
|
44
|
+
*/
|
|
45
|
+
writeU32LE(value) {
|
|
46
|
+
this.sb.writeUInt32LE(value >>> 0);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Writes a signed 32-bit integer (little-endian)
|
|
50
|
+
*/
|
|
51
|
+
writeI32LE(value) {
|
|
52
|
+
this.sb.writeInt32LE(value);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Writes a 32-bit float (little-endian)
|
|
56
|
+
*/
|
|
57
|
+
writeF32LE(value) {
|
|
58
|
+
this.sb.writeFloatLE(value);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Writes a 64-bit float (little-endian)
|
|
62
|
+
*/
|
|
63
|
+
writeF64LE(value) {
|
|
64
|
+
this.sb.writeDoubleLE(value);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Writes raw bytes
|
|
68
|
+
*/
|
|
69
|
+
writeBytes(data) {
|
|
70
|
+
this.sb.writeBuffer(data);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Writes a VarInt (variable-length integer) using protobufjs
|
|
74
|
+
* FL Studio uses this encoding for TEXT and DATA event sizes
|
|
75
|
+
*/
|
|
76
|
+
writeVarInt(value) {
|
|
77
|
+
const writer = protobuf.Writer.create();
|
|
78
|
+
writer.uint32(value);
|
|
79
|
+
const encoded = writer.finish();
|
|
80
|
+
this.sb.writeBuffer(Buffer.from(encoded));
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Writes an ASCII string (null-terminated)
|
|
84
|
+
*/
|
|
85
|
+
writeAsciiString(str) {
|
|
86
|
+
this.sb.writeString(str + "\0", "ascii");
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Writes a UTF-16LE string (null-terminated)
|
|
90
|
+
*/
|
|
91
|
+
writeUtf16LEString(str) {
|
|
92
|
+
const buf = Buffer.from(str + "\0", "utf16le");
|
|
93
|
+
this.sb.writeBuffer(buf);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Gets the final buffer
|
|
97
|
+
*/
|
|
98
|
+
toBuffer() {
|
|
99
|
+
return this.sb.toBuffer();
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Encodes a VarInt to a Buffer using protobufjs (standalone utility)
|
|
104
|
+
*/
|
|
105
|
+
export function encodeVarInt(value) {
|
|
106
|
+
const writer = protobuf.Writer.create();
|
|
107
|
+
writer.uint32(value);
|
|
108
|
+
return Buffer.from(writer.finish());
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Calculates the byte size needed for a VarInt
|
|
112
|
+
*/
|
|
113
|
+
export function varIntSize(value) {
|
|
114
|
+
if (value < 0x80)
|
|
115
|
+
return 1;
|
|
116
|
+
if (value < 0x4000)
|
|
117
|
+
return 2;
|
|
118
|
+
if (value < 0x200000)
|
|
119
|
+
return 3;
|
|
120
|
+
if (value < 0x10000000)
|
|
121
|
+
return 4;
|
|
122
|
+
return 5;
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=BinaryWriter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BinaryWriter.js","sourceRoot":"","sources":["../../../src/io/BinaryWriter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FL Studio .flp file parser and serializer
|
|
3
|
+
* Conservative patch approach: preserves all unknown data byte-for-byte
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Represents a single event in an FLP file
|
|
7
|
+
* Stores raw bytes to enable conservative patching
|
|
8
|
+
*/
|
|
9
|
+
export interface FlpEvent {
|
|
10
|
+
/** Event ID (0-255) */
|
|
11
|
+
id: number;
|
|
12
|
+
/** Data type classification */
|
|
13
|
+
kind: "u8" | "i8" | "u16" | "i16" | "u32" | "i32" | "f32" | "text" | "data" | "unknown";
|
|
14
|
+
/** Original header bytes (ID + size for variable-length events) */
|
|
15
|
+
header: Buffer;
|
|
16
|
+
/** Event payload data */
|
|
17
|
+
payload: Buffer;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Represents a parsed FLP file
|
|
21
|
+
* Contains all data needed for conservative round-trip
|
|
22
|
+
*/
|
|
23
|
+
export interface ParsedFlp {
|
|
24
|
+
/** FLhd chunk (header) - 14 bytes total */
|
|
25
|
+
headerChunkBytes: Buffer;
|
|
26
|
+
/** FLdt chunk header (magic + size placeholder) - 8 bytes */
|
|
27
|
+
fldtHeaderBytes: Buffer;
|
|
28
|
+
/** All events from the FLdt chunk */
|
|
29
|
+
events: FlpEvent[];
|
|
30
|
+
/** Any trailing bytes after events (should be empty) */
|
|
31
|
+
trailingBytes: Buffer | undefined;
|
|
32
|
+
/** Detected FL version for string encoding */
|
|
33
|
+
flVersion: string;
|
|
34
|
+
/** Whether to use UTF-16LE for strings (FL >= 11.5) */
|
|
35
|
+
useUnicode: boolean;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Parses an FL Studio project file
|
|
39
|
+
*
|
|
40
|
+
* @param buffer - Raw file data
|
|
41
|
+
* @returns Parsed FLP structure
|
|
42
|
+
* @throws Error if file is corrupted or invalid
|
|
43
|
+
*/
|
|
44
|
+
export declare function parseFlp(buffer: Buffer): ParsedFlp;
|
|
45
|
+
/**
|
|
46
|
+
* Serializes a parsed FLP back to a buffer
|
|
47
|
+
* Recalculates FLdt chunk size if events have changed
|
|
48
|
+
*
|
|
49
|
+
* @param parsed - Parsed FLP structure
|
|
50
|
+
* @returns Serialized buffer
|
|
51
|
+
*/
|
|
52
|
+
export declare function serializeFlp(parsed: ParsedFlp): Buffer;
|
|
53
|
+
/**
|
|
54
|
+
* Creates a new event with the given ID and payload
|
|
55
|
+
*/
|
|
56
|
+
export declare function createEvent(id: number, payload: Buffer): FlpEvent;
|
|
57
|
+
/**
|
|
58
|
+
* Applies a patcher function to all events
|
|
59
|
+
* Returns a new ParsedFlp with patched events
|
|
60
|
+
*
|
|
61
|
+
* @param parsed - Original parsed FLP
|
|
62
|
+
* @param patcher - Function that transforms each event
|
|
63
|
+
* @returns New ParsedFlp with patched events
|
|
64
|
+
*/
|
|
65
|
+
export declare function patchEvents(parsed: ParsedFlp, patcher: (event: FlpEvent, index: number) => FlpEvent): ParsedFlp;
|
|
66
|
+
/**
|
|
67
|
+
* Finds all events with a specific ID
|
|
68
|
+
*/
|
|
69
|
+
export declare function findEvents(parsed: ParsedFlp, eventId: number): FlpEvent[];
|
|
70
|
+
/**
|
|
71
|
+
* Finds the first event with a specific ID
|
|
72
|
+
*/
|
|
73
|
+
export declare function findFirstEvent(parsed: ParsedFlp, eventId: number): FlpEvent | undefined;
|
|
74
|
+
/**
|
|
75
|
+
* Gets event payload as a string (handles encoding)
|
|
76
|
+
*/
|
|
77
|
+
export declare function getEventString(event: FlpEvent, useUnicode: boolean): string;
|
|
78
|
+
/**
|
|
79
|
+
* Creates a text payload with proper encoding
|
|
80
|
+
*/
|
|
81
|
+
export declare function createTextPayload(text: string, useUnicode: boolean): Buffer;
|
|
82
|
+
/**
|
|
83
|
+
* Gets event payload as a number
|
|
84
|
+
*/
|
|
85
|
+
export declare function getEventNumber(event: FlpEvent): number;
|
|
86
|
+
/**
|
|
87
|
+
* Creates a numeric payload
|
|
88
|
+
*/
|
|
89
|
+
export declare function createNumberPayload(value: number, kind: "u8" | "i8" | "u16" | "i16" | "u32" | "i32" | "f32"): Buffer;
|
|
90
|
+
//# sourceMappingURL=FlpParser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FlpParser.d.ts","sourceRoot":"","sources":["../../../src/parser/FlpParser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH;;;GAGG;AACH,MAAM,WAAW,QAAQ;IACvB,uBAAuB;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,+BAA+B;IAC/B,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IACxF,mEAAmE;IACnE,MAAM,EAAE,MAAM,CAAC;IACf,yBAAyB;IACzB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,2CAA2C;IAC3C,gBAAgB,EAAE,MAAM,CAAC;IACzB,6DAA6D;IAC7D,eAAe,EAAE,MAAM,CAAC;IACxB,qCAAqC;IACrC,MAAM,EAAE,QAAQ,EAAE,CAAC;IACnB,wDAAwD;IACxD,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,8CAA8C;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,uDAAuD;IACvD,UAAU,EAAE,OAAO,CAAC;CACrB;AASD;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CA0HlD;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAgCtD;AAuBD;;GAEG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,QAAQ,CAiBjE;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,KAAK,QAAQ,GACpD,SAAS,CAsBX;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,QAAQ,EAAE,CAEzE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAEvF;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,GAAG,MAAM,CAc3E;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,GAAG,MAAM,CAM3E;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAqBtD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GACxD,MAAM,CA4BR"}
|