@hyperfixi/vite-plugin 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,3512 @@
1
+ // src/language-keywords.ts
2
+ var SUPPORTED_LANGUAGES = [
3
+ "en",
4
+ "es",
5
+ "pt",
6
+ "fr",
7
+ "de",
8
+ "it",
9
+ "vi",
10
+ // Western (Latin script)
11
+ "pl",
12
+ "ru",
13
+ "uk",
14
+ // Slavic (Latin/Cyrillic)
15
+ "ja",
16
+ "zh",
17
+ "ko",
18
+ // East Asian
19
+ "ar",
20
+ // RTL (Arabic script)
21
+ "hi",
22
+ "bn",
23
+ // South Asian (Indic scripts)
24
+ "th",
25
+ // Southeast Asian (Thai script)
26
+ "tr",
27
+ // Agglutinative Latin
28
+ "id",
29
+ "sw",
30
+ "qu",
31
+ // Other
32
+ "tl"
33
+ // Tagalog (auto-added)
34
+ ];
35
+ var REGIONS = {
36
+ western: ["en", "es", "pt", "fr", "de", "it"],
37
+ "east-asian": ["ja", "zh", "ko"],
38
+ slavic: ["pl", "ru", "uk"],
39
+ "south-asian": ["hi", "bn"],
40
+ priority: [
41
+ "en",
42
+ "es",
43
+ "pt",
44
+ "fr",
45
+ "de",
46
+ "it",
47
+ "ja",
48
+ "zh",
49
+ "ko",
50
+ "ar",
51
+ "tr",
52
+ "ru",
53
+ "hi"
54
+ ],
55
+ all: SUPPORTED_LANGUAGES
56
+ };
57
+ var JAPANESE_KEYWORDS = /* @__PURE__ */ new Set([
58
+ "\u5207\u308A\u66FF\u3048",
59
+ "\u5207\u308A\u66FF\u3048\u308B",
60
+ "\u30C8\u30B0\u30EB",
61
+ "\u30C8\u30B0\u30EB\u3059\u308B",
62
+ "\u8FFD\u52A0",
63
+ "\u8FFD\u52A0\u3059\u308B",
64
+ "\u52A0\u3048\u308B",
65
+ "\u524A\u9664",
66
+ "\u524A\u9664\u3059\u308B",
67
+ "\u53D6\u308A\u9664\u304F",
68
+ "\u8868\u793A",
69
+ "\u8868\u793A\u3059\u308B",
70
+ "\u898B\u305B\u308B",
71
+ "\u96A0\u3059",
72
+ "\u975E\u8868\u793A",
73
+ "\u975E\u8868\u793A\u306B\u3059\u308B",
74
+ "\u8A2D\u5B9A",
75
+ "\u8A2D\u5B9A\u3059\u308B",
76
+ "\u30BB\u30C3\u30C8",
77
+ "\u5897\u52A0",
78
+ "\u5897\u3084\u3059",
79
+ "\u30A4\u30F3\u30AF\u30EA\u30E1\u30F3\u30C8",
80
+ "\u6E1B\u5C11",
81
+ "\u6E1B\u3089\u3059",
82
+ "\u30C7\u30AF\u30EA\u30E1\u30F3\u30C8",
83
+ "\u5F15\u304D\u91D1",
84
+ "\u767A\u706B",
85
+ "\u30C8\u30EA\u30AC\u30FC",
86
+ "\u9001\u308B",
87
+ "\u9001\u4FE1",
88
+ "\u3082\u3057",
89
+ "\u6761\u4EF6",
90
+ "\u305D\u3046\u3067\u306A\u3051\u308C\u3070",
91
+ "\u305D\u308C\u4EE5\u5916",
92
+ "\u7E70\u308A\u8FD4\u3057",
93
+ "\u7E70\u308A\u8FD4\u3059",
94
+ "\u30EA\u30D4\u30FC\u30C8",
95
+ "\u5F85\u3064",
96
+ "\u5F85\u6A5F",
97
+ "\u306E\u9593",
98
+ "\u9593"
99
+ ]);
100
+ var KOREAN_KEYWORDS = /* @__PURE__ */ new Set([
101
+ "\uD1A0\uAE00",
102
+ "\uC804\uD658",
103
+ "\uCD94\uAC00",
104
+ "\uC81C\uAC70",
105
+ "\uC0AD\uC81C",
106
+ "\uBCF4\uC774\uB2E4",
107
+ "\uD45C\uC2DC",
108
+ "\uBCF4\uC774\uAE30",
109
+ "\uC228\uAE30\uB2E4",
110
+ "\uC228\uAE30\uAE30",
111
+ "\uC124\uC815",
112
+ "\uC99D\uAC00",
113
+ "\uAC10\uC18C",
114
+ "\uD2B8\uB9AC\uAC70",
115
+ "\uBCF4\uB0B4\uB2E4",
116
+ "\uB9CC\uC57D",
117
+ "\uC544\uB2C8\uBA74",
118
+ "\uBC18\uBCF5",
119
+ "\uB300\uAE30",
120
+ "\uB3D9\uC548"
121
+ ]);
122
+ var CHINESE_KEYWORDS = /* @__PURE__ */ new Set([
123
+ "\u5207\u6362",
124
+ "\u6DFB\u52A0",
125
+ "\u52A0",
126
+ "\u79FB\u9664",
127
+ "\u5220\u9664",
128
+ "\u53BB\u6389",
129
+ "\u663E\u793A",
130
+ "\u5C55\u793A",
131
+ "\u9690\u85CF",
132
+ "\u8BBE\u7F6E",
133
+ "\u8BBE\u5B9A",
134
+ "\u589E\u52A0",
135
+ "\u51CF\u5C11",
136
+ "\u89E6\u53D1",
137
+ "\u53D1\u9001",
138
+ "\u5982\u679C",
139
+ "\u5426\u5219",
140
+ "\u91CD\u590D",
141
+ "\u7B49\u5F85",
142
+ "\u5F53"
143
+ ]);
144
+ var ARABIC_KEYWORDS = /* @__PURE__ */ new Set([
145
+ "\u0628\u062F\u0644",
146
+ "\u0628\u062F\u0651\u0644",
147
+ "\u063A\u064A\u0651\u0631",
148
+ "\u063A\u064A\u0631",
149
+ "\u0623\u0636\u0641",
150
+ "\u0627\u0636\u0641",
151
+ "\u0632\u0650\u062F",
152
+ "\u0627\u062D\u0630\u0641",
153
+ "\u0623\u0632\u0644",
154
+ "\u0627\u0645\u0633\u062D",
155
+ "\u0627\u0638\u0647\u0631",
156
+ "\u0623\u0638\u0647\u0631",
157
+ "\u0627\u0639\u0631\u0636",
158
+ "\u0627\u062E\u0641",
159
+ "\u0623\u062E\u0641\u0650",
160
+ "\u0627\u062E\u0641\u064A",
161
+ "\u0627\u0636\u0628\u0637",
162
+ "\u0639\u064A\u0651\u0646",
163
+ "\u062D\u062F\u062F",
164
+ "\u0627\u0631\u0641\u0639",
165
+ "\u0623\u0646\u0642\u0635",
166
+ "\u0642\u0644\u0644",
167
+ "\u062A\u0634\u063A\u064A\u0644",
168
+ "\u0623\u0637\u0644\u0642",
169
+ "\u0641\u0639\u0651\u0644",
170
+ "\u0623\u0631\u0633\u0644",
171
+ "\u0625\u0630\u0627",
172
+ "\u0648\u0625\u0644\u0627",
173
+ "\u062E\u0644\u0627\u0641 \u0630\u0644\u0643",
174
+ "\u0643\u0631\u0631",
175
+ "\u0627\u0646\u062A\u0638\u0631",
176
+ "\u0628\u064A\u0646\u0645\u0627"
177
+ ]);
178
+ var SPANISH_KEYWORDS = /* @__PURE__ */ new Set([
179
+ "alternar",
180
+ "cambiar",
181
+ "conmutar",
182
+ "agregar",
183
+ "a\xF1adir",
184
+ "quitar",
185
+ "eliminar",
186
+ "remover",
187
+ "sacar",
188
+ "mostrar",
189
+ "ense\xF1ar",
190
+ "ocultar",
191
+ "esconder",
192
+ "establecer",
193
+ "fijar",
194
+ "definir",
195
+ "incrementar",
196
+ "aumentar",
197
+ "decrementar",
198
+ "disminuir",
199
+ "disparar",
200
+ "activar",
201
+ "enviar",
202
+ "si",
203
+ "sino",
204
+ "de lo contrario",
205
+ "repetir",
206
+ "esperar",
207
+ "mientras"
208
+ ]);
209
+ var PORTUGUESE_KEYWORDS = /* @__PURE__ */ new Set([
210
+ "alternar",
211
+ "trocar",
212
+ "adicionar",
213
+ "acrescentar",
214
+ "remover",
215
+ "eliminar",
216
+ "apagar",
217
+ "mostrar",
218
+ "exibir",
219
+ "ocultar",
220
+ "esconder",
221
+ "definir",
222
+ "configurar",
223
+ "incrementar",
224
+ "aumentar",
225
+ "decrementar",
226
+ "diminuir",
227
+ "disparar",
228
+ "ativar",
229
+ "enviar",
230
+ "se",
231
+ "sen\xE3o",
232
+ "repetir",
233
+ "esperar",
234
+ "aguardar",
235
+ "enquanto"
236
+ ]);
237
+ var FRENCH_KEYWORDS = /* @__PURE__ */ new Set([
238
+ "basculer",
239
+ "permuter",
240
+ "alterner",
241
+ "ajouter",
242
+ "supprimer",
243
+ "enlever",
244
+ "retirer",
245
+ "montrer",
246
+ "afficher",
247
+ "cacher",
248
+ "masquer",
249
+ "d\xE9finir",
250
+ "\xE9tablir",
251
+ "incr\xE9menter",
252
+ "augmenter",
253
+ "d\xE9cr\xE9menter",
254
+ "diminuer",
255
+ "d\xE9clencher",
256
+ "envoyer",
257
+ "si",
258
+ "sinon",
259
+ "r\xE9p\xE9ter",
260
+ "attendre",
261
+ "pendant"
262
+ ]);
263
+ var GERMAN_KEYWORDS = /* @__PURE__ */ new Set([
264
+ "umschalten",
265
+ "wechseln",
266
+ "hinzuf\xFCgen",
267
+ "entfernen",
268
+ "l\xF6schen",
269
+ "zeigen",
270
+ "anzeigen",
271
+ "verbergen",
272
+ "verstecken",
273
+ "festlegen",
274
+ "definieren",
275
+ "erh\xF6hen",
276
+ "verringern",
277
+ "vermindern",
278
+ "ausl\xF6sen",
279
+ "senden",
280
+ "schicken",
281
+ "wenn",
282
+ "falls",
283
+ "sonst",
284
+ "ansonsten",
285
+ "wiederholen",
286
+ "warten",
287
+ "solange",
288
+ "w\xE4hrend"
289
+ ]);
290
+ var TURKISH_KEYWORDS = /* @__PURE__ */ new Set([
291
+ "de\u011Fi\u015Ftir",
292
+ "a\xE7/kapat",
293
+ "ekle",
294
+ "kald\u0131r",
295
+ "sil",
296
+ "g\xF6ster",
297
+ "gizle",
298
+ "ayarla",
299
+ "yap",
300
+ "belirle",
301
+ "art\u0131r",
302
+ "azalt",
303
+ "tetikle",
304
+ "g\xF6nder",
305
+ "e\u011Fer",
306
+ "yoksa",
307
+ "tekrarla",
308
+ "bekle",
309
+ "iken"
310
+ ]);
311
+ var INDONESIAN_KEYWORDS = /* @__PURE__ */ new Set([
312
+ "alihkan",
313
+ "ganti",
314
+ "tukar",
315
+ "tambah",
316
+ "tambahkan",
317
+ "hapus",
318
+ "buang",
319
+ "hilangkan",
320
+ "tampilkan",
321
+ "perlihatkan",
322
+ "sembunyikan",
323
+ "tutup",
324
+ "atur",
325
+ "tetapkan",
326
+ "tingkatkan",
327
+ "naikkan",
328
+ "turunkan",
329
+ "kurangi",
330
+ "picu",
331
+ "jalankan",
332
+ "kirim",
333
+ "kirimkan",
334
+ "jika",
335
+ "kalau",
336
+ "bila",
337
+ "selainnya",
338
+ "ulangi",
339
+ "tunggu",
340
+ "selama"
341
+ ]);
342
+ var SWAHILI_KEYWORDS = /* @__PURE__ */ new Set([
343
+ "badilisha",
344
+ "geuza",
345
+ "ongeza",
346
+ "weka",
347
+ "ondoa",
348
+ "futa",
349
+ "toa",
350
+ "onyesha",
351
+ "ficha",
352
+ "mficho",
353
+ "seti",
354
+ "punguza",
355
+ "chochea",
356
+ "anzisha",
357
+ "tuma",
358
+ "peleka",
359
+ "kama",
360
+ "ikiwa",
361
+ "vinginevyo",
362
+ "sivyo",
363
+ "rudia",
364
+ "subiri",
365
+ "ngoja",
366
+ "wakati"
367
+ ]);
368
+ var QUECHUA_KEYWORDS = /* @__PURE__ */ new Set([
369
+ "t",
370
+ "tikray",
371
+ "kutichiy",
372
+ "yapay",
373
+ "yapaykuy",
374
+ "qichuy",
375
+ "hurquy",
376
+ "anchuchiy",
377
+ "rikuchiy",
378
+ "qawachiy",
379
+ "pakay",
380
+ "pakakuy",
381
+ "churay",
382
+ "kamaykuy",
383
+ "yapachiy",
384
+ "pisiyachiy",
385
+ "qallarichiy",
386
+ "kachay",
387
+ "apachiy",
388
+ "sichus",
389
+ "manachus",
390
+ "hukniraq",
391
+ "kutipay",
392
+ "muyu",
393
+ "suyay",
394
+ "kaykamaqa"
395
+ ]);
396
+ var ITALIAN_KEYWORDS = /* @__PURE__ */ new Set([
397
+ "commutare",
398
+ "alternare",
399
+ "cambiare",
400
+ "aggiungere",
401
+ "aggiungi",
402
+ "rimuovere",
403
+ "eliminare",
404
+ "togliere",
405
+ "mostrare",
406
+ "visualizzare",
407
+ "nascondere",
408
+ "impostare",
409
+ "definire",
410
+ "incrementare",
411
+ "aumentare",
412
+ "decrementare",
413
+ "diminuire",
414
+ "scatenare",
415
+ "attivare",
416
+ "inviare",
417
+ "se",
418
+ "altrimenti",
419
+ "ripetere",
420
+ "aspettare",
421
+ "attendere",
422
+ "mentre"
423
+ ]);
424
+ var VIETNAMESE_KEYWORDS = /* @__PURE__ */ new Set([
425
+ "chuy\u1EC3n \u0111\u1ED5i",
426
+ "b\u1EADt t\u1EAFt",
427
+ "chuy\u1EC3n",
428
+ "th\xEAm",
429
+ "b\u1ED5 sung",
430
+ "x\xF3a",
431
+ "g\u1EE1 b\u1ECF",
432
+ "lo\u1EA1i b\u1ECF",
433
+ "b\u1ECF",
434
+ "hi\u1EC3n th\u1ECB",
435
+ "hi\u1EC7n",
436
+ "\u1EA9n",
437
+ "che",
438
+ "gi\u1EA5u",
439
+ "g\xE1n",
440
+ "thi\u1EBFt l\u1EADp",
441
+ "\u0111\u1EB7t",
442
+ "t\u0103ng",
443
+ "t\u0103ng l\xEAn",
444
+ "gi\u1EA3m",
445
+ "gi\u1EA3m \u0111i",
446
+ "k\xEDch ho\u1EA1t",
447
+ "g\u1EEDi",
448
+ "n\u1EBFu",
449
+ "kh\xF4ng th\xEC",
450
+ "n\u1EBFu kh\xF4ng",
451
+ "l\u1EB7p l\u1EA1i",
452
+ "ch\u1EDD",
453
+ "\u0111\u1EE3i",
454
+ "trong khi"
455
+ ]);
456
+ var POLISH_KEYWORDS = /* @__PURE__ */ new Set([
457
+ "prze\u0142\u0105cz",
458
+ "przelacz",
459
+ "dodaj",
460
+ "usu\u0144",
461
+ "usun",
462
+ "wyczy\u015B\u0107",
463
+ "wyczysc",
464
+ "poka\u017C",
465
+ "pokaz",
466
+ "wy\u015Bwietl",
467
+ "wyswietl",
468
+ "ukryj",
469
+ "schowaj",
470
+ "ustaw",
471
+ "okre\u015Bl",
472
+ "okresl",
473
+ "zwi\u0119ksz",
474
+ "zwieksz",
475
+ "zmniejsz",
476
+ "wywo\u0142aj",
477
+ "wywolaj",
478
+ "wyzw\xF3l",
479
+ "wyzwol",
480
+ "wy\u015Blij",
481
+ "wyslij",
482
+ "je\u015Bli",
483
+ "jesli",
484
+ "je\u017Celi",
485
+ "jezeli",
486
+ "inaczej",
487
+ "wpp",
488
+ "powt\xF3rz",
489
+ "powtorz",
490
+ "czekaj",
491
+ "poczekaj",
492
+ "dop\xF3ki",
493
+ "dopoki",
494
+ "podczas"
495
+ ]);
496
+ var RUSSIAN_KEYWORDS = /* @__PURE__ */ new Set([
497
+ "\u043F\u0435\u0440\u0435\u043A\u043B\u044E\u0447\u0438\u0442\u044C",
498
+ "\u043F\u0435\u0440\u0435\u043A\u043B\u044E\u0447\u0438",
499
+ "\u0434\u043E\u0431\u0430\u0432\u0438\u0442\u044C",
500
+ "\u0434\u043E\u0431\u0430\u0432\u044C",
501
+ "\u0443\u0434\u0430\u043B\u0438\u0442\u044C",
502
+ "\u0443\u0434\u0430\u043B\u0438",
503
+ "\u0443\u0431\u0440\u0430\u0442\u044C",
504
+ "\u0443\u0431\u0435\u0440\u0438",
505
+ "\u043F\u043E\u043A\u0430\u0437\u0430\u0442\u044C",
506
+ "\u043F\u043E\u043A\u0430\u0436\u0438",
507
+ "\u0441\u043A\u0440\u044B\u0442\u044C",
508
+ "\u0441\u043A\u0440\u043E\u0439",
509
+ "\u0441\u043F\u0440\u044F\u0442\u0430\u0442\u044C",
510
+ "\u0441\u043F\u0440\u044F\u0447\u044C",
511
+ "\u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C",
512
+ "\u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438",
513
+ "\u0437\u0430\u0434\u0430\u0442\u044C",
514
+ "\u0437\u0430\u0434\u0430\u0439",
515
+ "\u0443\u0432\u0435\u043B\u0438\u0447\u0438\u0442\u044C",
516
+ "\u0443\u0432\u0435\u043B\u0438\u0447\u044C",
517
+ "\u0443\u043C\u0435\u043D\u044C\u0448\u0438\u0442\u044C",
518
+ "\u0443\u043C\u0435\u043D\u044C\u0448\u0438",
519
+ "\u0432\u044B\u0437\u0432\u0430\u0442\u044C",
520
+ "\u0432\u044B\u0437\u043E\u0432\u0438",
521
+ "\u043E\u0442\u043F\u0440\u0430\u0432\u0438\u0442\u044C",
522
+ "\u043E\u0442\u043F\u0440\u0430\u0432\u044C",
523
+ "\u0435\u0441\u043B\u0438",
524
+ "\u0438\u043D\u0430\u0447\u0435",
525
+ "\u043F\u043E\u0432\u0442\u043E\u0440\u0438\u0442\u044C",
526
+ "\u043F\u043E\u0432\u0442\u043E\u0440\u0438",
527
+ "\u0436\u0434\u0430\u0442\u044C",
528
+ "\u0436\u0434\u0438",
529
+ "\u043F\u043E\u0434\u043E\u0436\u0434\u0438",
530
+ "\u043F\u043E\u043A\u0430"
531
+ ]);
532
+ var UKRAINIAN_KEYWORDS = /* @__PURE__ */ new Set([
533
+ "\u043F\u0435\u0440\u0435\u043C\u043A\u043D\u0443\u0442\u0438",
534
+ "\u043F\u0435\u0440\u0435\u043C\u043A\u043D\u0438",
535
+ "\u0434\u043E\u0434\u0430\u0442\u0438",
536
+ "\u0434\u043E\u0434\u0430\u0439",
537
+ "\u0432\u0438\u0434\u0430\u043B\u0438\u0442\u0438",
538
+ "\u0432\u0438\u0434\u0430\u043B\u0438",
539
+ "\u043F\u0440\u0438\u0431\u0440\u0430\u0442\u0438",
540
+ "\u043F\u0440\u0438\u0431\u0435\u0440\u0438",
541
+ "\u043F\u043E\u043A\u0430\u0437\u0430\u0442\u0438",
542
+ "\u043F\u043E\u043A\u0430\u0436\u0438",
543
+ "\u0441\u0445\u043E\u0432\u0430\u0442\u0438",
544
+ "\u0441\u0445\u043E\u0432\u0430\u0439",
545
+ "\u043F\u0440\u0438\u0445\u043E\u0432\u0430\u0442\u0438",
546
+ "\u043F\u0440\u0438\u0445\u043E\u0432\u0430\u0439",
547
+ "\u0432\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u0438",
548
+ "\u0432\u0441\u0442\u0430\u043D\u043E\u0432\u0438",
549
+ "\u0437\u0430\u0434\u0430\u0442\u0438",
550
+ "\u0437\u0430\u0434\u0430\u0439",
551
+ "\u0437\u0431\u0456\u043B\u044C\u0448\u0438\u0442\u0438",
552
+ "\u0437\u0431\u0456\u043B\u044C\u0448",
553
+ "\u0437\u043C\u0435\u043D\u0448\u0438\u0442\u0438",
554
+ "\u0437\u043C\u0435\u043D\u0448",
555
+ "\u0432\u0438\u043A\u043B\u0438\u043A\u0430\u0442\u0438",
556
+ "\u0432\u0438\u043A\u043B\u0438\u0447",
557
+ "\u043D\u0430\u0434\u0456\u0441\u043B\u0430\u0442\u0438",
558
+ "\u043D\u0430\u0434\u0456\u0448\u043B\u0438",
559
+ "\u044F\u043A\u0449\u043E",
560
+ "\u0456\u043D\u0430\u043A\u0448\u0435",
561
+ "\u043F\u043E\u0432\u0442\u043E\u0440\u0438\u0442\u0438",
562
+ "\u043F\u043E\u0432\u0442\u043E\u0440\u0438",
563
+ "\u0447\u0435\u043A\u0430\u0442\u0438",
564
+ "\u0447\u0435\u043A\u0430\u0439",
565
+ "\u0437\u0430\u0447\u0435\u043A\u0430\u0439",
566
+ "\u043F\u043E\u043A\u0438"
567
+ ]);
568
+ var HINDI_KEYWORDS = /* @__PURE__ */ new Set([
569
+ "\u091F\u0949\u0917\u0932",
570
+ "\u092C\u0926\u0932\u0947\u0902",
571
+ "\u092C\u0926\u0932",
572
+ "\u091C\u094B\u0921\u093C\u0947\u0902",
573
+ "\u091C\u094B\u0921\u093C",
574
+ "\u0939\u091F\u093E\u090F\u0902",
575
+ "\u0939\u091F\u093E",
576
+ "\u092E\u093F\u091F\u093E\u090F\u0902",
577
+ "\u0926\u093F\u0916\u093E\u090F\u0902",
578
+ "\u0926\u093F\u0916\u093E",
579
+ "\u091B\u093F\u092A\u093E\u090F\u0902",
580
+ "\u091B\u093F\u092A\u093E",
581
+ "\u0938\u0947\u091F",
582
+ "\u0928\u093F\u0930\u094D\u0927\u093E\u0930\u093F\u0924",
583
+ "\u092C\u0922\u093C\u093E\u090F\u0902",
584
+ "\u092C\u0922\u093C\u093E",
585
+ "\u0918\u091F\u093E\u090F\u0902",
586
+ "\u0918\u091F\u093E",
587
+ "\u091F\u094D\u0930\u093F\u0917\u0930",
588
+ "\u092D\u0947\u091C\u0947\u0902",
589
+ "\u092D\u0947\u091C",
590
+ "\u0905\u0917\u0930",
591
+ "\u092F\u0926\u093F",
592
+ "\u0935\u0930\u0928\u093E",
593
+ "\u0928\u0939\u0940\u0902 \u0924\u094B",
594
+ "\u0926\u094B\u0939\u0930\u093E\u090F\u0902",
595
+ "\u0926\u094B\u0939\u0930\u093E",
596
+ "\u092A\u094D\u0930\u0924\u0940\u0915\u094D\u0937\u093E",
597
+ "\u0930\u0941\u0915\u0947\u0902",
598
+ "\u091C\u092C \u0924\u0915"
599
+ ]);
600
+ var BENGALI_KEYWORDS = /* @__PURE__ */ new Set([
601
+ "\u099F\u0997\u09B2",
602
+ "\u09AA\u09B0\u09BF\u09AC\u09B0\u09CD\u09A4\u09A8",
603
+ "\u09AF\u09CB\u0997",
604
+ "\u09AF\u09CB\u0997 \u0995\u09B0\u09C1\u09A8",
605
+ "\u09B8\u09B0\u09BE\u09A8",
606
+ "\u09B8\u09B0\u09BF\u09AF\u09BC\u09C7 \u09AB\u09C7\u09B2\u09C1\u09A8",
607
+ "\u09AE\u09C1\u099B\u09C1\u09A8",
608
+ "\u09A6\u09C7\u0996\u09BE\u09A8",
609
+ "\u09A6\u09C7\u0996\u09BE\u0993",
610
+ "\u09B2\u09C1\u0995\u09BE\u09A8",
611
+ "\u09B2\u09C1\u0995\u09BE\u0993",
612
+ "\u09B8\u09C7\u099F",
613
+ "\u09A8\u09BF\u09B0\u09CD\u09A7\u09BE\u09B0\u09A3",
614
+ "\u09AC\u09C3\u09A6\u09CD\u09A7\u09BF",
615
+ "\u09AC\u09BE\u09A1\u09BC\u09BE\u09A8",
616
+ "\u09B9\u09CD\u09B0\u09BE\u09B8",
617
+ "\u0995\u09AE\u09BE\u09A8",
618
+ "\u099F\u09CD\u09B0\u09BF\u0997\u09BE\u09B0",
619
+ "\u09AA\u09BE\u09A0\u09BE\u09A8",
620
+ "\u09AA\u09BE\u09A0\u09BE\u0993",
621
+ "\u09AF\u09A6\u09BF",
622
+ "\u09A8\u09A4\u09C1\u09AC\u09BE",
623
+ "\u09A8\u09BE \u09B9\u09B2\u09C7",
624
+ "\u09AA\u09C1\u09A8\u09B0\u09BE\u09AC\u09C3\u09A4\u09CD\u09A4\u09BF",
625
+ "\u09AC\u09BE\u09B0 \u09AC\u09BE\u09B0",
626
+ "\u0985\u09AA\u09C7\u0995\u09CD\u09B7\u09BE",
627
+ "\u09A5\u09BE\u09AE\u09C1\u09A8",
628
+ "\u09AF\u09A4\u0995\u09CD\u09B7\u09A3"
629
+ ]);
630
+ var THAI_KEYWORDS = /* @__PURE__ */ new Set([
631
+ "\u0E2A\u0E25\u0E31\u0E1A",
632
+ "\u0E40\u0E1E\u0E34\u0E48\u0E21",
633
+ "\u0E25\u0E1A",
634
+ "\u0E25\u0E1A\u0E2D\u0E2D\u0E01",
635
+ "\u0E41\u0E2A\u0E14\u0E07",
636
+ "\u0E0B\u0E48\u0E2D\u0E19",
637
+ "\u0E15\u0E31\u0E49\u0E07",
638
+ "\u0E01\u0E33\u0E2B\u0E19\u0E14",
639
+ "\u0E40\u0E1E\u0E34\u0E48\u0E21\u0E04\u0E48\u0E32",
640
+ "\u0E25\u0E14\u0E04\u0E48\u0E32",
641
+ "\u0E17\u0E23\u0E34\u0E01\u0E40\u0E01\u0E2D\u0E23\u0E4C",
642
+ "\u0E2A\u0E48\u0E07",
643
+ "\u0E16\u0E49\u0E32",
644
+ "\u0E2B\u0E32\u0E01",
645
+ "\u0E44\u0E21\u0E48\u0E07\u0E31\u0E49\u0E19",
646
+ "\u0E44\u0E21\u0E48\u0E40\u0E0A\u0E48\u0E19\u0E19\u0E31\u0E49\u0E19",
647
+ "\u0E17\u0E33\u0E0B\u0E49\u0E33",
648
+ "\u0E23\u0E2D",
649
+ "\u0E43\u0E19\u0E02\u0E13\u0E30\u0E17\u0E35\u0E48"
650
+ ]);
651
+ var TL_KEYWORDS = /* @__PURE__ */ new Set([
652
+ "palitan",
653
+ "itoggle",
654
+ "idagdag",
655
+ "magdagdag",
656
+ "alisin",
657
+ "tanggalin",
658
+ "ipakita",
659
+ "magpakita",
660
+ "itago",
661
+ "magtago",
662
+ "itakda",
663
+ "magtakda",
664
+ "dagdagan",
665
+ "taasan",
666
+ "bawasan",
667
+ "ibaba",
668
+ "magpatugtog",
669
+ "ipadala",
670
+ "magpadala",
671
+ "kung",
672
+ "kapag",
673
+ "kung_hindi",
674
+ "kundi",
675
+ "ulitin",
676
+ "paulit-ulit",
677
+ "maghintay",
678
+ "hintay",
679
+ "habang"
680
+ ]);
681
+ var LANGUAGE_KEYWORDS = {
682
+ en: /* @__PURE__ */ new Set(),
683
+ // English is the default, no detection needed
684
+ ja: JAPANESE_KEYWORDS,
685
+ ko: KOREAN_KEYWORDS,
686
+ zh: CHINESE_KEYWORDS,
687
+ ar: ARABIC_KEYWORDS,
688
+ es: SPANISH_KEYWORDS,
689
+ pt: PORTUGUESE_KEYWORDS,
690
+ fr: FRENCH_KEYWORDS,
691
+ de: GERMAN_KEYWORDS,
692
+ it: ITALIAN_KEYWORDS,
693
+ vi: VIETNAMESE_KEYWORDS,
694
+ pl: POLISH_KEYWORDS,
695
+ ru: RUSSIAN_KEYWORDS,
696
+ uk: UKRAINIAN_KEYWORDS,
697
+ hi: HINDI_KEYWORDS,
698
+ bn: BENGALI_KEYWORDS,
699
+ th: THAI_KEYWORDS,
700
+ tr: TURKISH_KEYWORDS,
701
+ id: INDONESIAN_KEYWORDS,
702
+ sw: SWAHILI_KEYWORDS,
703
+ qu: QUECHUA_KEYWORDS,
704
+ tl: TL_KEYWORDS
705
+ };
706
+ function containsLanguageKeywords(script, language) {
707
+ const keywords = LANGUAGE_KEYWORDS[language];
708
+ if (!keywords || keywords.size === 0) return false;
709
+ const nonLatinLangs = ["ja", "ko", "zh", "ar", "ru", "uk", "hi", "bn", "th"];
710
+ if (nonLatinLangs.includes(language)) {
711
+ for (const keyword of keywords) {
712
+ if (script.includes(keyword)) {
713
+ return true;
714
+ }
715
+ }
716
+ return false;
717
+ }
718
+ const lowerScript = script.toLowerCase();
719
+ for (const keyword of keywords) {
720
+ if (keyword.length <= 2) continue;
721
+ const pattern = new RegExp(`\\b${escapeRegExp(keyword.toLowerCase())}\\b`);
722
+ if (pattern.test(lowerScript)) {
723
+ return true;
724
+ }
725
+ }
726
+ return false;
727
+ }
728
+ function escapeRegExp(str) {
729
+ return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
730
+ }
731
+ function detectLanguages(script) {
732
+ const detected = /* @__PURE__ */ new Set();
733
+ for (const lang of SUPPORTED_LANGUAGES) {
734
+ if (lang === "en") continue;
735
+ if (containsLanguageKeywords(script, lang)) {
736
+ detected.add(lang);
737
+ }
738
+ }
739
+ return detected;
740
+ }
741
+ var customKeywordRegistry = /* @__PURE__ */ new Map();
742
+ function registerCustomKeywords(code, config) {
743
+ const existing = LANGUAGE_KEYWORDS[code];
744
+ const nonLatinLangs = ["ja", "ko", "zh", "ar", "ru", "uk", "hi", "bn", "th"];
745
+ const isNonLatin = config.isNonLatin ?? nonLatinLangs.includes(code);
746
+ if (config.extend && existing) {
747
+ const merged = /* @__PURE__ */ new Set([...existing, ...config.keywords]);
748
+ customKeywordRegistry.set(code, { keywords: merged, isNonLatin });
749
+ } else {
750
+ customKeywordRegistry.set(code, { keywords: config.keywords, isNonLatin });
751
+ }
752
+ }
753
+ function getKeywordsForLanguage(code) {
754
+ const custom = customKeywordRegistry.get(code);
755
+ if (custom) return custom.keywords;
756
+ return LANGUAGE_KEYWORDS[code];
757
+ }
758
+ function isNonLatinLanguage(code) {
759
+ const custom = customKeywordRegistry.get(code);
760
+ if (custom) return custom.isNonLatin;
761
+ const nonLatinLangs = ["ja", "ko", "zh", "ar", "ru", "uk", "hi", "bn", "th"];
762
+ return nonLatinLangs.includes(code);
763
+ }
764
+ function getAllLanguageCodes() {
765
+ const builtin = [...SUPPORTED_LANGUAGES];
766
+ const custom = [...customKeywordRegistry.keys()];
767
+ return [.../* @__PURE__ */ new Set([...builtin, ...custom])];
768
+ }
769
+ function clearCustomKeywords() {
770
+ customKeywordRegistry.clear();
771
+ }
772
+ function getOptimalRegion(languages) {
773
+ if (languages.size === 0) return null;
774
+ const langArray = [...languages];
775
+ if (langArray.every((l) => REGIONS.western.includes(l))) {
776
+ return "western";
777
+ }
778
+ if (langArray.every((l) => REGIONS["east-asian"].includes(l))) {
779
+ return "east-asian";
780
+ }
781
+ if (langArray.every((l) => REGIONS.slavic.includes(l))) {
782
+ return "slavic";
783
+ }
784
+ if (langArray.every((l) => REGIONS["south-asian"].includes(l))) {
785
+ return "south-asian";
786
+ }
787
+ if (langArray.every((l) => REGIONS.priority.includes(l))) {
788
+ return "priority";
789
+ }
790
+ return "all";
791
+ }
792
+
793
+ // src/scanner.ts
794
+ var HTMX_REQUEST_PATTERN = /\b(hx-get|hx-post|hx-put|hx-patch|hx-delete)\s*=\s*["']([^"']+)["']/gi;
795
+ var FIXI_ACTION_PATTERN = /\bfx-action\s*=\s*["']([^"']+)["']/gi;
796
+ var FIXI_METHOD_PATTERN = /\bfx-method\s*=\s*["'](GET|POST|PUT|PATCH|DELETE)["']/gi;
797
+ var HTMX_SWAP_PATTERN = /\b(hx-swap|fx-swap)\s*=\s*["']([^"']+)["']/gi;
798
+ var HTMX_TARGET_PATTERN = /\b(hx-target|fx-target)\s*=\s*["']([^"']+)["']/gi;
799
+ var HTMX_TRIGGER_PATTERN = /\b(hx-trigger|fx-trigger)\s*=\s*["']([^"']+)["']/gi;
800
+ var HTMX_URL_PATTERN = /\b(hx-push-url|hx-replace-url)\s*=\s*["'][^"']+["']/gi;
801
+ var HTMX_CONFIRM_PATTERN = /\bhx-confirm\s*=\s*["']/gi;
802
+ var HTMX_ON_PATTERN = /\bhx-on:(\w+)\s*=\s*["']([^"']+)["']/g;
803
+ function toRegex(pattern, defaultPattern) {
804
+ if (!pattern) return defaultPattern;
805
+ if (pattern instanceof RegExp) return pattern;
806
+ if (Array.isArray(pattern)) {
807
+ const escaped = pattern.map((p) => p.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
808
+ return new RegExp(`(${escaped.join("|")})`);
809
+ }
810
+ return defaultPattern;
811
+ }
812
+ var Scanner = class {
813
+ constructor(options) {
814
+ this.include = toRegex(
815
+ options.include,
816
+ /\.(html?|vue|svelte|jsx?|tsx?|astro|php|erb|ejs|hbs|handlebars)$/
817
+ );
818
+ this.exclude = toRegex(options.exclude, /node_modules|\.git/);
819
+ this.debug = options.debug ?? false;
820
+ }
821
+ /**
822
+ * Check if a file should be scanned
823
+ */
824
+ shouldScan(id) {
825
+ return this.include.test(id) && !this.exclude.test(id);
826
+ }
827
+ /**
828
+ * Scan code for hyperscript usage
829
+ */
830
+ scan(code, id) {
831
+ const usage = {
832
+ commands: /* @__PURE__ */ new Set(),
833
+ blocks: /* @__PURE__ */ new Set(),
834
+ positional: false,
835
+ detectedLanguages: /* @__PURE__ */ new Set()
836
+ };
837
+ const attrPatterns = [
838
+ /_\s*=\s*"([^"]+)"/g,
839
+ // _="..."
840
+ /_\s*=\s*'([^']+)'/g,
841
+ // _='...'
842
+ /_\s*=\s*`([^`]+)`/g,
843
+ // _=`...`
844
+ /_=\{`([^`]+)`\}/g,
845
+ // _={`...`} (JSX)
846
+ /_=\{['"]([^'"]+)['"]\}/g
847
+ // _={"..."} or _={'...'} (JSX)
848
+ ];
849
+ for (const pattern of attrPatterns) {
850
+ let match2;
851
+ while (match2 = pattern.exec(code)) {
852
+ this.analyzeScript(match2[1], usage);
853
+ }
854
+ }
855
+ const scriptPattern = /<script[^>]*type=["']?text\/hyperscript["']?[^>]*>([^<]+)<\/script>/gi;
856
+ let match;
857
+ while (match = scriptPattern.exec(code)) {
858
+ this.analyzeScript(match[1], usage);
859
+ }
860
+ const htmxUsage = this.scanHtmxAttributes(code);
861
+ if (htmxUsage.hasHtmxAttributes) {
862
+ usage.htmx = htmxUsage;
863
+ this.inferCommandsFromHtmx(htmxUsage, usage);
864
+ for (const handlerCode of htmxUsage.onHandlers) {
865
+ this.analyzeScript(handlerCode, usage);
866
+ }
867
+ if (/hx-target\s*=\s*["'](closest|next|previous|find)\s/i.test(code)) {
868
+ usage.positional = true;
869
+ }
870
+ }
871
+ if (this.debug && (usage.commands.size > 0 || usage.blocks.size > 0 || usage.detectedLanguages.size > 0 || usage.htmx?.hasHtmxAttributes)) {
872
+ console.log(`[hyperfixi] Scanned ${id}:`, {
873
+ commands: [...usage.commands],
874
+ blocks: [...usage.blocks],
875
+ positional: usage.positional,
876
+ languages: [...usage.detectedLanguages],
877
+ htmx: usage.htmx ? {
878
+ hasHtmxAttributes: usage.htmx.hasHtmxAttributes,
879
+ hasFixiAttributes: usage.htmx.hasFixiAttributes,
880
+ httpMethods: [...usage.htmx.httpMethods],
881
+ swapStrategies: [...usage.htmx.swapStrategies]
882
+ } : void 0
883
+ });
884
+ }
885
+ return usage;
886
+ }
887
+ /**
888
+ * Analyze a hyperscript snippet for commands, blocks, and expressions
889
+ */
890
+ analyzeScript(script, usage) {
891
+ const commandPattern = /\b(toggle|add|remove|removeClass|show|hide|set|get|put|append|take|increment|decrement|log|send|trigger|wait|transition|go|call|focus|blur|return)\b/g;
892
+ let match;
893
+ while (match = commandPattern.exec(script)) {
894
+ usage.commands.add(match[1]);
895
+ }
896
+ if (/\bif\b/.test(script)) usage.blocks.add("if");
897
+ if (/\bunless\b/.test(script)) usage.blocks.add("if");
898
+ if (/\brepeat\s+(\d+|:\w+|\$\w+|[\w.]+)\s+times?\b/i.test(script)) usage.blocks.add("repeat");
899
+ if (/\bfor\s+(each|every)\b/i.test(script)) usage.blocks.add("for");
900
+ if (/\bwhile\b/.test(script)) usage.blocks.add("while");
901
+ if (/\bfetch\b/.test(script)) usage.blocks.add("fetch");
902
+ if (/\b(first|last|next|previous|closest|parent)\b/.test(script)) {
903
+ usage.positional = true;
904
+ }
905
+ const languages = detectLanguages(script);
906
+ for (const lang of languages) {
907
+ usage.detectedLanguages.add(lang);
908
+ }
909
+ }
910
+ /**
911
+ * Scan for htmx/fixi attributes
912
+ */
913
+ scanHtmxAttributes(code) {
914
+ const usage = {
915
+ hasHtmxAttributes: false,
916
+ hasFixiAttributes: false,
917
+ httpMethods: /* @__PURE__ */ new Set(),
918
+ swapStrategies: /* @__PURE__ */ new Set(),
919
+ onHandlers: [],
920
+ triggerModifiers: /* @__PURE__ */ new Set(),
921
+ urlManagement: /* @__PURE__ */ new Set(),
922
+ usesConfirm: false
923
+ };
924
+ let match;
925
+ const requestPattern = new RegExp(HTMX_REQUEST_PATTERN.source, "gi");
926
+ while (match = requestPattern.exec(code)) {
927
+ usage.hasHtmxAttributes = true;
928
+ usage.httpMethods.add(match[1].replace("hx-", "").toUpperCase());
929
+ }
930
+ if (new RegExp(FIXI_ACTION_PATTERN.source, "gi").test(code)) {
931
+ usage.hasHtmxAttributes = true;
932
+ usage.hasFixiAttributes = true;
933
+ }
934
+ const fixiMethodPattern = new RegExp(FIXI_METHOD_PATTERN.source, "gi");
935
+ while (match = fixiMethodPattern.exec(code)) {
936
+ usage.hasHtmxAttributes = true;
937
+ usage.hasFixiAttributes = true;
938
+ usage.httpMethods.add(match[1].toUpperCase());
939
+ }
940
+ const swapPattern = new RegExp(HTMX_SWAP_PATTERN.source, "gi");
941
+ while (match = swapPattern.exec(code)) {
942
+ usage.hasHtmxAttributes = true;
943
+ usage.swapStrategies.add(match[2].split(/\s+/)[0]);
944
+ }
945
+ const triggerPattern = new RegExp(HTMX_TRIGGER_PATTERN.source, "gi");
946
+ while (match = triggerPattern.exec(code)) {
947
+ usage.hasHtmxAttributes = true;
948
+ const trigger = match[2];
949
+ if (/delay:/i.test(trigger)) usage.triggerModifiers.add("debounce");
950
+ if (/throttle:/i.test(trigger)) usage.triggerModifiers.add("throttle");
951
+ if (/\bonce\b/i.test(trigger)) usage.triggerModifiers.add("once");
952
+ }
953
+ if (new RegExp(HTMX_URL_PATTERN.source, "gi").test(code)) {
954
+ usage.hasHtmxAttributes = true;
955
+ if (/hx-push-url/i.test(code)) usage.urlManagement.add("push-url");
956
+ if (/hx-replace-url/i.test(code)) usage.urlManagement.add("replace-url");
957
+ }
958
+ if (new RegExp(HTMX_CONFIRM_PATTERN.source, "gi").test(code)) {
959
+ usage.hasHtmxAttributes = true;
960
+ usage.usesConfirm = true;
961
+ }
962
+ const onPattern = new RegExp(HTMX_ON_PATTERN.source, "g");
963
+ while (match = onPattern.exec(code)) {
964
+ usage.hasHtmxAttributes = true;
965
+ usage.onHandlers.push(match[2]);
966
+ }
967
+ const targetPattern = new RegExp(HTMX_TARGET_PATTERN.source, "gi");
968
+ while (match = targetPattern.exec(code)) {
969
+ usage.hasHtmxAttributes = true;
970
+ }
971
+ return usage;
972
+ }
973
+ /**
974
+ * Infer commands from htmx usage
975
+ */
976
+ inferCommandsFromHtmx(htmx, usage) {
977
+ if (htmx.httpMethods.size > 0) {
978
+ usage.blocks.add("fetch");
979
+ usage.commands.add("put");
980
+ }
981
+ for (const swap of htmx.swapStrategies) {
982
+ switch (swap.toLowerCase()) {
983
+ case "morph":
984
+ usage.commands.add("morph");
985
+ break;
986
+ case "delete":
987
+ usage.commands.add("remove");
988
+ break;
989
+ default:
990
+ usage.commands.add("put");
991
+ }
992
+ }
993
+ if (htmx.usesConfirm) {
994
+ usage.blocks.add("if");
995
+ }
996
+ }
997
+ /**
998
+ * Scan all files in a project directory
999
+ * Used during production build to scan the entire codebase
1000
+ */
1001
+ async scanProject(dir) {
1002
+ const results = /* @__PURE__ */ new Map();
1003
+ try {
1004
+ const { glob } = await import("glob");
1005
+ const fs = await import("fs");
1006
+ const files = await glob("**/*.{html,htm,vue,svelte,js,jsx,ts,tsx,astro,php,erb,ejs,hbs}", {
1007
+ cwd: dir,
1008
+ ignore: ["node_modules/**", "dist/**", ".git/**"],
1009
+ absolute: true
1010
+ });
1011
+ for (const file of files) {
1012
+ if (this.shouldScan(file)) {
1013
+ try {
1014
+ const code = fs.readFileSync(file, "utf-8");
1015
+ const usage = this.scan(code, file);
1016
+ if (usage.commands.size > 0 || usage.blocks.size > 0 || usage.positional || usage.detectedLanguages.size > 0) {
1017
+ results.set(file, usage);
1018
+ }
1019
+ } catch {
1020
+ }
1021
+ }
1022
+ }
1023
+ } catch (error) {
1024
+ console.warn("[hyperfixi] Error scanning project:", error);
1025
+ }
1026
+ return results;
1027
+ }
1028
+ };
1029
+
1030
+ // src/aggregator.ts
1031
+ var Aggregator = class {
1032
+ constructor() {
1033
+ this.fileUsage = /* @__PURE__ */ new Map();
1034
+ this.cachedUsage = null;
1035
+ }
1036
+ /**
1037
+ * Add or update usage for a file
1038
+ * @returns true if the overall usage changed
1039
+ */
1040
+ add(filePath, usage) {
1041
+ const existing = this.fileUsage.get(filePath);
1042
+ if (existing) {
1043
+ const commandsEqual = this.setsEqual(existing.commands, usage.commands);
1044
+ const blocksEqual = this.setsEqual(existing.blocks, usage.blocks);
1045
+ const positionalEqual = existing.positional === usage.positional;
1046
+ const languagesEqual = this.setsEqual(existing.detectedLanguages, usage.detectedLanguages);
1047
+ const htmxEqual = this.htmxUsageEqual(existing.htmx, usage.htmx);
1048
+ if (commandsEqual && blocksEqual && positionalEqual && languagesEqual && htmxEqual) {
1049
+ return false;
1050
+ }
1051
+ }
1052
+ this.fileUsage.set(filePath, usage);
1053
+ this.cachedUsage = null;
1054
+ return true;
1055
+ }
1056
+ /**
1057
+ * Remove a file from tracking (e.g., when deleted)
1058
+ * @returns true if the overall usage changed
1059
+ */
1060
+ remove(filePath) {
1061
+ const existed = this.fileUsage.delete(filePath);
1062
+ if (existed) {
1063
+ this.cachedUsage = null;
1064
+ }
1065
+ return existed;
1066
+ }
1067
+ /**
1068
+ * Get aggregated usage across all files
1069
+ */
1070
+ getUsage() {
1071
+ if (this.cachedUsage) {
1072
+ return this.cachedUsage;
1073
+ }
1074
+ const commands = /* @__PURE__ */ new Set();
1075
+ const blocks = /* @__PURE__ */ new Set();
1076
+ const detectedLanguages = /* @__PURE__ */ new Set();
1077
+ let positional = false;
1078
+ const htmx = {
1079
+ hasHtmxAttributes: false,
1080
+ hasFixiAttributes: false,
1081
+ httpMethods: /* @__PURE__ */ new Set(),
1082
+ swapStrategies: /* @__PURE__ */ new Set(),
1083
+ onHandlers: [],
1084
+ triggerModifiers: /* @__PURE__ */ new Set(),
1085
+ urlManagement: /* @__PURE__ */ new Set(),
1086
+ usesConfirm: false
1087
+ };
1088
+ for (const usage of this.fileUsage.values()) {
1089
+ for (const cmd of usage.commands) commands.add(cmd);
1090
+ for (const block of usage.blocks) blocks.add(block);
1091
+ for (const lang of usage.detectedLanguages) detectedLanguages.add(lang);
1092
+ if (usage.positional) positional = true;
1093
+ if (usage.htmx) {
1094
+ if (usage.htmx.hasHtmxAttributes) htmx.hasHtmxAttributes = true;
1095
+ if (usage.htmx.hasFixiAttributes) htmx.hasFixiAttributes = true;
1096
+ for (const method of usage.htmx.httpMethods) htmx.httpMethods.add(method);
1097
+ for (const swap of usage.htmx.swapStrategies) htmx.swapStrategies.add(swap);
1098
+ htmx.onHandlers.push(...usage.htmx.onHandlers);
1099
+ for (const modifier of usage.htmx.triggerModifiers) htmx.triggerModifiers.add(modifier);
1100
+ for (const url of usage.htmx.urlManagement) htmx.urlManagement.add(url);
1101
+ if (usage.htmx.usesConfirm) htmx.usesConfirm = true;
1102
+ }
1103
+ }
1104
+ this.cachedUsage = {
1105
+ commands,
1106
+ blocks,
1107
+ positional,
1108
+ detectedLanguages,
1109
+ htmx,
1110
+ fileUsage: new Map(this.fileUsage)
1111
+ };
1112
+ return this.cachedUsage;
1113
+ }
1114
+ /**
1115
+ * Load usage from a project scan
1116
+ */
1117
+ loadFromScan(scannedFiles) {
1118
+ this.fileUsage = new Map(scannedFiles);
1119
+ this.cachedUsage = null;
1120
+ }
1121
+ /**
1122
+ * Check if any hyperscript usage has been detected
1123
+ */
1124
+ hasUsage() {
1125
+ const usage = this.getUsage();
1126
+ return usage.commands.size > 0 || usage.blocks.size > 0 || usage.positional || usage.detectedLanguages.size > 0;
1127
+ }
1128
+ /**
1129
+ * Get summary for logging
1130
+ */
1131
+ getSummary() {
1132
+ const usage = this.getUsage();
1133
+ return {
1134
+ commands: [...usage.commands].sort(),
1135
+ blocks: [...usage.blocks].sort(),
1136
+ positional: usage.positional,
1137
+ languages: [...usage.detectedLanguages].sort(),
1138
+ fileCount: this.fileUsage.size
1139
+ };
1140
+ }
1141
+ /**
1142
+ * Clear all tracked usage
1143
+ */
1144
+ clear() {
1145
+ this.fileUsage.clear();
1146
+ this.cachedUsage = null;
1147
+ }
1148
+ /**
1149
+ * Compare two sets for equality
1150
+ */
1151
+ setsEqual(a, b) {
1152
+ if (a.size !== b.size) return false;
1153
+ for (const item of a) {
1154
+ if (!b.has(item)) return false;
1155
+ }
1156
+ return true;
1157
+ }
1158
+ /**
1159
+ * Compare two HtmxUsage objects for equality
1160
+ */
1161
+ htmxUsageEqual(a, b) {
1162
+ if (!a && !b) return true;
1163
+ if (!a || !b) return false;
1164
+ return a.hasHtmxAttributes === b.hasHtmxAttributes && a.hasFixiAttributes === b.hasFixiAttributes && this.setsEqual(a.httpMethods, b.httpMethods) && this.setsEqual(a.swapStrategies, b.swapStrategies) && this.setsEqual(a.triggerModifiers, b.triggerModifiers) && this.setsEqual(a.urlManagement, b.urlManagement) && a.usesConfirm === b.usesConfirm;
1165
+ }
1166
+ };
1167
+
1168
+ // src/generator.ts
1169
+ import {
1170
+ COMMAND_IMPLEMENTATIONS as COMMAND_IMPL_TS,
1171
+ BLOCK_IMPLEMENTATIONS as BLOCK_IMPL_TS,
1172
+ STYLE_COMMANDS,
1173
+ ELEMENT_ARRAY_COMMANDS,
1174
+ MORPH_COMMANDS,
1175
+ LITE_PARSER_TEMPLATE,
1176
+ HYBRID_PARSER_TEMPLATE,
1177
+ canUseLiteParser,
1178
+ FULL_RUNTIME_ONLY_COMMANDS,
1179
+ isAvailableCommand
1180
+ } from "@hyperfixi/core/bundle-generator";
1181
+
1182
+ // src/semantic-integration.ts
1183
+ var MULTILINGUAL_COMMAND_ALIASES = {
1184
+ ja: {
1185
+ \u30C8\u30B0\u30EB: "toggle",
1186
+ \u5207\u308A\u66FF\u3048: "toggle",
1187
+ \u8FFD\u52A0: "add",
1188
+ \u524A\u9664: "remove",
1189
+ \u8868\u793A: "show",
1190
+ \u96A0\u3059: "hide",
1191
+ \u975E\u8868\u793A: "hide",
1192
+ \u8A2D\u5B9A: "set",
1193
+ \u30BB\u30C3\u30C8: "set",
1194
+ \u5897\u52A0: "increment",
1195
+ \u6E1B\u5C11: "decrement",
1196
+ \u30ED\u30B0: "log",
1197
+ \u51FA\u529B: "log"
1198
+ },
1199
+ ko: {
1200
+ \uD1A0\uAE00: "toggle",
1201
+ \uC804\uD658: "toggle",
1202
+ \uCD94\uAC00: "add",
1203
+ \uC81C\uAC70: "remove",
1204
+ \uC0AD\uC81C: "remove",
1205
+ \uD45C\uC2DC: "show",
1206
+ \uC228\uAE30\uB2E4: "hide",
1207
+ \uC124\uC815: "set",
1208
+ \uC99D\uAC00: "increment",
1209
+ \uAC10\uC18C: "decrement",
1210
+ \uB85C\uADF8: "log"
1211
+ },
1212
+ zh: {
1213
+ \u5207\u6362: "toggle",
1214
+ \u6DFB\u52A0: "add",
1215
+ \u79FB\u9664: "remove",
1216
+ \u5220\u9664: "remove",
1217
+ \u663E\u793A: "show",
1218
+ \u9690\u85CF: "hide",
1219
+ \u8BBE\u7F6E: "set",
1220
+ \u8BBE\u5B9A: "set",
1221
+ \u589E\u52A0: "increment",
1222
+ \u51CF\u5C11: "decrement",
1223
+ \u65E5\u5FD7: "log",
1224
+ \u8BB0\u5F55: "log"
1225
+ },
1226
+ ar: {
1227
+ \u0628\u062F\u0651\u0644: "toggle",
1228
+ \u0628\u062F\u0644: "toggle",
1229
+ \u0623\u0636\u0641: "add",
1230
+ \u0627\u0636\u0641: "add",
1231
+ \u0623\u0632\u0644: "remove",
1232
+ \u0627\u0632\u0644: "remove",
1233
+ \u0627\u062D\u0630\u0641: "remove",
1234
+ \u0623\u0638\u0647\u0631: "show",
1235
+ \u0627\u0638\u0647\u0631: "show",
1236
+ \u0623\u062E\u0641\u0650: "hide",
1237
+ \u0627\u062E\u0641: "hide",
1238
+ \u0636\u0639: "set",
1239
+ \u0627\u0636\u0639: "set",
1240
+ \u0632\u0650\u062F: "increment",
1241
+ \u0623\u0646\u0642\u0635: "decrement"
1242
+ },
1243
+ es: {
1244
+ alternar: "toggle",
1245
+ a\u00F1adir: "add",
1246
+ agregar: "add",
1247
+ quitar: "remove",
1248
+ eliminar: "remove",
1249
+ mostrar: "show",
1250
+ ocultar: "hide",
1251
+ esconder: "hide",
1252
+ establecer: "set",
1253
+ fijar: "set",
1254
+ incrementar: "increment",
1255
+ decrementar: "decrement"
1256
+ },
1257
+ pt: {
1258
+ alternar: "toggle",
1259
+ adicionar: "add",
1260
+ remover: "remove",
1261
+ mostrar: "show",
1262
+ esconder: "hide",
1263
+ ocultar: "hide",
1264
+ definir: "set",
1265
+ incrementar: "increment",
1266
+ decrementar: "decrement"
1267
+ },
1268
+ fr: {
1269
+ basculer: "toggle",
1270
+ ajouter: "add",
1271
+ supprimer: "remove",
1272
+ retirer: "remove",
1273
+ afficher: "show",
1274
+ montrer: "show",
1275
+ cacher: "hide",
1276
+ masquer: "hide",
1277
+ d\u00E9finir: "set",
1278
+ incr\u00E9menter: "increment",
1279
+ d\u00E9cr\u00E9menter: "decrement"
1280
+ },
1281
+ de: {
1282
+ umschalten: "toggle",
1283
+ hinzuf\u00FCgen: "add",
1284
+ entfernen: "remove",
1285
+ l\u00F6schen: "remove",
1286
+ anzeigen: "show",
1287
+ zeigen: "show",
1288
+ verbergen: "hide",
1289
+ verstecken: "hide",
1290
+ setzen: "set",
1291
+ festlegen: "set",
1292
+ erh\u00F6hen: "increment",
1293
+ verringern: "decrement"
1294
+ },
1295
+ tr: {
1296
+ de\u011Fi\u015Ftir: "toggle",
1297
+ de\u011Fistir: "toggle",
1298
+ ekle: "add",
1299
+ kald\u0131r: "remove",
1300
+ kaldir: "remove",
1301
+ sil: "remove",
1302
+ g\u00F6ster: "show",
1303
+ gizle: "hide",
1304
+ sakla: "hide",
1305
+ ayarla: "set",
1306
+ belirle: "set",
1307
+ artt\u0131r: "increment",
1308
+ azalt: "decrement"
1309
+ },
1310
+ id: {
1311
+ alih: "toggle",
1312
+ beralih: "toggle",
1313
+ tambah: "add",
1314
+ hapus: "remove",
1315
+ buang: "remove",
1316
+ tampilkan: "show",
1317
+ sembunyikan: "hide",
1318
+ atur: "set",
1319
+ tetapkan: "set",
1320
+ tambahkan: "increment",
1321
+ kurangi: "decrement"
1322
+ },
1323
+ sw: {
1324
+ badilisha: "toggle",
1325
+ ongeza: "add",
1326
+ ondoa: "remove",
1327
+ futa: "remove",
1328
+ onyesha: "show",
1329
+ ficha: "hide",
1330
+ weka: "set",
1331
+ sanidi: "set",
1332
+ ongezea: "increment",
1333
+ punguza: "decrement"
1334
+ },
1335
+ qu: {
1336
+ tikray: "toggle",
1337
+ yapay: "add",
1338
+ qichuy: "remove",
1339
+ pichay: "remove",
1340
+ rikuchiy: "show",
1341
+ pakay: "hide",
1342
+ churay: "set",
1343
+ pisiyachiy: "decrement"
1344
+ }
1345
+ };
1346
+ function getMultilingualCommandAliases(languages) {
1347
+ const aliases = {};
1348
+ for (const lang of languages) {
1349
+ const langAliases = MULTILINGUAL_COMMAND_ALIASES[lang];
1350
+ if (langAliases) {
1351
+ Object.assign(aliases, langAliases);
1352
+ }
1353
+ }
1354
+ return aliases;
1355
+ }
1356
+ function generateMultilingualAliases(languages) {
1357
+ const aliases = {};
1358
+ for (const lang of languages) {
1359
+ const langAliases = MULTILINGUAL_COMMAND_ALIASES[lang];
1360
+ if (langAliases) {
1361
+ Object.assign(aliases, langAliases);
1362
+ }
1363
+ }
1364
+ if (Object.keys(aliases).length === 0) {
1365
+ return `
1366
+ // No multilingual aliases needed - just pass through
1367
+ function preprocessMultilingual(code) { return code; }
1368
+ `;
1369
+ }
1370
+ const aliasEntries = Object.entries(aliases).map(([key, val]) => ` '${key}': '${val}'`).join(",\n");
1371
+ const escapedKeys = Object.keys(aliases).map((k) => k.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|");
1372
+ return `
1373
+ // Multilingual command aliases for HybridParser fallback
1374
+ const MULTILINGUAL_ALIASES = {
1375
+ ${aliasEntries}
1376
+ };
1377
+
1378
+ // Register multilingual aliases with the parser
1379
+ addCommandAliases(MULTILINGUAL_ALIASES);
1380
+
1381
+ // Preprocessing regex to translate multilingual keywords to English
1382
+ // The HybridParser tokenizer only accepts ASCII identifiers, so we need
1383
+ // to translate non-ASCII keywords before parsing.
1384
+ const MULTILINGUAL_KEYWORD_REGEX = new RegExp('(^|\\\\s)(${escapedKeys})(?=\\\\s|\\\\.|$)', 'g');
1385
+
1386
+ /**
1387
+ * Preprocess multilingual code to replace non-ASCII keywords with English equivalents.
1388
+ * This is needed because HybridParser's tokenizer only accepts ASCII identifiers.
1389
+ */
1390
+ function preprocessMultilingual(code) {
1391
+ return code.replace(MULTILINGUAL_KEYWORD_REGEX, (match, prefix, keyword) => {
1392
+ const english = MULTILINGUAL_ALIASES[keyword];
1393
+ return english ? prefix + english : match;
1394
+ });
1395
+ }
1396
+ `;
1397
+ }
1398
+ function resolveSemanticConfig(options, detectedLanguages) {
1399
+ const grammarEnabled = options.grammar ?? false;
1400
+ let semanticEnabled = grammarEnabled;
1401
+ if (options.semantic === true || options.semantic === "auto") {
1402
+ semanticEnabled = true;
1403
+ } else if (options.semantic === "en") {
1404
+ semanticEnabled = true;
1405
+ } else if (options.semantic === false) {
1406
+ semanticEnabled = false;
1407
+ }
1408
+ if (!semanticEnabled) {
1409
+ return {
1410
+ enabled: false,
1411
+ bundleType: null,
1412
+ languages: /* @__PURE__ */ new Set(),
1413
+ grammarEnabled: false
1414
+ };
1415
+ }
1416
+ const languages = /* @__PURE__ */ new Set();
1417
+ for (const lang of detectedLanguages) {
1418
+ languages.add(lang);
1419
+ }
1420
+ if (options.languages) {
1421
+ for (const lang of options.languages) {
1422
+ languages.add(lang);
1423
+ }
1424
+ }
1425
+ if (options.extraLanguages) {
1426
+ for (const lang of options.extraLanguages) {
1427
+ languages.add(lang);
1428
+ }
1429
+ }
1430
+ let bundleType = selectBundleType(options, languages);
1431
+ return {
1432
+ enabled: true,
1433
+ bundleType,
1434
+ languages,
1435
+ grammarEnabled
1436
+ };
1437
+ }
1438
+ function selectBundleType(options, languages) {
1439
+ if (options.region) {
1440
+ return options.region;
1441
+ }
1442
+ if (options.semantic === "en") {
1443
+ return "en";
1444
+ }
1445
+ if (options.languages?.length) {
1446
+ return selectOptimalBundle(new Set(options.languages));
1447
+ }
1448
+ if (languages.size === 0) {
1449
+ return "en";
1450
+ }
1451
+ return selectOptimalBundle(languages);
1452
+ }
1453
+ var SINGLE_LANGUAGE_BUNDLES = [
1454
+ "ar",
1455
+ "bn",
1456
+ "de",
1457
+ "en",
1458
+ "es",
1459
+ "es-MX",
1460
+ "fr",
1461
+ "he",
1462
+ "hi",
1463
+ "id",
1464
+ "it",
1465
+ "ja",
1466
+ "ko",
1467
+ "ms",
1468
+ "pl",
1469
+ "pt",
1470
+ "qu",
1471
+ "ru",
1472
+ "sw",
1473
+ "th",
1474
+ "tl",
1475
+ "tr",
1476
+ "uk",
1477
+ "vi",
1478
+ "zh"
1479
+ ];
1480
+ function selectOptimalBundle(languages) {
1481
+ if (languages.size === 0) {
1482
+ return "en";
1483
+ }
1484
+ const langArray = [...languages];
1485
+ if (langArray.length === 1) {
1486
+ const lang = langArray[0];
1487
+ if (SINGLE_LANGUAGE_BUNDLES.includes(lang)) {
1488
+ return lang;
1489
+ }
1490
+ }
1491
+ if (langArray.length === 2 && langArray.includes("en") && langArray.includes("es")) {
1492
+ return "es-en";
1493
+ }
1494
+ if (langArray.every((l) => REGIONS.western.includes(l))) {
1495
+ return "western";
1496
+ }
1497
+ if (langArray.every((l) => REGIONS["east-asian"].includes(l))) {
1498
+ return "east-asian";
1499
+ }
1500
+ if (langArray.every((l) => REGIONS.priority.includes(l))) {
1501
+ return "priority";
1502
+ }
1503
+ return "all";
1504
+ }
1505
+ var SEMANTIC_BUNDLE_SIZES = {
1506
+ // Single-language bundles (all 25 languages)
1507
+ ar: { raw: "66 KB", gzip: "~17 KB" },
1508
+ bn: { raw: "56 KB", gzip: "~14 KB" },
1509
+ de: { raw: "57 KB", gzip: "~14 KB" },
1510
+ en: { raw: "82 KB", gzip: "~20 KB" },
1511
+ es: { raw: "64 KB", gzip: "~16 KB" },
1512
+ "es-MX": { raw: "64 KB", gzip: "~16 KB" },
1513
+ fr: { raw: "57 KB", gzip: "~14 KB" },
1514
+ he: { raw: "56 KB", gzip: "~14 KB" },
1515
+ hi: { raw: "56 KB", gzip: "~14 KB" },
1516
+ id: { raw: "57 KB", gzip: "~14 KB" },
1517
+ it: { raw: "57 KB", gzip: "~14 KB" },
1518
+ ja: { raw: "67 KB", gzip: "~17 KB" },
1519
+ ko: { raw: "69 KB", gzip: "~18 KB" },
1520
+ ms: { raw: "56 KB", gzip: "~14 KB" },
1521
+ pl: { raw: "56 KB", gzip: "~14 KB" },
1522
+ pt: { raw: "56 KB", gzip: "~14 KB" },
1523
+ qu: { raw: "56 KB", gzip: "~14 KB" },
1524
+ ru: { raw: "56 KB", gzip: "~14 KB" },
1525
+ sw: { raw: "56 KB", gzip: "~14 KB" },
1526
+ th: { raw: "56 KB", gzip: "~14 KB" },
1527
+ tl: { raw: "56 KB", gzip: "~14 KB" },
1528
+ tr: { raw: "73 KB", gzip: "~18 KB" },
1529
+ uk: { raw: "56 KB", gzip: "~14 KB" },
1530
+ vi: { raw: "56 KB", gzip: "~14 KB" },
1531
+ zh: { raw: "58 KB", gzip: "~15 KB" },
1532
+ // Regional bundles
1533
+ "es-en": { raw: "99 KB", gzip: "~25 KB" },
1534
+ western: { raw: "127 KB", gzip: "~30 KB" },
1535
+ "east-asian": { raw: "99 KB", gzip: "~24 KB" },
1536
+ priority: { raw: "231 KB", gzip: "~48 KB" },
1537
+ all: { raw: "324 KB", gzip: "~61 KB" }
1538
+ };
1539
+ function getSemanticBundleSize(bundleType) {
1540
+ return SEMANTIC_BUNDLE_SIZES[bundleType] ?? SEMANTIC_BUNDLE_SIZES.all;
1541
+ }
1542
+ var LANGUAGES_WITH_ESM_EXPORTS = /* @__PURE__ */ new Set([
1543
+ "ar",
1544
+ "bn",
1545
+ "de",
1546
+ "en",
1547
+ "es",
1548
+ "es-MX",
1549
+ "fr",
1550
+ "he",
1551
+ "hi",
1552
+ "id",
1553
+ "it",
1554
+ "ja",
1555
+ "ko",
1556
+ "ms",
1557
+ "pl",
1558
+ "pt",
1559
+ "qu",
1560
+ "ru",
1561
+ "sw",
1562
+ "th",
1563
+ "tl",
1564
+ "tr",
1565
+ "uk",
1566
+ "vi",
1567
+ "zh"
1568
+ ]);
1569
+ function getLanguagesForBundleType(bundleType, configLanguages) {
1570
+ const languages = new Set(configLanguages);
1571
+ switch (bundleType) {
1572
+ case "western":
1573
+ REGIONS.western.forEach((l) => languages.add(l));
1574
+ break;
1575
+ case "east-asian":
1576
+ REGIONS["east-asian"].forEach((l) => languages.add(l));
1577
+ break;
1578
+ case "priority":
1579
+ REGIONS.priority.forEach((l) => languages.add(l));
1580
+ break;
1581
+ case "all":
1582
+ REGIONS.all.forEach((l) => languages.add(l));
1583
+ break;
1584
+ case "es-en":
1585
+ languages.add("en");
1586
+ languages.add("es");
1587
+ break;
1588
+ default:
1589
+ if (typeof bundleType === "string" && bundleType.length <= 3) {
1590
+ languages.add(bundleType);
1591
+ }
1592
+ break;
1593
+ }
1594
+ languages.add("en");
1595
+ return languages;
1596
+ }
1597
+ function filterToAvailableLanguages(languages) {
1598
+ const available = /* @__PURE__ */ new Set();
1599
+ for (const lang of languages) {
1600
+ if (LANGUAGES_WITH_ESM_EXPORTS.has(lang)) {
1601
+ available.add(lang);
1602
+ }
1603
+ }
1604
+ available.add("en");
1605
+ return available;
1606
+ }
1607
+ function generateSemanticIntegrationCode(config) {
1608
+ if (!config.enabled || !config.bundleType) {
1609
+ return "";
1610
+ }
1611
+ const resolvedLanguages = getLanguagesForBundleType(config.bundleType, config.languages);
1612
+ const availableLanguages = filterToAvailableLanguages(resolvedLanguages);
1613
+ const languages = [...config.languages].join("', '");
1614
+ let code = `
1615
+ // =============================================================================
1616
+ // SEMANTIC PARSER INTEGRATION
1617
+ // =============================================================================
1618
+
1619
+ // Core infrastructure (no language data bundled)
1620
+ import {
1621
+ createSemanticAnalyzer,
1622
+ buildAST,
1623
+ isLanguageSupported,
1624
+ } from '@lokascript/semantic/core';
1625
+
1626
+ // Register required languages (self-registering side-effect imports)
1627
+ `;
1628
+ const sortedLangs = [...availableLanguages].sort();
1629
+ for (const lang of sortedLangs) {
1630
+ code += `import '@lokascript/semantic/languages/${lang}';
1631
+ `;
1632
+ }
1633
+ if (config.grammarEnabled) {
1634
+ code += `
1635
+ import { GrammarTransformer, translate } from '@lokascript/i18n';
1636
+
1637
+ const grammarTransformer = new GrammarTransformer();
1638
+ `;
1639
+ }
1640
+ const aliasesCode = generateMultilingualAliases(config.languages);
1641
+ code += `
1642
+ const semanticAnalyzer = createSemanticAnalyzer();
1643
+ const SUPPORTED_SEMANTIC_LANGUAGES = ['${languages}', 'en'];
1644
+ const SEMANTIC_CONFIDENCE_THRESHOLD = 0.7;
1645
+
1646
+ ${aliasesCode}
1647
+
1648
+ /**
1649
+ * Parse hyperscript using semantic parser with auto-language detection.
1650
+ * Tries each supported language until one returns a high-confidence result.
1651
+ * Falls back to HybridParser if none match.
1652
+ *
1653
+ * @param code - The hyperscript code to parse
1654
+ * @param lang - Optional language hint. If provided, tries this language first.
1655
+ */
1656
+ function parseWithSemantic(code, lang = null) {
1657
+ // Determine languages to try: specified lang first, then others
1658
+ let languagesToTry = [...SUPPORTED_SEMANTIC_LANGUAGES];
1659
+ if (lang && !languagesToTry.includes(lang)) {
1660
+ languagesToTry.unshift(lang);
1661
+ } else if (lang) {
1662
+ // Move specified lang to front
1663
+ languagesToTry = [lang, ...languagesToTry.filter(l => l !== lang)];
1664
+ }
1665
+
1666
+ // Try each language until one succeeds
1667
+ for (const tryLang of languagesToTry) {
1668
+ if (!isLanguageSupported(tryLang)) continue;
1669
+ try {
1670
+ const result = semanticAnalyzer.analyze(code, tryLang);
1671
+ if (result && result.confidence >= SEMANTIC_CONFIDENCE_THRESHOLD) {
1672
+ // buildAST returns {ast, warnings} - extract the ast
1673
+ const buildResult = buildAST(result.node);
1674
+ const ast = buildResult.ast;
1675
+
1676
+ // Semantic parser doesn't fully handle event handlers - fallback to HybridParser
1677
+ // Event handlers like "on click toggle .active" produce incomplete AST
1678
+ if (ast && ast.type === 'command' && ast.name === 'on') {
1679
+ break; // Fallback to HybridParser
1680
+ }
1681
+
1682
+ return ast;
1683
+ }
1684
+ } catch (e) {
1685
+ // Continue trying other languages
1686
+ }
1687
+ }
1688
+
1689
+ // Fallback to HybridParser for event handlers and unrecognized patterns
1690
+ // Preprocess to translate non-ASCII keywords to English (tokenizer only accepts ASCII)
1691
+ const preprocessedCode = preprocessMultilingual(code);
1692
+ return new HybridParser(preprocessedCode).parse();
1693
+ }
1694
+ `;
1695
+ if (config.grammarEnabled) {
1696
+ code += `
1697
+ /**
1698
+ * Translate hyperscript between languages.
1699
+ */
1700
+ function translateHyperscript(code, fromLang, toLang) {
1701
+ return translate(code, fromLang, toLang);
1702
+ }
1703
+ `;
1704
+ }
1705
+ return code;
1706
+ }
1707
+ function getSemanticExports(config) {
1708
+ const exports = [];
1709
+ if (config.enabled) {
1710
+ exports.push("parseWithSemantic");
1711
+ exports.push("SUPPORTED_SEMANTIC_LANGUAGES");
1712
+ }
1713
+ if (config.grammarEnabled) {
1714
+ exports.push("translateHyperscript");
1715
+ exports.push("grammarTransformer");
1716
+ }
1717
+ return exports;
1718
+ }
1719
+
1720
+ // src/generator.ts
1721
+ function stripTypes(code) {
1722
+ return code.replace(/\s+as\s+\w+<[^>]*(?:<[^>]*>[^>]*)*>/g, "").replace(/\s+as\s+\w+(?:\[\])?/g, "").replace(/:\s*\w+<[^>]*(?:<[^>]*>[^>]*)*>(?:\[\])?(?=\s*[=;,)\]])/g, "").replace(
1723
+ /:\s*(?:string|number|boolean|any|unknown|void|never|null|undefined|object|symbol|bigint)(?=\s*[=;,)\]])/g,
1724
+ ""
1725
+ ).replace(/:\s*[A-Z]\w*(?:\[\])?(?=\s*[=;,)\]])/g, "").replace(/\((\w+):\s*(?:\w+|unknown|any)\)/g, "($1)").replace(/Promise<[^>]+>/g, "Promise").replace(/Array<[^>]+>/g, "Array").replace(/\):\s*\w+(?:<[^>]*>)?(?:\[\])?\s*(?=[{=])/g, ") ").replace(/\):\s*\w+(?:<[^>]*>)?\s*=>/g, ") =>").replace(
1726
+ /:\s*(?:TransitionEvent|MouseEvent|KeyboardEvent|Event|Element|HTMLElement|Node)(?=\s*[=;,)\]])/g,
1727
+ ""
1728
+ ).replace(/(\w)!(?=[,;)\].\s])/g, "$1");
1729
+ }
1730
+ var COMMAND_IMPLEMENTATIONS = {};
1731
+ var BLOCK_IMPLEMENTATIONS = {};
1732
+ for (const [name, code] of Object.entries(COMMAND_IMPL_TS)) {
1733
+ COMMAND_IMPLEMENTATIONS[name] = stripTypes(code);
1734
+ }
1735
+ for (const [name, code] of Object.entries(BLOCK_IMPL_TS)) {
1736
+ BLOCK_IMPLEMENTATIONS[name] = stripTypes(code);
1737
+ }
1738
+ function generateBundleCode(config) {
1739
+ const {
1740
+ name,
1741
+ commands,
1742
+ blocks = [],
1743
+ htmxIntegration = false,
1744
+ globalName = "hyperfixi",
1745
+ positionalExpressions = false,
1746
+ autoInit = true,
1747
+ esModule = true,
1748
+ parserType = "hybrid"
1749
+ } = config;
1750
+ const needsStyleHelpers = commands.some((cmd) => STYLE_COMMANDS.includes(cmd));
1751
+ const needsElementArrayHelper = commands.some((cmd) => ELEMENT_ARRAY_COMMANDS.includes(cmd));
1752
+ const needsMorphlex = commands.some((cmd) => MORPH_COMMANDS.includes(cmd));
1753
+ const hasBlocks = blocks.length > 0;
1754
+ const hasReturn = commands.includes("return");
1755
+ const commandCases = commands.filter((cmd) => COMMAND_IMPLEMENTATIONS[cmd]).map((cmd) => COMMAND_IMPLEMENTATIONS[cmd]).join("\n");
1756
+ const blockCases = blocks.filter((block) => BLOCK_IMPLEMENTATIONS[block]).map((block) => BLOCK_IMPLEMENTATIONS[block]).join("\n");
1757
+ const parserTemplate = parserType === "lite" ? LITE_PARSER_TEMPLATE : HYBRID_PARSER_TEMPLATE;
1758
+ const morphlexImport = needsMorphlex ? `import { morph as morphlexMorph, morphInner as morphlexMorphInner } from 'morphlex';
1759
+
1760
+ ` : "";
1761
+ return `/**
1762
+ * LokaScript ${name} Bundle (Auto-Generated)
1763
+ *
1764
+ * Generated by: @hyperfixi/vite-plugin
1765
+ * Parser: ${parserType}
1766
+ * Commands: ${commands.join(", ")}${blocks.length > 0 ? `
1767
+ * Blocks: ${blocks.join(", ")}` : ""}${positionalExpressions ? "\n * Positional expressions: enabled" : ""}${needsMorphlex ? "\n * Morphing: morphlex (~2.5KB)" : ""}
1768
+ *
1769
+ * DO NOT EDIT - This file is automatically regenerated.
1770
+ */
1771
+
1772
+ ${morphlexImport}// Embedded ${parserType} parser (no external dependencies)
1773
+ ${parserTemplate}
1774
+
1775
+ // Runtime state
1776
+ const globalVars = new Map();
1777
+ ${hasBlocks ? "const MAX_LOOP_ITERATIONS = 1000;" : ""}
1778
+
1779
+ async function evaluate(node, ctx) {
1780
+ switch (node.type) {
1781
+ case 'literal': return node.value;
1782
+
1783
+ case 'identifier':
1784
+ if (node.value === 'me' || node.value === 'my') return ctx.me;
1785
+ if (node.value === 'it') return ctx.it;
1786
+ if (node.value === 'you') return ctx.you;
1787
+ if (node.value === 'event') return ctx.event;
1788
+ if (node.value === 'body') return document.body;
1789
+ if (node.value === 'document') return document;
1790
+ if (node.value === 'window') return window;
1791
+ if (ctx.locals.has(node.value)) return ctx.locals.get(node.value);
1792
+ if (node.value in ctx.me) return ctx.me[node.value];
1793
+ return node.value;
1794
+
1795
+ case 'contextReference':
1796
+ // Semantic AST format for context references (me, you, it, etc.)
1797
+ switch (node.contextType || node.name) {
1798
+ case 'me': return ctx.me;
1799
+ case 'it': return ctx.it;
1800
+ case 'you': return ctx.you;
1801
+ case 'event': return ctx.event;
1802
+ case 'body': return document.body;
1803
+ case 'document': return document;
1804
+ case 'window': return window;
1805
+ default: return ctx.me;
1806
+ }
1807
+
1808
+ case 'variable':
1809
+ if (node.scope === 'local') return ctx.locals.get(node.name.slice(1));
1810
+ const gName = node.name.slice(1);
1811
+ if (globalVars.has(gName)) return globalVars.get(gName);
1812
+ return window[node.name];
1813
+
1814
+ case 'selector':
1815
+ const elements = document.querySelectorAll(node.value);
1816
+ return elements.length === 1 ? elements[0] : Array.from(elements);
1817
+
1818
+ case 'binary':
1819
+ return evaluateBinary(node, ctx);
1820
+
1821
+ case 'possessive':
1822
+ case 'member':
1823
+ const obj = await evaluate(node.object, ctx);
1824
+ if (obj == null) return undefined;
1825
+ const prop = node.computed ? await evaluate(node.property, ctx) : node.property;
1826
+ return obj[prop];
1827
+
1828
+ case 'call': {
1829
+ let callContext = null;
1830
+ let callee;
1831
+
1832
+ if (node.callee.type === 'member' || node.callee.type === 'possessive') {
1833
+ callContext = await evaluate(node.callee.object, ctx);
1834
+ const p = node.callee.computed
1835
+ ? await evaluate(node.callee.property, ctx)
1836
+ : node.callee.property;
1837
+ callee = callContext?.[p];
1838
+ } else {
1839
+ callee = await evaluate(node.callee, ctx);
1840
+ }
1841
+
1842
+ const args = await Promise.all(node.args.map(a => evaluate(a, ctx)));
1843
+ if (typeof callee === 'function') return callee.apply(callContext, args);
1844
+ return undefined;
1845
+ }
1846
+ ${positionalExpressions ? `
1847
+ case 'positional':
1848
+ return evaluatePositional(node, ctx);
1849
+ ` : ""}
1850
+ default: return undefined;
1851
+ }
1852
+ }
1853
+
1854
+ async function evaluateBinary(node, ctx) {
1855
+ if (node.operator === 'has') {
1856
+ const left = await evaluate(node.left, ctx);
1857
+ if (left instanceof Element && node.right.type === 'selector' && node.right.value.startsWith('.')) {
1858
+ return left.classList.contains(node.right.value.slice(1));
1859
+ }
1860
+ return false;
1861
+ }
1862
+
1863
+ const left = await evaluate(node.left, ctx);
1864
+ const right = await evaluate(node.right, ctx);
1865
+
1866
+ switch (node.operator) {
1867
+ case '+': return left + right;
1868
+ case '-': return left - right;
1869
+ case '*': return left * right;
1870
+ case '/': return left / right;
1871
+ case '%': return left % right;
1872
+ case '==': case 'is': return left == right;
1873
+ case '!=': case 'is not': return left != right;
1874
+ case '<': return left < right;
1875
+ case '>': return left > right;
1876
+ case '<=': return left <= right;
1877
+ case '>=': return left >= right;
1878
+ case 'and': case '&&': return left && right;
1879
+ case 'or': case '||': return left || right;
1880
+ case 'contains': case 'includes':
1881
+ if (typeof left === 'string') return left.includes(right);
1882
+ if (Array.isArray(left)) return left.includes(right);
1883
+ if (left instanceof Element) return left.contains(right);
1884
+ return false;
1885
+ case 'matches':
1886
+ if (left instanceof Element) return left.matches(right);
1887
+ if (typeof left === 'string') return new RegExp(right).test(left);
1888
+ return false;
1889
+ default: return undefined;
1890
+ }
1891
+ }
1892
+ ${positionalExpressions ? `
1893
+ function evaluatePositional(node, ctx) {
1894
+ const target = node.target;
1895
+ let elements = [];
1896
+
1897
+ let selector = null;
1898
+ if (target.type === 'selector') {
1899
+ selector = target.value;
1900
+ } else if (target.type === 'identifier') {
1901
+ selector = target.value;
1902
+ } else if (target.type === 'htmlSelector') {
1903
+ selector = target.value;
1904
+ }
1905
+ if (selector) {
1906
+ elements = Array.from(document.querySelectorAll(selector));
1907
+ }
1908
+
1909
+ switch (node.position) {
1910
+ case 'first': return elements[0] || null;
1911
+ case 'last': return elements[elements.length - 1] || null;
1912
+ case 'next': return ctx.me.nextElementSibling;
1913
+ case 'previous': return ctx.me.previousElementSibling;
1914
+ case 'closest': return target.value ? ctx.me.closest(target.value) : null;
1915
+ case 'parent': return ctx.me.parentElement;
1916
+ default: return elements[0] || null;
1917
+ }
1918
+ }
1919
+ ` : ""}
1920
+ ${needsStyleHelpers ? `
1921
+ const isStyleProp = (prop) => prop?.startsWith('*');
1922
+ const getStyleName = (prop) => prop.substring(1);
1923
+ const setStyleProp = (el, prop, value) => {
1924
+ if (!isStyleProp(prop)) return false;
1925
+ el.style.setProperty(getStyleName(prop), String(value));
1926
+ return true;
1927
+ };
1928
+ ` : ""}
1929
+
1930
+ ${needsElementArrayHelper ? `
1931
+ const toElementArray = (val) => {
1932
+ if (Array.isArray(val)) return val.filter(e => e instanceof Element);
1933
+ if (val instanceof Element) return [val];
1934
+ if (typeof val === 'string') return Array.from(document.querySelectorAll(val));
1935
+ return [];
1936
+ };
1937
+ ` : ""}
1938
+
1939
+ async function executeCommand(cmd, ctx) {
1940
+ const getTarget = async () => {
1941
+ // Support both HybridParser (cmd.target) and semantic AST (cmd.modifiers.on) formats
1942
+ const target = cmd.target || cmd.modifiers?.on;
1943
+ if (!target) return [ctx.me];
1944
+ const t = await evaluate(target, ctx);
1945
+ if (Array.isArray(t)) return t;
1946
+ if (t instanceof Element) return [t];
1947
+ if (typeof t === 'string') return Array.from(document.querySelectorAll(t));
1948
+ return [ctx.me];
1949
+ };
1950
+
1951
+ const getClassName = (node) => {
1952
+ if (!node) return '';
1953
+ if (node.type === 'selector') return node.value.slice(1);
1954
+ if (node.type === 'string' || node.type === 'literal') {
1955
+ const val = node.value;
1956
+ return typeof val === 'string' && val.startsWith('.') ? val.slice(1) : String(val);
1957
+ }
1958
+ if (node.type === 'identifier') return node.value;
1959
+ return '';
1960
+ };
1961
+
1962
+ switch (cmd.name) {
1963
+ ${commandCases}
1964
+
1965
+ default:
1966
+ console.warn(\`${name} bundle: Unknown command '\${cmd.name}'\`);
1967
+ return null;
1968
+ }
1969
+ }
1970
+ ${hasBlocks ? `
1971
+ async function executeBlock(block, ctx) {
1972
+ switch (block.type) {
1973
+ ${blockCases}
1974
+
1975
+ default:
1976
+ console.warn(\`${name} bundle: Unknown block '\${block.type}'\`);
1977
+ return null;
1978
+ }
1979
+ }
1980
+ ` : ""}
1981
+ async function executeSequence(nodes, ctx) {
1982
+ let result;
1983
+ for (const node of nodes) {
1984
+ if (node.type === 'command') {
1985
+ result = await executeCommand(node, ctx);
1986
+ }${hasBlocks ? ` else if (['if', 'repeat', 'for', 'while', 'fetch'].includes(node.type)) {
1987
+ result = await executeBlock(node, ctx);
1988
+ }` : ""}
1989
+ }
1990
+ return result;
1991
+ }
1992
+ ${hasBlocks ? `
1993
+ async function executeSequenceWithBlocks(nodes, ctx) {
1994
+ try {
1995
+ return await executeSequence(nodes, ctx);
1996
+ } catch (e) {
1997
+ if (e?.type === 'return') throw e;
1998
+ throw e;
1999
+ }
2000
+ }
2001
+ ` : ""}
2002
+ async function executeAST(ast, me, event) {
2003
+ const ctx = { me, event, locals: new Map() };
2004
+
2005
+ if (ast.type === 'sequence') {
2006
+ ${hasReturn || hasBlocks ? "try { return await executeSequence(ast.commands, ctx); } catch (e) { if (e?.type === 'return') return e.value; throw e; }" : "return executeSequence(ast.commands, ctx);"}
2007
+ }
2008
+
2009
+ if (ast.type === 'event') {
2010
+ const eventNode = ast;
2011
+ const eventName = eventNode.event;
2012
+
2013
+ if (eventName === 'init') {
2014
+ ${hasReturn || hasBlocks ? "try { await executeSequence(eventNode.body, ctx); } catch (e) { if (e?.type !== 'return') throw e; }" : "await executeSequence(eventNode.body, ctx);"}
2015
+ return;
2016
+ }
2017
+
2018
+ const target = eventNode.filter ? await evaluate(eventNode.filter, ctx) : me;
2019
+ const targetEl = target instanceof Element ? target : me;
2020
+ const mods = eventNode.modifiers;
2021
+
2022
+ let handler = async (e) => {
2023
+ if (mods.prevent) e.preventDefault();
2024
+ if (mods.stop) e.stopPropagation();
2025
+
2026
+ const handlerCtx = {
2027
+ me, event: e,
2028
+ you: e.target instanceof Element ? e.target : undefined,
2029
+ locals: new Map(),
2030
+ };
2031
+ ${hasReturn || hasBlocks ? "try { await executeSequence(eventNode.body, handlerCtx); } catch (err) { if (err?.type !== 'return') throw err; }" : "await executeSequence(eventNode.body, handlerCtx);"}
2032
+ };
2033
+
2034
+ if (mods.debounce) {
2035
+ let timeout;
2036
+ const orig = handler;
2037
+ handler = async (e) => {
2038
+ clearTimeout(timeout);
2039
+ timeout = setTimeout(() => orig(e), mods.debounce);
2040
+ };
2041
+ }
2042
+
2043
+ if (mods.throttle) {
2044
+ let lastCall = 0;
2045
+ const orig = handler;
2046
+ handler = async (e) => {
2047
+ const now = Date.now();
2048
+ if (now - lastCall >= mods.throttle) {
2049
+ lastCall = now;
2050
+ await orig(e);
2051
+ }
2052
+ };
2053
+ }
2054
+
2055
+ targetEl.addEventListener(eventName, handler, { once: !!mods.once });
2056
+ return;
2057
+ }
2058
+
2059
+ // Handle single command (not wrapped in event or sequence)
2060
+ if (ast.type === 'command') {
2061
+ return executeCommand(ast, ctx);
2062
+ }
2063
+
2064
+ return null;
2065
+ }
2066
+
2067
+ function processElement(el) {
2068
+ const code = el.getAttribute('_');
2069
+ if (!code) return;
2070
+
2071
+ try {
2072
+ const ast = ${parserType === "lite" ? "parseLite(code)" : "new HybridParser(code).parse()"};
2073
+ executeAST(ast, el);
2074
+ } catch (err) {
2075
+ console.error('LokaScript ${name} error:', err, 'Code:', code);
2076
+ }
2077
+ }
2078
+
2079
+ function processElements(root = document) {
2080
+ const elements = root.querySelectorAll('[_]');
2081
+ elements.forEach(processElement);
2082
+ }
2083
+
2084
+ const api = {
2085
+ version: '1.0.0-${name.toLowerCase().replace(/\s+/g, "-")}',
2086
+
2087
+ parse(code) {
2088
+ return ${parserType === "lite" ? "parseLite(code)" : "new HybridParser(code).parse()"};
2089
+ },
2090
+
2091
+ async execute(code, element) {
2092
+ const me = element || document.body;
2093
+ const ast = ${parserType === "lite" ? "parseLite(code)" : "new HybridParser(code).parse()"};
2094
+ return executeAST(ast, me);
2095
+ },
2096
+
2097
+ run: async (code, element) => api.execute(code, element),
2098
+ eval: async (code, element) => api.execute(code, element),
2099
+
2100
+ init: processElements,
2101
+ process: processElements,
2102
+
2103
+ commands: ${JSON.stringify(commands)},
2104
+ ${blocks.length > 0 ? `blocks: ${JSON.stringify(blocks)},` : ""}
2105
+ parserName: '${parserType}',
2106
+ };
2107
+ ${autoInit ? `
2108
+ if (typeof window !== 'undefined') {
2109
+ window.${globalName} = api;
2110
+ window._hyperscript = api;
2111
+
2112
+ if (document.readyState === 'loading') {
2113
+ document.addEventListener('DOMContentLoaded', () => processElements());
2114
+ } else {
2115
+ processElements();
2116
+ }
2117
+ ${htmxIntegration ? `
2118
+ document.addEventListener('htmx:afterSettle', (e) => {
2119
+ const target = e.detail?.target;
2120
+ if (target) processElements(target);
2121
+ });
2122
+ ` : ""}
2123
+ }
2124
+ ` : ""}
2125
+ ${esModule ? `
2126
+ export default api;
2127
+ export { api, processElements };
2128
+ ` : ""}`;
2129
+ }
2130
+ var Generator = class {
2131
+ constructor(options) {
2132
+ this.debug = options.debug ?? false;
2133
+ }
2134
+ /**
2135
+ * Generate bundle code from aggregated usage
2136
+ */
2137
+ generate(usage, options) {
2138
+ const commands = [...usage.commands, ...options.extraCommands ?? []];
2139
+ const blocks = [...usage.blocks, ...options.extraBlocks ?? []];
2140
+ const positional = usage.positional || options.positional || false;
2141
+ const semanticConfig = resolveSemanticConfig(options, usage.detectedLanguages);
2142
+ if (commands.length === 0 && blocks.length === 0 && !positional && !semanticConfig.enabled) {
2143
+ return this.generateEmptyBundle(options);
2144
+ }
2145
+ const unsupportedCommands = this.getUnsupportedCommands(commands);
2146
+ if (unsupportedCommands.length > 0) {
2147
+ if (this.debug) {
2148
+ console.log(
2149
+ `[hyperfixi] Commands detected that require full runtime: ${unsupportedCommands.join(", ")}
2150
+ Falling back to full browser bundle for complete functionality.`
2151
+ );
2152
+ }
2153
+ return this.generateDevFallback("full");
2154
+ }
2155
+ const parserType = canUseLiteParser(commands, blocks, positional) ? "lite" : "hybrid";
2156
+ const config = {
2157
+ name: options.bundleName ?? "ViteAutoGenerated",
2158
+ commands,
2159
+ blocks,
2160
+ positionalExpressions: positional,
2161
+ htmxIntegration: options.htmx ?? usage.htmx?.hasHtmxAttributes ?? false,
2162
+ globalName: options.globalName ?? "hyperfixi",
2163
+ parserType,
2164
+ autoInit: true,
2165
+ esModule: true
2166
+ };
2167
+ if (this.debug) {
2168
+ const bundleInfo = {
2169
+ commands,
2170
+ blocks,
2171
+ positional,
2172
+ htmx: config.htmxIntegration,
2173
+ semantic: semanticConfig.enabled,
2174
+ parserType
2175
+ };
2176
+ if (semanticConfig.enabled && semanticConfig.bundleType) {
2177
+ const sizeInfo = getSemanticBundleSize(semanticConfig.bundleType);
2178
+ bundleInfo.semanticBundle = semanticConfig.bundleType;
2179
+ bundleInfo.semanticSize = sizeInfo.gzip;
2180
+ bundleInfo.languages = [...semanticConfig.languages];
2181
+ bundleInfo.grammar = semanticConfig.grammarEnabled;
2182
+ }
2183
+ console.log("[hyperfixi] Generating bundle:", bundleInfo);
2184
+ if (semanticConfig.bundleType === "all" || semanticConfig.bundleType === "priority") {
2185
+ console.log(
2186
+ `[hyperfixi] Note: Using '${semanticConfig.bundleType}' semantic bundle (${getSemanticBundleSize(semanticConfig.bundleType).gzip}). Consider using 'region' option to select a smaller regional bundle if all languages aren't needed.`
2187
+ );
2188
+ }
2189
+ }
2190
+ let bundleCode = generateBundleCode(config);
2191
+ if (semanticConfig.enabled) {
2192
+ bundleCode = this.addSemanticIntegration(bundleCode, semanticConfig);
2193
+ }
2194
+ return bundleCode;
2195
+ }
2196
+ /**
2197
+ * Add semantic integration code to the bundle
2198
+ */
2199
+ addSemanticIntegration(bundleCode, config) {
2200
+ const semanticCode = generateSemanticIntegrationCode(config);
2201
+ const semanticExports = getSemanticExports(config);
2202
+ const parserImportEnd = bundleCode.indexOf("// Runtime state");
2203
+ if (parserImportEnd === -1) {
2204
+ bundleCode = semanticCode + "\n" + bundleCode;
2205
+ } else {
2206
+ bundleCode = bundleCode.slice(0, parserImportEnd) + semanticCode + "\n\n" + bundleCode.slice(parserImportEnd);
2207
+ }
2208
+ bundleCode = bundleCode.replace(
2209
+ /function processElement\(el\) \{\s*const code = el\.getAttribute\('_'\);\s*if \(!code\) return;\s*try \{\s*const ast = (?:new HybridParser\(code\)\.parse\(\)|parseLite\(code\));/g,
2210
+ `function processElement(el) {
2211
+ const code = el.getAttribute('_');
2212
+ if (!code) return;
2213
+
2214
+ try {
2215
+ const ast = parseWithSemantic(code);`
2216
+ );
2217
+ bundleCode = bundleCode.replace(
2218
+ /parse\(code\) \{\s*return (?:new HybridParser\(code\)\.parse\(\)|parseLite\(code\));/g,
2219
+ `parse(code, lang = null) {
2220
+ return parseWithSemantic(code, lang);`
2221
+ );
2222
+ bundleCode = bundleCode.replace(
2223
+ /async execute\(code, element\) \{\s*const me = element \|\| document\.body;\s*const ast = (?:new HybridParser\(code\)\.parse\(\)|parseLite\(code\));/g,
2224
+ `async execute(code, element, lang = null) {
2225
+ const me = element || document.body;
2226
+ const ast = parseWithSemantic(code, lang);`
2227
+ );
2228
+ if (semanticExports.length > 0) {
2229
+ const apiExportsMarkerRegex = /parserName: '(?:lite|hybrid)',/;
2230
+ const additionalApiProps = semanticExports.map((exp) => ` ${exp},`).join("\n");
2231
+ bundleCode = bundleCode.replace(
2232
+ apiExportsMarkerRegex,
2233
+ `parserName: 'semantic',
2234
+ ${additionalApiProps}`
2235
+ );
2236
+ }
2237
+ return bundleCode;
2238
+ }
2239
+ /**
2240
+ * Get commands that require the full runtime and are not available in generated bundles
2241
+ */
2242
+ getUnsupportedCommands(commands) {
2243
+ const unsupported = [];
2244
+ for (const cmd of commands) {
2245
+ if (FULL_RUNTIME_ONLY_COMMANDS.includes(cmd)) {
2246
+ unsupported.push(cmd);
2247
+ } else if (!isAvailableCommand(cmd) && !COMMAND_IMPLEMENTATIONS[cmd]) {
2248
+ unsupported.push(cmd);
2249
+ }
2250
+ }
2251
+ return unsupported;
2252
+ }
2253
+ /**
2254
+ * Check if any commands require full runtime and should trigger fallback
2255
+ */
2256
+ requiresFullRuntime(commands) {
2257
+ return this.getUnsupportedCommands(commands).length > 0;
2258
+ }
2259
+ /**
2260
+ * Generate an empty bundle when no hyperscript is detected
2261
+ */
2262
+ generateEmptyBundle(options) {
2263
+ const globalName = options.globalName ?? "hyperfixi";
2264
+ return `/**
2265
+ * LokaScript Empty Bundle (Auto-Generated)
2266
+ *
2267
+ * No hyperscript usage detected. This bundle provides a minimal API.
2268
+ * Add hyperscript attributes (_="...") to your HTML to enable features.
2269
+ *
2270
+ * Generated by: @hyperfixi/vite-plugin
2271
+ */
2272
+
2273
+ const api = {
2274
+ version: '1.0.0-empty',
2275
+ commands: [],
2276
+ parserName: 'none',
2277
+
2278
+ parse() {
2279
+ console.warn('LokaScript: No parser loaded. Add hyperscript to your HTML to enable parsing.');
2280
+ return { type: 'empty' };
2281
+ },
2282
+
2283
+ async execute(code, element) {
2284
+ console.warn('LokaScript: No commands loaded. Detected commands will be automatically included.');
2285
+ return null;
2286
+ },
2287
+
2288
+ run: async (code, element) => api.execute(code, element),
2289
+ eval: async (code, element) => api.execute(code, element),
2290
+
2291
+ init() {},
2292
+ process() {},
2293
+ };
2294
+
2295
+ if (typeof window !== 'undefined') {
2296
+ (window).${globalName} = api;
2297
+ (window)._hyperscript = api;
2298
+ }
2299
+
2300
+ export default api;
2301
+ export { api };
2302
+ `;
2303
+ }
2304
+ /**
2305
+ * Generate a development fallback bundle
2306
+ */
2307
+ generateDevFallback(fallback) {
2308
+ const bundle = fallback === "full" ? "@hyperfixi/core/browser" : "@hyperfixi/core/browser/hybrid-complete";
2309
+ return `/**
2310
+ * LokaScript Dev Fallback Bundle
2311
+ *
2312
+ * Using pre-built ${fallback} bundle for faster development.
2313
+ * Production builds will generate minimal bundles.
2314
+ *
2315
+ * Generated by: @hyperfixi/vite-plugin
2316
+ */
2317
+
2318
+ export * from '${bundle}';
2319
+ export { default } from '${bundle}';
2320
+ `;
2321
+ }
2322
+ };
2323
+
2324
+ // src/compiler.ts
2325
+ import { HybridParser } from "@hyperfixi/core/parser/hybrid/parser-core";
2326
+ var semanticAnalyzer = null;
2327
+ var buildASTFn = null;
2328
+ function setSemanticParser(analyzer, buildAST) {
2329
+ semanticAnalyzer = analyzer;
2330
+ buildASTFn = buildAST;
2331
+ }
2332
+ function clearSemanticParser() {
2333
+ semanticAnalyzer = null;
2334
+ buildASTFn = null;
2335
+ }
2336
+ function hasSemanticParser() {
2337
+ return semanticAnalyzer !== null && buildASTFn !== null;
2338
+ }
2339
+ var SEMANTIC_CONFIDENCE_THRESHOLD = 0.7;
2340
+ var multilingualAliases = {};
2341
+ var multilingualRegex = null;
2342
+ function setMultilingualAliases(aliases) {
2343
+ multilingualAliases = { ...aliases };
2344
+ if (Object.keys(aliases).length > 0) {
2345
+ const escapedKeys = Object.keys(aliases).map((k) => k.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|");
2346
+ multilingualRegex = new RegExp(`(^|\\s)(${escapedKeys})(?=\\s|\\.|$)`, "g");
2347
+ } else {
2348
+ multilingualRegex = null;
2349
+ }
2350
+ }
2351
+ function preprocessMultilingual(code) {
2352
+ if (!multilingualRegex) return code;
2353
+ return code.replace(multilingualRegex, (match, prefix, keyword) => {
2354
+ const english = multilingualAliases[keyword];
2355
+ return english ? prefix + english : match;
2356
+ });
2357
+ }
2358
+ function sanitizeClassName(name) {
2359
+ if (!/^-?[a-zA-Z_][a-zA-Z0-9_-]*$/.test(name)) {
2360
+ return null;
2361
+ }
2362
+ return name;
2363
+ }
2364
+ function sanitizeSelector(selector) {
2365
+ return selector.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\0/g, "");
2366
+ }
2367
+ function hashScript(script) {
2368
+ let hash = 5381;
2369
+ for (let i = 0; i < script.length; i++) {
2370
+ hash = (hash << 5) + hash ^ script.charCodeAt(i);
2371
+ }
2372
+ return Math.abs(hash).toString(36).slice(0, 4);
2373
+ }
2374
+ var usedIds = /* @__PURE__ */ new Set();
2375
+ function resetCompiler() {
2376
+ usedIds.clear();
2377
+ }
2378
+ function generateHandlerId(event, command, script) {
2379
+ const hash = hashScript(script);
2380
+ let id = `${event}_${command}_${hash}`;
2381
+ let suffix = 0;
2382
+ while (usedIds.has(id)) {
2383
+ id = `${event}_${command}_${hash}${suffix++}`;
2384
+ }
2385
+ usedIds.add(id);
2386
+ return id;
2387
+ }
2388
+ function compile(script, options = {}) {
2389
+ const { language = "en", debug = false } = options;
2390
+ try {
2391
+ let ast;
2392
+ if (language !== "en" && semanticAnalyzer && buildASTFn) {
2393
+ if (semanticAnalyzer.supportsLanguage(language)) {
2394
+ const result = semanticAnalyzer.analyze(script, language);
2395
+ if (result.node && result.confidence >= SEMANTIC_CONFIDENCE_THRESHOLD) {
2396
+ const { ast: builtAST, warnings } = buildASTFn(result.node);
2397
+ if (debug && warnings.length > 0) {
2398
+ console.log(`[hyperfixi] Semantic AST warnings for "${script}":`, warnings);
2399
+ }
2400
+ ast = builtAST;
2401
+ if (debug) {
2402
+ console.log(
2403
+ `[hyperfixi] Compiled ${language}: "${script}" (confidence: ${result.confidence.toFixed(2)})`
2404
+ );
2405
+ }
2406
+ } else {
2407
+ if (debug) {
2408
+ const reason = result.errors?.join(", ") || `low confidence (${result.confidence.toFixed(2)})`;
2409
+ console.log(`[hyperfixi] Semantic parse failed for "${script}": ${reason}`);
2410
+ }
2411
+ return null;
2412
+ }
2413
+ } else {
2414
+ if (debug) {
2415
+ console.log(`[hyperfixi] Language "${language}" not supported by semantic parser`);
2416
+ }
2417
+ return null;
2418
+ }
2419
+ } else if (language !== "en") {
2420
+ if (debug) {
2421
+ console.log(
2422
+ `[hyperfixi] Semantic parser not available for "${language}". Install @lokascript/semantic and call setSemanticParser().`
2423
+ );
2424
+ }
2425
+ return null;
2426
+ } else {
2427
+ const preprocessedScript = preprocessMultilingual(script);
2428
+ const parser = new HybridParser(preprocessedScript);
2429
+ ast = parser.parse();
2430
+ }
2431
+ return compileAST(ast, script);
2432
+ } catch (error) {
2433
+ if (debug) {
2434
+ console.warn(`[hyperfixi] Failed to compile: ${script}`, error);
2435
+ }
2436
+ return null;
2437
+ }
2438
+ }
2439
+ function extractPrimaryCommand(body) {
2440
+ if (body.length === 0) return "handler";
2441
+ const first = body[0];
2442
+ if (first.type === "command") {
2443
+ return first.name || "cmd";
2444
+ }
2445
+ return first.type || "handler";
2446
+ }
2447
+ function compileAST(ast, original) {
2448
+ if (ast.type !== "event") {
2449
+ return null;
2450
+ }
2451
+ const eventNode = ast;
2452
+ const event = eventNode.event;
2453
+ const modifiers = eventNode.modifiers || {};
2454
+ const body = eventNode.body || [];
2455
+ const { code, needsEvaluator, needsLocals, needsGlobals } = compileBody(body);
2456
+ if (code === null || code === "") {
2457
+ return null;
2458
+ }
2459
+ const command = extractPrimaryCommand(body);
2460
+ const id = generateHandlerId(event, command, original);
2461
+ return {
2462
+ id,
2463
+ event,
2464
+ modifiers: {
2465
+ prevent: modifiers.prevent,
2466
+ stop: modifiers.stop,
2467
+ once: modifiers.once,
2468
+ debounce: modifiers.debounce,
2469
+ throttle: modifiers.throttle
2470
+ },
2471
+ code,
2472
+ needsEvaluator: needsEvaluator || needsLocals || needsGlobals,
2473
+ original
2474
+ };
2475
+ }
2476
+ function compileBody(nodes) {
2477
+ const statements = [];
2478
+ let needsEvaluator = false;
2479
+ let needsLocals = false;
2480
+ let needsGlobals = false;
2481
+ for (const node of nodes) {
2482
+ const result = compileNode(node);
2483
+ if (result === null) {
2484
+ return { code: null, needsEvaluator: false, needsLocals: false, needsGlobals: false };
2485
+ }
2486
+ statements.push(result.code);
2487
+ needsEvaluator = needsEvaluator || result.needsEvaluator;
2488
+ needsLocals = needsLocals || result.needsLocals;
2489
+ needsGlobals = needsGlobals || result.needsGlobals;
2490
+ }
2491
+ return {
2492
+ code: statements.join("\n"),
2493
+ needsEvaluator,
2494
+ needsLocals,
2495
+ needsGlobals
2496
+ };
2497
+ }
2498
+ function compileNode(node) {
2499
+ if (node.type === "command") {
2500
+ return compileCommand(node);
2501
+ }
2502
+ return null;
2503
+ }
2504
+ function compileCommand(cmd) {
2505
+ const target = cmd.target ? compileTarget(cmd.target) : "m";
2506
+ switch (cmd.name) {
2507
+ case "toggle":
2508
+ return compileToggle(cmd.args, target);
2509
+ case "add":
2510
+ return compileAdd(cmd.args, target);
2511
+ case "remove":
2512
+ return compileRemove(cmd.args, target);
2513
+ case "removeClass":
2514
+ return compileRemoveClass(cmd.args, target);
2515
+ case "show":
2516
+ return {
2517
+ code: `${target}.style.display = ''`,
2518
+ needsEvaluator: false,
2519
+ needsLocals: false,
2520
+ needsGlobals: false
2521
+ };
2522
+ case "hide":
2523
+ return {
2524
+ code: `${target}.style.display = 'none'`,
2525
+ needsEvaluator: false,
2526
+ needsLocals: false,
2527
+ needsGlobals: false
2528
+ };
2529
+ case "focus":
2530
+ return {
2531
+ code: `${target}.focus()`,
2532
+ needsEvaluator: false,
2533
+ needsLocals: false,
2534
+ needsGlobals: false
2535
+ };
2536
+ case "blur":
2537
+ return {
2538
+ code: `${target}.blur()`,
2539
+ needsEvaluator: false,
2540
+ needsLocals: false,
2541
+ needsGlobals: false
2542
+ };
2543
+ case "log":
2544
+ return compileLog(cmd.args);
2545
+ case "set":
2546
+ return compileSet(cmd.args);
2547
+ case "increment":
2548
+ return compileIncrement(cmd.args);
2549
+ case "decrement":
2550
+ return compileDecrement(cmd.args);
2551
+ case "put":
2552
+ return compilePut(cmd.args, target, cmd.modifier);
2553
+ case "send":
2554
+ case "trigger":
2555
+ return compileTrigger(cmd.args, target);
2556
+ case "wait":
2557
+ return compileWait(cmd.args);
2558
+ default:
2559
+ return null;
2560
+ }
2561
+ }
2562
+ function compileToggle(args, target) {
2563
+ const className = extractClassName(args[0]);
2564
+ if (!className) return null;
2565
+ if (target === "m") {
2566
+ return {
2567
+ code: `m.classList.toggle('${className}')`,
2568
+ needsEvaluator: false,
2569
+ needsLocals: false,
2570
+ needsGlobals: false
2571
+ };
2572
+ }
2573
+ return {
2574
+ code: `${target}.forEach(el => el.classList.toggle('${className}'))`,
2575
+ needsEvaluator: false,
2576
+ needsLocals: false,
2577
+ needsGlobals: false
2578
+ };
2579
+ }
2580
+ function compileAdd(args, target) {
2581
+ const className = extractClassName(args[0]);
2582
+ if (!className) return null;
2583
+ if (target === "m") {
2584
+ return {
2585
+ code: `m.classList.add('${className}')`,
2586
+ needsEvaluator: false,
2587
+ needsLocals: false,
2588
+ needsGlobals: false
2589
+ };
2590
+ }
2591
+ return {
2592
+ code: `${target}.forEach(el => el.classList.add('${className}'))`,
2593
+ needsEvaluator: false,
2594
+ needsLocals: false,
2595
+ needsGlobals: false
2596
+ };
2597
+ }
2598
+ function compileRemove(args, target) {
2599
+ if (!args || args.length === 0) {
2600
+ return {
2601
+ code: `${target}.remove()`,
2602
+ needsEvaluator: false,
2603
+ needsLocals: false,
2604
+ needsGlobals: false
2605
+ };
2606
+ }
2607
+ const className = extractClassName(args[0]);
2608
+ if (!className) return null;
2609
+ if (target === "m") {
2610
+ return {
2611
+ code: `m.classList.remove('${className}')`,
2612
+ needsEvaluator: false,
2613
+ needsLocals: false,
2614
+ needsGlobals: false
2615
+ };
2616
+ }
2617
+ return {
2618
+ code: `${target}.forEach(el => el.classList.remove('${className}'))`,
2619
+ needsEvaluator: false,
2620
+ needsLocals: false,
2621
+ needsGlobals: false
2622
+ };
2623
+ }
2624
+ function compileRemoveClass(args, target) {
2625
+ const className = extractClassName(args[0]);
2626
+ if (!className) return null;
2627
+ if (target === "m") {
2628
+ return {
2629
+ code: `m.classList.remove('${className}')`,
2630
+ needsEvaluator: false,
2631
+ needsLocals: false,
2632
+ needsGlobals: false
2633
+ };
2634
+ }
2635
+ return {
2636
+ code: `${target}.forEach(el => el.classList.remove('${className}'))`,
2637
+ needsEvaluator: false,
2638
+ needsLocals: false,
2639
+ needsGlobals: false
2640
+ };
2641
+ }
2642
+ function compileLog(args) {
2643
+ const compiled = args.map(compileExpression).filter(Boolean);
2644
+ if (compiled.length !== args.length) {
2645
+ return {
2646
+ code: `console.log(${compiled.join(", ")})`,
2647
+ needsEvaluator: true,
2648
+ needsLocals: false,
2649
+ needsGlobals: false
2650
+ };
2651
+ }
2652
+ return {
2653
+ code: `console.log(${compiled.join(", ")})`,
2654
+ needsEvaluator: false,
2655
+ needsLocals: false,
2656
+ needsGlobals: false
2657
+ };
2658
+ }
2659
+ function compileSet(args) {
2660
+ if (args.length < 2) return null;
2661
+ const [target, value] = args;
2662
+ const compiledValue = compileExpression(value);
2663
+ if (!compiledValue) return null;
2664
+ if (target.type === "variable") {
2665
+ const varNode = target;
2666
+ if (varNode.scope === "local") {
2667
+ const varName = varNode.name.slice(1);
2668
+ return {
2669
+ code: `L.${varName} = ${compiledValue}`,
2670
+ needsEvaluator: false,
2671
+ needsLocals: true,
2672
+ needsGlobals: false
2673
+ };
2674
+ }
2675
+ if (varNode.scope === "global") {
2676
+ const varName = varNode.name.slice(1);
2677
+ return {
2678
+ code: `G.${varName} = ${compiledValue}`,
2679
+ needsEvaluator: false,
2680
+ needsLocals: false,
2681
+ needsGlobals: true
2682
+ };
2683
+ }
2684
+ }
2685
+ if (target.type === "possessive") {
2686
+ const possNode = target;
2687
+ const obj = compileExpression(possNode.object);
2688
+ const prop = possNode.property;
2689
+ if (!obj) return null;
2690
+ if (prop.startsWith("*")) {
2691
+ const styleProp = prop.slice(1);
2692
+ return {
2693
+ code: `${obj}.style.${styleProp} = ${compiledValue}`,
2694
+ needsEvaluator: false,
2695
+ needsLocals: false,
2696
+ needsGlobals: false
2697
+ };
2698
+ }
2699
+ return {
2700
+ code: `${obj}.${prop} = ${compiledValue}`,
2701
+ needsEvaluator: false,
2702
+ needsLocals: false,
2703
+ needsGlobals: false
2704
+ };
2705
+ }
2706
+ if (target.type === "member") {
2707
+ const memNode = target;
2708
+ const obj = compileExpression(memNode.object);
2709
+ const prop = typeof memNode.property === "string" ? memNode.property : null;
2710
+ if (!obj || !prop) return null;
2711
+ if (prop.startsWith("*")) {
2712
+ const styleProp = prop.slice(1);
2713
+ return {
2714
+ code: `${obj}.style.${styleProp} = ${compiledValue}`,
2715
+ needsEvaluator: false,
2716
+ needsLocals: false,
2717
+ needsGlobals: false
2718
+ };
2719
+ }
2720
+ return {
2721
+ code: `${obj}.${prop} = ${compiledValue}`,
2722
+ needsEvaluator: false,
2723
+ needsLocals: false,
2724
+ needsGlobals: false
2725
+ };
2726
+ }
2727
+ return null;
2728
+ }
2729
+ function compileIncrement(args) {
2730
+ if (args.length < 1) return null;
2731
+ const target = args[0];
2732
+ const amount = args.length > 1 ? compileExpression(args[1]) : "1";
2733
+ if (target.type === "variable") {
2734
+ const varNode = target;
2735
+ if (varNode.scope === "local") {
2736
+ const varName = varNode.name.slice(1);
2737
+ return {
2738
+ code: `L.${varName} = (L.${varName} || 0) + ${amount}`,
2739
+ needsEvaluator: false,
2740
+ needsLocals: true,
2741
+ needsGlobals: false
2742
+ };
2743
+ }
2744
+ if (varNode.scope === "global") {
2745
+ const varName = varNode.name.slice(1);
2746
+ return {
2747
+ code: `G.${varName} = (G.${varName} || 0) + ${amount}`,
2748
+ needsEvaluator: false,
2749
+ needsLocals: false,
2750
+ needsGlobals: true
2751
+ };
2752
+ }
2753
+ }
2754
+ const compiled = compileExpression(target);
2755
+ if (compiled) {
2756
+ return {
2757
+ code: `${compiled}.textContent = (parseFloat(${compiled}.textContent) || 0) + ${amount}`,
2758
+ needsEvaluator: false,
2759
+ needsLocals: false,
2760
+ needsGlobals: false
2761
+ };
2762
+ }
2763
+ return null;
2764
+ }
2765
+ function compileDecrement(args) {
2766
+ if (args.length < 1) return null;
2767
+ const target = args[0];
2768
+ const amount = args.length > 1 ? compileExpression(args[1]) : "1";
2769
+ if (target.type === "variable") {
2770
+ const varNode = target;
2771
+ if (varNode.scope === "local") {
2772
+ const varName = varNode.name.slice(1);
2773
+ return {
2774
+ code: `L.${varName} = (L.${varName} || 0) - ${amount}`,
2775
+ needsEvaluator: false,
2776
+ needsLocals: true,
2777
+ needsGlobals: false
2778
+ };
2779
+ }
2780
+ if (varNode.scope === "global") {
2781
+ const varName = varNode.name.slice(1);
2782
+ return {
2783
+ code: `G.${varName} = (G.${varName} || 0) - ${amount}`,
2784
+ needsEvaluator: false,
2785
+ needsLocals: false,
2786
+ needsGlobals: true
2787
+ };
2788
+ }
2789
+ }
2790
+ const compiled = compileExpression(target);
2791
+ if (compiled) {
2792
+ return {
2793
+ code: `${compiled}.textContent = (parseFloat(${compiled}.textContent) || 0) - ${amount}`,
2794
+ needsEvaluator: false,
2795
+ needsLocals: false,
2796
+ needsGlobals: false
2797
+ };
2798
+ }
2799
+ return null;
2800
+ }
2801
+ function compilePut(args, target, modifier) {
2802
+ if (args.length < 1) return null;
2803
+ const content = compileExpression(args[0]);
2804
+ if (!content) return null;
2805
+ const mod = modifier || "into";
2806
+ switch (mod) {
2807
+ case "into":
2808
+ return {
2809
+ code: `${target}.innerHTML = ${content}`,
2810
+ needsEvaluator: false,
2811
+ needsLocals: false,
2812
+ needsGlobals: false
2813
+ };
2814
+ case "before":
2815
+ return {
2816
+ code: `${target}.insertAdjacentHTML('beforebegin', ${content})`,
2817
+ needsEvaluator: false,
2818
+ needsLocals: false,
2819
+ needsGlobals: false
2820
+ };
2821
+ case "after":
2822
+ return {
2823
+ code: `${target}.insertAdjacentHTML('afterend', ${content})`,
2824
+ needsEvaluator: false,
2825
+ needsLocals: false,
2826
+ needsGlobals: false
2827
+ };
2828
+ case "at start of":
2829
+ return {
2830
+ code: `${target}.insertAdjacentHTML('afterbegin', ${content})`,
2831
+ needsEvaluator: false,
2832
+ needsLocals: false,
2833
+ needsGlobals: false
2834
+ };
2835
+ case "at end of":
2836
+ return {
2837
+ code: `${target}.insertAdjacentHTML('beforeend', ${content})`,
2838
+ needsEvaluator: false,
2839
+ needsLocals: false,
2840
+ needsGlobals: false
2841
+ };
2842
+ default:
2843
+ return {
2844
+ code: `${target}.innerHTML = ${content}`,
2845
+ needsEvaluator: false,
2846
+ needsLocals: false,
2847
+ needsGlobals: false
2848
+ };
2849
+ }
2850
+ }
2851
+ function compileTrigger(args, target) {
2852
+ if (args.length < 1) return null;
2853
+ const eventName = compileExpression(args[0]);
2854
+ if (!eventName) return null;
2855
+ return {
2856
+ code: `${target}.dispatchEvent(new CustomEvent(${eventName}, { bubbles: true }))`,
2857
+ needsEvaluator: false,
2858
+ needsLocals: false,
2859
+ needsGlobals: false
2860
+ };
2861
+ }
2862
+ function compileWait(args) {
2863
+ if (args.length < 1) return null;
2864
+ const duration = compileExpression(args[0]);
2865
+ if (!duration) return null;
2866
+ return {
2867
+ code: `await new Promise(r => setTimeout(r, ${duration}))`,
2868
+ needsEvaluator: false,
2869
+ needsLocals: false,
2870
+ needsGlobals: false
2871
+ };
2872
+ }
2873
+ function compileExpression(node) {
2874
+ if (!node) return null;
2875
+ switch (node.type) {
2876
+ case "literal": {
2877
+ const litNode = node;
2878
+ return JSON.stringify(litNode.value);
2879
+ }
2880
+ case "identifier": {
2881
+ const idNode = node;
2882
+ const val = idNode.value;
2883
+ if (val === "me" || val === "my") return "m";
2884
+ if (val === "you") return "y";
2885
+ if (val === "it") return "it";
2886
+ if (val === "event") return "e";
2887
+ if (val === "body") return "document.body";
2888
+ if (val === "document") return "document";
2889
+ if (val === "window") return "window";
2890
+ return val;
2891
+ }
2892
+ case "variable": {
2893
+ const varNode = node;
2894
+ const name = varNode.name.slice(1);
2895
+ return varNode.scope === "local" ? `L.${name}` : `G.${name}`;
2896
+ }
2897
+ case "selector": {
2898
+ const selNode = node;
2899
+ const sanitized = sanitizeSelector(selNode.value);
2900
+ return `document.querySelector('${sanitized}')`;
2901
+ }
2902
+ case "possessive": {
2903
+ const possNode = node;
2904
+ const obj = compileExpression(possNode.object);
2905
+ const prop = possNode.property;
2906
+ if (!obj) return null;
2907
+ if (prop.startsWith("*")) {
2908
+ return `${obj}.style.${prop.slice(1)}`;
2909
+ }
2910
+ return `${obj}.${prop}`;
2911
+ }
2912
+ case "member": {
2913
+ const memNode = node;
2914
+ const obj = compileExpression(memNode.object);
2915
+ const prop = typeof memNode.property === "string" ? memNode.property : null;
2916
+ if (!obj || !prop) return null;
2917
+ if (prop.startsWith("*")) {
2918
+ return `${obj}.style.${prop.slice(1)}`;
2919
+ }
2920
+ return `${obj}.${prop}`;
2921
+ }
2922
+ case "binary": {
2923
+ const binNode = node;
2924
+ const left = compileExpression(binNode.left);
2925
+ const right = compileExpression(binNode.right);
2926
+ if (!left || !right) return null;
2927
+ const op = binNode.operator;
2928
+ switch (op) {
2929
+ case "+":
2930
+ case "-":
2931
+ case "*":
2932
+ case "/":
2933
+ case "%":
2934
+ return `(${left} ${op} ${right})`;
2935
+ case "==":
2936
+ case "is":
2937
+ return `(${left} == ${right})`;
2938
+ case "!=":
2939
+ case "is not":
2940
+ return `(${left} != ${right})`;
2941
+ case "<":
2942
+ case ">":
2943
+ case "<=":
2944
+ case ">=":
2945
+ return `(${left} ${op} ${right})`;
2946
+ case "and":
2947
+ case "&&":
2948
+ return `(${left} && ${right})`;
2949
+ case "or":
2950
+ case "||":
2951
+ return `(${left} || ${right})`;
2952
+ case "has": {
2953
+ const rightSel = binNode.right;
2954
+ const className = rightSel.value?.slice(1) || "";
2955
+ const sanitizedClass = sanitizeClassName(className);
2956
+ if (!sanitizedClass) return null;
2957
+ return `${left}.classList.contains('${sanitizedClass}')`;
2958
+ }
2959
+ default:
2960
+ return null;
2961
+ }
2962
+ }
2963
+ case "call": {
2964
+ const callNode = node;
2965
+ const callee = callNode.callee;
2966
+ const args = (callNode.args || []).map(compileExpression);
2967
+ if (args.some((a) => a === null)) return null;
2968
+ if (callee.type === "member" || callee.type === "possessive") {
2969
+ const memCallee = callee;
2970
+ const obj = compileExpression(memCallee.object);
2971
+ const prop = typeof memCallee.property === "string" ? memCallee.property : null;
2972
+ if (!obj || !prop) return null;
2973
+ return `${obj}.${prop}(${args.join(", ")})`;
2974
+ }
2975
+ const fn = compileExpression(callee);
2976
+ if (!fn) return null;
2977
+ return `${fn}(${args.join(", ")})`;
2978
+ }
2979
+ case "positional": {
2980
+ const posNode = node;
2981
+ const position = posNode.position;
2982
+ const target = posNode.target;
2983
+ switch (position) {
2984
+ case "first":
2985
+ if (target?.type === "selector") {
2986
+ const selNode = target;
2987
+ const sanitized = sanitizeSelector(selNode.value);
2988
+ return `document.querySelector('${sanitized}')`;
2989
+ }
2990
+ return null;
2991
+ // Arrays need runtime
2992
+ case "last":
2993
+ if (target?.type === "selector") {
2994
+ const selNode = target;
2995
+ const sanitized = sanitizeSelector(selNode.value);
2996
+ return `(()=>{const e=document.querySelectorAll('${sanitized}');return e[e.length-1]})()`;
2997
+ }
2998
+ return null;
2999
+ // Arrays need runtime
3000
+ case "next":
3001
+ return "m.nextElementSibling";
3002
+ case "previous":
3003
+ return "m.previousElementSibling";
3004
+ case "closest":
3005
+ if (target?.type === "selector") {
3006
+ const selNode = target;
3007
+ const sanitized = sanitizeSelector(selNode.value);
3008
+ return `m.closest('${sanitized}')`;
3009
+ }
3010
+ return null;
3011
+ case "parent":
3012
+ return "m.parentElement";
3013
+ default:
3014
+ return null;
3015
+ }
3016
+ }
3017
+ default:
3018
+ return null;
3019
+ }
3020
+ }
3021
+ function compileTarget(target) {
3022
+ if (target.type === "identifier") {
3023
+ const idNode = target;
3024
+ if (idNode.value === "me" || idNode.value === "my") return "m";
3025
+ if (idNode.value === "you") return "y";
3026
+ }
3027
+ if (target.type === "selector") {
3028
+ const selNode = target;
3029
+ const sanitized = sanitizeSelector(selNode.value);
3030
+ return `document.querySelectorAll('${sanitized}')`;
3031
+ }
3032
+ const compiled = compileExpression(target);
3033
+ return compiled || "m";
3034
+ }
3035
+ function extractClassName(node) {
3036
+ if (!node) return null;
3037
+ if (node.type === "selector") {
3038
+ const selNode = node;
3039
+ const val = selNode.value;
3040
+ const rawClass = val.startsWith(".") ? val.slice(1) : val;
3041
+ return sanitizeClassName(rawClass);
3042
+ }
3043
+ if (node.type === "literal" || node.type === "string") {
3044
+ const litNode = node;
3045
+ const val = litNode.value;
3046
+ if (typeof val === "string") {
3047
+ const rawClass = val.startsWith(".") ? val.slice(1) : val;
3048
+ return sanitizeClassName(rawClass);
3049
+ }
3050
+ }
3051
+ if (node.type === "identifier") {
3052
+ const idNode = node;
3053
+ return sanitizeClassName(idNode.value);
3054
+ }
3055
+ return null;
3056
+ }
3057
+
3058
+ // src/compiled-generator.ts
3059
+ function generateSourceMapTable(handlers) {
3060
+ if (handlers.length === 0) return "";
3061
+ const lines = [
3062
+ " *",
3063
+ " * Handler Source Map:",
3064
+ " * \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510"
3065
+ ];
3066
+ for (const h of handlers) {
3067
+ const original = h.original.replace(/\n/g, " ").slice(0, 40);
3068
+ const truncated = original.length < h.original.length ? original + "..." : original;
3069
+ lines.push(` * \u2502 ${h.id.padEnd(20)} \u2190 ${truncated.padEnd(40)} \u2502`);
3070
+ }
3071
+ lines.push(" * \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518");
3072
+ lines.push(" *");
3073
+ return lines.join("\n");
3074
+ }
3075
+ function generateCompiledBundle(options) {
3076
+ const {
3077
+ handlers,
3078
+ needsLocals,
3079
+ needsGlobals,
3080
+ globalName = "hyperfixi",
3081
+ htmx = false,
3082
+ debug = false
3083
+ } = options;
3084
+ const handlerEntries = handlers.map((h) => {
3085
+ const isAsync = h.code.includes("await");
3086
+ const fn = isAsync ? `async(m,e,y)=>{${h.code}}` : `(m,e,y)=>{${h.code}}`;
3087
+ if (debug) {
3088
+ const escapedOriginal = h.original.replace(/\*/g, "\\*").replace(/\n/g, " ");
3089
+ return `
3090
+ /* ${escapedOriginal} */
3091
+ ${h.id}:${fn}`;
3092
+ }
3093
+ return `${h.id}:${fn}`;
3094
+ });
3095
+ const registrations = handlers.map((h) => {
3096
+ const modsCode = generateModifiersCode(h);
3097
+ return ` case '${h.id}': r(el,'${h.event}',H.${h.id}${modsCode}); break;`;
3098
+ });
3099
+ const localsCode = needsLocals ? "const L={};" : "";
3100
+ const globalsCode = needsGlobals ? "const G={};" : "";
3101
+ const sourceMapTable = debug ? generateSourceMapTable(handlers) : "";
3102
+ return `/**
3103
+ * HyperFixi Compiled Bundle (Auto-Generated)
3104
+ *
3105
+ * Pre-compiled hyperscript - no runtime parser needed!
3106
+ * Handlers: ${handlers.length}
3107
+ *
3108
+ * DO NOT EDIT - Regenerate with build.
3109
+ ${sourceMapTable} */
3110
+
3111
+ ${localsCode}${globalsCode}
3112
+ const H={${handlerEntries.join(",")}};
3113
+
3114
+ function r(el,ev,fn${hasModifiers(handlers) ? ",m" : ""}){
3115
+ let h=e=>fn(el,e,e.target);
3116
+ ${generateModifierWrappers(handlers)}
3117
+ el.addEventListener(ev,h${hasOnce(handlers) ? ",{once:m?.o}" : ""});
3118
+ }
3119
+
3120
+ function init(root=document){
3121
+ root.querySelectorAll('[data-h]').forEach(el=>{
3122
+ switch(el.dataset.h){
3123
+ ${registrations.join("\n")}
3124
+ }
3125
+ });
3126
+ }
3127
+
3128
+ ${htmx ? `document.addEventListener('htmx:afterSettle',e=>init(e.detail?.target));` : ""}
3129
+
3130
+ const api={
3131
+ version:'1.0.0-compiled',
3132
+ commands:${JSON.stringify(handlers.map((h) => h.id))},
3133
+ init,
3134
+ process:init,
3135
+ };
3136
+
3137
+ if(typeof window!=='undefined'){
3138
+ window.${globalName}=api;
3139
+ window._hyperscript=api;
3140
+ document.readyState==='loading'
3141
+ ?document.addEventListener('DOMContentLoaded',()=>init())
3142
+ :init();
3143
+ }
3144
+
3145
+ export default api;
3146
+ export{api,init};
3147
+ `;
3148
+ }
3149
+ function generateModifiersCode(h) {
3150
+ const mods = [];
3151
+ if (h.modifiers.prevent) mods.push("p:1");
3152
+ if (h.modifiers.stop) mods.push("s:1");
3153
+ if (h.modifiers.once) mods.push("o:1");
3154
+ if (h.modifiers.debounce) mods.push(`d:${h.modifiers.debounce}`);
3155
+ if (h.modifiers.throttle) mods.push(`t:${h.modifiers.throttle}`);
3156
+ if (mods.length === 0) return "";
3157
+ return `,{${mods.join(",")}}`;
3158
+ }
3159
+ function hasModifiers(handlers) {
3160
+ return handlers.some(
3161
+ (h) => h.modifiers.prevent || h.modifiers.stop || h.modifiers.once || h.modifiers.debounce || h.modifiers.throttle
3162
+ );
3163
+ }
3164
+ function hasOnce(handlers) {
3165
+ return handlers.some((h) => h.modifiers.once);
3166
+ }
3167
+ function generateModifierWrappers(handlers) {
3168
+ const lines = [];
3169
+ if (handlers.some((h) => h.modifiers.prevent || h.modifiers.stop)) {
3170
+ lines.push(
3171
+ ` if(m?.p||m?.s){const _h=h;h=e=>{m.p&&e.preventDefault();m.s&&e.stopPropagation();_h(e.currentTarget,e,e.target)};}`
3172
+ );
3173
+ }
3174
+ if (handlers.some((h) => h.modifiers.debounce)) {
3175
+ lines.push(
3176
+ ` if(m?.d){let t;const _h=h;h=e=>{clearTimeout(t);t=setTimeout(()=>_h(e.currentTarget,e,e.target),m.d)};}`
3177
+ );
3178
+ }
3179
+ if (handlers.some((h) => h.modifiers.throttle)) {
3180
+ lines.push(
3181
+ ` if(m?.t){let l=0;const _h=h;h=e=>{const n=Date.now();if(n-l>=m.t){l=n;_h(e.currentTarget,e,e.target)}};}`
3182
+ );
3183
+ }
3184
+ return lines.join("\n");
3185
+ }
3186
+
3187
+ // src/html-transformer.ts
3188
+ function transformHTML(html, handlerMap, fallbackScripts) {
3189
+ let modified = false;
3190
+ const fallbacks = [];
3191
+ const patterns = [
3192
+ /(\s)_\s*=\s*"([^"]+)"/g,
3193
+ // _="..."
3194
+ /(\s)_\s*=\s*'([^']+)'/g,
3195
+ // _='...'
3196
+ /(\s)_\s*=\s*`([^`]+)`/g
3197
+ // _=`...`
3198
+ ];
3199
+ let result = html;
3200
+ for (const pattern of patterns) {
3201
+ result = result.replace(pattern, (match, whitespace, script) => {
3202
+ const handlerId = handlerMap.get(script);
3203
+ if (handlerId) {
3204
+ modified = true;
3205
+ return `${whitespace}data-h="${handlerId}"`;
3206
+ }
3207
+ if (fallbackScripts.has(script)) {
3208
+ fallbacks.push(script);
3209
+ return match;
3210
+ }
3211
+ fallbacks.push(script);
3212
+ return match;
3213
+ });
3214
+ }
3215
+ return {
3216
+ code: result,
3217
+ modified,
3218
+ fallbacks
3219
+ };
3220
+ }
3221
+ function extractScripts(html) {
3222
+ const scripts = [];
3223
+ const patterns = [/_\s*=\s*"([^"]+)"/g, /_\s*=\s*'([^']+)'/g, /_\s*=\s*`([^`]+)`/g];
3224
+ for (const pattern of patterns) {
3225
+ let match;
3226
+ while (match = pattern.exec(html)) {
3227
+ scripts.push(match[1]);
3228
+ }
3229
+ }
3230
+ return scripts;
3231
+ }
3232
+
3233
+ // src/index.ts
3234
+ var VIRTUAL_MODULE_ID = "virtual:hyperfixi";
3235
+ var RESOLVED_VIRTUAL_MODULE_ID = "\0" + VIRTUAL_MODULE_ID;
3236
+ var IMPORT_ALIASES = ["hyperfixi", "@hyperfixi/core", "virtual:hyperfixi"];
3237
+ function hyperfixi(options = {}) {
3238
+ const mode = options.mode ?? "interpret";
3239
+ const scanner = new Scanner(options);
3240
+ const aggregator = new Aggregator();
3241
+ const generator = new Generator(options);
3242
+ let server = null;
3243
+ let cachedBundle = null;
3244
+ let lastUsageHash = "";
3245
+ let isDev = false;
3246
+ const compiledHandlers = [];
3247
+ const handlerMap = /* @__PURE__ */ new Map();
3248
+ const fallbackScripts = /* @__PURE__ */ new Set();
3249
+ let needsLocals = false;
3250
+ let needsGlobals = false;
3251
+ function computeUsageHash(usage) {
3252
+ const commands = [...usage.commands].sort().join(",");
3253
+ const blocks = [...usage.blocks].sort().join(",");
3254
+ const languages = [...usage.detectedLanguages].sort().join(",");
3255
+ return `${commands}|${blocks}|${usage.positional}|${languages}`;
3256
+ }
3257
+ function invalidateVirtualModule() {
3258
+ if (!server) return;
3259
+ const mod = server.moduleGraph.getModuleById(RESOLVED_VIRTUAL_MODULE_ID);
3260
+ if (mod) {
3261
+ server.moduleGraph.invalidateModule(mod);
3262
+ server.ws.send({ type: "full-reload" });
3263
+ if (options.debug) {
3264
+ console.log("[hyperfixi] Virtual module invalidated, triggering reload");
3265
+ }
3266
+ }
3267
+ }
3268
+ function compileScript(script) {
3269
+ if (handlerMap.has(script)) {
3270
+ return handlerMap.get(script);
3271
+ }
3272
+ if (fallbackScripts.has(script)) {
3273
+ return null;
3274
+ }
3275
+ const handler = compile(script);
3276
+ if (handler) {
3277
+ compiledHandlers.push(handler);
3278
+ handlerMap.set(script, handler.id);
3279
+ if (handler.needsEvaluator) {
3280
+ if (handler.code.includes("L.")) needsLocals = true;
3281
+ if (handler.code.includes("G.")) needsGlobals = true;
3282
+ }
3283
+ if (options.debug) {
3284
+ console.log(`[hyperfixi] Compiled: "${script}" -> ${handler.id}`);
3285
+ }
3286
+ return handler.id;
3287
+ }
3288
+ fallbackScripts.add(script);
3289
+ if (options.debug) {
3290
+ console.log(`[hyperfixi] Fallback (not compilable): "${script}"`);
3291
+ }
3292
+ return null;
3293
+ }
3294
+ function generateInterpretBundle() {
3295
+ const usage = aggregator.getUsage();
3296
+ const usageHash = computeUsageHash(usage);
3297
+ if (cachedBundle && usageHash === lastUsageHash) {
3298
+ return cachedBundle;
3299
+ }
3300
+ if (isDev && options.devFallback && options.devFallback !== "auto") {
3301
+ cachedBundle = generator.generateDevFallback(options.devFallback);
3302
+ } else {
3303
+ cachedBundle = generator.generate(usage, options);
3304
+ }
3305
+ lastUsageHash = usageHash;
3306
+ if (options.debug) {
3307
+ const summary = aggregator.getSummary();
3308
+ console.log("[hyperfixi] Bundle generated:", summary);
3309
+ }
3310
+ return cachedBundle;
3311
+ }
3312
+ function generateCompiledBundleCode() {
3313
+ if (fallbackScripts.size > 0) {
3314
+ if (options.debug) {
3315
+ console.log(`[hyperfixi] ${fallbackScripts.size} scripts need interpreter fallback`);
3316
+ }
3317
+ return generateInterpretBundle();
3318
+ }
3319
+ const bundle = generateCompiledBundle({
3320
+ handlers: compiledHandlers,
3321
+ needsLocals,
3322
+ needsGlobals,
3323
+ globalName: options.globalName,
3324
+ htmx: options.htmx,
3325
+ debug: options.debug
3326
+ });
3327
+ if (options.debug) {
3328
+ console.log(`[hyperfixi] Compiled bundle: ${compiledHandlers.length} handlers`);
3329
+ }
3330
+ return bundle;
3331
+ }
3332
+ function generateBundle() {
3333
+ if (mode === "compile") {
3334
+ return generateCompiledBundleCode();
3335
+ }
3336
+ return generateInterpretBundle();
3337
+ }
3338
+ return {
3339
+ name: "vite-plugin-hyperfixi",
3340
+ enforce: "pre",
3341
+ /**
3342
+ * Configure plugin based on Vite mode
3343
+ */
3344
+ configResolved(config) {
3345
+ isDev = config.command === "serve";
3346
+ if (options.debug) {
3347
+ console.log("[hyperfixi] Plugin initialized, mode:", isDev ? "development" : "production");
3348
+ }
3349
+ },
3350
+ /**
3351
+ * Store server reference and pre-scan HTML files for HMR
3352
+ */
3353
+ async configureServer(_server) {
3354
+ server = _server;
3355
+ const cwd = _server.config.root;
3356
+ if (options.debug) {
3357
+ console.log("[hyperfixi] Pre-scanning project:", cwd);
3358
+ }
3359
+ const scannedFiles = await scanner.scanProject(cwd);
3360
+ aggregator.loadFromScan(scannedFiles);
3361
+ if (options.debug) {
3362
+ const summary = aggregator.getSummary();
3363
+ console.log("[hyperfixi] Pre-scan complete:", summary);
3364
+ }
3365
+ },
3366
+ /**
3367
+ * Resolve virtual module imports
3368
+ */
3369
+ resolveId(id) {
3370
+ if (IMPORT_ALIASES.includes(id)) {
3371
+ return RESOLVED_VIRTUAL_MODULE_ID;
3372
+ }
3373
+ return null;
3374
+ },
3375
+ /**
3376
+ * Load the virtual module with generated bundle
3377
+ */
3378
+ load(id) {
3379
+ if (id === RESOLVED_VIRTUAL_MODULE_ID) {
3380
+ return generateBundle();
3381
+ }
3382
+ return null;
3383
+ },
3384
+ /**
3385
+ * Scan files during transform for hyperscript usage
3386
+ */
3387
+ transform(code, id) {
3388
+ if (!scanner.shouldScan(id)) {
3389
+ return null;
3390
+ }
3391
+ if (mode === "compile" && !isDev) {
3392
+ const scripts = extractScripts(code);
3393
+ for (const script of scripts) {
3394
+ compileScript(script);
3395
+ }
3396
+ const result = transformHTML(code, handlerMap, fallbackScripts);
3397
+ if (result.modified) {
3398
+ if (options.debug) {
3399
+ console.log(`[hyperfixi] Transformed: ${id.split("/").pop()}`);
3400
+ }
3401
+ return { code: result.code, map: null };
3402
+ }
3403
+ return null;
3404
+ }
3405
+ const usage = scanner.scan(code, id);
3406
+ const changed = aggregator.add(id, usage);
3407
+ if (changed && server) {
3408
+ setImmediate(() => {
3409
+ const currentHash = computeUsageHash(aggregator.getUsage());
3410
+ if (currentHash !== lastUsageHash) {
3411
+ invalidateVirtualModule();
3412
+ }
3413
+ });
3414
+ }
3415
+ return null;
3416
+ },
3417
+ /**
3418
+ * Handle file changes in HMR
3419
+ */
3420
+ async handleHotUpdate(ctx) {
3421
+ const { file, read } = ctx;
3422
+ if (scanner.shouldScan(file)) {
3423
+ try {
3424
+ const content = await read();
3425
+ const usage = scanner.scan(content, file);
3426
+ const changed = aggregator.add(file, usage);
3427
+ if (options.debug) {
3428
+ console.log("[hyperfixi] HMR: Re-scanned", file.split("/").pop(), usage);
3429
+ }
3430
+ if (changed) {
3431
+ const currentHash = computeUsageHash(aggregator.getUsage());
3432
+ if (currentHash !== lastUsageHash) {
3433
+ invalidateVirtualModule();
3434
+ }
3435
+ }
3436
+ } catch {
3437
+ if (aggregator.remove(file)) {
3438
+ invalidateVirtualModule();
3439
+ }
3440
+ }
3441
+ }
3442
+ return void 0;
3443
+ },
3444
+ /**
3445
+ * Scan entire project before production build
3446
+ */
3447
+ async buildStart() {
3448
+ if (!isDev) {
3449
+ if (mode === "compile") {
3450
+ resetCompiler();
3451
+ compiledHandlers.length = 0;
3452
+ handlerMap.clear();
3453
+ fallbackScripts.clear();
3454
+ needsLocals = false;
3455
+ needsGlobals = false;
3456
+ if (options.debug) {
3457
+ console.log("[hyperfixi] Compile mode: ready for build");
3458
+ }
3459
+ }
3460
+ const cwd = process.cwd();
3461
+ if (options.debug) {
3462
+ console.log("[hyperfixi] Scanning project for hyperscript usage...");
3463
+ }
3464
+ const scannedFiles = await scanner.scanProject(cwd);
3465
+ aggregator.loadFromScan(scannedFiles);
3466
+ if (mode === "compile") {
3467
+ const usage = aggregator.getUsage();
3468
+ if (usage.detectedLanguages.size > 0) {
3469
+ const aliases = getMultilingualCommandAliases(
3470
+ usage.detectedLanguages
3471
+ );
3472
+ if (Object.keys(aliases).length > 0) {
3473
+ setMultilingualAliases(aliases);
3474
+ if (options.debug) {
3475
+ console.log(
3476
+ `[hyperfixi] Compile mode: configured ${Object.keys(aliases).length} multilingual aliases`
3477
+ );
3478
+ }
3479
+ }
3480
+ }
3481
+ }
3482
+ if (options.debug) {
3483
+ const summary = aggregator.getSummary();
3484
+ console.log(`[hyperfixi] Found ${summary.fileCount} files with hyperscript:`, {
3485
+ commands: summary.commands,
3486
+ blocks: summary.blocks,
3487
+ positional: summary.positional,
3488
+ languages: summary.languages
3489
+ });
3490
+ }
3491
+ }
3492
+ }
3493
+ };
3494
+ }
3495
+ var index_default = hyperfixi;
3496
+ export {
3497
+ REGIONS,
3498
+ SUPPORTED_LANGUAGES,
3499
+ clearCustomKeywords,
3500
+ clearSemanticParser,
3501
+ index_default as default,
3502
+ detectLanguages,
3503
+ getAllLanguageCodes,
3504
+ getKeywordsForLanguage,
3505
+ getOptimalRegion,
3506
+ hasSemanticParser,
3507
+ hyperfixi,
3508
+ isNonLatinLanguage,
3509
+ registerCustomKeywords,
3510
+ setSemanticParser
3511
+ };
3512
+ //# sourceMappingURL=index.js.map