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