@gaialabs/core 0.2.3 → 0.2.5

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.
Files changed (44) hide show
  1. package/client/client.d.ts +1 -0
  2. package/client/client.js +5 -0
  3. package/client/default.d.ts +1 -0
  4. package/client/default.js +5 -0
  5. package/client/edge.d.ts +1 -0
  6. package/client/edge.js +373 -0
  7. package/client/index-browser.js +399 -0
  8. package/client/index.d.ts +34222 -0
  9. package/client/index.js +373 -0
  10. package/client/package.json +144 -0
  11. package/client/query_compiler_fast_bg.js +2 -0
  12. package/client/query_compiler_fast_bg.wasm +0 -0
  13. package/client/query_compiler_fast_bg.wasm-base64.js +2 -0
  14. package/client/query_engine-windows.dll.node +0 -0
  15. package/client/query_engine_bg.js +2 -0
  16. package/client/query_engine_bg.wasm +0 -0
  17. package/client/runtime/client.d.ts +3358 -0
  18. package/client/runtime/client.js +86 -0
  19. package/client/runtime/edge-esm.js +35 -0
  20. package/client/runtime/edge.js +35 -0
  21. package/client/runtime/index-browser.d.ts +90 -0
  22. package/client/runtime/index-browser.js +6 -0
  23. package/client/runtime/library.d.ts +3982 -0
  24. package/client/runtime/library.js +147 -0
  25. package/client/runtime/react-native.js +84 -0
  26. package/client/runtime/wasm-compiler-edge.js +76 -0
  27. package/client/runtime/wasm-engine-edge.js +38 -0
  28. package/client/schema.prisma +404 -0
  29. package/client/wasm-edge-light-loader.mjs +5 -0
  30. package/client/wasm-worker-loader.mjs +5 -0
  31. package/client/wasm.d.ts +1 -0
  32. package/client/wasm.js +421 -0
  33. package/dist/index.cjs +1282 -454
  34. package/dist/index.cjs.map +1 -1
  35. package/dist/index.d.cts +1044 -352
  36. package/dist/index.d.cts.map +1 -0
  37. package/dist/index.d.mts +1044 -352
  38. package/dist/index.d.mts.map +1 -0
  39. package/dist/index.mjs +1279 -451
  40. package/dist/index.mjs.map +1 -1
  41. package/package.json +15 -1
  42. package/prisma.cjs +1 -0
  43. package/prisma.d.ts +1 -0
  44. package/prisma.mjs +9 -0
package/dist/index.mjs CHANGED
@@ -1,6 +1,846 @@
1
- import { writeFileSync } from "fs";
2
1
  import { createClient } from "@supabase/supabase-js";
3
2
 
3
+ //#region snes/addressingModes.json
4
+ var addressingModes_default = {
5
+ Absolute: {
6
+ "shorthand": "abs",
7
+ "operands": ["Offset"],
8
+ "size": 3,
9
+ "formatString": "${0:X4}",
10
+ "parseRegex": "^\\$([A-Fa-f0-9]{4}|&[A-Za-z0-9-+_]+)$",
11
+ "instructions": {
12
+ "ADC": 109,
13
+ "AND": 45,
14
+ "ASL": 14,
15
+ "BIT": 44,
16
+ "CMP": 205,
17
+ "CPX": 236,
18
+ "CPY": 204,
19
+ "DEC": 206,
20
+ "EOR": 77,
21
+ "INC": 238,
22
+ "JMP": 76,
23
+ "JSR": 32,
24
+ "LDA": 173,
25
+ "LDX": 174,
26
+ "LDY": 172,
27
+ "LSR": 78,
28
+ "ORA": 13,
29
+ "PEA": 244,
30
+ "ROL": 46,
31
+ "ROR": 110,
32
+ "SBC": 237,
33
+ "STA": 141,
34
+ "STX": 142,
35
+ "STY": 140,
36
+ "STZ": 156,
37
+ "TRB": 28,
38
+ "TSB": 12
39
+ }
40
+ },
41
+ AbsoluteIndexedX: {
42
+ "shorthand": "abs_x",
43
+ "operands": ["Offset"],
44
+ "size": 3,
45
+ "formatString": "${0:X4}, X",
46
+ "parseRegex": "^(\\$[A-Fa-f0-9]{4}|\\$?&[A-Za-z0-9-+_]+),\\s?[Xx]$",
47
+ "instructions": {
48
+ "ADC": 125,
49
+ "AND": 61,
50
+ "ASL": 30,
51
+ "BIT": 60,
52
+ "CMP": 221,
53
+ "DEC": 222,
54
+ "EOR": 93,
55
+ "INC": 254,
56
+ "LDA": 189,
57
+ "LDY": 188,
58
+ "LSR": 94,
59
+ "ORA": 29,
60
+ "ROL": 62,
61
+ "ROR": 126,
62
+ "SBC": 253,
63
+ "STA": 157,
64
+ "STZ": 158
65
+ }
66
+ },
67
+ AbsoluteIndexedY: {
68
+ "shorthand": "abs_y",
69
+ "operands": ["Offset"],
70
+ "size": 3,
71
+ "formatString": "${0:X4}, Y",
72
+ "parseRegex": "^(\\$[A-Fa-f0-9]{4}|\\$?&[A-Za-z0-9-+_]+),\\s?[Yy]$",
73
+ "instructions": {
74
+ "ADC": 121,
75
+ "AND": 57,
76
+ "CMP": 217,
77
+ "EOR": 89,
78
+ "LDA": 185,
79
+ "LDX": 190,
80
+ "ORA": 25,
81
+ "SBC": 249,
82
+ "STA": 153
83
+ }
84
+ },
85
+ AbsoluteIndirect: {
86
+ "shorthand": "abs_ind",
87
+ "operands": ["Offset"],
88
+ "size": 3,
89
+ "formatString": "(${0})",
90
+ "parseRegex": "^\\((\\$[A-Fa-f0-9]{4}|\\$?&[A-Za-z0-9-+_]+)\\)$",
91
+ "instructions": { "JMP": 108 }
92
+ },
93
+ AbsoluteIndirectLong: {
94
+ "shorthand": "abs_indl",
95
+ "operands": ["Offset"],
96
+ "size": 3,
97
+ "formatString": "[${0}]",
98
+ "parseRegex": "^\\[(\\$[A-Fa-f0-9]{4}|\\$?&[A-Za-z0-9-+_]+)\\]$",
99
+ "instructions": { "JML": 220 }
100
+ },
101
+ AbsoluteIndexedIndirect: {
102
+ "shorthand": "abs_x_ind",
103
+ "operands": ["Offset"],
104
+ "size": 3,
105
+ "formatString": "(${0}, X)",
106
+ "parseRegex": "^\\((\\$[A-Fa-f0-9]{4}|\\$?&[A-Za-z0-9-+_]+),\\s*[Xx]\\)$",
107
+ "instructions": {
108
+ "JMP": 124,
109
+ "JSR": 252
110
+ }
111
+ },
112
+ AbsoluteLong: {
113
+ "shorthand": "long",
114
+ "operands": ["Address"],
115
+ "size": 4,
116
+ "formatString": "${0:X6}",
117
+ "parseRegex": "^\\$([A-Fa-f0-9]{6}|\\@[A-Za-z0-9-+_]+)$",
118
+ "instructions": {
119
+ "ADC": 111,
120
+ "AND": 47,
121
+ "CMP": 207,
122
+ "EOR": 79,
123
+ "JML": 92,
124
+ "JSL": 34,
125
+ "LDA": 175,
126
+ "ORA": 15,
127
+ "SBC": 239,
128
+ "STA": 143
129
+ }
130
+ },
131
+ AbsoluteLongIndexedX: {
132
+ "shorthand": "long_x",
133
+ "operands": ["Address"],
134
+ "size": 4,
135
+ "formatString": "${0:X6}, X",
136
+ "parseRegex": "^(\\$[A-Fa-f0-9]{6}|\\$?@[A-Za-z0-9-+_]+),\\s?[Xx]$",
137
+ "instructions": {
138
+ "ADC": 127,
139
+ "AND": 63,
140
+ "CMP": 223,
141
+ "EOR": 95,
142
+ "LDA": 191,
143
+ "ORA": 31,
144
+ "SBC": 255,
145
+ "STA": 159
146
+ }
147
+ },
148
+ DirectPage: {
149
+ "shorthand": "dp",
150
+ "operands": ["Direct"],
151
+ "size": 2,
152
+ "formatString": "${0:X2}",
153
+ "parseRegex": "^\\$([A-Fa-f0-9]{2})$",
154
+ "instructions": {
155
+ "ADC": 101,
156
+ "AND": 37,
157
+ "ASL": 6,
158
+ "BIT": 36,
159
+ "CMP": 197,
160
+ "CPX": 228,
161
+ "CPY": 196,
162
+ "DEC": 198,
163
+ "EOR": 69,
164
+ "INC": 230,
165
+ "LDA": 165,
166
+ "LDX": 166,
167
+ "LDY": 164,
168
+ "LSR": 70,
169
+ "ORA": 5,
170
+ "ROL": 38,
171
+ "ROR": 102,
172
+ "SBC": 229,
173
+ "STA": 133,
174
+ "STX": 134,
175
+ "STY": 132,
176
+ "STZ": 100,
177
+ "TRB": 20,
178
+ "TSB": 4
179
+ }
180
+ },
181
+ DirectPageIndexedX: {
182
+ "shorthand": "dp_x",
183
+ "operands": ["Direct"],
184
+ "size": 2,
185
+ "formatString": "${0:X2}, X",
186
+ "parseRegex": "^\\$([A-Fa-f0-9]{2}),\\s?[Xx]$",
187
+ "instructions": {
188
+ "ADC": 117,
189
+ "AND": 53,
190
+ "ASL": 22,
191
+ "BIT": 52,
192
+ "CMP": 213,
193
+ "DEC": 214,
194
+ "EOR": 85,
195
+ "INC": 246,
196
+ "LDA": 181,
197
+ "LDY": 180,
198
+ "LSR": 86,
199
+ "ORA": 21,
200
+ "ROL": 54,
201
+ "ROR": 118,
202
+ "SBC": 245,
203
+ "STA": 149,
204
+ "STY": 148,
205
+ "STZ": 116
206
+ }
207
+ },
208
+ DirectPageIndexedY: {
209
+ "shorthand": "dp_y",
210
+ "operands": ["Direct"],
211
+ "size": 2,
212
+ "formatString": "${0:X2}, Y",
213
+ "parseRegex": "^\\$([A-Fa-f0-9]{2}),\\s?[Yy]$",
214
+ "instructions": {
215
+ "LDX": 182,
216
+ "STX": 150
217
+ }
218
+ },
219
+ DirectPageIndirect: {
220
+ "shorthand": "dp_ind",
221
+ "operands": ["Direct"],
222
+ "size": 2,
223
+ "formatString": "(${0:X2})",
224
+ "parseRegex": "^\\(\\$([A-Fa-f0-9]{2})\\)$",
225
+ "instructions": {
226
+ "ADC": 114,
227
+ "AND": 50,
228
+ "CMP": 210,
229
+ "EOR": 82,
230
+ "LDA": 178,
231
+ "ORA": 18,
232
+ "PEI": 212,
233
+ "SBC": 242,
234
+ "STA": 146
235
+ }
236
+ },
237
+ DirectPageIndirectLong: {
238
+ "shorthand": "dp_indl",
239
+ "operands": ["Direct"],
240
+ "size": 2,
241
+ "formatString": "[${0:X2}]",
242
+ "parseRegex": "^\\[\\$([A-Fa-f0-9]{2})\\]$",
243
+ "instructions": {
244
+ "ADC": 103,
245
+ "AND": 39,
246
+ "CMP": 199,
247
+ "EOR": 71,
248
+ "LDA": 167,
249
+ "ORA": 7,
250
+ "SBC": 231,
251
+ "STA": 135
252
+ }
253
+ },
254
+ DirectPageIndexedIndirectX: {
255
+ "shorthand": "dp_x_ind",
256
+ "operands": ["Direct"],
257
+ "size": 2,
258
+ "formatString": "(${0:X2}, X)",
259
+ "parseRegex": "^\\(\\$([A-Fa-f0-9]{2}),\\s?[Xx]\\)$",
260
+ "instructions": {
261
+ "ADC": 97,
262
+ "AND": 33,
263
+ "CMP": 193,
264
+ "EOR": 65,
265
+ "LDA": 161,
266
+ "ORA": 1,
267
+ "SBC": 225,
268
+ "STA": 129
269
+ }
270
+ },
271
+ DirectPageIndirectIndexedY: {
272
+ "shorthand": "dp_ind_y",
273
+ "operands": ["Direct"],
274
+ "size": 2,
275
+ "formatString": "(${0:X2}), Y",
276
+ "parseRegex": "^\\(\\$([A-Fa-f0-9]{2})\\),\\s?[Yy]$",
277
+ "instructions": {
278
+ "ADC": 113,
279
+ "AND": 49,
280
+ "CMP": 209,
281
+ "EOR": 81,
282
+ "LDA": 177,
283
+ "ORA": 17,
284
+ "SBC": 241,
285
+ "STA": 145
286
+ }
287
+ },
288
+ DirectPageIndirectLongIndexedY: {
289
+ "shorthand": "dp_indl_y",
290
+ "operands": ["Direct"],
291
+ "size": 2,
292
+ "formatString": "[${0:X2}], Y",
293
+ "parseRegex": "^\\[\\$([A-Fa-f0-9]{2})\\],\\s?[Yy]$",
294
+ "instructions": {
295
+ "ADC": 119,
296
+ "AND": 55,
297
+ "CMP": 215,
298
+ "EOR": 87,
299
+ "LDA": 183,
300
+ "ORA": 23,
301
+ "SBC": 247,
302
+ "STA": 151
303
+ }
304
+ },
305
+ Immediate: {
306
+ "shorthand": "imm",
307
+ "operands": ["Immediate"],
308
+ "size": 2,
309
+ "formatString": "#${0:X2}",
310
+ "parseRegex": "^#(\\$[A-Fa-f0-9]{2,4}|\\$?[&^*][A-Za-z0-9-+_]+)$",
311
+ "instructions": {
312
+ "ADC": 105,
313
+ "AND": 41,
314
+ "BIT": 137,
315
+ "CMP": 201,
316
+ "CPX": 224,
317
+ "CPY": 192,
318
+ "EOR": 73,
319
+ "LDA": 169,
320
+ "LDX": 162,
321
+ "LDY": 160,
322
+ "ORA": 9,
323
+ "REP": 194,
324
+ "SBC": 233,
325
+ "SEP": 226
326
+ }
327
+ },
328
+ Implied: {
329
+ "shorthand": "imp",
330
+ "operands": [],
331
+ "size": 1,
332
+ "formatString": null,
333
+ "parseRegex": null,
334
+ "instructions": {
335
+ "CLC": 24,
336
+ "CLD": 216,
337
+ "CLI": 88,
338
+ "CLV": 184,
339
+ "DEX": 202,
340
+ "DEY": 136,
341
+ "INX": 232,
342
+ "INY": 200,
343
+ "NOP": 234,
344
+ "SEC": 56,
345
+ "SED": 248,
346
+ "SEI": 120,
347
+ "STP": 219,
348
+ "TAX": 170,
349
+ "TAY": 168,
350
+ "TCD": 91,
351
+ "TCS": 27,
352
+ "TDC": 123,
353
+ "TSC": 59,
354
+ "TSX": 186,
355
+ "TXA": 138,
356
+ "TXS": 154,
357
+ "TXY": 155,
358
+ "TYA": 152,
359
+ "TYX": 187,
360
+ "WAI": 203,
361
+ "WDM": 66,
362
+ "XBA": 235,
363
+ "XCE": 251
364
+ }
365
+ },
366
+ Accumulator: {
367
+ "shorthand": "acc",
368
+ "operands": [],
369
+ "size": 1,
370
+ "formatString": null,
371
+ "parseRegex": null,
372
+ "instructions": {
373
+ "ASL": 10,
374
+ "DEC": 58,
375
+ "INC": 26,
376
+ "LSR": 74,
377
+ "ROL": 42,
378
+ "ROR": 106
379
+ }
380
+ },
381
+ PCRelative: {
382
+ "shorthand": "rel",
383
+ "operands": ["Relative"],
384
+ "size": 2,
385
+ "formatString": "{0}",
386
+ "parseRegex": "^([A-Za-z_][A-Za-z0-9_]*|\\$[A-Fa-f0-9]{2})$",
387
+ "instructions": {
388
+ "BPL": 16,
389
+ "BMI": 48,
390
+ "BRA": 128,
391
+ "BCC": 144,
392
+ "BCS": 176,
393
+ "BNE": 208,
394
+ "BEQ": 240,
395
+ "BVC": 80,
396
+ "BVS": 112
397
+ }
398
+ },
399
+ PCRelativeLong: {
400
+ "shorthand": "rel16",
401
+ "operands": ["RelativeLong"],
402
+ "size": 3,
403
+ "formatString": "{0}",
404
+ "parseRegex": "^([A-Za-z_][A-Za-z0-9_]*|\\$[A-Fa-f0-9]{4})$",
405
+ "instructions": {
406
+ "BRL": 130,
407
+ "PER": 98
408
+ }
409
+ },
410
+ StackRelative: {
411
+ "shorthand": "stkr",
412
+ "operands": ["Byte"],
413
+ "size": 2,
414
+ "formatString": "${0:X2}, S",
415
+ "parseRegex": "^\\$([A-Fa-f0-9]{2}),\\s?[Ss]$",
416
+ "instructions": {
417
+ "ADC": 99,
418
+ "AND": 35,
419
+ "CMP": 195,
420
+ "EOR": 67,
421
+ "LDA": 163,
422
+ "ORA": 3,
423
+ "SBC": 227,
424
+ "STA": 131
425
+ }
426
+ },
427
+ StackRelativeIndirectIndexedY: {
428
+ "shorthand": "stkr_ind_y",
429
+ "operands": ["Byte"],
430
+ "size": 2,
431
+ "formatString": "(${0:X2}, S), Y",
432
+ "parseRegex": "^\\(\\$([A-Fa-f0-9]{2}),\\s?[Ss]\\),\\s?[Yy]$",
433
+ "instructions": {
434
+ "ADC": 115,
435
+ "AND": 51,
436
+ "CMP": 211,
437
+ "EOR": 83,
438
+ "LDA": 179,
439
+ "ORA": 19,
440
+ "SBC": 243,
441
+ "STA": 147
442
+ }
443
+ },
444
+ BlockMove: {
445
+ "shorthand": "src_dest",
446
+ "operands": ["Byte", "Byte"],
447
+ "size": 3,
448
+ "formatString": "#${0:X2}, #${1:X2}",
449
+ "parseRegex": "^#\\$([A-Fa-f0-9]{2}|\\^[A-Za-z0-9-+_]+),\\s?#\\$([A-Fa-f0-9]{2}|\\^[A-Za-z0-9-+_]+)$",
450
+ "instructions": {
451
+ "MVN": 84,
452
+ "MVP": 68
453
+ }
454
+ },
455
+ StackInterrupt: {
456
+ "shorthand": "stk_int",
457
+ "operands": ["Byte"],
458
+ "size": 2,
459
+ "formatString": "#${0:X2}",
460
+ "parseRegex": "^#\\$([A-Fa-f0-9]{2})$",
461
+ "instructions": {
462
+ "BRK": 0,
463
+ "COP": 2
464
+ }
465
+ },
466
+ Stack: {
467
+ "shorthand": "stk",
468
+ "operands": [],
469
+ "size": 1,
470
+ "formatString": null,
471
+ "parseRegex": null,
472
+ "instructions": {
473
+ "PHA": 72,
474
+ "PHB": 139,
475
+ "PHD": 11,
476
+ "PHK": 75,
477
+ "PHP": 8,
478
+ "PHX": 218,
479
+ "PHY": 90,
480
+ "PLA": 104,
481
+ "PLB": 171,
482
+ "PLD": 43,
483
+ "PLP": 40,
484
+ "PLX": 250,
485
+ "PLY": 122,
486
+ "RTI": 64,
487
+ "RTL": 107,
488
+ "RTS": 96
489
+ }
490
+ }
491
+ };
492
+
493
+ //#endregion
494
+ //#region snes/vectors.json
495
+ var vectors_default = {
496
+ "8448": "INIDISP",
497
+ "8449": "OBJSEL",
498
+ "8450": "OAMADDL",
499
+ "8451": "OAMADDH",
500
+ "8452": "OAMDATA",
501
+ "8453": "BGMODE",
502
+ "8454": "MOSAIC",
503
+ "8455": "BG1SC",
504
+ "8456": "BG2SC",
505
+ "8457": "BG3SC",
506
+ "8458": "BG4SC",
507
+ "8459": "BG12NBA",
508
+ "8460": "BG34NBA",
509
+ "8461": "BG1HOFS",
510
+ "8462": "BG1VOFS",
511
+ "8463": "BG2HOFS",
512
+ "8464": "BG2VOFS",
513
+ "8465": "BG3HOFS",
514
+ "8466": "BG3VOFS",
515
+ "8467": "BG4HOFS",
516
+ "8468": "BG4VOFS",
517
+ "8469": "VMAIN",
518
+ "8470": "VMADDL",
519
+ "8471": "VMADDH",
520
+ "8472": "VMDATAL",
521
+ "8473": "VMDATAH",
522
+ "8474": "M7SEL",
523
+ "8475": "M7A",
524
+ "8476": "M7B",
525
+ "8477": "M7C",
526
+ "8478": "M7D",
527
+ "8479": "M7X",
528
+ "8480": "M7Y",
529
+ "8481": "CGADD",
530
+ "8482": "CGDATA",
531
+ "8483": "W12SEL",
532
+ "8484": "W34SEL",
533
+ "8485": "WOBJSEL",
534
+ "8486": "WH0",
535
+ "8487": "WH1",
536
+ "8488": "WH2",
537
+ "8489": "WH3",
538
+ "8490": "WBGLOG",
539
+ "8491": "WOBJLOG",
540
+ "8492": "_TM",
541
+ "8493": "_TS",
542
+ "8494": "TMW",
543
+ "8495": "TSW",
544
+ "8496": "CGWSEL",
545
+ "8497": "CGADSUB",
546
+ "8498": "COLDATA",
547
+ "8499": "SETINI",
548
+ "8500": "MPYL",
549
+ "8501": "MPYM",
550
+ "8502": "MPYH",
551
+ "8503": "SLHV",
552
+ "8504": "OAMDATAREAD",
553
+ "8505": "VMDATALREAD",
554
+ "8506": "VMDATAHREAD",
555
+ "8507": "CGDATAREAD",
556
+ "8508": "OPHCT",
557
+ "8509": "OPVCT",
558
+ "8510": "STAT77",
559
+ "8511": "STAT78",
560
+ "8512": "APUIO0",
561
+ "8513": "APUIO1",
562
+ "8514": "APUIO2",
563
+ "8515": "APUIO3",
564
+ "8576": "WMDATA",
565
+ "8577": "WMADDL",
566
+ "8578": "WMADDM",
567
+ "8579": "WMADDH",
568
+ "16406": "JOYSER0",
569
+ "16407": "JOYSER1",
570
+ "16896": "NMITIMEN",
571
+ "16897": "WRIO",
572
+ "16898": "WRMPYA",
573
+ "16899": "WRMPYB",
574
+ "16900": "WRDIVL",
575
+ "16901": "WRDIVH",
576
+ "16902": "WRDIVB",
577
+ "16903": "HTIMEL",
578
+ "16904": "HTIMEH",
579
+ "16905": "VTIMEL",
580
+ "16906": "VTIMEH",
581
+ "16907": "MDMAEN",
582
+ "16908": "HDMAEN",
583
+ "16909": "MEMSEL",
584
+ "16912": "RDNMI",
585
+ "16913": "TIMEUP",
586
+ "16914": "HVBJOY",
587
+ "16915": "RDIO",
588
+ "16916": "RDDIVL",
589
+ "16917": "RDDIVH",
590
+ "16918": "RDMPYL",
591
+ "16919": "RDMPYH",
592
+ "16920": "JOY1L",
593
+ "16921": "JOY1H",
594
+ "16922": "JOY2L",
595
+ "16923": "JOY2H",
596
+ "16924": "JOY3L",
597
+ "16925": "JOY3H",
598
+ "16926": "JOY4L",
599
+ "16927": "JOY4H",
600
+ "17152": "DMAP0",
601
+ "17153": "BBAD0",
602
+ "17154": "A1T0L",
603
+ "17155": "A1T0H",
604
+ "17156": "A1B0",
605
+ "17157": "DAS0L",
606
+ "17158": "DAS0H",
607
+ "17159": "DASB0",
608
+ "17160": "A2A0L",
609
+ "17161": "A2A0H",
610
+ "17162": "NLTR0",
611
+ "17168": "DMAP1",
612
+ "17169": "BBAD1",
613
+ "17170": "A1T1L",
614
+ "17171": "A1T1H",
615
+ "17172": "A1B1",
616
+ "17173": "DAS1L",
617
+ "17174": "DAS1H",
618
+ "17175": "DASB1",
619
+ "17176": "A2A1L",
620
+ "17177": "A2A1H",
621
+ "17178": "NLTR1",
622
+ "17184": "DMAP2",
623
+ "17185": "BBAD2",
624
+ "17186": "A1T2L",
625
+ "17187": "A1T2H",
626
+ "17188": "A1B2",
627
+ "17189": "DAS2L",
628
+ "17190": "DAS2H",
629
+ "17191": "DASB2",
630
+ "17192": "A2A2L",
631
+ "17193": "A2A2H",
632
+ "17194": "NLTR2",
633
+ "17200": "DMAP3",
634
+ "17201": "BBAD3",
635
+ "17202": "A1T3L",
636
+ "17203": "A1T3H",
637
+ "17204": "A1B3",
638
+ "17205": "DAS3L",
639
+ "17206": "DAS3H",
640
+ "17207": "DASB3",
641
+ "17208": "A2A3L",
642
+ "17209": "A2A3H",
643
+ "17210": "NLTR3",
644
+ "17216": "DMAP4",
645
+ "17217": "BBAD4",
646
+ "17218": "A1T4L",
647
+ "17219": "A1T4H",
648
+ "17220": "A1B4",
649
+ "17221": "DAS4L",
650
+ "17222": "DAS4H",
651
+ "17223": "DASB4",
652
+ "17224": "A2A4L",
653
+ "17225": "A2A4H",
654
+ "17226": "NLTR4",
655
+ "17232": "DMAP5",
656
+ "17233": "BBAD5",
657
+ "17234": "A1T5L",
658
+ "17235": "A1T5H",
659
+ "17236": "A1B5",
660
+ "17237": "DAS5L",
661
+ "17238": "DAS5H",
662
+ "17239": "DASB5",
663
+ "17240": "A2A5L",
664
+ "17241": "A2A5H",
665
+ "17242": "NLTR5",
666
+ "17248": "DMAP6",
667
+ "17249": "BBAD6",
668
+ "17250": "A1T6L",
669
+ "17251": "A1T6H",
670
+ "17252": "A1B6",
671
+ "17253": "DAS6L",
672
+ "17254": "DAS6H",
673
+ "17255": "DASB6",
674
+ "17256": "A2A6L",
675
+ "17257": "A2A6H",
676
+ "17258": "NLTR6",
677
+ "17264": "DMAP7",
678
+ "17265": "BBAD7",
679
+ "17266": "A1T7L",
680
+ "17267": "A1T7H",
681
+ "17268": "A1B7",
682
+ "17269": "DAS7L",
683
+ "17270": "DAS7H",
684
+ "17271": "DASB7",
685
+ "17272": "A2A7L",
686
+ "17273": "A2A7H",
687
+ "17274": "NLTR7"
688
+ };
689
+
690
+ //#endregion
691
+ //#region snes/headers.json
692
+ var headers_default = [{
693
+ "address": 65456,
694
+ "condition": "values.developerId === 51",
695
+ "parts": [
696
+ {
697
+ "name": "makerCode",
698
+ "size": 2,
699
+ "type": "string"
700
+ },
701
+ {
702
+ "name": "gameCode",
703
+ "size": 4,
704
+ "type": "string"
705
+ },
706
+ {
707
+ "name": "reserved",
708
+ "size": 10,
709
+ "type": "byte",
710
+ "value": 0
711
+ }
712
+ ]
713
+ }, {
714
+ "address": 65472,
715
+ "parts": [
716
+ {
717
+ "name": "gameTitle",
718
+ "size": 21,
719
+ "type": "string"
720
+ },
721
+ {
722
+ "name": "mapMode",
723
+ "size": 1,
724
+ "type": "byte"
725
+ },
726
+ {
727
+ "name": "chipset",
728
+ "size": 1,
729
+ "type": "byte"
730
+ },
731
+ {
732
+ "name": "romSize",
733
+ "size": 1,
734
+ "type": "byte"
735
+ },
736
+ {
737
+ "name": "ramSize",
738
+ "size": 1,
739
+ "type": "byte"
740
+ },
741
+ {
742
+ "name": "countryCode",
743
+ "size": 1,
744
+ "type": "byte"
745
+ },
746
+ {
747
+ "name": "developerId",
748
+ "size": 1,
749
+ "type": "byte"
750
+ },
751
+ {
752
+ "name": "gameVersion",
753
+ "size": 1,
754
+ "type": "byte"
755
+ },
756
+ {
757
+ "name": "compliment",
758
+ "size": 2,
759
+ "type": "word"
760
+ },
761
+ {
762
+ "name": "checksum",
763
+ "size": 2,
764
+ "type": "word"
765
+ },
766
+ {
767
+ "name": "reserved",
768
+ "size": 4,
769
+ "type": "byte",
770
+ "value": 0
771
+ },
772
+ {
773
+ "name": "nativeCop",
774
+ "size": 2,
775
+ "type": "entry"
776
+ },
777
+ {
778
+ "name": "nativeBrk",
779
+ "size": 2,
780
+ "type": "entry"
781
+ },
782
+ {
783
+ "name": "nativeAbort",
784
+ "size": 2,
785
+ "type": "entry"
786
+ },
787
+ {
788
+ "name": "nativeNmi",
789
+ "size": 2,
790
+ "type": "entry"
791
+ },
792
+ {
793
+ "name": "reserved",
794
+ "size": 2,
795
+ "type": "byte",
796
+ "value": 0
797
+ },
798
+ {
799
+ "name": "nativeIrq",
800
+ "size": 2,
801
+ "type": "entry"
802
+ },
803
+ {
804
+ "name": "reserved",
805
+ "size": 4,
806
+ "type": "byte",
807
+ "value": 0
808
+ },
809
+ {
810
+ "name": "emulationCop",
811
+ "size": 2,
812
+ "type": "entry"
813
+ },
814
+ {
815
+ "name": "reserved",
816
+ "size": 2,
817
+ "type": "byte",
818
+ "value": 0
819
+ },
820
+ {
821
+ "name": "emulationAbort",
822
+ "size": 2,
823
+ "type": "entry"
824
+ },
825
+ {
826
+ "name": "emulationNmi",
827
+ "size": 2,
828
+ "type": "entry"
829
+ },
830
+ {
831
+ "name": "emulationReset",
832
+ "size": 2,
833
+ "type": "entry"
834
+ },
835
+ {
836
+ "name": "emulationBrk",
837
+ "size": 2,
838
+ "type": "entry"
839
+ }
840
+ ]
841
+ }];
842
+
843
+ //#endregion
4
844
  //#region src/rom/state.ts
5
845
  /**
6
846
  * Lightweight ROM state placeholder used during early development.
@@ -808,23 +1648,6 @@ var CompressionRegistry = class {
808
1648
  //#endregion
809
1649
  //#region src/types/files.ts
810
1650
  /**
811
- * Types that should have a compression header by default but should not be compressed
812
- */
813
- const UNCOMPRESSED_TYPES = [
814
- "Bitmap",
815
- "Tilemap",
816
- "Tileset",
817
- "Spritemap",
818
- "Meta17"
819
- ];
820
- /**
821
- * Type guard to check if a type is an uncompressed type
822
- * Works with both BinType enum values and string values
823
- */
824
- function isUncompressedType(type) {
825
- return UNCOMPRESSED_TYPES.includes(type);
826
- }
827
- /**
828
1651
  * Chunk file for ROM processing
829
1652
  * Converted from GaiaLib/Types/ChunkFile.cs
830
1653
  */
@@ -851,7 +1674,7 @@ var ChunkFile = class {
851
1674
  this.size = size;
852
1675
  this.location = location;
853
1676
  this.mnemonics = {};
854
- this.compressed = isUncompressedType(type.type) ? false : void 0;
1677
+ this.compressed = type.compressed;
855
1678
  this.type = type;
856
1679
  }
857
1680
  };
@@ -897,7 +1720,7 @@ function enrichWithRawDataFromDbFile(rom, chunkFile, compression, dbFile, fileTy
897
1720
  }
898
1721
  let length = dbFile.end - start;
899
1722
  let fileData;
900
- if (dbFile.compressed === true) {
1723
+ if (dbFile.compressed === true && compression) {
901
1724
  const expanded = compression.expand(rom, start, length);
902
1725
  fileData = combineHeader(expanded, 0, expanded.length, header, fileType.type);
903
1726
  } else {
@@ -950,12 +1773,12 @@ var ChunkFileUtils = class {
950
1773
  */
951
1774
  static calculateSize(chunkFile) {
952
1775
  if (!chunkFile.parts) {
953
- let size$1 = chunkFile.rawData?.length ?? chunkFile.size;
1776
+ let size = chunkFile.rawData?.length ?? chunkFile.size;
954
1777
  if (chunkFile.type.header === -2 || chunkFile.compressed === false) {
955
- size$1 += 2;
956
- chunkFile.size = size$1;
1778
+ size += 2;
1779
+ chunkFile.size = size;
957
1780
  }
958
- return size$1;
1781
+ return size;
959
1782
  }
960
1783
  let size = 0;
961
1784
  for (let x = 0; x < chunkFile.parts.length; x++) {
@@ -1697,18 +2520,18 @@ var DbFile = class {
1697
2520
  group;
1698
2521
  scene;
1699
2522
  constructor(data) {
1700
- this.name = data.name ?? "";
1701
- this.type = data.type ?? "";
1702
- this.start = data.start ?? void 0;
1703
- this.end = data.end ?? 0;
2523
+ if (!data.name) throw new Error("Name is required");
2524
+ if (!data.type) throw new Error("Type is required");
2525
+ if (typeof data.start !== "number") throw new Error("Start is required");
2526
+ if (typeof data.end !== "number") throw new Error("End is required");
2527
+ this.name = data.name;
2528
+ this.type = data.type;
2529
+ this.start = data.start;
2530
+ this.end = data.end;
1704
2531
  this.compressed = data.compressed ?? void 0;
1705
2532
  this.upper = data.upper ?? void 0;
1706
2533
  this.group = data.group || void 0;
1707
2534
  this.scene = data.scene || void 0;
1708
- if (!this.name) throw new Error("Name is required");
1709
- if (!this.type) throw new Error("Type is required");
1710
- if (this.start === void 0) throw new Error("Start is required");
1711
- if (!this.end) throw new Error("End is required");
1712
2535
  }
1713
2536
  };
1714
2537
  var DbFileType = class {
@@ -1718,6 +2541,7 @@ var DbFileType = class {
1718
2541
  isPatch;
1719
2542
  isBlock;
1720
2543
  header;
2544
+ compressed;
1721
2545
  constructor(data) {
1722
2546
  this.name = data.name ?? "";
1723
2547
  this.extension = data.extension ?? "";
@@ -1725,6 +2549,7 @@ var DbFileType = class {
1725
2549
  this.isPatch = data.isPatch ?? false;
1726
2550
  this.isBlock = data.isBlock ?? false;
1727
2551
  this.header = data.header ?? 0;
2552
+ this.compressed = data.compressed ?? void 0;
1728
2553
  if (!this.name) throw new Error("Name is required");
1729
2554
  if (!this.extension) throw new Error("Extension is required");
1730
2555
  if (!this.type) throw new Error("Type is required");
@@ -1764,17 +2589,17 @@ var DbAddressingMode = class {
1764
2589
  parseRegex;
1765
2590
  instructions;
1766
2591
  constructor(data) {
1767
- this.name = data.name ?? "";
1768
- this.shorthand = data.shorthand ?? "";
2592
+ if (!data.name) throw new Error("Addressing mode name is required");
2593
+ if (!data.shorthand) throw new Error("Addressing mode shorthand is required");
2594
+ if (!data.instructions) throw new Error("Addressing mode instructions are required");
2595
+ if (!data.size) throw new Error("Addressing mode size is required");
2596
+ this.name = data.name;
2597
+ this.shorthand = data.shorthand;
1769
2598
  this.operands = data.operands ?? [];
1770
2599
  this.size = data.size ?? 1;
1771
2600
  this.formatString = data.formatString ?? void 0;
1772
2601
  this.parseRegex = data.parseRegex ?? void 0;
1773
- this.instructions = data.instructions ?? void 0;
1774
- if (!this.name) throw new Error("Addressing mode name is required");
1775
- if (!this.shorthand) throw new Error("Addressing mode shorthand is required");
1776
- if (!this.instructions) throw new Error("Addressing mode instructions are required");
1777
- if (!this.size) throw new Error("Addressing mode size is required");
2602
+ this.instructions = data.instructions;
1778
2603
  }
1779
2604
  };
1780
2605
 
@@ -1790,14 +2615,16 @@ var DbStringCommand = class {
1790
2615
  types;
1791
2616
  delimiter;
1792
2617
  halt;
2618
+ dictionary;
1793
2619
  constructor(data) {
1794
- this.id = data.id ?? void 0;
1795
- this.name = data.name ?? "";
2620
+ if (typeof data.id !== "number") throw new Error("Id is required");
2621
+ if (!data.name) throw new Error("Name is required");
2622
+ this.id = data.id;
2623
+ this.name = data.name;
1796
2624
  this.types = data.types ?? [];
1797
2625
  this.delimiter = data.delimiter ?? void 0;
1798
2626
  this.halt = data.halt ?? false;
1799
- if (!this.id && this.id !== 0) throw new Error("Id is required");
1800
- if (!this.name) throw new Error("Name is required");
2627
+ this.dictionary = data.dictionary ?? void 0;
1801
2628
  }
1802
2629
  };
1803
2630
  var DbStringDictionary = class {
@@ -1807,14 +2634,14 @@ var DbStringDictionary = class {
1807
2634
  name;
1808
2635
  entries;
1809
2636
  constructor(data) {
2637
+ if (typeof data.base !== "number" && typeof data.command !== "number") throw new Error("Base or command is required");
2638
+ if (!data.name) throw new Error("Name is required");
2639
+ if (!data.entries || data.entries.length === 0) throw new Error("Entries is required");
1810
2640
  this.base = data.base ?? void 0;
1811
2641
  this.range = data.range ?? 0;
1812
2642
  this.command = data.command ?? void 0;
1813
- this.name = data.name ?? "";
1814
- this.entries = data.entries ?? void 0;
1815
- if (this.base === void 0 && this.command === void 0) throw new Error("Base or command is required");
1816
- if (!this.name) throw new Error("Name is required");
1817
- if (!this.entries) throw new Error("Entries is required");
2643
+ this.name = data.name;
2644
+ this.entries = data.entries;
1818
2645
  if (this.base !== void 0) this.range = this.base + this.entries.length;
1819
2646
  }
1820
2647
  };
@@ -1826,8 +2653,6 @@ var DbStringType = class {
1826
2653
  name;
1827
2654
  delimiter;
1828
2655
  terminator;
1829
- shiftType;
1830
- characterMap;
1831
2656
  commands;
1832
2657
  commandLookup;
1833
2658
  layers;
@@ -1835,13 +2660,15 @@ var DbStringType = class {
1835
2660
  dictionaries;
1836
2661
  dictionaryLookup;
1837
2662
  constructor(data) {
1838
- this.name = data.name ?? "";
1839
- this.delimiter = data.delimiter ?? "";
1840
- this.terminator = data.terminator ?? 0;
1841
- this.shiftType = data.shiftType ?? void 0;
1842
- this.characterMap = data.characterMap;
2663
+ if (!data.name) throw new Error("Name is required");
2664
+ if (!data.delimiter) throw new Error("Delimiter is required");
2665
+ if (typeof data.terminator !== "number") throw new Error("Terminator is required");
2666
+ if (!data.layers || !data.layers.length) throw new Error("Layers are required");
2667
+ this.name = data.name;
2668
+ this.delimiter = data.delimiter;
2669
+ this.terminator = data.terminator;
1843
2670
  this.commands = data.commands ?? {};
1844
- this.layers = data.layers ?? [];
2671
+ this.layers = data.layers;
1845
2672
  this.greedyTerminator = data.greedyTerminator ?? false;
1846
2673
  this.dictionaries = data.dictionaries ?? {};
1847
2674
  this.commandLookup = Object.values(this.commands).reduce((acc, x) => {
@@ -1850,12 +2677,8 @@ var DbStringType = class {
1850
2677
  }, {});
1851
2678
  this.dictionaryLookup = Object.values(this.dictionaries).flatMap((y) => y.entries.map((z, ix) => ({
1852
2679
  text: z,
1853
- id: y.command << 8 | y.base + ix
2680
+ id: (y.command ?? 0) | (y.base ?? 0 + ix)
1854
2681
  }))).sort((a, b) => b.text.length - a.text.length);
1855
- if (!this.name) throw new Error("Name is required");
1856
- if (!this.delimiter) throw new Error("Delimiter is required");
1857
- if (!this.terminator && this.terminator !== 0) throw new Error("Terminator is required");
1858
- if (!this.characterMap) throw new Error("Character map is required");
1859
2682
  }
1860
2683
  };
1861
2684
  /**
@@ -1893,13 +2716,13 @@ var CopDef = class {
1893
2716
  parts;
1894
2717
  halt;
1895
2718
  constructor(data) {
1896
- this.name = data.name ?? void 0;
1897
- this.id = data.id ?? void 0;
2719
+ if (!data.name) throw new Error("Name is required");
2720
+ if (typeof data.id !== "number") throw new Error("ID is required");
2721
+ this.name = data.name;
2722
+ this.id = data.id;
1898
2723
  this.parts = data.parts ?? [];
1899
2724
  this.halt = data.halt ?? false;
1900
2725
  this.size = data.size ?? 0;
1901
- if (!this.name) throw new Error("Name is required");
1902
- if (this.id === void 0) throw new Error("ID is required");
1903
2726
  }
1904
2727
  };
1905
2728
 
@@ -2049,13 +2872,17 @@ async function listDirectory(dirPath, options = {}) {
2049
2872
  for (const item of items) {
2050
2873
  const itemPath = pathModule.join(fullPath, item);
2051
2874
  const stats = await stat(itemPath);
2875
+ const isFile = stats.isFile();
2876
+ const extIx = isFile ? item.indexOf(".") : -1;
2877
+ const ext = extIx > 0 ? item.substring(extIx + 1) : null;
2052
2878
  const entry = {
2053
- name: item,
2879
+ name: extIx > 0 ? item.substring(0, extIx) : item,
2054
2880
  path: itemPath,
2055
- isDirectory: stats.isDirectory(),
2056
- isFile: stats.isFile()
2881
+ extension: ext,
2882
+ isFile,
2883
+ isDirectory: stats.isDirectory()
2057
2884
  };
2058
- if (extension && entry.isFile && !entry.name.endsWith(extension)) continue;
2885
+ if (extension && ext !== extension) continue;
2059
2886
  if (filter && !filter(entry)) continue;
2060
2887
  entries.push(entry);
2061
2888
  if (recursive && entry.isDirectory) {
@@ -2298,129 +3125,6 @@ function decodeBase64String(base64String) {
2298
3125
  }
2299
3126
  }
2300
3127
 
2301
- //#endregion
2302
- //#region src/utils/debug-export.ts
2303
- /**
2304
- * Debug utility to export processing results as JSON for comparison
2305
- */
2306
- var DebugExporter = class {
2307
- /**
2308
- * Export chunk files to JSON for comparison with C# output
2309
- */
2310
- static exportChunkFiles(files, filename) {
2311
- const exportData = {
2312
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2313
- totalFiles: files.length,
2314
- files: files.map((file) => ({
2315
- name: file.name,
2316
- type: file.type,
2317
- size: file.size,
2318
- location: file.location,
2319
- bank: file.bank,
2320
- upper: file.upper,
2321
- compressed: file.compressed,
2322
- hasTextData: !!file.textData,
2323
- textDataLength: file.textData?.length || 0,
2324
- hasParts: !!file.parts,
2325
- partsCount: file.parts?.length || 0,
2326
- hasIncludes: !!file.includes,
2327
- includesCount: file.includes?.size || 0,
2328
- includesList: file.includes ? Array.from(file.includes).sort() : [],
2329
- parts: file.parts?.map((part) => ({
2330
- label: part.label,
2331
- location: part.location,
2332
- size: part.size,
2333
- objListCount: part.objList?.length || 0,
2334
- hasObjList: !!part.objList,
2335
- objList: part.objList?.map((obj) => ({
2336
- location: obj.location,
2337
- size: obj.size,
2338
- hasObject: !!obj.object,
2339
- objectType: obj.object?.constructor?.name || "unknown"
2340
- })) || []
2341
- })) || []
2342
- }))
2343
- };
2344
- try {
2345
- writeFileSync(filename, JSON.stringify(exportData, null, 2));
2346
- console.log(`📄 Exported ${files.length} files to ${filename}`);
2347
- } catch (error) {
2348
- console.error(`❌ Failed to export to ${filename}:`, error);
2349
- }
2350
- }
2351
- /**
2352
- * Export patch application summary
2353
- */
2354
- static exportPatchSummary(originalFiles, patchedFiles, patches, filename) {
2355
- const summary = {
2356
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2357
- originalFileCount: originalFiles.length,
2358
- patchedFileCount: patchedFiles.length,
2359
- patchCount: patches.length,
2360
- patches: patches.map((patch) => ({
2361
- name: patch.name,
2362
- partsCount: patch.parts?.length || 0,
2363
- includesCount: patch.includes?.size || 0,
2364
- includes: patch.includes ? Array.from(patch.includes).sort() : []
2365
- })),
2366
- sizeChanges: patchedFiles.map((file) => {
2367
- const original = originalFiles.find((f) => f.name === file.name);
2368
- return {
2369
- name: file.name,
2370
- originalSize: original?.size || 0,
2371
- patchedSize: file.size || 0,
2372
- sizeDelta: (file.size || 0) - (original?.size || 0),
2373
- originalPartsCount: original?.parts?.length || 0,
2374
- patchedPartsCount: file.parts?.length || 0,
2375
- partsCountDelta: (file.parts?.length || 0) - (original?.parts?.length || 0)
2376
- };
2377
- }).filter((change) => change.sizeDelta !== 0 || change.partsCountDelta !== 0)
2378
- };
2379
- try {
2380
- writeFileSync(filename, JSON.stringify(summary, null, 2));
2381
- console.log(`📊 Exported patch summary to ${filename}`);
2382
- } catch (error) {
2383
- console.error(`❌ Failed to export patch summary to ${filename}:`, error);
2384
- }
2385
- }
2386
- /**
2387
- * Export layout debugging information
2388
- */
2389
- static exportLayoutDebug(files, filename) {
2390
- const layoutData = {
2391
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2392
- totalFiles: files.length,
2393
- filesWithSize: files.filter((f) => (f.size || 0) > 0).length,
2394
- filesWithoutSize: files.filter((f) => (f.size || 0) === 0).length,
2395
- asmFiles: files.filter((f) => !!f.parts).length,
2396
- binaryFiles: files.filter((f) => !f.parts).length,
2397
- files: files.map((file) => ({
2398
- name: file.name,
2399
- size: file.size || 0,
2400
- hasSize: (file.size || 0) > 0,
2401
- isAsm: !!file.parts,
2402
- bank: file.bank,
2403
- upper: file.upper,
2404
- location: file.location,
2405
- partsCount: file.parts?.length || 0
2406
- })).sort((a, b) => {
2407
- const aAsm = a.isAsm ? 0 : 1;
2408
- const bAsm = b.isAsm ? 0 : 1;
2409
- if (aAsm !== bAsm) return aAsm - bAsm;
2410
- if (b.size !== a.size) return b.size - a.size;
2411
- return a.location - b.location;
2412
- }),
2413
- zeroSizeFiles: files.filter((f) => (f.size || 0) === 0).map((f) => f.name)
2414
- };
2415
- try {
2416
- writeFileSync(filename, JSON.stringify(layoutData, null, 2));
2417
- console.log(`🏗️ Exported layout debug info to ${filename}`);
2418
- } catch (error) {
2419
- console.error(`❌ Failed to export layout debug to ${filename}:`, error);
2420
- }
2421
- }
2422
- };
2423
-
2424
3128
  //#endregion
2425
3129
  //#region src/utils/index.ts
2426
3130
  /**
@@ -2532,16 +3236,16 @@ var DbPart = class {
2532
3236
  bank;
2533
3237
  order;
2534
3238
  constructor(data) {
2535
- this.name = data.name ?? "";
2536
- this.start = data.start ?? void 0;
2537
- this.end = data.end ?? 0;
2538
- this.type = data.type ?? "";
3239
+ if (typeof data.start !== "number") throw new Error("Start is required");
3240
+ if (!data.name) throw new Error("Name is required");
3241
+ if (!data.end) throw new Error("End is required");
3242
+ if (!data.type) throw new Error("Struct is required");
3243
+ this.name = data.name;
3244
+ this.start = data.start;
3245
+ this.end = data.end;
3246
+ this.type = data.type;
2539
3247
  this.bank = data.bank ?? void 0;
2540
3248
  this.order = data.order ?? void 0;
2541
- if (!this.name) throw new Error("Name is required");
2542
- if (this.start === void 0) throw new Error("Start is required");
2543
- if (!this.end) throw new Error("End is required");
2544
- if (!this.type) throw new Error("Struct is required");
2545
3249
  }
2546
3250
  };
2547
3251
 
@@ -2787,7 +3491,6 @@ var PostProcessor = class {
2787
3491
  //#region src/rom/extraction/writer.ts
2788
3492
  const isWindows = (() => {
2789
3493
  if (typeof process !== "undefined" && process.platform) return process.platform === "win32";
2790
- if (typeof navigator !== "undefined" && navigator.userAgent) return navigator.userAgent.includes("Windows");
2791
3494
  return false;
2792
3495
  })();
2793
3496
  const NEWLINE = isWindows ? "\r\n" : "\n";
@@ -3251,13 +3954,13 @@ var AsmReader = class AsmReader {
3251
3954
  clearDestinationRegister(code, reg) {
3252
3955
  switch (code.mnem) {
3253
3956
  case "LDA":
3254
- reg.value["accumulator"] = void 0;
3957
+ delete reg.value["accumulator"];
3255
3958
  break;
3256
3959
  case "LDX":
3257
- reg.value["xIndex"] = void 0;
3960
+ delete reg.value["xIndex"];
3258
3961
  break;
3259
3962
  case "LDY":
3260
- reg.value["yIndex"] = void 0;
3963
+ delete reg.value["yIndex"];
3261
3964
  break;
3262
3965
  }
3263
3966
  }
@@ -3350,14 +4053,17 @@ var TypeParser = class {
3350
4053
  name: targetType.name,
3351
4054
  parts
3352
4055
  };
3353
- for (let i = 0; i < memberCount; i++) parts[i] = this.parseType(types[i], null, depth + 1, bank);
4056
+ for (let i = 0; i < memberCount; i++) parts[i] = this.parseType(types[i], reg, depth + 1, bank);
3354
4057
  if (discOffset !== void 0 && discOffset === this._romDataReader.position - prevPosition) this._romDataReader.position++;
3355
4058
  objects.push(def);
3356
4059
  }
3357
4060
  let checkPosition = startPosition;
3358
- while (++checkPosition < this._romDataReader.position) if (this._referenceManager.containsStruct(checkPosition)) {
3359
- this._romDataReader.position = checkPosition;
3360
- break;
4061
+ while (++checkPosition < this._romDataReader.position) {
4062
+ const struct = this._referenceManager.tryGetStruct(checkPosition);
4063
+ if (struct.found && struct.chunkType !== "Code") {
4064
+ this._romDataReader.position = checkPosition;
4065
+ break;
4066
+ }
3361
4067
  }
3362
4068
  if (!this._blockReader.partCanContinue()) break;
3363
4069
  }
@@ -3689,8 +4395,9 @@ var BlockReader = class {
3689
4395
  * Creates assembly ChunkFiles from DbBlocks (enriched with parts)
3690
4396
  */
3691
4397
  createChunkFilesFromDbBlocks() {
4398
+ const fileType = Object.values(this._root.fileTypes).find((x) => x.isBlock);
3692
4399
  for (const block of this._root.blocks) {
3693
- const chunkFile = createChunkFileFromDbBlock(block, Object.values(this._root.fileTypes).find((x) => x.isBlock), this._root.config.memoryMode);
4400
+ const chunkFile = createChunkFileFromDbBlock(block, fileType, this._root.config.memoryMode);
3694
4401
  this._enrichedChunks.push(chunkFile);
3695
4402
  }
3696
4403
  }
@@ -3849,6 +4556,7 @@ var RomLayout = class RomLayout {
3849
4556
  let offset = 0;
3850
4557
  while (remain > 0 && this.sfxFiles.length) {
3851
4558
  const file = this.sfxFiles.shift();
4559
+ if (!file) continue;
3852
4560
  file.location = start + offset;
3853
4561
  console.log(` ${file.location.toString(16).toUpperCase().padStart(6, "0")}: ${file.name}`);
3854
4562
  offset += file.size;
@@ -3961,12 +4669,15 @@ var RomProcessor = class RomProcessor {
3961
4669
  async repack(allFiles) {
3962
4670
  const patches = [];
3963
4671
  const asmFiles = [];
4672
+ const compression = this.writer.root.compression;
4673
+ const canCompress = !!compression;
4674
+ const conditionFiles = [];
3964
4675
  for (const file of allFiles) {
3965
4676
  if (file.type.type === "Patch") patches.push(file);
3966
4677
  else if (file.type.type !== "Assembly") {
3967
- if (file.compressed === true) if (this.writer.root.config.uncompress) file.compressed = false;
4678
+ if (file.compressed === true && canCompress) if (this.writer.root.config.uncompress) file.compressed = false;
3968
4679
  else {
3969
- let newData = this.writer.root.compression.compact(file.rawData, file.type.header);
4680
+ let newData = compression.compact(file.rawData, file.type.header);
3970
4681
  if (file.type.header) newData = new Uint8Array([...file.rawData.slice(0, file.type.header), ...newData]);
3971
4682
  file.rawData = newData;
3972
4683
  file.size = newData.length;
@@ -3974,27 +4685,34 @@ var RomProcessor = class RomProcessor {
3974
4685
  continue;
3975
4686
  }
3976
4687
  asmFiles.push(file);
3977
- if (!file.parts) {
3978
- const { blocks, includes, reqBank } = new Assembler(this.writer.root, file.textData).parseAssembly();
3979
- file.parts = blocks;
3980
- file.includes = includes;
3981
- file.bank = reqBank ?? void 0;
3982
- }
4688
+ conditionFiles.push(file.name);
4689
+ }
4690
+ for (const file of asmFiles) if (!file.parts) {
4691
+ const { blocks, includes, reqBank } = new Assembler(this.writer.root, file.textData, conditionFiles).parseAssembly();
4692
+ file.parts = blocks;
4693
+ file.includes = includes;
4694
+ file.bank = reqBank ?? void 0;
3983
4695
  }
3984
4696
  RomProcessor.applyPatches(asmFiles, patches);
3985
4697
  for (const file of allFiles) ChunkFileUtils.calculateSize(file);
3986
4698
  const pages = new RomLayout(allFiles, this.writer.root).organize();
3987
4699
  for (const file of asmFiles) ChunkFileUtils.rebase(file);
4700
+ const masterLookup = /* @__PURE__ */ new Map();
3988
4701
  for (const f of asmFiles) {
3989
4702
  const includeBlocks = asmFiles.filter((x) => f.includes?.has(x.name.toUpperCase())).flatMap((x) => x.parts).filter((b) => !!b.label);
3990
4703
  f.includeLookup = /* @__PURE__ */ new Map();
3991
4704
  for (const b of includeBlocks) if (b.label) f.includeLookup.set(b.label.toUpperCase(), b);
3992
- for (const b of (f.parts || []).filter((x) => !!x.label)) if (b.label) f.includeLookup.set(b.label.toUpperCase(), b);
4705
+ for (const b of f.parts) if (b.label) {
4706
+ const nameUpper = b.label.toUpperCase();
4707
+ masterLookup.set(nameUpper, b.location);
4708
+ f.includeLookup.set(nameUpper, b);
4709
+ }
3993
4710
  }
3994
- const blockLookup = /* @__PURE__ */ new Map();
3995
- for (const f of allFiles) blockLookup.set(f.name.toUpperCase(), f.location);
4711
+ const fileLookup = /* @__PURE__ */ new Map();
4712
+ for (const f of allFiles) fileLookup.set(f.name.toUpperCase(), f.location);
3996
4713
  this.writer.allocate(pages);
3997
- for (const file of allFiles) await this.writer.writeFile(file, blockLookup);
4714
+ for (const file of allFiles) await this.writer.writeFile(file, fileLookup);
4715
+ return masterLookup;
3998
4716
  }
3999
4717
  static applyPatches(asmFiles, patches) {
4000
4718
  for (const patch of patches.filter((x) => x.includes && x.includes.size > 0)) {
@@ -4040,19 +4758,13 @@ var RomWriter = class {
4040
4758
  bpsPath;
4041
4759
  outBuffer;
4042
4760
  romSize;
4043
- cartName;
4044
- makerCode;
4045
4761
  root;
4046
- constructor(root, cartName, makerCode) {
4047
- this.cartName = cartName;
4048
- this.makerCode = makerCode;
4762
+ constructor(root) {
4049
4763
  this.root = root;
4050
4764
  }
4051
4765
  async repack(files) {
4052
- await new RomProcessor(this).repack(files);
4053
- this.writeHeader();
4054
- this.writeEntryPoints(files.filter((x) => !!x.parts));
4055
- this.writeChecksum();
4766
+ const masterLookup = await new RomProcessor(this).repack(files);
4767
+ this.writeHeaders(masterLookup);
4056
4768
  return this.outBuffer;
4057
4769
  }
4058
4770
  allocate(pages) {
@@ -4066,36 +4778,93 @@ var RomWriter = class {
4066
4778
  this.romSize = bits;
4067
4779
  this.outBuffer = new Uint8Array(target);
4068
4780
  }
4069
- writeHeader() {
4781
+ writeHeaders(masterLookup) {
4782
+ const values = this.prepareHeaderValues();
4783
+ for (const header of this.root.headers) {
4784
+ if (header.condition && !eval(header.condition)) continue;
4785
+ this.writeHeader(header, values, masterLookup);
4786
+ }
4787
+ this.writeChecksum(values);
4788
+ }
4789
+ prepareHeaderValues() {
4790
+ const values = { ...this.root.config };
4791
+ values.romSize = this.romSize;
4792
+ values.checksum = 0;
4793
+ values.compliment = 65535;
4794
+ values.mapMode = 32 | (values.cpuMode === CpuMode.Fast ? 16 : 0) | (values.memoryMode === MemoryMapMode.Hi ? 1 : values.memoryMode === MemoryMapMode.ExHi ? 5 : 0);
4795
+ return values;
4796
+ }
4797
+ writeHeader(header, values, masterLookup) {
4070
4798
  const buf = this.outBuffer;
4071
- let pos = this.root.config.memoryMode === MemoryMapMode.Lo ? 32688 : 65456;
4072
- this.writeAscii(this.makerCode.padEnd(6, " "), pos);
4073
- pos += 6;
4074
- for (let i = 0; i < 10; i++) buf[pos++] = 0;
4075
- this.writeAscii(this.cartName.toUpperCase().padEnd(21, " "), pos);
4076
- pos += 21;
4077
- buf[pos++] = 32 | (this.root.config.cpuMode === CpuMode.Fast ? 16 : 0) | (this.root.config.memoryMode === MemoryMapMode.Hi ? 1 : this.root.config.memoryMode === MemoryMapMode.ExHi ? 5 : 0);
4078
- buf[pos++] = this.root.config.chipset;
4079
- buf[pos++] = this.romSize;
4080
- buf[pos++] = this.root.config.ramSize;
4081
- buf[pos++] = 1;
4082
- buf[pos++] = 51;
4083
- buf[pos++] = 0;
4084
- }
4085
- writeChecksum() {
4799
+ let pos = new Address(header.bank, header.address, this.root.config.memoryMode).toLocation();
4800
+ for (const part of header.parts) {
4801
+ let type = part.type;
4802
+ let value = part.value ?? values[part.name] ?? (type === "string" ? "" : 0);
4803
+ let size = part.size;
4804
+ if (!size) if (!type) {
4805
+ if (typeof value === "string") throw new Error(`String size for ${part.name} is not specified`);
4806
+ if (typeof value === "number") if (value <= 255) {
4807
+ size = 1;
4808
+ type = "byte";
4809
+ } else {
4810
+ size = 2;
4811
+ type = "word";
4812
+ }
4813
+ } else switch (type) {
4814
+ case "byte":
4815
+ size = 1;
4816
+ break;
4817
+ case "word":
4818
+ case "entry":
4819
+ size = 2;
4820
+ break;
4821
+ case "string": throw new Error(`String size for ${part.name} is not specified`);
4822
+ default: throw new Error(`Invalid type ${type} for ${part.name}`);
4823
+ }
4824
+ switch (part.type) {
4825
+ case "string":
4826
+ value = value.toString();
4827
+ value = value.length > size ? value.substring(0, size) : value.padEnd(size, " ");
4828
+ this.writeAscii(value, pos);
4829
+ break;
4830
+ case "byte":
4831
+ buf[pos] = value & 255;
4832
+ break;
4833
+ case "entry":
4834
+ let location = 0;
4835
+ if (typeof value === "string") location = value === "" ? 0 : masterLookup.get(value.toUpperCase()) ?? 0;
4836
+ else if (typeof value === "number") location = value;
4837
+ value = location;
4838
+ case "word":
4839
+ buf[pos] = value & 255;
4840
+ buf[pos + 1] = value >> 8 & 255;
4841
+ break;
4842
+ }
4843
+ part.value = value;
4844
+ part.size = size;
4845
+ part.type = type;
4846
+ pos += size;
4847
+ }
4848
+ }
4849
+ writeChecksum(values) {
4086
4850
  const buf = this.outBuffer;
4087
- let pos = this.root.config.memoryMode === MemoryMapMode.Lo ? 32732 : 65500;
4088
- buf[pos] = 255;
4089
- buf[pos + 1] = 255;
4090
- buf[pos + 2] = 0;
4091
- buf[pos + 3] = 0;
4092
4851
  let sum = 0;
4093
4852
  for (let i = 0; i < buf.length; i++) sum += buf[i];
4094
- buf[pos + 2] = sum & 255;
4095
- buf[pos + 3] = sum >> 8 & 255;
4096
4853
  const comp = ~sum;
4097
- buf[pos] = comp & 255;
4098
- buf[pos + 1] = comp >> 8 & 255;
4854
+ for (const header of this.root.headers) {
4855
+ if (header.condition && !eval(header.condition)) continue;
4856
+ let pos = new Address(header.bank, header.address, this.root.config.memoryMode).toLocation();
4857
+ for (const part of header.parts) {
4858
+ if (part.name === "checksum") {
4859
+ buf[pos] = sum & 255;
4860
+ buf[pos + 1] = sum >> 8 & 255;
4861
+ } else if (part.name === "compliment") {
4862
+ buf[pos] = comp & 255;
4863
+ buf[pos + 1] = comp >> 8 & 255;
4864
+ }
4865
+ pos += part.size;
4866
+ }
4867
+ }
4099
4868
  }
4100
4869
  writeEntryPoints(asmFiles) {
4101
4870
  const buf = this.outBuffer;
@@ -4110,7 +4879,7 @@ var RomWriter = class {
4110
4879
  }
4111
4880
  }
4112
4881
  }
4113
- async writeFile(file, _chunkLookup) {
4882
+ async writeFile(file, fileLookup) {
4114
4883
  const start = file.location;
4115
4884
  let pos = start;
4116
4885
  const buf = this.outBuffer;
@@ -4140,7 +4909,7 @@ var RomWriter = class {
4140
4909
  }
4141
4910
  } else if (file.parts && file.parts.length > 0) {
4142
4911
  if (file.parts[0].location !== file.location && (file.location || 0) !== 0) throw new Error("Assembly was not based properly");
4143
- this.parseAssembly(file.parts, _chunkLookup, file.includeLookup);
4912
+ this.parseAssembly(file.parts, fileLookup, file.includeLookup);
4144
4913
  }
4145
4914
  return pos - start;
4146
4915
  }
@@ -4152,11 +4921,12 @@ var RomWriter = class {
4152
4921
  * Parse assembly blocks and write binary data to output buffer
4153
4922
  * Converted from ext/GaiaLib/Rom/Rebuild/RomWriter.cs ParseAssembly method
4154
4923
  */
4155
- parseAssembly(blocks, chunkLookup, includeLookup) {
4924
+ parseAssembly(blocks, fileLookup, includeLookup) {
4156
4925
  if (!blocks) throw new Error("Assembly has not been parsed");
4157
4926
  const buf = this.outBuffer;
4158
4927
  let bix = 0;
4159
4928
  for (const block of blocks) {
4929
+ let oldPos = null;
4160
4930
  let position = block.location;
4161
4931
  const objList = block.objList;
4162
4932
  let oix = 0;
@@ -4164,7 +4934,7 @@ var RomWriter = class {
4164
4934
  const processObject = (obj, parentOp) => {
4165
4935
  let currentObj = obj;
4166
4936
  while (true) if (Array.isArray(currentObj)) {
4167
- for (const obj$1 of currentObj) processObject(obj$1, parentOp);
4937
+ for (const obj of currentObj) processObject(obj, parentOp);
4168
4938
  break;
4169
4939
  } else if (this.isTableEntry(currentObj)) {
4170
4940
  currentObj = currentObj.object;
@@ -4201,29 +4971,32 @@ var RomWriter = class {
4201
4971
  label = label.substring(0, operatorIdx);
4202
4972
  }
4203
4973
  const labelUpper = label.toUpperCase();
4204
- let target;
4974
+ let target = null;
4205
4975
  if (includeLookup.has(labelUpper)) {
4206
4976
  target = includeLookup.get(labelUpper);
4207
4977
  loc = target.location;
4208
- } else if (chunkLookup.has(labelUpper)) loc = chunkLookup.get(labelUpper);
4978
+ } else if (fileLookup.has(labelUpper)) loc = fileLookup.get(labelUpper);
4209
4979
  else {
4210
4980
  if (label.startsWith("#")) label = label.substring(1);
4211
4981
  if (label.startsWith("$")) label = label.substring(1);
4212
4982
  if (isRelative && label.length > 4) throw new Error(`Invalid relative operand '${label}'`);
4213
- else switch (label.length) {
4214
- case 1:
4215
- case 2:
4216
- currentObj = new Byte(parseInt(label, 16));
4217
- continue;
4218
- case 3:
4219
- case 4:
4220
- currentObj = new Word(parseInt(label, 16));
4221
- continue;
4222
- case 5:
4223
- case 6:
4224
- currentObj = new Long(parseInt(label, 16));
4225
- continue;
4226
- default: throw new Error(`Invalid operand '${label}'`);
4983
+ else {
4984
+ let num;
4985
+ switch (label.length) {
4986
+ case 1:
4987
+ case 2:
4988
+ currentObj = new Byte(parseInt(label, 16));
4989
+ continue;
4990
+ case 3:
4991
+ case 4:
4992
+ currentObj = new Word(parseInt(label, 16));
4993
+ continue;
4994
+ case 5:
4995
+ case 6:
4996
+ currentObj = new Long(parseInt(label, 16));
4997
+ continue;
4998
+ default: throw new Error(`Invalid operand '${label}'`);
4999
+ }
4227
5000
  }
4228
5001
  }
4229
5002
  let type = isRelative ? parentOp?.size === 3 ? AddressType.WRelative : AddressType.Relative : Address.typeFromCode(str[0]);
@@ -4233,7 +5006,7 @@ var RomWriter = class {
4233
5006
  if (type === AddressType.Unknown && !(loc < 128 || loc >= 4194176)) throw new Error("Relative out of range");
4234
5007
  }
4235
5008
  if (offset !== null) loc += offset;
4236
- else if (useMarker && target) {
5009
+ else if (useMarker && target instanceof AsmBlock) {
4237
5010
  let markerOffset = 0;
4238
5011
  for (const part of target.objList) if (this.isStringMarker(part)) {
4239
5012
  loc += markerOffset;
@@ -4320,6 +5093,36 @@ var RomWriter = class {
4320
5093
  }
4321
5094
  };
4322
5095
 
5096
+ //#endregion
5097
+ //#region src/database/header.ts
5098
+ var DbHeader = class {
5099
+ bank;
5100
+ address;
5101
+ condition;
5102
+ parts;
5103
+ constructor(data) {
5104
+ if (typeof data.address !== "number") throw new Error("Address is required");
5105
+ if (!data.parts || !data.parts.length) throw new Error("Parts are required");
5106
+ this.bank = data.bank ?? 0;
5107
+ this.address = data.address;
5108
+ this.condition = data.condition ?? void 0;
5109
+ this.parts = data.parts.map((p) => new DbHeaderPart(p));
5110
+ }
5111
+ };
5112
+ var DbHeaderPart = class {
5113
+ name;
5114
+ size;
5115
+ type;
5116
+ value;
5117
+ constructor(data) {
5118
+ if (!data.name) throw new Error("Name is required");
5119
+ this.name = data.name;
5120
+ this.size = data.size ?? 0;
5121
+ this.type = data.type ?? "";
5122
+ this.value = data.value ?? void 0;
5123
+ }
5124
+ };
5125
+
4323
5126
  //#endregion
4324
5127
  //#region src/database/root.ts
4325
5128
  /**
@@ -4329,33 +5132,6 @@ var DbRootUtils = class {
4329
5132
  /**
4330
5133
  * JSON serialization options
4331
5134
  */
4332
- /**
4333
- * Load database from a single file
4334
- */
4335
- static async fromFolder(folderPath, systemPath) {
4336
- return this.fromGameModule(await this.gameModuleFromFolder(folderPath, systemPath));
4337
- }
4338
- /**
4339
- * Load database from folder structure
4340
- */
4341
- static async gameModuleFromFolder(folderPath, systemPath) {
4342
- return {
4343
- mnemonics: await readJsonFile(`${folderPath}/mnemonics.json`),
4344
- overrides: await readJsonFile(`${folderPath}/overrides.json`),
4345
- rewrites: await readJsonFile(`${folderPath}/rewrites.json`),
4346
- blocks: await readJsonFile(`${folderPath}/blocks.json`),
4347
- files: await readJsonFile(`${folderPath}/files.json`),
4348
- config: await readJsonFile(`${folderPath}/config.json`),
4349
- labels: await readJsonFile(`${folderPath}/labels.json`),
4350
- structs: await readJsonFile(`${folderPath}/structs.json`),
4351
- copdef: await readJsonFile(`${folderPath}/copdef.json`),
4352
- addrModes: await readJsonFile(`${systemPath}/addressingModes.json`),
4353
- strings: await readJsonFile(`${folderPath}/stringTypes.json`),
4354
- transforms: await readJsonFile(`${folderPath}/transforms.json`),
4355
- groups: await readJsonFile(`${folderPath}/groups.json`),
4356
- fileTypes: await readJsonFile(`${folderPath}/fileTypes.json`)
4357
- };
4358
- }
4359
5135
  static fromGameModule(module) {
4360
5136
  const opCodes = {};
4361
5137
  const opLookup = {};
@@ -4399,7 +5175,7 @@ var DbRootUtils = class {
4399
5175
  const groupLookup = Object.entries(module.groups).reduce((acc, x) => {
4400
5176
  const groupData = x[1];
4401
5177
  const groupName = x[0];
4402
- const scenes = Object.entries(groupData.scenes).reduce((acc$1, y) => {
5178
+ const scenes = Object.entries(groupData.scenes ?? {}).reduce((acc, y) => {
4403
5179
  const sceneData = y[1];
4404
5180
  const sceneName = y[0];
4405
5181
  const scene = new DbScene({
@@ -4407,8 +5183,8 @@ var DbRootUtils = class {
4407
5183
  name: sceneName
4408
5184
  });
4409
5185
  sceneLookup[scene.id] = scene;
4410
- acc$1[sceneName] = scene;
4411
- return acc$1;
5186
+ acc[sceneName] = scene;
5187
+ return acc;
4412
5188
  }, {});
4413
5189
  acc[groupName] = new DbGroup({
4414
5190
  ...groupData,
@@ -4429,19 +5205,25 @@ var DbRootUtils = class {
4429
5205
  const stringLookup = Object.entries(module.strings).reduce((acc, x) => {
4430
5206
  const stringType = x[1];
4431
5207
  const name = x[0];
4432
- const commands = Object.entries(stringType.commands ?? {}).reduce((acc$1, y) => {
4433
- acc$1[y[0]] = new DbStringCommand({
5208
+ const commands = Object.entries(stringType.commands ?? {}).reduce((acc, y) => {
5209
+ acc[y[0]] = new DbStringCommand({
4434
5210
  ...y[1],
4435
5211
  name: y[0]
4436
5212
  });
4437
- return acc$1;
5213
+ return acc;
4438
5214
  }, {});
4439
- const dictionaries = Object.entries(stringType.dictionaries ?? {}).reduce((acc$1, y) => {
4440
- acc$1[y[0]] = new DbStringDictionary({
5215
+ const dictionaries = Object.entries(stringType.dictionaries ?? {}).reduce((acc, y) => {
5216
+ const dictionary = new DbStringDictionary({
4441
5217
  ...y[1],
4442
5218
  name: y[0]
4443
5219
  });
4444
- return acc$1;
5220
+ acc[y[0]] = dictionary;
5221
+ if (dictionary.command !== void 0) commands[dictionary.command] = new DbStringCommand({
5222
+ id: dictionary.command,
5223
+ name: dictionary.name,
5224
+ dictionary
5225
+ });
5226
+ return acc;
4445
5227
  }, {});
4446
5228
  const st = new DbStringType({
4447
5229
  ...stringType,
@@ -4486,15 +5268,13 @@ var DbRootUtils = class {
4486
5268
  return acc;
4487
5269
  }, {});
4488
5270
  const cfg = module.config;
4489
- const compression = cfg.compression ? CompressionAlgorithms[cfg.compression]() : null;
5271
+ const compression = cfg.compression ? CompressionAlgorithms[cfg.compression]() : void 0;
4490
5272
  return {
5273
+ headers: module.headers.map((h) => new DbHeader(h)),
4491
5274
  mnemonics: module.mnemonics,
4492
5275
  overrides: module.overrides,
4493
5276
  rewrites: module.rewrites,
4494
- labels: module.labels.reduce((acc, x) => {
4495
- acc[x.location] = x.label;
4496
- return acc;
4497
- }, {}),
5277
+ labels: module.labels,
4498
5278
  structs: structLookup,
4499
5279
  blocks: blocksArray.sort((a, b) => {
4500
5280
  const orderA = a.order ?? 0;
@@ -4522,17 +5302,13 @@ var DbRootUtils = class {
4522
5302
  }
4523
5303
  static async applyFolder(root, folderPath, sourceFiles = []) {
4524
5304
  const chunkFiles = sourceFiles;
4525
- const folderEntries = await listDirectory(folderPath);
4526
- for (const entry of folderEntries) if (entry.isDirectory) await this.applyFolder(root, entry.path, chunkFiles);
4527
- else {
4528
- const index = entry.name.indexOf(".");
4529
- if (!index) continue;
4530
- const name = entry.name.substring(0, index);
4531
- const extension = entry.name.substring(index + 1);
4532
- const type = root.fileExtLookup[extension];
5305
+ const folderEntries = await listDirectory(folderPath, { recursive: true });
5306
+ for (const entry of folderEntries) {
5307
+ if (!entry.isFile || !entry.extension) continue;
5308
+ const type = root.fileExtLookup[entry.extension];
4533
5309
  if (!type) continue;
4534
- const existing = chunkFiles.find((x) => x.name === name && x.type.type === type.type);
4535
- const chunkFile = existing ?? new ChunkFile(name, 0, 0, type);
5310
+ const existing = chunkFiles.find((x) => x.name === entry.name && x.type.type === type.type);
5311
+ const chunkFile = existing ?? new ChunkFile(entry.name, 0, 0, type);
4536
5312
  if (chunkFile.type.type === "Assembly" || chunkFile.type.type === "Patch") {
4537
5313
  const chunkData = await readFileAsText(entry.path);
4538
5314
  chunkFile.textData = chunkData;
@@ -4543,7 +5319,7 @@ var DbRootUtils = class {
4543
5319
  chunkFile.size = chunkData.length;
4544
5320
  }
4545
5321
  if (!existing) {
4546
- const sourceFile = root.files.find((x) => x.name === name && x.type === type.type);
5322
+ const sourceFile = root.files.find((x) => x.name === entry.name && x.type === type.type);
4547
5323
  if (sourceFile) {
4548
5324
  chunkFile.location = sourceFile.start;
4549
5325
  chunkFile.upper = sourceFile.upper;
@@ -4573,7 +5349,7 @@ var DbRootUtils = class {
4573
5349
  static async rebuildAllContent(root, inPath, outPath) {
4574
5350
  var sourceFiles = [];
4575
5351
  for (const path of inPath) sourceFiles = await this.applyFolder(root, path, sourceFiles);
4576
- await saveFileAsBinary(outPath, await new RomWriter(root, "TEST", "TEST").repack(sourceFiles));
5352
+ await saveFileAsBinary(outPath, await new RomWriter(root).repack(sourceFiles));
4577
5353
  return sourceFiles;
4578
5354
  }
4579
5355
  };
@@ -4585,12 +5361,12 @@ var DbOverride = class {
4585
5361
  register;
4586
5362
  value;
4587
5363
  constructor(values) {
4588
- this.location = values.location ?? 0;
4589
- this.register = values.register ?? "";
4590
- this.value = values.value ?? void 0;
4591
- if (!this.location) throw new Error("Location is required");
4592
- if (!this.register) throw new Error("Register is required");
4593
- if (this.value === void 0) throw new Error("Value is required");
5364
+ if (typeof values.value !== "number") throw new Error("Value is required");
5365
+ if (typeof values.location !== "number") throw new Error("Location is required");
5366
+ if (!values.register) throw new Error("Register is required");
5367
+ this.location = values.location;
5368
+ this.register = values.register;
5369
+ this.value = values.value;
4594
5370
  }
4595
5371
  };
4596
5372
 
@@ -4621,7 +5397,8 @@ var StringReader = class StringReader {
4621
5397
  this._romDataReader = blockReader._romDataReader;
4622
5398
  }
4623
5399
  resolveCommand(cmd, builder) {
4624
- if (cmd.types && cmd.types.length > 0) {
5400
+ if (cmd.dictionary) builder.push(cmd.dictionary.entries[this._romDataReader.readByte() - (cmd.dictionary.base ?? 0)]);
5401
+ else if (cmd.types && cmd.types.length > 0) {
4625
5402
  builder.push(`[${cmd.name}`);
4626
5403
  let first = true;
4627
5404
  for (const t of cmd.types) {
@@ -4664,8 +5441,8 @@ var StringReader = class StringReader {
4664
5441
  const dictionaries = stringType.dictionaries;
4665
5442
  const builder = [];
4666
5443
  const strLoc = this._romDataReader.position;
4667
- const map = stringType.characterMap;
4668
5444
  const terminator = stringType.terminator;
5445
+ let currentLayer = stringType.layers[0];
4669
5446
  do {
4670
5447
  const c = this._romDataReader.readByte();
4671
5448
  if (c === terminator) {
@@ -4678,14 +5455,31 @@ var StringReader = class StringReader {
4678
5455
  if (cmd.halt) break;
4679
5456
  } else {
4680
5457
  let found = false;
4681
- for (const dictionary of Object.values(dictionaries)) if (c >= dictionary.base && c <= dictionary.range) {
5458
+ for (const dictionary of Object.values(dictionaries)) if (dictionary.base !== void 0 && c >= dictionary.base && c <= dictionary.range) {
4682
5459
  builder.push(dictionary.entries[c - dictionary.base]);
4683
5460
  found = true;
4684
5461
  break;
4685
5462
  }
4686
5463
  if (!found) {
4687
- const index = DbStringTypeUtils.getShiftDown(stringType.shiftType)(c);
4688
- if (index >= 0 && index < map.length) builder.push(map[index]);
5464
+ for (const layer of stringType.layers) if (layer.on !== void 0) {
5465
+ if (c === layer.on) {
5466
+ currentLayer = layer;
5467
+ found = true;
5468
+ break;
5469
+ }
5470
+ } else if (c >= (layer.base ?? 0) && c <= (layer.range ?? 255)) {
5471
+ let index = c - (layer.base ?? 0);
5472
+ if (index >= 0 && index < layer.map.length) {
5473
+ if (layer.shift) index = DbStringTypeUtils.getShiftDown(layer.shift)(index);
5474
+ builder.push(layer.map[index]);
5475
+ found = true;
5476
+ break;
5477
+ }
5478
+ }
5479
+ }
5480
+ if (!found) {
5481
+ const index = currentLayer.shift ? DbStringTypeUtils.getShiftDown(currentLayer.shift)(c) : c - (currentLayer.base ?? 0);
5482
+ if (index >= 0 && index < currentLayer.map.length) builder.push(currentLayer.map[index]);
4689
5483
  else builder.push(`[${c.toString(16).toUpperCase()}]`);
4690
5484
  }
4691
5485
  }
@@ -4748,6 +5542,7 @@ var StringProcessor = class {
4748
5542
  root;
4749
5543
  stringCharLookup;
4750
5544
  testRegex;
5545
+ inShift = false;
4751
5546
  constructor(context) {
4752
5547
  this.context = context;
4753
5548
  this.root = context.root;
@@ -4762,10 +5557,10 @@ var StringProcessor = class {
4762
5557
  str = this.context.lineBuffer.substring(1, endIx);
4763
5558
  this.context.lineBuffer = this.context.lineBuffer.substring(endIx + 1).replace(/^[\s,\t]+/, "");
4764
5559
  if (this.context.lineBuffer.startsWith("(")) {
4765
- const endIx$1 = this.context.lineBuffer.indexOf(")");
4766
- if (endIx$1 >= 0) {
4767
- fixedStr = parseInt(this.context.lineBuffer.substring(1, endIx$1), 10);
4768
- this.context.lineBuffer = this.context.lineBuffer.substring(endIx$1 + 1).replace(/^[\s,\t]+/, "");
5560
+ const endIx = this.context.lineBuffer.indexOf(")");
5561
+ if (endIx >= 0) {
5562
+ fixedStr = parseInt(this.context.lineBuffer.substring(1, endIx), 10);
5563
+ this.context.lineBuffer = this.context.lineBuffer.substring(endIx + 1).replace(/^[\s,\t]+/, "");
4769
5564
  }
4770
5565
  }
4771
5566
  } else {
@@ -4799,6 +5594,7 @@ var StringProcessor = class {
4799
5594
  const stringType = this.stringCharLookup[typeChar];
4800
5595
  const dictionary = stringType.dictionaryLookup;
4801
5596
  const cmdLookup = stringType.commands;
5597
+ let currentLayer = stringType.layers[0];
4802
5598
  let lastCmd = null;
4803
5599
  for (const entry of dictionary) {
4804
5600
  let index;
@@ -4808,7 +5604,7 @@ var StringProcessor = class {
4808
5604
  const c = str[x];
4809
5605
  if (c === "[") {
4810
5606
  const endIx = str.indexOf("]", x + 1);
4811
- const parts = str.substring(x + 1, endIx).split(/* @__PURE__ */ new RegExp(`[${[
5607
+ const parts = str.substring(x + 1, endIx).split(new RegExp(`[${[
4812
5608
  ":",
4813
5609
  ",",
4814
5610
  " "
@@ -4834,7 +5630,21 @@ var StringProcessor = class {
4834
5630
  }
4835
5631
  }
4836
5632
  lastCmd = null;
4837
- if (this.applyLayers(c, stringType)) continue;
5633
+ let found = false;
5634
+ for (const layer of stringType.layers) {
5635
+ for (let i = 0, len = layer.map.length; i < len; i++) if (c === layer.map[i]) {
5636
+ if (layer.on !== void 0 && currentLayer !== layer) {
5637
+ this.memBuffer.push(layer.on);
5638
+ currentLayer = layer;
5639
+ }
5640
+ let value = i + (layer.base ?? 0);
5641
+ if (layer.shift) value = DbStringTypeUtils.getShiftUp(layer.shift)(value);
5642
+ this.memBuffer.push(value);
5643
+ found = true;
5644
+ break;
5645
+ }
5646
+ if (found) break;
5647
+ }
4838
5648
  }
4839
5649
  if (this.fixedStr) {
4840
5650
  let count = this.fixedStr - this.totalSize;
@@ -4842,23 +5652,6 @@ var StringProcessor = class {
4842
5652
  } else if (lastCmd === null || !lastCmd.halt) this.memBuffer.push(stringType.terminator);
4843
5653
  this.flushBuffer(stringType, true);
4844
5654
  }
4845
- applyLayers(c, stringType) {
4846
- if (this.applyMap(c, stringType.characterMap, DbStringTypeUtils.getShiftUp(stringType.shiftType))) return true;
4847
- if (stringType.layers) {
4848
- for (const layer of stringType.layers) if (this.applyMap(c, layer.map, (x) => x + layer.base)) return true;
4849
- }
4850
- return false;
4851
- }
4852
- applyMap(c, map, shift) {
4853
- for (let i = 0, len = map.length; i < len; i++) {
4854
- const v = map[i];
4855
- if (v != null && c === v[0]) {
4856
- this.memBuffer.push(shift(i));
4857
- return true;
4858
- }
4859
- }
4860
- return false;
4861
- }
4862
5655
  processStringCommand(cmd, stringType, parts) {
4863
5656
  const hasPointer = cmd.types.includes(MemberType.Address) || cmd.types.includes(MemberType.Offset);
4864
5657
  if (hasPointer) this.flushBuffer(stringType, true);
@@ -5004,7 +5797,6 @@ var AssemblerState = class AssemblerState {
5004
5797
  }
5005
5798
  const location = parseInt(hex, 16);
5006
5799
  this.context.blocks.push(this.context.currentBlock = new AsmBlock(location));
5007
- this.context.blockIndex++;
5008
5800
  }
5009
5801
  static doMath(operand) {
5010
5802
  const ix = operand.search(/[-+]/);
@@ -5033,7 +5825,6 @@ var AssemblerState = class AssemblerState {
5033
5825
  const newBlock = new AsmBlock(this.context.currentBlock.location + this.context.currentBlock.size, 0, this.root.stringDelimiters.includes(operand[0]), mnemonic);
5034
5826
  this.context.blocks.push(newBlock);
5035
5827
  this.context.currentBlock = newBlock;
5036
- this.context.blockIndex++;
5037
5828
  if (labelChar === ":") this.context.lineBuffer = this.context.lineBuffer.substring(1);
5038
5829
  else if (labelChar === "[" || labelChar === "{") {
5039
5830
  this.context.lineBuffer = operand.substring(1).replace(/^[\s,\t]+/, "");
@@ -5120,8 +5911,8 @@ var AssemblerState = class AssemblerState {
5120
5911
  }
5121
5912
  this.context.lineBuffer = "";
5122
5913
  if (!operand) {
5123
- const opCode$1 = codes.find((x) => this.root.addrLookup[x.mode].size === 1);
5124
- this.context.currentBlock.objList.push(new Op(opCode$1, 0, [], 1));
5914
+ const opCode = codes.find((x) => this.root.addrLookup[x.mode].size === 1);
5915
+ this.context.currentBlock.objList.push(new Op(opCode, 0, [], 1));
5125
5916
  this.context.currentBlock.size++;
5126
5917
  continue;
5127
5918
  }
@@ -5197,16 +5988,20 @@ var Assembler = class {
5197
5988
  tags = new SortedMap();
5198
5989
  currentBlock = null;
5199
5990
  lineCount = 0;
5200
- blockIndex = 0;
5201
5991
  lastDelimiter = null;
5202
5992
  reqBank = null;
5203
5993
  eof = false;
5204
5994
  strDelimRegex;
5205
- constructor(dbRoot, textData) {
5995
+ conditionFiles;
5996
+ inCondition = false;
5997
+ exitCondition = false;
5998
+ failCondition = false;
5999
+ constructor(dbRoot, textData, conditionFiles) {
5206
6000
  this.root = dbRoot;
5207
6001
  this.lines = textData.split(/\r?\n/);
5208
6002
  this.stringProcessor = new StringProcessor(this);
5209
- this.strDelimRegex = /* @__PURE__ */ new RegExp(`[${this.root.stringDelimiters.map((c) => c.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("")}]`);
6003
+ this.strDelimRegex = new RegExp(`[${this.root.stringDelimiters.map((c) => c.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("")}]`);
6004
+ this.conditionFiles = conditionFiles;
5210
6005
  }
5211
6006
  parseAssembly() {
5212
6007
  this.blocks.push(this.currentBlock = new AsmBlock());
@@ -5245,6 +6040,10 @@ var Assembler = class {
5245
6040
  this.lineBuffer = "";
5246
6041
  continue;
5247
6042
  }
6043
+ if (this.failCondition) {
6044
+ this.lineBuffer = "";
6045
+ continue;
6046
+ }
5248
6047
  if (this.lineBuffer[0] === "!") {
5249
6048
  this.processTags();
5250
6049
  this.lineBuffer = "";
@@ -5264,7 +6063,7 @@ var Assembler = class {
5264
6063
  processDirectives() {
5265
6064
  let endIx = this.lineBuffer.search(RomProcessingConstants.COMMA_SPACE_REGEX);
5266
6065
  if (endIx < 0) endIx = this.lineBuffer.length;
5267
- const value = this.lineBuffer.substring(endIx).replace(/^[\s,\t]+/, "");
6066
+ let value = this.lineBuffer.substring(endIx).replace(/^[\s,\t]+/, "");
5268
6067
  switch (this.lineBuffer.substring(1, endIx).toUpperCase()) {
5269
6068
  case "BANK":
5270
6069
  this.reqBank = parseInt(value, 16);
@@ -5272,6 +6071,45 @@ var Assembler = class {
5272
6071
  case "INCLUDE":
5273
6072
  if (value.length > 0) this.includes.add(value.toUpperCase().replace(/'/g, ""));
5274
6073
  break;
6074
+ case "IF":
6075
+ if (this.inCondition) throw new Error("IF without ENDIF");
6076
+ value = value.replace(/'/g, "");
6077
+ if (!value) throw new Error("IF without condition");
6078
+ this.inCondition = true;
6079
+ if (!this.conditionFiles.includes(value)) {
6080
+ this.failCondition = true;
6081
+ this.exitCondition = false;
6082
+ } else {
6083
+ this.failCondition = false;
6084
+ this.exitCondition = true;
6085
+ }
6086
+ break;
6087
+ case "ELSEIF":
6088
+ if (!this.inCondition) throw new Error("ELSEIF without IF");
6089
+ value = value.replace(/'/g, "");
6090
+ if (!value) throw new Error("ELSEIF without condition");
6091
+ if (this.exitCondition || !this.conditionFiles.includes(value)) this.failCondition = true;
6092
+ else {
6093
+ this.exitCondition = true;
6094
+ this.failCondition = false;
6095
+ }
6096
+ break;
6097
+ case "ELSE":
6098
+ if (!this.inCondition) throw new Error("ELSE without IF");
6099
+ if (value) throw new Error("ELSE with condition");
6100
+ if (this.exitCondition) this.failCondition = true;
6101
+ else {
6102
+ this.failCondition = false;
6103
+ this.exitCondition = true;
6104
+ }
6105
+ break;
6106
+ case "ENDIF":
6107
+ if (!this.inCondition) throw new Error("ENDIF without IF");
6108
+ if (value) throw new Error("ENDIF with condition");
6109
+ this.failCondition = false;
6110
+ this.exitCondition = false;
6111
+ this.inCondition = false;
6112
+ break;
5275
6113
  }
5276
6114
  }
5277
6115
  processTags() {
@@ -5572,7 +6410,13 @@ async function fromSupabaseById(baseRomBranchId) {
5572
6410
  config,
5573
6411
  files,
5574
6412
  blocks,
5575
- fixups,
6413
+ rewrites,
6414
+ transforms,
6415
+ overrides,
6416
+ labels,
6417
+ mnemonics,
6418
+ fileTypes,
6419
+ groups,
5576
6420
  strings,
5577
6421
  structs,
5578
6422
  createdAt,
@@ -5585,7 +6429,6 @@ async function fromSupabaseById(baseRomBranchId) {
5585
6429
  notes,
5586
6430
  platformId,
5587
6431
  addressingModes,
5588
- instructionSet,
5589
6432
  vectors,
5590
6433
  types,
5591
6434
  createdAt,
@@ -5686,9 +6529,15 @@ async function fromSupabaseByName(options) {
5686
6529
  coplib,
5687
6530
  files,
5688
6531
  blocks,
5689
- fixups,
6532
+ rewrites,
6533
+ transforms,
6534
+ overrides,
6535
+ labels,
6536
+ mnemonics,
6537
+ fileTypes,
5690
6538
  strings,
5691
6539
  structs,
6540
+ groups,
5692
6541
  createdAt,
5693
6542
  updatedAt,
5694
6543
  platformBranch:PlatformBranch!inner(
@@ -5699,8 +6548,8 @@ async function fromSupabaseByName(options) {
5699
6548
  notes,
5700
6549
  platformId,
5701
6550
  addressingModes,
5702
- instructionSet,
5703
6551
  vectors,
6552
+ headers,
5704
6553
  types,
5705
6554
  createdAt,
5706
6555
  updatedAt
@@ -5905,7 +6754,13 @@ async function fromSupabaseByProject(projectName, branchId) {
5905
6754
  coplib,
5906
6755
  files,
5907
6756
  blocks,
5908
- fixups,
6757
+ rewrites,
6758
+ transforms,
6759
+ overrides,
6760
+ labels,
6761
+ mnemonics,
6762
+ fileTypes,
6763
+ groups,
5909
6764
  strings,
5910
6765
  structs,
5911
6766
  createdAt,
@@ -5940,8 +6795,8 @@ async function fromSupabaseByProject(projectName, branchId) {
5940
6795
  notes,
5941
6796
  platformId,
5942
6797
  addressingModes,
5943
- instructionSet,
5944
6798
  vectors,
6799
+ headers,
5945
6800
  types,
5946
6801
  createdAt,
5947
6802
  updatedAt,
@@ -5967,14 +6822,8 @@ async function fromSupabaseByProject(projectName, branchId) {
5967
6822
  });
5968
6823
  const baseRomBranch = branchData.baseRomBranch;
5969
6824
  const projectFiles = await loadProjectFiles(branchData.id);
5970
- const baseRomFiles = await loadBaseRomFiles(baseRomBranch.id);
6825
+ await loadBaseRomFiles(baseRomBranch.id);
5971
6826
  fileQueryTime = performance.now() - branchStart - branchQueryTime;
5972
- const payload = {
5973
- projectBranch: branchData,
5974
- projectFiles,
5975
- baseRomBranch,
5976
- baseRomFiles
5977
- };
5978
6827
  const totalTime = performance.now() - startTime;
5979
6828
  const stats = {
5980
6829
  branchQueryTime,
@@ -5983,7 +6832,23 @@ async function fromSupabaseByProject(projectName, branchId) {
5983
6832
  fileCount: projectFiles.length
5984
6833
  };
5985
6834
  console.log("Project ROM load stats:", stats);
5986
- return payload;
6835
+ return {
6836
+ mnemonics: baseRomBranch.gameRomBranch.mnemonics,
6837
+ overrides: baseRomBranch.gameRomBranch.overrides,
6838
+ rewrites: baseRomBranch.gameRomBranch.rewrites,
6839
+ blocks: baseRomBranch.gameRomBranch.blocks,
6840
+ files: baseRomBranch.gameRomBranch.files,
6841
+ config: baseRomBranch.gameRomBranch.config,
6842
+ labels: baseRomBranch.gameRomBranch.labels,
6843
+ structs: baseRomBranch.gameRomBranch.structs,
6844
+ copdef: baseRomBranch.gameRomBranch.coplib,
6845
+ strings: baseRomBranch.gameRomBranch.strings,
6846
+ transforms: baseRomBranch.gameRomBranch.transforms,
6847
+ groups: baseRomBranch.gameRomBranch.groups,
6848
+ fileTypes: baseRomBranch.gameRomBranch.fileTypes,
6849
+ addrModes: baseRomBranch.gameRomBranch.platformBranch.addressingModes,
6850
+ headers: baseRomBranch.gameRomBranch.platformBranch.headers
6851
+ };
5987
6852
  } catch (error) {
5988
6853
  if (error instanceof SupabaseFromError) throw error;
5989
6854
  throw new SupabaseFromError(`Failed to load Project data: ${error instanceof Error ? error.message : "Unknown error"}`, SupabaseErrorCode.NETWORK_ERROR, {
@@ -6012,7 +6877,13 @@ async function fromSupabaseByGameRom(gameName, regionName, platformName, branchI
6012
6877
  config,
6013
6878
  files,
6014
6879
  blocks,
6015
- fixups,
6880
+ rewrites,
6881
+ transforms,
6882
+ overrides,
6883
+ labels,
6884
+ mnemonics,
6885
+ fileTypes,
6886
+ groups,
6016
6887
  strings,
6017
6888
  structs,
6018
6889
  createdAt,
@@ -6047,7 +6918,7 @@ async function fromSupabaseByGameRom(gameName, regionName, platformName, branchI
6047
6918
  isActive,
6048
6919
  platformId,
6049
6920
  addressingModes,
6050
- instructionSet,
6921
+ headers,
6051
6922
  vectors,
6052
6923
  types,
6053
6924
  createdAt,
@@ -6171,6 +7042,7 @@ async function summaryFromSupabaseByProject(projectName) {
6171
7042
  version,
6172
7043
  isActive,
6173
7044
  notes,
7045
+ fileTypes,
6174
7046
  baseRomId,
6175
7047
  gameRomBranchId,
6176
7048
  createdAt,
@@ -6268,17 +7140,21 @@ async function summaryFromSupabaseByProject(projectName) {
6268
7140
  //#region src/rom/generator.ts
6269
7141
  var RomGenerator = class {
6270
7142
  projectName;
6271
- crc = 0;
6272
- branchId = "";
7143
+ crc;
6273
7144
  dbRoot = {};
6274
7145
  sourceData = new Uint8Array();
6275
- constructor(projectName) {
7146
+ constructor(projectName, crc) {
6276
7147
  this.projectName = projectName;
7148
+ this.crc = crc ?? 0;
6277
7149
  }
6278
- async initialize() {
6279
- var projectData = await summaryFromSupabaseByProject(this.projectName);
6280
- this.crc = projectData.baseRomBranch.gameRomBranch.gameRom.crc;
6281
- this.branchId = projectData.id;
7150
+ async validateAndDownload(sourceData) {
7151
+ if (crc32_buffer(sourceData) === this.crc) {
7152
+ const moduleData = await fromSupabaseByProject(this.projectName);
7153
+ this.dbRoot = DbRootUtils.fromGameModule(moduleData);
7154
+ this.sourceData = sourceData;
7155
+ return true;
7156
+ }
7157
+ return false;
6282
7158
  }
6283
7159
  async generateProject(modules, manualFiles, unshiftManualFiles = false) {
6284
7160
  if (!this.dbRoot) throw new Error("Database not initialized");
@@ -6294,45 +7170,20 @@ var RomGenerator = class {
6294
7170
  if (unshiftManualFiles) for (const file of manualFiles ?? []) this.applyPatchFile(file, chunkFiles, asmFiles, patchFiles);
6295
7171
  for (const module of modules) for (const file of moduleLookup.get(module)) this.applyPatchFile(file, chunkFiles, asmFiles, patchFiles);
6296
7172
  if (!unshiftManualFiles) for (const file of manualFiles ?? []) this.applyPatchFile(file, chunkFiles, asmFiles, patchFiles);
6297
- this.assembleCodeFromText(asmFiles);
6298
- RomProcessor.applyPatches(asmFiles, patchFiles);
6299
- for (const asm of chunkFiles) ChunkFileUtils.calculateSize(asm);
6300
- const pages = new RomLayout(chunkFiles, this.dbRoot).organize();
6301
- for (const file of asmFiles) ChunkFileUtils.rebase(file);
6302
- this.generateAsmIncludeLookups(asmFiles);
6303
- const blockLookup = /* @__PURE__ */ new Map();
6304
- for (const f of chunkFiles) blockLookup.set(f.name.toUpperCase(), f.location);
6305
- return await this.writeRom(blockLookup, chunkFiles, asmFiles, pages);
7173
+ return await new RomWriter(this.dbRoot).repack(chunkFiles);
6306
7174
  }
6307
7175
  applyProjectInit(chunkFiles, asmFiles, patchFiles) {
6308
7176
  const moduleLookup = /* @__PURE__ */ new Map();
6309
7177
  for (const chunkFile of this.dbRoot.projectFiles) {
6310
7178
  console.log(`Processing patch: ${chunkFile.name}`);
6311
7179
  if (chunkFile.group) {
6312
- let modArray;
6313
- if (!moduleLookup.has(chunkFile.group)) moduleLookup.set(chunkFile.group, modArray = []);
6314
- else modArray = moduleLookup.get(chunkFile.group);
7180
+ let modArray = moduleLookup.get(chunkFile.group);
7181
+ if (!modArray) moduleLookup.set(chunkFile.group, modArray = []);
6315
7182
  modArray.push(chunkFile);
6316
7183
  } else this.applyPatchFile(chunkFile, chunkFiles, asmFiles, patchFiles);
6317
7184
  }
6318
7185
  return moduleLookup;
6319
7186
  }
6320
- assembleCodeFromText(asmFiles) {
6321
- for (const block of asmFiles) {
6322
- const { blocks, includes, reqBank } = new Assembler(this.dbRoot, block.textData).parseAssembly();
6323
- block.parts = blocks;
6324
- block.includes = includes;
6325
- block.bank = reqBank ?? void 0;
6326
- }
6327
- }
6328
- generateAsmIncludeLookups(asmFiles) {
6329
- for (const f of asmFiles) {
6330
- const includeBlocks = asmFiles.filter((x) => f.includes?.has(x.name.toUpperCase())).flatMap((x) => x.parts).filter((b) => !!b.label);
6331
- f.includeLookup = /* @__PURE__ */ new Map();
6332
- for (const b of includeBlocks) if (b.label) f.includeLookup.set(b.label.toUpperCase(), b);
6333
- for (const b of (f.parts || []).filter((x) => !!x.label)) if (b.label) f.includeLookup.set(b.label.toUpperCase(), b);
6334
- }
6335
- }
6336
7187
  applyPatchFile(chunkFile, chunkFiles, asmFiles, patchFiles) {
6337
7188
  console.log(`Processing patch: ${chunkFile.name}`);
6338
7189
  const existing = chunkFiles.find((x) => x.name === chunkFile.name);
@@ -6347,15 +7198,6 @@ var RomGenerator = class {
6347
7198
  existing.size = chunkFile.size;
6348
7199
  } else chunkFiles.push(chunkFile);
6349
7200
  }
6350
- async writeRom(blockLookup, chunkFiles, asmFiles, pages) {
6351
- const romWriter = new RomWriter(this.dbRoot, "GAIALABS", "01JG ");
6352
- romWriter.allocate(pages);
6353
- for (const file of chunkFiles) await romWriter.writeFile(file, blockLookup);
6354
- romWriter.writeHeader();
6355
- romWriter.writeEntryPoints(asmFiles);
6356
- romWriter.writeChecksum();
6357
- return romWriter.outBuffer;
6358
- }
6359
7201
  };
6360
7202
 
6361
7203
  //#endregion
@@ -6590,27 +7432,13 @@ var SpriteMap = class SpriteMap {
6590
7432
 
6591
7433
  //#endregion
6592
7434
  //#region src/index.ts
6593
- /**
6594
- * GaiaCore - Universal ROM processing engine
6595
- *
6596
- * This package provides the core functionality for ROM processing
6597
- * that can run in both browser (Web Worker) and Node.js environments.
6598
- *
6599
- * High-level APIs:
6600
- * - RomProcessor: Unified ROM processing workflows
6601
- * - ProjectManager: Complete project lifecycle management
6602
- *
6603
- * Low-level modules:
6604
- * - ROM: ROM state management, project configuration
6605
- * - Assembly: 65816 instruction set, stack operations
6606
- * - Compression: QuintetLZ compression algorithm
6607
- * - Sprites: Sprite animation system
6608
- */
6609
- const GAIA_CORE_VERSION = "0.1.6";
6610
- const isPlatformBrowser = typeof window !== "undefined";
7435
+ const snes = {
7436
+ addressingModes: addressingModes_default,
7437
+ vectors: vectors_default,
7438
+ headers: headers_default
7439
+ };
6611
7440
  const isPlatformNode = typeof process !== "undefined" && process.versions?.node;
6612
- const isPlatformWebWorker = typeof importScripts !== "undefined";
6613
7441
 
6614
7442
  //#endregion
6615
- export { Address, AddressSpace, AddressType, AddressingModeHandler, AsmBlock, AsmBlockUtils, AsmReader, Assembler, AssemblerState, BinType, BitStream, BlockReader, BlockReaderConstants, BlockWriter, Byte, ChunkFile, ChunkFileUtils, CompressionAlgorithms, CompressionRegistry, CopCommandProcessor, CopDef, CpuMode, DbAddressingMode, DbBlock, DbFile, DbFileType, DbGroup, DbOverride, DbPart, DbRootUtils, DbScene, DbStringCommand, DbStringDictionary, DbStringType, DbStringTypeUtils, DbStruct, DbTransform, DebugExporter, GAIA_CORE_VERSION, LocationWrapper, Long, MapExt, MemberType, MemoryMapMode, ObjectType, Op, OpCode, OperationContext, PostProcessor, ProcessorStateManager, QuintetLZ, ReferenceManager, RegisterType, Registers, RomDataReader, RomGenerator, RomLayout, RomProcessingConstants, RomProcessor, RomState, RomStateUtils, RomWriter, SortedMap, SpriteFrame, SpriteGroup, SpriteMap, SpritePart, Stack, StackOperations, StatusFlags, StringProcessor, StringReader, StringSizeComparer, SupabaseErrorCode, SupabaseFromError, TableEntry, TransformProcessor, TypeParser, TypedNumber, Word, XformType, base64ToUint8Array, binaryToUtf8String, bytesToHex, clamp, crc32_buffer, crc32_text_utf16, crc32_text_utf8, createChunkFileFromDbBlock, createChunkFileFromDbFile, createDbPath, createSupabaseClient, createTempDirectory, decodeBase64, decodeBase64String, decodeDataString, encodeBase64, encodeBase64String, fileExists, fromSupabaseByGameRom, fromSupabaseById, fromSupabaseByName, fromSupabaseByProject, getDirectory, getEnvVar, getNestedProperty, getSupabaseClient, hexToBytes, hexToUint8Array, indexOfAny, isPlatformBrowser, isPlatformNode, isPlatformWebWorker, isValidBase64, listDirectory, readFileAsBinary, readFileAsText, readJsonFile, removeDirectory, resetSupabaseClient, saveFileAsBinary, saveFileAsText, summaryFromSupabaseByProject, uint8ArrayToBase64, validateEnvironmentVariables };
7443
+ export { Address, AddressSpace, AddressType, AddressingModeHandler, AsmBlock, AsmBlockUtils, AsmReader, Assembler, AssemblerState, BinType, BitStream, BlockReader, BlockReaderConstants, BlockWriter, Byte, ChunkFile, ChunkFileUtils, CompressionAlgorithms, CompressionRegistry, CopCommandProcessor, CopDef, CpuMode, DbAddressingMode, DbBlock, DbFile, DbFileType, DbGroup, DbHeader, DbHeaderPart, DbOverride, DbPart, DbRootUtils, DbScene, DbStringCommand, DbStringDictionary, DbStringType, DbStringTypeUtils, DbStruct, DbTransform, LocationWrapper, Long, MapExt, MemberType, MemoryMapMode, ObjectType, Op, OpCode, OperationContext, PostProcessor, ProcessorStateManager, QuintetLZ, ReferenceManager, RegisterType, Registers, RomDataReader, RomGenerator, RomLayout, RomProcessingConstants, RomProcessor, RomState, RomStateUtils, RomWriter, SortedMap, SpriteFrame, SpriteGroup, SpriteMap, SpritePart, Stack, StackOperations, StatusFlags, StringProcessor, StringReader, StringSizeComparer, SupabaseErrorCode, SupabaseFromError, TableEntry, TransformProcessor, TypeParser, TypedNumber, Word, XformType, base64ToUint8Array, binaryToUtf8String, bytesToHex, clamp, crc32_buffer, crc32_text_utf16, crc32_text_utf8, createChunkFileFromDbBlock, createChunkFileFromDbFile, createDbPath, createSupabaseClient, createTempDirectory, decodeBase64, decodeBase64String, decodeDataString, encodeBase64, encodeBase64String, fileExists, fromSupabaseByGameRom, fromSupabaseById, fromSupabaseByName, fromSupabaseByProject, getDirectory, getEnvVar, getNestedProperty, getSupabaseClient, hexToBytes, hexToUint8Array, indexOfAny, isPlatformNode, isValidBase64, listDirectory, readFileAsBinary, readFileAsText, readJsonFile, removeDirectory, resetSupabaseClient, saveFileAsBinary, saveFileAsText, snes, summaryFromSupabaseByProject, uint8ArrayToBase64, validateEnvironmentVariables };
6616
7444
  //# sourceMappingURL=index.mjs.map