@lokascript/i18n 2.7.2 → 2.9.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.
Files changed (61) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/README.md +1 -1
  3. package/dist/browser.cjs +649 -180
  4. package/dist/browser.cjs.map +1 -1
  5. package/dist/browser.d.cts +2 -2
  6. package/dist/browser.d.ts +2 -2
  7. package/dist/browser.js +649 -180
  8. package/dist/browser.js.map +1 -1
  9. package/dist/dictionaries/index.cjs +370 -174
  10. package/dist/dictionaries/index.cjs.map +1 -1
  11. package/dist/dictionaries/index.js +370 -174
  12. package/dist/dictionaries/index.js.map +1 -1
  13. package/dist/index.cjs +649 -180
  14. package/dist/index.cjs.map +1 -1
  15. package/dist/index.d.cts +1 -1
  16. package/dist/index.d.ts +1 -1
  17. package/dist/index.js +649 -180
  18. package/dist/index.js.map +1 -1
  19. package/dist/lokascript-i18n.min.js +1 -1
  20. package/dist/lokascript-i18n.min.js.map +1 -1
  21. package/dist/lokascript-i18n.mjs +678 -175
  22. package/dist/lokascript-i18n.mjs.map +1 -1
  23. package/dist/plugins/vite.cjs +370 -174
  24. package/dist/plugins/vite.cjs.map +1 -1
  25. package/dist/plugins/vite.js +370 -174
  26. package/dist/plugins/vite.js.map +1 -1
  27. package/dist/plugins/webpack.cjs +370 -174
  28. package/dist/plugins/webpack.cjs.map +1 -1
  29. package/dist/plugins/webpack.js +370 -174
  30. package/dist/plugins/webpack.js.map +1 -1
  31. package/dist/{transformer-DM7iplCU.d.cts → transformer--W46PGaW.d.cts} +8 -0
  32. package/dist/{transformer-BA8YX9u1.d.ts → transformer-FU06J6kG.d.ts} +8 -0
  33. package/package.json +9 -10
  34. package/src/dictionaries/ar.ts +20 -15
  35. package/src/dictionaries/bn.ts +10 -5
  36. package/src/dictionaries/de.ts +20 -8
  37. package/src/dictionaries/es.ts +10 -5
  38. package/src/dictionaries/fr.ts +15 -6
  39. package/src/dictionaries/he.ts +4 -0
  40. package/src/dictionaries/hi.ts +3 -2
  41. package/src/dictionaries/id.ts +31 -16
  42. package/src/dictionaries/it.ts +11 -4
  43. package/src/dictionaries/ja.ts +23 -15
  44. package/src/dictionaries/ko.ts +10 -5
  45. package/src/dictionaries/ms.ts +4 -1
  46. package/src/dictionaries/pl.ts +12 -5
  47. package/src/dictionaries/pt.ts +10 -5
  48. package/src/dictionaries/qu.ts +30 -19
  49. package/src/dictionaries/ru.ts +5 -2
  50. package/src/dictionaries/sw.ts +29 -14
  51. package/src/dictionaries/th.ts +5 -2
  52. package/src/dictionaries/tl.ts +4 -1
  53. package/src/dictionaries/tr.ts +24 -16
  54. package/src/dictionaries/uk.ts +5 -2
  55. package/src/dictionaries/vi.ts +23 -17
  56. package/src/dictionaries/zh.ts +24 -9
  57. package/src/grammar/grammar.test.ts +152 -0
  58. package/src/grammar/profiles/index.ts +316 -1
  59. package/src/grammar/transformer.ts +64 -1
  60. package/src/new-languages.test.ts +9 -3
  61. package/src/positional-keyword-drift.test.ts +6 -19
package/dist/browser.cjs CHANGED
@@ -595,17 +595,20 @@ var es = {
595
595
  mouseup: "rat\xF3narriba",
596
596
  mouseenter: "rat\xF3nentrar",
597
597
  mouseleave: "rat\xF3nsalir",
598
- mouseover: "rat\xF3nencima",
599
- mouseout: "rat\xF3nfuera",
598
+ // V3 Batch 2: fused forms split to the S5b/tokenizer-known forms (the fused
599
+ // spellings captured event=expression:undefined — broken listeners)
600
+ mouseover: "rat\xF3n encima",
601
+ mouseout: "rat\xF3n fuera",
600
602
  mousemove: "rat\xF3nmover",
601
- keydown: "teclaabajo",
602
- keyup: "teclaarriba",
603
+ keydown: "tecla abajo",
604
+ keyup: "tecla arriba",
603
605
  keypress: "teclapresar",
604
606
  focus: "enfocar",
605
607
  blur: "desenfocar",
606
608
  change: "cambiar",
607
609
  input: "entrada",
608
- submit: "enviar",
610
+ submit: "env\xEDo",
611
+ // Batch 3: enviar is the send verb — on-submit listener captured event "send"
609
612
  reset: "reiniciar",
610
613
  load: "cargar",
611
614
  unload: "descargar",
@@ -685,6 +688,9 @@ var es = {
685
688
  properties: "propiedades"
686
689
  },
687
690
  expressions: {
691
+ characters: "caracteres",
692
+ inclusive: "inclusivo",
693
+ exclusive: "exclusivo",
688
694
  first: "primero",
689
695
  last: "\xFAltimo",
690
696
  next: "siguiente",
@@ -776,7 +782,8 @@ var ja = {
776
782
  clear: "\u30AF\u30EA\u30A2",
777
783
  close: "\u9589\u3058\u308B",
778
784
  open: "\u958B\u304F",
779
- select: "\u9078\u629E",
785
+ select: "\u9078\u3076",
786
+ // Batch 3: 選択 is the pick keyword — bare select rendered with it parses null
780
787
  clone: "\u8907\u88FD",
781
788
  prepend: "\u5148\u982D\u8FFD\u52A0",
782
789
  socket: "\u30BD\u30B1\u30C3\u30C8"
@@ -801,17 +808,22 @@ var ja = {
801
808
  },
802
809
  events: {
803
810
  click: "\u30AF\u30EA\u30C3\u30AF",
804
- dblclick: "\u30C0\u30D6\u30EB\u30AF\u30EA\u30C3\u30AF",
811
+ dblclick: "dblclick",
805
812
  mousedown: "\u30DE\u30A6\u30B9\u62BC\u4E0B",
806
813
  mouseup: "\u30DE\u30A6\u30B9\u89E3\u653E",
807
- mouseenter: "\u30DE\u30A6\u30B9\u5165\u308B",
808
- mouseleave: "\u30DE\u30A6\u30B9\u96E2\u308C\u308B",
809
- mouseover: "\u30DE\u30A6\u30B9\u4E0A",
810
- mouseout: "\u30DE\u30A6\u30B9\u5916",
811
- mousemove: "\u30DE\u30A6\u30B9\u79FB\u52D5",
812
- keydown: "\u30AD\u30FC\u62BC\u4E0B",
813
- keyup: "\u30AD\u30FC\u89E3\u653E",
814
- keypress: "\u30AD\u30FC\u62BC\u3059",
814
+ // V3c burn-down (2026-07-14): English passthrough — no native form round-trips
815
+ // on the parse side (probe: split forms shatter, fused forms capture verbatim).
816
+ mouseenter: "mouseenter",
817
+ mouseleave: "mouseleave",
818
+ // V3 Batch 2: kanji compounds realigned to the S5b/tokenizer katakana
819
+ // loanwords (the standard JS event terms; the compounds captured
820
+ // event=expression:undefined — broken listeners)
821
+ mouseover: "\u30DE\u30A6\u30B9\u30AA\u30FC\u30D0\u30FC",
822
+ mouseout: "\u30DE\u30A6\u30B9\u30A2\u30A6\u30C8",
823
+ mousemove: "mousemove",
824
+ keydown: "\u30AD\u30FC\u30C0\u30A6\u30F3",
825
+ keyup: "\u30AD\u30FC\u30A2\u30C3\u30D7",
826
+ keypress: "\u30AD\u30FC\u30D7\u30EC\u30B9",
815
827
  focus: "\u30D5\u30A9\u30FC\u30AB\u30B9",
816
828
  blur: "\u307C\u304B\u3057",
817
829
  change: "\u5909\u66F4",
@@ -819,13 +831,13 @@ var ja = {
819
831
  submit: "\u9001\u4FE1",
820
832
  reset: "\u30EA\u30BB\u30C3\u30C8",
821
833
  load: "\u8AAD\u307F\u8FBC\u307F",
822
- unload: "\u8AAD\u307F\u8FBC\u307F\u89E3\u9664",
834
+ unload: "unload",
823
835
  resize: "\u30B5\u30A4\u30BA\u5909\u66F4",
824
836
  scroll: "\u30B9\u30AF\u30ED\u30FC\u30EB",
825
- touchstart: "\u30BF\u30C3\u30C1\u958B\u59CB",
826
- touchend: "\u30BF\u30C3\u30C1\u7D42\u4E86",
827
- touchmove: "\u30BF\u30C3\u30C1\u79FB\u52D5",
828
- touchcancel: "\u30BF\u30C3\u30C1\u30AD\u30E3\u30F3\u30BB\u30EB"
837
+ touchstart: "touchstart",
838
+ touchend: "touchend",
839
+ touchmove: "touchmove",
840
+ touchcancel: "touchcancel"
829
841
  },
830
842
  logical: {
831
843
  when: "\u6642",
@@ -897,6 +909,9 @@ var ja = {
897
909
  properties: "\u30D7\u30ED\u30D1\u30C6\u30A3\u7FA4"
898
910
  },
899
911
  expressions: {
912
+ characters: "\u6587\u5B57",
913
+ inclusive: "\u542B\u3080",
914
+ exclusive: "\u9664\u304F",
900
915
  first: "\u6700\u521D",
901
916
  last: "\u6700\u5F8C",
902
917
  next: "\u6B21",
@@ -1013,15 +1028,21 @@ var fr = {
1013
1028
  events: {
1014
1029
  click: "clic",
1015
1030
  dblclick: "doubleclic",
1016
- mousedown: "sourisappuy\xE9e",
1017
- mouseup: "sourisrel\xE2ch\xE9e",
1031
+ // mousedown/mouseup: English passthrough — no native form round-trips on the
1032
+ // parse side (V3c probe 2026-07-14: fused forms captured verbatim, split forms
1033
+ // shattered to their first word — live broken listeners in repeat-until-event).
1034
+ // The Batch-2 id-keyup precedent; revisit if S5b + tokenizer gain native entries.
1035
+ mousedown: "mousedown",
1036
+ mouseup: "mouseup",
1018
1037
  mouseenter: "sourisentrer",
1019
1038
  mouseleave: "sourissortir",
1020
- mouseover: "sourissur",
1021
- mouseout: "sourisdehors",
1039
+ // V3 Batch 2: fused forms split to the S5b/tokenizer-known forms (the fused
1040
+ // spellings captured event=expression:undefined — broken listeners)
1041
+ mouseover: "souris dessus",
1042
+ mouseout: "souris dehors",
1022
1043
  mousemove: "sourisbouger",
1023
- keydown: "toucheappuy\xE9e",
1024
- keyup: "toucherel\xE2ch\xE9e",
1044
+ keydown: "touche bas",
1045
+ keyup: "touche haut",
1025
1046
  keypress: "touchepress\xE9e",
1026
1047
  focus: "focus",
1027
1048
  blur: "flou",
@@ -1107,6 +1128,9 @@ var fr = {
1107
1128
  properties: "propri\xE9t\xE9s"
1108
1129
  },
1109
1130
  expressions: {
1131
+ characters: "caract\xE8res",
1132
+ inclusive: "inclusif",
1133
+ exclusive: "exclusif",
1110
1134
  first: "premier",
1111
1135
  last: "dernier",
1112
1136
  next: "suivant",
@@ -1202,7 +1226,8 @@ var de = {
1202
1226
  // löschen is a remove alternative in the profile
1203
1227
  close: "schlie\xDFen",
1204
1228
  open: "\xF6ffnen",
1205
- select: "ausw\xE4hlen",
1229
+ select: "markieren",
1230
+ // Batch 3: auswählen is the pick keyword — bare select rendered with it parses null
1206
1231
  clone: "klonen",
1207
1232
  prepend: "voranstellen",
1208
1233
  focus: "fokussieren"
@@ -1228,18 +1253,27 @@ var de = {
1228
1253
  events: {
1229
1254
  click: "klick",
1230
1255
  dblclick: "doppelklick",
1231
- mousedown: "mausunten",
1232
- mouseup: "mausoben",
1256
+ // mousedown/mouseup: English passthrough — no native form round-trips on the
1257
+ // parse side (V3c probe 2026-07-14: fused forms captured verbatim, split forms
1258
+ // shattered to their first word — live broken listeners in repeat-until-event).
1259
+ // The Batch-2 id-keyup precedent; revisit if S5b + tokenizer gain native entries.
1260
+ mousedown: "mousedown",
1261
+ mouseup: "mouseup",
1233
1262
  mouseenter: "mauseintreten",
1234
1263
  mouseleave: "mausverlassen",
1235
- mouseover: "maus\xFCber",
1236
- mouseout: "maushinaus",
1264
+ // V3 Batch 2: fused/dead event words realigned to the de tokenizer's
1265
+ // registered forms (S5b's `maus über`/`taste runter` are aspirational — they
1266
+ // do not tokenize; `mausüber` etc. captured event=expression:undefined).
1267
+ mouseover: "maus dr\xFCber",
1268
+ mouseout: "maus weg",
1237
1269
  mousemove: "mausbewegen",
1238
- keydown: "tasteunten",
1239
- keyup: "tasteoben",
1270
+ keydown: "taste unten",
1271
+ keyup: "taste oben",
1240
1272
  keypress: "tastedr\xFCcken",
1241
1273
  focus: "fokus",
1242
- blur: "unscharf",
1274
+ // matches commands.blur (which shadows this at render time) and the live
1275
+ // corpus render; `unscharf` was dead vocab that captured no event
1276
+ blur: "defokussieren",
1243
1277
  change: "\xE4ndern",
1244
1278
  input: "eingabe",
1245
1279
  submit: "absenden",
@@ -1322,6 +1356,9 @@ var de = {
1322
1356
  properties: "eigenschaften"
1323
1357
  },
1324
1358
  expressions: {
1359
+ characters: "Zeichen",
1360
+ inclusive: "inklusiv",
1361
+ exclusive: "exklusiv",
1325
1362
  first: "erste",
1326
1363
  last: "letzte",
1327
1364
  next: "n\xE4chste",
@@ -1419,7 +1456,8 @@ var ar = {
1419
1456
  // امسح is a remove alternative in the profile
1420
1457
  close: "\u0623\u063A\u0644\u0642",
1421
1458
  open: "\u0627\u0641\u062A\u062D",
1422
- select: "\u0627\u062E\u062A\u0631",
1459
+ select: "\u0638\u0644\u0644",
1460
+ // Batch 3: اختر is the pick keyword — bare select rendered with it parses null
1423
1461
  clone: "\u0627\u0633\u062A\u0646\u0633\u062E",
1424
1462
  prepend: "\u0633\u0628\u0642",
1425
1463
  socket: "\u0645\u0642\u0628\u0633"
@@ -1444,31 +1482,33 @@ var ar = {
1444
1482
  },
1445
1483
  events: {
1446
1484
  click: "\u0646\u0642\u0631",
1447
- dblclick: "\u0646\u0642\u0631 \u0645\u0632\u062F\u0648\u062C",
1448
- mousedown: "\u0641\u0623\u0631\u0629 \u0623\u0633\u0641\u0644",
1449
- mouseup: "\u0641\u0623\u0631\u0629 \u0623\u0639\u0644\u0649",
1450
- mouseenter: "\u0641\u0623\u0631\u0629 \u062F\u062E\u0648\u0644",
1451
- mouseleave: "\u0641\u0623\u0631\u0629 \u062E\u0631\u0648\u062C",
1485
+ // V3c burn-down (2026-07-14): English passthrough — no native form round-trips
1486
+ // on the parse side (probe: split forms shatter, fused forms capture verbatim).
1487
+ dblclick: "dblclick",
1488
+ mousedown: "mousedown",
1489
+ mouseup: "mouseup",
1490
+ mouseenter: "mouseenter",
1491
+ mouseleave: "mouseleave",
1452
1492
  mouseover: "\u0641\u0623\u0631\u0629 \u0641\u0648\u0642",
1453
- mouseout: "\u0641\u0623\u0631\u0629 \u062E\u0627\u0631\u062C",
1454
- mousemove: "\u0641\u0623\u0631\u0629 \u062A\u062D\u0631\u0643",
1493
+ mouseout: "mouseout",
1494
+ mousemove: "mousemove",
1455
1495
  keydown: "\u0645\u0641\u062A\u0627\u062D \u0623\u0633\u0641\u0644",
1456
1496
  keyup: "\u0645\u0641\u062A\u0627\u062D \u0623\u0639\u0644\u0649",
1457
- keypress: "\u0645\u0641\u062A\u0627\u062D \u0636\u063A\u0637",
1497
+ keypress: "keypress",
1458
1498
  focus: "\u062A\u0631\u0643\u064A\u0632",
1459
1499
  blur: "\u0636\u0628\u0627\u0628\u064A\u0629",
1460
1500
  change: "\u062A\u063A\u064A\u064A\u0631",
1461
1501
  input: "\u0625\u062F\u062E\u0627\u0644",
1462
1502
  submit: "\u0625\u0631\u0633\u0627\u0644",
1463
- reset: "\u0625\u0639\u0627\u062F\u0629 \u062A\u0639\u064A\u064A\u0646",
1503
+ reset: "reset",
1464
1504
  load: "\u062A\u062D\u0645\u064A\u0644",
1465
- unload: "\u0625\u0644\u063A\u0627\u0621 \u062A\u062D\u0645\u064A\u0644",
1505
+ unload: "unload",
1466
1506
  resize: "\u062A\u063A\u064A\u064A\u0631 \u062D\u062C\u0645",
1467
1507
  scroll: "\u062A\u0645\u0631\u064A\u0631",
1468
- touchstart: "\u0628\u062F\u0627\u064A\u0629 \u0644\u0645\u0633",
1469
- touchend: "\u0646\u0647\u0627\u064A\u0629 \u0644\u0645\u0633",
1470
- touchmove: "\u062A\u062D\u0631\u0643 \u0644\u0645\u0633",
1471
- touchcancel: "\u0625\u0644\u063A\u0627\u0621 \u0644\u0645\u0633"
1508
+ touchstart: "touchstart",
1509
+ touchend: "touchend",
1510
+ touchmove: "touchmove",
1511
+ touchcancel: "touchcancel"
1472
1512
  },
1473
1513
  logical: {
1474
1514
  when: "\u0639\u0646\u062F\u0645\u0627",
@@ -1540,6 +1580,9 @@ var ar = {
1540
1580
  properties: "\u062E\u0635\u0627\u0626\u0635"
1541
1581
  },
1542
1582
  expressions: {
1583
+ characters: "\u062D\u0631\u0648\u0641",
1584
+ inclusive: "\u0634\u0627\u0645\u0644",
1585
+ exclusive: "\u062D\u0635\u0631\u064A",
1543
1586
  first: "\u0623\u0648\u0644",
1544
1587
  last: "\u0622\u062E\u0631",
1545
1588
  next: "\u0627\u0644\u062A\u0627\u0644\u064A",
@@ -1632,7 +1675,8 @@ var ko = {
1632
1675
  clear: "\uC9C0\uC6B0\uAE30",
1633
1676
  close: "\uB2EB\uAE30",
1634
1677
  open: "\uC5F4\uAE30",
1635
- select: "\uC120\uD0DD",
1678
+ select: "\uACE0\uB974\uAE30",
1679
+ // Batch 3: 선택 is the pick keyword — bare select rendered with it parses null
1636
1680
  clone: "\uBCF5\uC81C",
1637
1681
  prepend: "\uC55E\uC5D0\uCD94\uAC00",
1638
1682
  socket: "\uC18C\uCF13"
@@ -1673,14 +1717,17 @@ var ko = {
1673
1717
  change: "\uBCC0\uACBD",
1674
1718
  input: "\uC785\uB825",
1675
1719
  submit: "\uC81C\uCD9C",
1676
- reset: "\uB9AC\uC14B",
1720
+ reset: "\uC7AC\uC124\uC815",
1721
+ // Batch 3: 리셋 captured on.event as expression (broken listener) — profile word round-trips
1677
1722
  load: "\uB85C\uB4DC",
1678
- unload: "\uC5B8\uB85C\uB4DC",
1723
+ unload: "unload",
1679
1724
  resize: "\uB9AC\uC0AC\uC774\uC988",
1680
1725
  scroll: "\uC2A4\uD06C\uB864",
1681
- touchstart: "\uD130\uCE58\uC2DC\uC791",
1726
+ // V3c burn-down (2026-07-14): English passthrough — no native form round-trips
1727
+ // on the parse side (probe: split forms shatter, fused forms capture verbatim).
1728
+ touchstart: "touchstart",
1682
1729
  touchend: "\uD130\uCE58\uC885\uB8CC",
1683
- touchmove: "\uD130\uCE58\uC774\uB3D9",
1730
+ touchmove: "touchmove",
1684
1731
  touchcancel: "\uD130\uCE58\uCDE8\uC18C"
1685
1732
  },
1686
1733
  logical: {
@@ -1753,6 +1800,9 @@ var ko = {
1753
1800
  properties: "\uD504\uB85C\uD37C\uD2F0\uB4E4"
1754
1801
  },
1755
1802
  expressions: {
1803
+ characters: "\uBB38\uC790",
1804
+ inclusive: "\uD3EC\uD568",
1805
+ exclusive: "\uC81C\uC678",
1756
1806
  first: "\uCCAB\uBC88\uC9F8",
1757
1807
  last: "\uB9C8\uC9C0\uB9C9",
1758
1808
  next: "\uB2E4\uC74C",
@@ -1871,16 +1921,26 @@ var zh = {
1871
1921
  events: {
1872
1922
  click: "\u70B9\u51FB",
1873
1923
  dblclick: "\u53CC\u51FB",
1874
- mousedown: "\u9F20\u6807\u6309\u4E0B",
1875
- mouseup: "\u9F20\u6807\u62AC\u8D77",
1876
- mouseenter: "\u9F20\u6807\u8FDB\u5165",
1877
- mouseleave: "\u9F20\u6807\u79BB\u5F00",
1878
- mouseover: "\u9F20\u6807\u60AC\u505C",
1924
+ // mousedown/mouseup: English passthrough — no native form round-trips on the
1925
+ // parse side (V3c probe 2026-07-14: fused forms captured verbatim, split forms
1926
+ // shattered to their first word — live broken listeners in repeat-until-event).
1927
+ // The Batch-2 id-keyup precedent; revisit if S5b + tokenizer gain native entries.
1928
+ mousedown: "mousedown",
1929
+ mouseup: "mouseup",
1930
+ mouseenter: "mouseenter",
1931
+ mouseleave: "mouseleave",
1932
+ // V3 Batch 2: 鼠标悬停 captured no event (expression:undefined) — realigned
1933
+ // to the tokenizer-registered 鼠标移入 (also S5b-listed). 按键抬起
1934
+ // prefix-shattered to 按键 and captured `keydown` (a keyup handler firing
1935
+ // on keydown) → 松键, the S5b/tokenizer form. keydown keeps 按键按下
1936
+ // (captures keydown via the registered 按键 prefix; S5b-aliased) — fixing
1937
+ // it to bare 按键 would collide with keypress below.
1938
+ mouseover: "\u9F20\u6807\u79FB\u5165",
1879
1939
  mouseout: "\u9F20\u6807\u79FB\u51FA",
1880
1940
  mousemove: "\u9F20\u6807\u79FB\u52A8",
1881
1941
  keydown: "\u6309\u952E\u6309\u4E0B",
1882
- keyup: "\u6309\u952E\u62AC\u8D77",
1883
- keypress: "\u6309\u952E",
1942
+ keyup: "\u677E\u952E",
1943
+ keypress: "keypress",
1884
1944
  focus: "\u805A\u7126",
1885
1945
  blur: "\u5931\u7126",
1886
1946
  change: "\u6539\u53D8",
@@ -1892,9 +1952,11 @@ var zh = {
1892
1952
  resize: "\u8C03\u6574\u5927\u5C0F",
1893
1953
  scroll: "\u6EDA\u52A8",
1894
1954
  touchstart: "\u89E6\u6478\u5F00\u59CB",
1895
- touchend: "\u89E6\u6478\u7ED3\u675F",
1955
+ touchend: "touchend",
1896
1956
  touchmove: "\u89E6\u6478\u79FB\u52A8",
1897
- touchcancel: "\u89E6\u6478\u53D6\u6D88"
1957
+ // V3c burn-down (2026-07-14): English passthrough — no native form round-trips
1958
+ // on the parse side (probe: split forms shatter, fused forms capture verbatim).
1959
+ touchcancel: "touchcancel"
1898
1960
  },
1899
1961
  logical: {
1900
1962
  when: "\u5F53",
@@ -1966,6 +2028,9 @@ var zh = {
1966
2028
  properties: "\u7279\u6027\u96C6"
1967
2029
  },
1968
2030
  expressions: {
2031
+ characters: "\u5B57\u7B26",
2032
+ inclusive: "\u5305\u542B",
2033
+ exclusive: "\u6392\u9664",
1969
2034
  first: "\u7B2C\u4E00\u4E2A",
1970
2035
  last: "\u6700\u540E\u4E00\u4E2A",
1971
2036
  next: "\u4E0B\u4E00\u4E2A",
@@ -2058,7 +2123,8 @@ var tr = {
2058
2123
  clear: "temizle",
2059
2124
  close: "kapat",
2060
2125
  open: "a\xE7",
2061
- select: "se\xE7",
2126
+ select: "vurgula",
2127
+ // Batch 3: seç is the pick keyword — bare select rendered with it parses null
2062
2128
  clone: "klonla",
2063
2129
  prepend: "ba\u015F\u0131naekle",
2064
2130
  socket: "soket"
@@ -2083,34 +2149,40 @@ var tr = {
2083
2149
  },
2084
2150
  events: {
2085
2151
  click: "t\u0131klama",
2086
- dblclick: "\xE7ift_t\u0131klama",
2152
+ dblclick: "dblclick",
2087
2153
  // Fused (no `_`): the semantic tokenizer splits on `_`, breaking event
2088
2154
  // recognition (mousedown → "bas" / mouseup mis-captured). Mirrors the #535
2089
2155
  // ru/uk fuse + #510 resize fix.
2090
2156
  mousedown: "farebas",
2091
2157
  mouseup: "fareb\u0131rak",
2092
- mouseenter: "fare_gir",
2093
- mouseleave: "fare_\xE7\u0131k",
2094
- mouseover: "fare_\xFCst\xFC",
2095
- mouseout: "fare_d\u0131\u015F\u0131",
2096
- mousemove: "fare_hareket",
2097
- keydown: "tu\u015F_bas",
2098
- keyup: "tu\u015F_b\u0131rak",
2099
- keypress: "tu\u015F_bas\u0131m",
2158
+ mouseenter: "mouseenter",
2159
+ mouseleave: "mouseleave",
2160
+ // V3 Batch 2: same `_`-split class (tuş_bas captured verbatim `bas` — a
2161
+ // listener for a DOM event named "bas") — realigned to the S5b/tokenizer
2162
+ // fused forms.
2163
+ mouseover: "farei\xE7inde",
2164
+ mouseout: "fared\u0131\u015F\u0131nda",
2165
+ mousemove: "mousemove",
2166
+ keydown: "tu\u015Fbasma",
2167
+ keyup: "tu\u015Fb\u0131rakma",
2168
+ // V3c burn-down (2026-07-14): English passthrough — no native form round-trips
2169
+ // on the parse side (probe: split forms shatter, fused forms capture verbatim).
2170
+ keypress: "keypress",
2100
2171
  focus: "odak",
2101
2172
  blur: "bulan\u0131k",
2102
2173
  change: "de\u011Fi\u015Fim",
2103
2174
  input: "giri\u015F",
2104
- submit: "g\xF6nder",
2175
+ submit: "g\xF6nderme",
2176
+ // Batch 3: gönder is the send verb — on-submit listener captured event "send"
2105
2177
  reset: "s\u0131f\u0131rla",
2106
2178
  load: "y\xFCkle",
2107
- unload: "y\xFCkle_kald\u0131r",
2179
+ unload: "unload",
2108
2180
  resize: "boyutland\u0131rma",
2109
2181
  scroll: "kayd\u0131r",
2110
- touchstart: "dokunma_ba\u015Fla",
2111
- touchend: "dokunma_bitir",
2112
- touchmove: "dokunma_hareket",
2113
- touchcancel: "dokunma_iptal"
2182
+ touchstart: "touchstart",
2183
+ touchend: "touchend",
2184
+ touchmove: "touchmove",
2185
+ touchcancel: "touchcancel"
2114
2186
  },
2115
2187
  logical: {
2116
2188
  when: "iken",
@@ -2181,6 +2253,9 @@ var tr = {
2181
2253
  properties: "\xF6zellikler"
2182
2254
  },
2183
2255
  expressions: {
2256
+ characters: "karakterler",
2257
+ inclusive: "dahil",
2258
+ exclusive: "hari\xE7",
2184
2259
  first: "ilk",
2185
2260
  // 'son' is also the END keyword emission (block terminator), and the
2186
2261
  // parser's end-recognizers match it by value — so a positional `last`
@@ -2282,9 +2357,11 @@ var id = {
2282
2357
  breakpoint: "titik-henti",
2283
2358
  clear: "bersihkan",
2284
2359
  // hapus is the remove PRIMARY in the profile
2285
- close: "tutup",
2360
+ close: "tutupkan",
2361
+ // Batch 3: tutup is the hide keyword — rendered close parsed as action=hide
2286
2362
  open: "buka",
2287
- select: "pilih",
2363
+ select: "tandai",
2364
+ // Batch 3: pilih is the pick keyword — bare select rendered with it parses null
2288
2365
  clone: "klon",
2289
2366
  prepend: "awali"
2290
2367
  },
@@ -2308,17 +2385,27 @@ var id = {
2308
2385
  },
2309
2386
  events: {
2310
2387
  click: "klik",
2311
- dblclick: "klik_ganda",
2312
- mousedown: "tekan_mouse",
2313
- mouseup: "lepas_mouse",
2314
- mouseenter: "mouse_masuk",
2315
- mouseleave: "mouse_keluar",
2316
- mouseover: "mouse_atas",
2317
- mouseout: "mouse_luar",
2318
- mousemove: "gerak_mouse",
2388
+ dblclick: "dblclick",
2389
+ // mousedown/mouseup: English passthrough — no native form round-trips on the
2390
+ // parse side (V3c probe 2026-07-14: fused forms captured verbatim, split forms
2391
+ // shattered to their first word — live broken listeners in repeat-until-event).
2392
+ // The Batch-2 id-keyup precedent; revisit if S5b + tokenizer gain native entries.
2393
+ mousedown: "mousedown",
2394
+ mouseup: "mouseup",
2395
+ mouseenter: "mouseenter",
2396
+ mouseleave: "mouseleave",
2397
+ // V3 Batch 2: mouse_atas/mouse_luar captured no event (the S5b forms
2398
+ // `mouse masuk`/`mouse keluar` are aspirational — they don't tokenize
2399
+ // either) — realigned to the tokenizer-registered natives. keydown keeps
2400
+ // tekan_tombol (captures keydown via the registered `tekan`; S5b-aliased).
2401
+ // keyup has NO parseable native (lepas is unregistered) → English
2402
+ // passthrough, matching the blur/reset precedent below.
2403
+ mouseover: "arahkan",
2404
+ mouseout: "tinggalkan",
2405
+ mousemove: "mousemove",
2319
2406
  keydown: "tekan_tombol",
2320
- keyup: "lepas_tombol",
2321
- keypress: "pencet_tombol",
2407
+ keyup: "keyup",
2408
+ keypress: "keypress",
2322
2409
  focus: "fokus",
2323
2410
  blur: "blur",
2324
2411
  change: "ubah",
@@ -2329,10 +2416,12 @@ var id = {
2329
2416
  unload: "bongkar",
2330
2417
  resize: "ubah_ukuran",
2331
2418
  scroll: "gulir",
2332
- touchstart: "mulai_sentuh",
2333
- touchend: "akhir_sentuh",
2334
- touchmove: "gerak_sentuh",
2335
- touchcancel: "batal_sentuh"
2419
+ touchstart: "touchstart",
2420
+ touchend: "touchend",
2421
+ touchmove: "touchmove",
2422
+ // V3c burn-down (2026-07-14): English passthrough — no native form round-trips
2423
+ // on the parse side (probe: split forms shatter, fused forms capture verbatim).
2424
+ touchcancel: "touchcancel"
2336
2425
  },
2337
2426
  logical: {
2338
2427
  when: "ketika",
@@ -2403,6 +2492,9 @@ var id = {
2403
2492
  properties: "properti_properti"
2404
2493
  },
2405
2494
  expressions: {
2495
+ characters: "karakter",
2496
+ inclusive: "inklusif",
2497
+ exclusive: "eksklusif",
2406
2498
  first: "pertama",
2407
2499
  last: "terakhir",
2408
2500
  next: "berikutnya",
@@ -2513,8 +2605,10 @@ var qu = {
2513
2605
  breakpoint: "sayachinay",
2514
2606
  clear: "pichay",
2515
2607
  close: "wichqay",
2516
- open: "kichay",
2517
- select: "akllay",
2608
+ open: "paskay",
2609
+ // Batch 3: kichay is the trigger keyword — rendered open parsed null
2610
+ select: "marcay",
2611
+ // Batch 3: akllay is the pick keyword — bare select rendered with it parses null
2518
2612
  clone: "kikinchay",
2519
2613
  prepend: "\xF1awpachiy",
2520
2614
  socket: "tinkina"
@@ -2539,33 +2633,42 @@ var qu = {
2539
2633
  },
2540
2634
  events: {
2541
2635
  click: "\xF1itiy",
2542
- dblclick: "iskay_\xF1itiy",
2636
+ dblclick: "dblclick",
2543
2637
  // Fused (no `_`): the semantic tokenizer splits on `_` — and `rat_ñitiy` then
2544
2638
  // mis-captured as the `click` event (ñitiy→click). Mirrors the #535 ru/uk fuse.
2545
2639
  mousedown: "rat\xF1itiy",
2546
2640
  mouseup: "rathuqariy",
2547
- mouseenter: "rat_yaykuy",
2548
- mouseleave: "rat_lluqsiy",
2549
- mouseover: "rat_hawapi",
2550
- mouseout: "rat_hawamanta",
2551
- mousemove: "rat_kuyuy",
2552
- keydown: "yupana_\xF1itiy",
2553
- keyup: "yupana_huqariy",
2554
- keypress: "yupana_\xF1itana",
2641
+ mouseenter: "mouseenter",
2642
+ mouseleave: "mouseleave",
2643
+ mouseover: "mouseover",
2644
+ mouseout: "mouseout",
2645
+ mousemove: "mousemove",
2646
+ // V3 Batch 2: `yupana_ñitiy` split at `_` and mis-captured as the `click`
2647
+ // event (ñitiy→click, the same mechanism as the mousedown fuse above);
2648
+ // `yupana_huqariy` captured verbatim `huqariy`. Realigned to the
2649
+ // S5b/tokenizer forms.
2650
+ keydown: "llave uray",
2651
+ keyup: "llave hawa",
2652
+ keypress: "keypress",
2555
2653
  focus: "qhaway",
2556
2654
  blur: "paqariy",
2557
- change: "tikray",
2655
+ change: "kambiay",
2656
+ // Batch 3: tikray is the toggle verb — on-change listener captured event "toggle"
2558
2657
  input: "yaykuchiy",
2559
- submit: "kachay",
2560
- reset: "qallariy",
2658
+ submit: "apaykachay",
2659
+ // Batch 3: kachay is the send verb — on-submit captured "send" in one corpus slot
2660
+ reset: "musuqchay",
2661
+ // Batch 3: qallariy is the init/start word — on-reset listener captured event "default"
2561
2662
  load: "apakuy",
2562
- unload: "urmay",
2663
+ unload: "unload",
2563
2664
  resize: "hatun_kay",
2564
2665
  scroll: "kunray",
2565
- touchstart: "llamiy_qallay",
2566
- touchend: "llamiy_tukuy",
2567
- touchmove: "llamiy_kuyuy",
2568
- touchcancel: "llamiy_hark_ay"
2666
+ // V3c burn-down (2026-07-14): English passthrough — no native form round-trips
2667
+ // on the parse side (probe: split forms shatter, fused forms capture verbatim).
2668
+ touchstart: "touchstart",
2669
+ touchend: "touchend",
2670
+ touchmove: "touchmove",
2671
+ touchcancel: "touchcancel"
2569
2672
  },
2570
2673
  logical: {
2571
2674
  when: "maykama",
@@ -2640,6 +2743,11 @@ var qu = {
2640
2743
  properties: "kanaykuna"
2641
2744
  },
2642
2745
  expressions: {
2746
+ // Pick unit word (arc 3): native-first per qu convention — `sanampa`
2747
+ // ("sign/letter", the standard term for alphabet characters) over a
2748
+ // loanword. Paired with the QUECHUA_EXTRAS entry in the semantic
2749
+ // tokenizer; both surfaces must match verbatim.
2750
+ characters: "sanampa",
2643
2751
  first: "\xF1awpaq",
2644
2752
  last: "qhipa",
2645
2753
  next: "qhipantin",
@@ -2703,7 +2811,10 @@ var sw = {
2703
2811
  wait: "ngoja",
2704
2812
  fetch: "leta",
2705
2813
  call: "ita",
2706
- return: "rudi",
2814
+ // `rudisha` (transitive, "give back a value"), not `rudi` ("go back"): the
2815
+ // semantic profile reads `rudisha`/`rejea`, so emitting `rudi` produced sw code
2816
+ // the parser could not read back. Kept clear of `rudia` (= `repeat`).
2817
+ return: "rudisha",
2707
2818
  make: "tengeneza",
2708
2819
  // auditor: dict emitted a word the profile reads differently
2709
2820
  log: "andika",
@@ -2717,7 +2828,8 @@ var sw = {
2717
2828
  go: "nenda",
2718
2829
  pushUrl: "sukumaUrl",
2719
2830
  replaceUrl: "badilishaUrl",
2720
- copy: "nakili",
2831
+ copy: "nakala",
2832
+ // Batch 3: nakili is the clone keyword — rendered copy parsed as action=clone
2721
2833
  pick: "chagua",
2722
2834
  beep: "lia",
2723
2835
  js: "js",
@@ -2736,7 +2848,8 @@ var sw = {
2736
2848
  // futa is a remove alternative in the profile
2737
2849
  close: "funga",
2738
2850
  open: "fungua",
2739
- select: "chagua",
2851
+ select: "alama",
2852
+ // Batch 3: chagua is the pick keyword — bare select rendered with it parses null
2740
2853
  clone: "nakili",
2741
2854
  prepend: "tanguliza",
2742
2855
  focus: "lenga",
@@ -2769,31 +2882,42 @@ var sw = {
2769
2882
  },
2770
2883
  events: {
2771
2884
  click: "bonyeza",
2772
- dblclick: "bonyeza_mara_mbili",
2885
+ // V3c burn-down (2026-07-14): English passthrough — no native form round-trips
2886
+ // on the parse side (probe: split forms shatter, fused forms capture verbatim).
2887
+ dblclick: "dblclick",
2773
2888
  mousedown: "panya_shuka",
2774
2889
  mouseup: "panya_juu",
2775
2890
  mouseenter: "panya_ingia",
2776
2891
  mouseleave: "panya_toka",
2777
- mouseover: "panya_juu",
2892
+ // V3 Batch 2: panya_juu is mouseup's form (shared here by mistake — the
2893
+ // tokenizer deliberately maps it to mouseup for the corpus row, so a
2894
+ // mouseover handler captured `mouseup`) — realigned to the
2895
+ // tokenizer-registered `sogeza juu`.
2896
+ mouseover: "sogeza juu",
2778
2897
  mouseout: "panya_nje",
2779
2898
  mousemove: "panya_sogea",
2780
2899
  keydown: "kitufe_shuka",
2781
2900
  keyup: "kitufe_juu",
2782
- keypress: "kitufe_bonyeza",
2783
- focus: "zingatia",
2784
- blur: "poteza_macho",
2785
- change: "badilisha",
2901
+ keypress: "keypress",
2902
+ // V3 Batch 2: zingatia captured no event → lenga (S5b/tokenizer form);
2903
+ // poteza_macho was a null parse → `blur` (the S5b identity form — matches
2904
+ // the live corpus render `kwenye blur`); badilisha is the toggle VERB
2905
+ // homonym (a change handler captured event=`toggle` — a listener for a DOM
2906
+ // event named "toggle") → kubadilisha (S5b/tokenizer form).
2907
+ focus: "lenga",
2908
+ blur: "blur",
2909
+ change: "kubadilisha",
2786
2910
  input: "ingizo",
2787
2911
  submit: "wasilisha",
2788
- reset: "weka_upya",
2912
+ reset: "reset",
2789
2913
  load: "pakia",
2790
2914
  unload: "shuka",
2791
2915
  resize: "badilisha_ukubwa",
2792
2916
  scroll: "sogeza",
2793
- touchstart: "gusa_anza",
2794
- touchend: "gusa_mwisho",
2795
- touchmove: "gusa_sogea",
2796
- touchcancel: "gusa_ghairi"
2917
+ touchstart: "touchstart",
2918
+ touchend: "touchend",
2919
+ touchmove: "touchmove",
2920
+ touchcancel: "touchcancel"
2797
2921
  },
2798
2922
  logical: {
2799
2923
  when: "wakati",
@@ -2864,6 +2988,7 @@ var sw = {
2864
2988
  properties: "mali"
2865
2989
  },
2866
2990
  expressions: {
2991
+ characters: "herufi",
2867
2992
  first: "kwanza",
2868
2993
  // 'mwisho' is the END keyword (block terminator) — the tokenizer's keyword
2869
2994
  // map is last-wins, so a positional `last` emission of 'mwisho' reads as
@@ -2998,18 +3123,21 @@ var pt = {
2998
3123
  mouseup: "mouseCima",
2999
3124
  mouseenter: "mouseEntrar",
3000
3125
  mouseleave: "mouseSair",
3001
- mouseover: "mouseSobre",
3002
- mouseout: "mouseFora",
3126
+ // V3 Batch 2: camelCase forms split to the S5b/tokenizer-known forms (the
3127
+ // fused spellings captured event=expression:undefined — broken listeners)
3128
+ mouseover: "mouse sobre",
3129
+ mouseout: "mouse fora",
3003
3130
  mousemove: "mouseMover",
3004
- keydown: "teclaBaixo",
3005
- keyup: "teclaCima",
3131
+ keydown: "tecla baixo",
3132
+ keyup: "tecla cima",
3006
3133
  keypress: "teclaPressionar",
3007
3134
  focus: "foco",
3008
3135
  blur: "desfoque",
3009
3136
  change: "mudan\xE7a",
3010
3137
  input: "entrada",
3011
3138
  submit: "envio",
3012
- reset: "reiniciar",
3139
+ reset: "redefinir",
3140
+ // Batch 3: reiniciar captured on.event as expression (broken listener) — profile word round-trips
3013
3141
  load: "carregar",
3014
3142
  unload: "descarregar",
3015
3143
  resize: "redimensionar",
@@ -3088,6 +3216,9 @@ var pt = {
3088
3216
  properties: "propriedades"
3089
3217
  },
3090
3218
  expressions: {
3219
+ characters: "caracteres",
3220
+ inclusive: "inclusivo",
3221
+ exclusive: "exclusivo",
3091
3222
  first: "primeiro",
3092
3223
  last: "\xFAltimo",
3093
3224
  next: "pr\xF3ximo",
@@ -3203,8 +3334,12 @@ var it = {
3203
3334
  events: {
3204
3335
  click: "clic",
3205
3336
  dblclick: "doppioclic",
3206
- mousedown: "mousegi\xF9",
3207
- mouseup: "mousesu",
3337
+ // mousedown/mouseup: English passthrough — no native form round-trips on the
3338
+ // parse side (V3c probe 2026-07-14: fused forms captured verbatim, split forms
3339
+ // shattered to their first word — live broken listeners in repeat-until-event).
3340
+ // The Batch-2 id-keyup precedent; revisit if S5b + tokenizer gain native entries.
3341
+ mousedown: "mousedown",
3342
+ mouseup: "mouseup",
3208
3343
  mouseenter: "mouseentra",
3209
3344
  mouseleave: "mouseesce",
3210
3345
  mouseover: "mousesopra",
@@ -3214,11 +3349,13 @@ var it = {
3214
3349
  keyup: "tastosu",
3215
3350
  keypress: "tastopremi",
3216
3351
  focus: "fuoco",
3217
- blur: "sfuocatura",
3352
+ blur: "sfuocare",
3353
+ // Batch 3: the noun form parsed the blur command with no patient; the verb round-trips both event and command slots
3218
3354
  change: "cambio",
3219
3355
  input: "input",
3220
3356
  submit: "invio",
3221
- reset: "reset",
3357
+ reset: "reimpostare",
3358
+ // Batch 3: English passthrough captured on.event as expression — profile verb round-trips
3222
3359
  load: "carica",
3223
3360
  unload: "scarica",
3224
3361
  resize: "ridimensiona",
@@ -3297,6 +3434,9 @@ var it = {
3297
3434
  properties: "propriet\xE0"
3298
3435
  },
3299
3436
  expressions: {
3437
+ characters: "caratteri",
3438
+ inclusive: "inclusivo",
3439
+ exclusive: "esclusivo",
3300
3440
  first: "primo",
3301
3441
  last: "ultimo",
3302
3442
  next: "prossimo",
@@ -3384,15 +3524,18 @@ var vi = {
3384
3524
  init: "kh\u1EDFi t\u1EA1o",
3385
3525
  behavior: "h\xE0nh vi",
3386
3526
  install: "c\xE0i \u0111\u1EB7t",
3387
- clone: "sao ch\xE9p",
3388
- prepend: "th\xEAm \u0111\u1EA7u",
3527
+ clone: "nh\xE2n b\u1EA3n",
3528
+ // Batch 3: 'sao chép' is the copy verb — rendered clone parsed as action=copy
3529
+ prepend: "th\xEAm v\xE0o \u0111\u1EA7u",
3530
+ // Batch 3: 'thêm đầu' shatters at 'thêm' (add) — parsed as action=add
3389
3531
  else: "kh\xF4ng th\xEC",
3390
3532
  breakpoint: "\u0111i\u1EC3m-d\u1EEBng",
3391
3533
  clear: "t\u1EA9y",
3392
3534
  // xóa is the remove PRIMARY in the profile
3393
3535
  close: "\u0111\xF3ng",
3394
3536
  open: "m\u1EDF",
3395
- select: "ch\u1ECDn"
3537
+ select: "\u0111\xE1nh-d\u1EA5u"
3538
+ // Batch 3: 'chọn' is the pick keyword — bare select rendered with it parses null
3396
3539
  },
3397
3540
  modifiers: {
3398
3541
  into: "v\xE0o",
@@ -3415,21 +3558,24 @@ var vi = {
3415
3558
  },
3416
3559
  events: {
3417
3560
  click: "nh\u1EA5p",
3418
- dblclick: "nh\u1EA5p \u0111\xFAp",
3561
+ dblclick: "dblclick",
3419
3562
  input: "nh\u1EADp",
3420
- change: "thay \u0111\u1ED5i",
3421
- submit: "g\u1EEDi",
3422
- keydown: "ph\xEDm xu\u1ED1ng",
3423
- keyup: "ph\xEDm l\xEAn",
3424
- keypress: "nh\u1EA5n ph\xEDm",
3425
- mouseover: "chu\u1ED9t v\xE0o",
3426
- mouseout: "chu\u1ED9t ra",
3427
- mouseenter: "chu\u1ED9t v\xE0o",
3428
- mouseleave: "chu\u1ED9t r\u1EDDi",
3429
- focus: "t\u1EADp trung",
3430
- blur: "m\u1EA5t t\u1EADp trung",
3431
- reset: "\u0111\u1EB7t-l\u1EA1i",
3432
- load: "t\u1EA3i",
3563
+ change: "change",
3564
+ submit: "n\u1ED9p",
3565
+ // Batch 3: 'gửi' is the send verb — on-submit listener captured event "send"
3566
+ keydown: "keydown",
3567
+ keyup: "keyup",
3568
+ keypress: "keypress",
3569
+ mouseover: "mouseover",
3570
+ mouseout: "mouseout",
3571
+ mouseenter: "mouseenter",
3572
+ mouseleave: "mouseleave",
3573
+ focus: "focus",
3574
+ blur: "blur",
3575
+ // V3c burn-down (2026-07-14): English passthrough — no native form round-trips
3576
+ // on the parse side (probe: split forms shatter, fused forms capture verbatim).
3577
+ reset: "reset",
3578
+ load: "load",
3433
3579
  scroll: "cu\u1ED9n",
3434
3580
  resize: "\u0111\u1ED5i k\xEDch th\u01B0\u1EDBc"
3435
3581
  },
@@ -3505,6 +3651,10 @@ var vi = {
3505
3651
  selected: "\u0111\u01B0\u1EE3c ch\u1ECDn"
3506
3652
  },
3507
3653
  expressions: {
3654
+ random: "ng\u1EABu nhi\xEAn",
3655
+ characters: "k\xFD t\u1EF1",
3656
+ inclusive: "bao g\u1ED3m",
3657
+ exclusive: "lo\u1EA1i tr\u1EEB",
3508
3658
  me: "t\xF4i",
3509
3659
  my: "c\u1EE7a t\xF4i",
3510
3660
  it: "n\xF3",
@@ -3601,7 +3751,8 @@ var pl = {
3601
3751
  // wyczyść is a remove alternative in the profile
3602
3752
  close: "zamknij",
3603
3753
  open: "otw\xF3rz",
3604
- select: "wybierz",
3754
+ select: "zaznacz",
3755
+ // Batch 3: wybierz is the pick keyword — bare select rendered with it parses null
3605
3756
  clone: "sklonuj",
3606
3757
  prepend: "poprzed\u017A",
3607
3758
  focus: "skup"
@@ -3627,8 +3778,12 @@ var pl = {
3627
3778
  events: {
3628
3779
  click: "klikni\u0119cie",
3629
3780
  dblclick: "podw\xF3jneklikni\u0119cie",
3630
- mousedown: "myszd\xF3\u0142",
3631
- mouseup: "myszg\xF3ra",
3781
+ // mousedown/mouseup: English passthrough — no native form round-trips on the
3782
+ // parse side (V3c probe 2026-07-14: fused forms captured verbatim, split forms
3783
+ // shattered to their first word — live broken listeners in repeat-until-event).
3784
+ // The Batch-2 id-keyup precedent; revisit if S5b + tokenizer gain native entries.
3785
+ mousedown: "mousedown",
3786
+ mouseup: "mouseup",
3632
3787
  mouseenter: "myszwej\u015Bcie",
3633
3788
  mouseleave: "myszwyj\u015Bcie",
3634
3789
  mouseover: "mysznad",
@@ -3641,8 +3796,10 @@ var pl = {
3641
3796
  blur: "rozmycie",
3642
3797
  change: "zmiana",
3643
3798
  input: "wej\u015Bcie",
3644
- submit: "wy\u015Blij",
3645
- reset: "resetuj",
3799
+ submit: "wys\u0142aniu",
3800
+ // Batch 3: wyślij is the send verb — on-submit listener captured event "send"
3801
+ reset: "zresetuj",
3802
+ // Batch 3: resetuj captured on.event as expression (broken listener) — profile word round-trips
3646
3803
  load: "za\u0142aduj",
3647
3804
  unload: "wy\u0142aduj",
3648
3805
  resize: "zmie\u0144rozmiar",
@@ -3721,6 +3878,9 @@ var pl = {
3721
3878
  properties: "w\u0142a\u015Bciwo\u015Bci"
3722
3879
  },
3723
3880
  expressions: {
3881
+ characters: "znaki",
3882
+ inclusive: "w\u0142\u0105cznie",
3883
+ exclusive: "wy\u0142\u0105cznie",
3724
3884
  first: "pierwszy",
3725
3885
  last: "ostatni",
3726
3886
  next: "nast\u0119pny",
@@ -3821,7 +3981,8 @@ var russianDictionary = {
3821
3981
  clear: "\u043E\u0447\u0438\u0441\u0442\u0438\u0442\u044C",
3822
3982
  close: "\u0437\u0430\u043A\u0440\u044B\u0442\u044C",
3823
3983
  open: "\u043E\u0442\u043A\u0440\u044B\u0442\u044C",
3824
- select: "\u0432\u044B\u0431\u0440\u0430\u0442\u044C"
3984
+ select: "\u0432\u044B\u0434\u0435\u043B\u0438\u0442\u044C"
3985
+ // Batch 3: выбрать is the pick keyword — bare select rendered with it parses null
3825
3986
  },
3826
3987
  modifiers: {
3827
3988
  to: "\u043A",
@@ -3863,7 +4024,8 @@ var russianDictionary = {
3863
4024
  change: "\u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u0435",
3864
4025
  input: "\u0432\u0432\u043E\u0434",
3865
4026
  submit: "\u043E\u0442\u043F\u0440\u0430\u0432\u043A\u0430",
3866
- reset: "\u0441\u0431\u0440\u043E\u0441",
4027
+ reset: "\u0441\u0431\u0440\u043E\u0441\u0438\u0442\u044C",
4028
+ // Batch 3: сброс captured on.event as expression (broken listener) — profile verb round-trips
3867
4029
  load: "\u0437\u0430\u0433\u0440\u0443\u0437\u043A\u0430",
3868
4030
  unload: "\u0432\u044B\u0433\u0440\u0443\u0437\u043A\u0430",
3869
4031
  resize: "\u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u0435\u0440\u0430\u0437\u043C\u0435\u0440\u0430",
@@ -3963,6 +4125,9 @@ var russianDictionary = {
3963
4125
  html: "html"
3964
4126
  },
3965
4127
  expressions: {
4128
+ characters: "\u0441\u0438\u043C\u0432\u043E\u043B\u044B",
4129
+ inclusive: "\u0432\u043A\u043B\u044E\u0447\u0438\u0442\u0435\u043B\u044C\u043D\u043E",
4130
+ exclusive: "\u0438\u0441\u043A\u043B\u044E\u0447\u0438\u0442\u0435\u043B\u044C\u043D\u043E",
3966
4131
  first: "\u043F\u0435\u0440\u0432\u044B\u0439",
3967
4132
  last: "\u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0438\u0439",
3968
4133
  next: "\u0441\u043B\u0435\u0434\u0443\u044E\u0449\u0438\u0439",
@@ -4063,7 +4228,8 @@ var ukrainianDictionary = {
4063
4228
  clear: "\u043E\u0447\u0438\u0441\u0442\u0438\u0442\u0438",
4064
4229
  close: "\u0437\u0430\u043A\u0440\u0438\u0442\u0438",
4065
4230
  open: "\u0432\u0456\u0434\u043A\u0440\u0438\u0442\u0438",
4066
- select: "\u0432\u0438\u0431\u0440\u0430\u0442\u0438"
4231
+ select: "\u0432\u0438\u0434\u0456\u043B\u0438\u0442\u0438"
4232
+ // Batch 3: вибрати is the pick keyword — bare select rendered with it parses null
4067
4233
  },
4068
4234
  modifiers: {
4069
4235
  to: "\u0434\u043E",
@@ -4104,7 +4270,8 @@ var ukrainianDictionary = {
4104
4270
  change: "\u0437\u043C\u0456\u043D\u0430",
4105
4271
  input: "\u0432\u0432\u0435\u0434\u0435\u043D\u043D\u044F",
4106
4272
  submit: "\u043D\u0430\u0434\u0441\u0438\u043B\u0430\u043D\u043D\u044F",
4107
- reset: "\u0441\u043A\u0438\u0434\u0430\u043D\u043D\u044F",
4273
+ reset: "\u0441\u043A\u0438\u043D\u0443\u0442\u0438",
4274
+ // Batch 3: скидання captured on.event as expression (broken listener) — profile verb round-trips
4108
4275
  load: "\u0437\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0435\u043D\u043D\u044F",
4109
4276
  unload: "\u0432\u0438\u0432\u0430\u043D\u0442\u0430\u0436\u0435\u043D\u043D\u044F",
4110
4277
  resize: "\u0437\u043C\u0456\u043D\u0430\u0440\u043E\u0437\u043C\u0456\u0440\u0443",
@@ -4204,6 +4371,9 @@ var ukrainianDictionary = {
4204
4371
  html: "html"
4205
4372
  },
4206
4373
  expressions: {
4374
+ characters: "\u0441\u0438\u043C\u0432\u043E\u043B\u0438",
4375
+ inclusive: "\u0432\u043A\u043B\u044E\u0447\u043D\u043E",
4376
+ exclusive: "\u0432\u0438\u043A\u043B\u044E\u0447\u043D\u043E",
4207
4377
  first: "\u043F\u0435\u0440\u0448\u0438\u0439",
4208
4378
  last: "\u043E\u0441\u0442\u0430\u043D\u043D\u0456\u0439",
4209
4379
  next: "\u043D\u0430\u0441\u0442\u0443\u043F\u043D\u0438\u0439",
@@ -4293,13 +4463,15 @@ var hindiDictionary = {
4293
4463
  behavior: "\u0935\u094D\u092F\u0935\u0939\u093E\u0930",
4294
4464
  focus: "\u092B\u094B\u0915\u0938",
4295
4465
  blur: "\u0927\u0941\u0902\u0927\u0932\u093E",
4296
- clone: "\u0915\u0949\u092A\u0940",
4466
+ clone: "\u0915\u094D\u0932\u094B\u0928",
4467
+ // Batch 3: कॉपी is the copy verb — rendered clone parsed as action=copy
4297
4468
  prepend: "\u091C\u094B\u0921\u093C\u0947\u0902_\u0936\u0941\u0930\u0942",
4298
4469
  breakpoint: "\u092C\u094D\u0930\u0947\u0915\u092A\u094D\u0935\u093E\u0907\u0902\u091F",
4299
4470
  clear: "\u0938\u093E\u092B\u093C-\u0915\u0930\u0947\u0902",
4300
4471
  close: "\u092C\u0902\u0926-\u0915\u0930\u0947\u0902",
4301
4472
  open: "\u0916\u094B\u0932\u0947\u0902",
4302
- select: "\u091A\u0941\u0928\u0947\u0902",
4473
+ select: "\u091A\u093F\u0939\u094D\u0928\u093F\u0924-\u0915\u0930\u0947\u0902",
4474
+ // Batch 3: चुनें is the pick keyword — bare select rendered with it parses null
4303
4475
  socket: "\u0938\u0949\u0915\u0947\u091F"
4304
4476
  },
4305
4477
  modifiers: {
@@ -4444,6 +4616,7 @@ var hindiDictionary = {
4444
4616
  html: "html"
4445
4617
  },
4446
4618
  expressions: {
4619
+ characters: "\u0905\u0915\u094D\u0937\u0930",
4447
4620
  first: "\u092A\u0939\u0932\u093E",
4448
4621
  last: "\u0905\u0902\u0924\u093F\u092E",
4449
4622
  next: "\u0905\u0917\u0932\u093E",
@@ -4518,7 +4691,8 @@ var bengaliDictionary = {
4518
4691
  init: "\u09B6\u09C1\u09B0\u09C1",
4519
4692
  behavior: "\u0986\u099A\u09B0\u09A3",
4520
4693
  install: "\u0987\u09A8\u09B8\u09CD\u099F\u09B2",
4521
- clone: "\u0995\u09AA\u09BF",
4694
+ clone: "\u0995\u09CD\u09B2\u09CB\u09A8",
4695
+ // Batch 3: কপি is the copy verb — rendered clone parsed as action=copy
4522
4696
  swap: "\u09AC\u09A6\u09B2",
4523
4697
  morph: "\u09B0\u09C2\u09AA\u09BE\u09A8\u09CD\u09A4\u09B0",
4524
4698
  beep: "\u09AC\u09C0\u09AA",
@@ -4565,10 +4739,12 @@ var bengaliDictionary = {
4565
4739
  focus: "\u09AB\u09CB\u0995\u09BE\u09B8",
4566
4740
  blur: "\u099D\u09BE\u09AA\u09B8\u09BE",
4567
4741
  reset: "\u09B0\u09BF\u09B8\u09C7\u099F",
4568
- keydown: "\u0995\u09BF-\u09A1\u09BE\u0989\u09A8",
4569
- keyup: "\u0995\u09BF-\u0986\u09AA",
4570
- mouseover: "\u09AE\u09BE\u0989\u09B8-\u0993\u09AD\u09BE\u09B0",
4571
- mouseout: "\u09AE\u09BE\u0989\u09B8-\u0986\u0989\u099F",
4742
+ keydown: "keydown",
4743
+ keyup: "keyup",
4744
+ // V3c burn-down (2026-07-14): English passthrough — no native form round-trips
4745
+ // on the parse side (probe: split forms shatter, fused forms capture verbatim).
4746
+ mouseover: "mouseover",
4747
+ mouseout: "mouseout",
4572
4748
  scroll: "\u09B8\u09CD\u0995\u09CD\u09B0\u09CB\u09B2",
4573
4749
  resize: "\u09B0\u09BF\u09B8\u09BE\u0987\u099C",
4574
4750
  every: "\u09AA\u09CD\u09B0\u09A4\u09BF"
@@ -4630,6 +4806,9 @@ var bengaliDictionary = {
4630
4806
  checked: "\u099A\u09C7\u0995 \u0995\u09B0\u09BE"
4631
4807
  },
4632
4808
  expressions: {
4809
+ characters: "\u0985\u0995\u09CD\u09B7\u09B0",
4810
+ inclusive: "\u0985\u09A8\u09CD\u09A4\u09B0\u09CD\u09AD\u09C1\u0995\u09CD\u09A4",
4811
+ exclusive: "\u09AC\u09BE\u09A6",
4633
4812
  first: "\u09AA\u09CD\u09B0\u09A5\u09AE",
4634
4813
  last: "\u09B6\u09C7\u09B7",
4635
4814
  next: "\u09AA\u09B0\u09AC\u09B0\u09CD\u09A4\u09C0",
@@ -4704,7 +4883,8 @@ var thaiDictionary = {
4704
4883
  init: "\u0E40\u0E23\u0E34\u0E48\u0E21\u0E15\u0E49\u0E19",
4705
4884
  behavior: "\u0E1E\u0E24\u0E15\u0E34\u0E01\u0E23\u0E23\u0E21",
4706
4885
  install: "\u0E15\u0E34\u0E14\u0E15\u0E31\u0E49\u0E07",
4707
- clone: "\u0E04\u0E31\u0E14\u0E25\u0E2D\u0E01",
4886
+ clone: "\u0E42\u0E04\u0E25\u0E19",
4887
+ // Batch 3: คัดลอก is the copy verb — rendered clone parsed as action=copy
4708
4888
  swap: "\u0E2A\u0E25\u0E31\u0E1A\u0E17\u0E35\u0E48",
4709
4889
  morph: "\u0E41\u0E1B\u0E25\u0E07\u0E23\u0E48\u0E32\u0E07",
4710
4890
  beep: "\u0E1A\u0E35\u0E4A\u0E1A",
@@ -4719,7 +4899,8 @@ var thaiDictionary = {
4719
4899
  clear: "\u0E40\u0E04\u0E25\u0E35\u0E22\u0E23\u0E4C",
4720
4900
  close: "\u0E1B\u0E34\u0E14",
4721
4901
  open: "\u0E40\u0E1B\u0E34\u0E14",
4722
- select: "\u0E40\u0E25\u0E37\u0E2D\u0E01"
4902
+ select: "\u0E17\u0E33\u0E40\u0E04\u0E23\u0E37\u0E48\u0E2D\u0E07\u0E2B\u0E21\u0E32\u0E22"
4903
+ // Batch 3: เลือก is the pick keyword — bare select rendered with it parses null
4723
4904
  },
4724
4905
  modifiers: {
4725
4906
  to: "\u0E44\u0E1B\u0E22\u0E31\u0E07",
@@ -4814,6 +4995,9 @@ var thaiDictionary = {
4814
4995
  checked: "\u0E40\u0E25\u0E37\u0E2D\u0E01\u0E41\u0E25\u0E49\u0E27"
4815
4996
  },
4816
4997
  expressions: {
4998
+ characters: "\u0E2D\u0E31\u0E01\u0E02\u0E23\u0E30",
4999
+ inclusive: "\u0E23\u0E27\u0E21",
5000
+ exclusive: "\u0E22\u0E01\u0E40\u0E27\u0E49\u0E19",
4817
5001
  first: "\u0E41\u0E23\u0E01",
4818
5002
  last: "\u0E2A\u0E38\u0E14\u0E17\u0E49\u0E32\u0E22",
4819
5003
  next: "\u0E16\u0E31\u0E14\u0E44\u0E1B",
@@ -4906,7 +5090,8 @@ var malayDictionary = {
4906
5090
  // padam is a remove alternative in the profile
4907
5091
  close: "tutup",
4908
5092
  open: "buka",
4909
- select: "pilih",
5093
+ select: "tandai",
5094
+ // Batch 3: pilih is the pick keyword — bare select rendered with it parses null
4910
5095
  socket: "soket"
4911
5096
  // derived from the ms profile (socket.primary); see generate-i18n-dictionaries
4912
5097
  },
@@ -5046,6 +5231,9 @@ var malayDictionary = {
5046
5231
  checked: "ditanda"
5047
5232
  },
5048
5233
  expressions: {
5234
+ characters: "aksara",
5235
+ inclusive: "inklusif",
5236
+ exclusive: "eksklusif",
5049
5237
  first: "pertama",
5050
5238
  last: "terakhir",
5051
5239
  next: "seterusnya",
@@ -5144,7 +5332,8 @@ var tagalogDictionary = {
5144
5332
  install: "ikabit",
5145
5333
  behavior: "ugali",
5146
5334
  init: "simulan",
5147
- clone: "kopyahin",
5335
+ clone: "i-clone",
5336
+ // Batch 3: kopyahin is the copy verb — rendered clone parsed as action=copy
5148
5337
  breakpoint: "breakpoint",
5149
5338
  clear: "burahin",
5150
5339
  close: "isara",
@@ -5291,6 +5480,9 @@ var tagalogDictionary = {
5291
5480
  checked: "naka_tsek"
5292
5481
  },
5293
5482
  expressions: {
5483
+ characters: "karakter",
5484
+ inclusive: "kasama",
5485
+ exclusive: "bukod",
5294
5486
  first: "una",
5295
5487
  last: "huli",
5296
5488
  next: "susunod",
@@ -5419,6 +5611,10 @@ var he = {
5419
5611
  },
5420
5612
  attributes: {},
5421
5613
  expressions: {
5614
+ random: "\u05D0\u05E7\u05E8\u05D0\u05D9",
5615
+ characters: "\u05EA\u05D5\u05D5\u05D9\u05DD",
5616
+ inclusive: "\u05DB\u05D5\u05DC\u05DC",
5617
+ exclusive: "\u05D1\u05DC\u05E2\u05D3\u05D9",
5422
5618
  last: "\u05D0\u05D7\u05E8\u05D5\u05DF"
5423
5619
  }
5424
5620
  };
@@ -6126,6 +6322,91 @@ var englishProfile = {
6126
6322
  { form: "for", role: "duration", position: "preposition", required: false }
6127
6323
  ]
6128
6324
  };
6325
+ function sovHaltCallFusedRule(cfg) {
6326
+ return {
6327
+ name: "halt-call-fused-verb-final",
6328
+ description: "Split the swept `halt <operand> call <args>` blob; both verbs clause-final",
6329
+ priority: 95,
6330
+ match: {
6331
+ commands: ["halt"],
6332
+ requiredRoles: ["action", "event", "patient"],
6333
+ // Only the juxtaposed-call blob: a plain `halt`/`halt the event` handler
6334
+ // keeps its default render. The translated call verb must be present to
6335
+ // split on — if the dictionary emission drifts, the rule stands down
6336
+ // rather than emitting a mangled clause.
6337
+ predicate: (parsed) => {
6338
+ const p = parsed.roles.get("patient");
6339
+ return !!p && /\bcall\b/.test(p.value) && !!p.translated && p.translated.includes(cfg.callVerb);
6340
+ }
6341
+ },
6342
+ transform: {
6343
+ roleOrder: [],
6344
+ // unused — custom takes over
6345
+ custom: (parsed) => {
6346
+ const p = parsed.roles.get("patient");
6347
+ const ev = parsed.roles.get("event");
6348
+ const act = parsed.roles.get("action");
6349
+ let blob = (p.translated ?? p.value).trim();
6350
+ const PH = "EVENTBLOCKPLACEHOLDER";
6351
+ let tail = "";
6352
+ if (blob.endsWith(PH)) {
6353
+ blob = blob.slice(0, -PH.length).trim();
6354
+ tail = ` ${PH}`;
6355
+ }
6356
+ const at = blob.indexOf(cfg.callVerb);
6357
+ const haltOperand = blob.slice(0, at).trim();
6358
+ const callArgs = blob.slice(at + cfg.callVerb.length).trim();
6359
+ return [
6360
+ haltOperand,
6361
+ cfg.patientMarker,
6362
+ ev.translated ?? ev.value,
6363
+ cfg.eventMarker,
6364
+ act.translated ?? act.value,
6365
+ cfg.connective,
6366
+ callArgs,
6367
+ cfg.patientMarker,
6368
+ cfg.callVerb
6369
+ ].join(" ") + tail;
6370
+ }
6371
+ }
6372
+ };
6373
+ }
6374
+ function sovPickRangeRule(cfg) {
6375
+ return {
6376
+ name: "pick-range-verb-final",
6377
+ description: "Reassemble the pick range (unit + endpoints + root) adjacent, verb-final",
6378
+ priority: 95,
6379
+ match: {
6380
+ commands: ["pick"],
6381
+ requiredRoles: ["action", "patient", "destination"],
6382
+ predicate: (parsed) => {
6383
+ const p = parsed.roles.get("patient");
6384
+ const d = parsed.roles.get("destination");
6385
+ return !!p && !!d && /^\S+\s+\d+$/.test(p.value.trim()) && /^\d+\s+of\s+\S+$/.test(d.value.trim());
6386
+ }
6387
+ },
6388
+ transform: {
6389
+ roleOrder: [],
6390
+ // unused — custom takes over
6391
+ custom: (parsed) => {
6392
+ const p = parsed.roles.get("patient");
6393
+ const d = parsed.roles.get("destination");
6394
+ const act = parsed.roles.get("action");
6395
+ const ev = parsed.roles.get("event");
6396
+ const pParts = (p.translated ?? p.value).trim().split(/\s+/);
6397
+ const a = pParts[pParts.length - 1];
6398
+ const unit = pParts.slice(0, -1).join(" ");
6399
+ const dMatch = d.value.trim().match(/^(\d+)\s+of\s+(\S+)$/);
6400
+ const b = dMatch[1];
6401
+ const root = dMatch[2];
6402
+ const verb = act.translated ?? act.value;
6403
+ const head = [root, cfg.genitive, unit, a, cfg.rangeSep, b, cfg.patientMarker];
6404
+ const eventPart = ev ? [ev.translated ?? ev.value, cfg.eventMarker] : [];
6405
+ return [...head, ...eventPart, verb].join(" ");
6406
+ }
6407
+ }
6408
+ };
6409
+ }
6129
6410
  var japaneseProfile = {
6130
6411
  code: "ja",
6131
6412
  name: "\u65E5\u672C\u8A9E",
@@ -6210,7 +6491,21 @@ var japaneseProfile = {
6210
6491
  roleOrder: ["patient", "destination", "action"],
6211
6492
  insertMarkers: true
6212
6493
  }
6213
- }
6494
+ },
6495
+ // the イベント を 送信 で 停止 それから validateForm() を 呼び出し
6496
+ sovHaltCallFusedRule({
6497
+ callVerb: "\u547C\u3073\u51FA\u3057",
6498
+ patientMarker: "\u3092",
6499
+ eventMarker: "\u3067",
6500
+ connective: "\u305D\u308C\u304B\u3089"
6501
+ }),
6502
+ // #note の 文字 0 から 5 を クリック で 選択
6503
+ sovPickRangeRule({
6504
+ genitive: "\u306E",
6505
+ rangeSep: "\u304B\u3089",
6506
+ patientMarker: "\u3092",
6507
+ eventMarker: "\u3067"
6508
+ })
6214
6509
  ]
6215
6510
  };
6216
6511
  var koreanProfile = {
@@ -6310,7 +6605,21 @@ var koreanProfile = {
6310
6605
  roleOrder: ["patient", "destination", "action"],
6311
6606
  insertMarkers: true
6312
6607
  }
6313
- }
6608
+ },
6609
+ // the 이벤트 를 제출 할 때 정지 그러면 validateForm() 를 호출
6610
+ sovHaltCallFusedRule({
6611
+ callVerb: "\uD638\uCD9C",
6612
+ patientMarker: "\uB97C",
6613
+ eventMarker: "\uD560 \uB54C",
6614
+ connective: "\uADF8\uB7EC\uBA74"
6615
+ }),
6616
+ // #note 의 문자 0 부터 5 를 클릭 할 때 선택
6617
+ sovPickRangeRule({
6618
+ genitive: "\uC758",
6619
+ rangeSep: "\uBD80\uD130",
6620
+ patientMarker: "\uB97C",
6621
+ eventMarker: "\uD560 \uB54C"
6622
+ })
6314
6623
  ]
6315
6624
  };
6316
6625
  var chineseProfile = {
@@ -6451,6 +6760,12 @@ var turkishProfile = {
6451
6760
  adpositionType: "postposition",
6452
6761
  morphology: "agglutinative",
6453
6762
  direction: "ltr",
6763
+ // NOTE: roles absent from this order are safety-net-appended AFTER the verb
6764
+ // by reorderRoles. That stranding is what the semantic parser's generated
6765
+ // patterns + reclaim tolerances were built around, so extending this order
6766
+ // wholesale re-renders (and breaks) the whole tr corpus — fix individual
6767
+ // defective shapes with per-command `rules` below instead (see the
6768
+ // wait/repeat-until rules from the transformer-rendering arc).
6454
6769
  canonicalOrder: ["patient", "event", "action"],
6455
6770
  markers: [
6456
6771
  // Turkish case suffixes - using spaced form for tokenization
@@ -6544,7 +6859,59 @@ var turkishProfile = {
6544
6859
  roleOrder: ["patient", "destination", "action"],
6545
6860
  insertMarkers: true
6546
6861
  }
6547
- }
6862
+ },
6863
+ {
6864
+ name: "wait-oblique-verb-final",
6865
+ description: "Keep wait's from-phrase and or-run inside the clause, verb-final",
6866
+ priority: 90,
6867
+ match: {
6868
+ commands: ["wait", "bekle"],
6869
+ // Only the multi-argument form (`wait for X or Y from Z`) strands:
6870
+ // without this rule the safety-net appends duration+source AFTER the
6871
+ // verb (`bekle … belge den`), and the stranded from-phrase is captured
6872
+ // by the NEXT statement as a junk trigger event (behavior-sortable R3).
6873
+ requiredRoles: ["action", "duration", "source"],
6874
+ // Never reorder a fused single-line handler — its event must stay put.
6875
+ predicate: (parsed) => !parsed.roles.has("event")
6876
+ },
6877
+ transform: {
6878
+ // belge den pointermove(clientY) veya pointerup(clientY) bekle
6879
+ roleOrder: ["patient", "source", "duration", "action"],
6880
+ insertMarkers: true
6881
+ }
6882
+ },
6883
+ {
6884
+ name: "repeat-until-event-verb-final",
6885
+ description: "Keep repeat-until-event's from-phrase before the verb",
6886
+ priority: 90,
6887
+ match: {
6888
+ commands: ["repeat", "tekrarla"],
6889
+ requiredRoles: ["action", "patient", "source"],
6890
+ // Gate to the until-event head; `repeat for item in .items` also
6891
+ // carries patient+source and must keep its (parseable) default order.
6892
+ predicate: (parsed) => /^repeat\s+until\s+event\b/i.test((parsed.original ?? "").trim())
6893
+ },
6894
+ transform: {
6895
+ // kadar olay pointerup i belge den tekrarla — matched semantic-side by
6896
+ // repeat-tr-until-head-verb-final.
6897
+ roleOrder: ["patient", "source", "action"],
6898
+ insertMarkers: true
6899
+ }
6900
+ },
6901
+ // the olay i gönder de durdur ardından validateForm() i çağır
6902
+ sovHaltCallFusedRule({
6903
+ callVerb: "\xE7a\u011F\u0131r",
6904
+ patientMarker: "i",
6905
+ eventMarker: "de",
6906
+ connective: "ard\u0131ndan"
6907
+ }),
6908
+ // #note nin karakterler 0 ile 5 i tıklama de seç
6909
+ sovPickRangeRule({
6910
+ genitive: "nin",
6911
+ rangeSep: "ile",
6912
+ patientMarker: "i",
6913
+ eventMarker: "de"
6914
+ })
6548
6915
  ]
6549
6916
  };
6550
6917
  var spanishProfile = {
@@ -6667,6 +7034,8 @@ var quechuaProfile = {
6667
7034
  morphology: "agglutinative",
6668
7035
  // Actually polysynthetic
6669
7036
  direction: "ltr",
7037
+ // NOTE: roles absent from this order are safety-net-appended AFTER the verb
7038
+ // (see the Turkish profile note) — extend via per-command `rules`, not here.
6670
7039
  canonicalOrder: ["patient", "source", "destination", "event", "action"],
6671
7040
  markers: [
6672
7041
  // Quechua case suffixes - using spaced form for tokenization
@@ -6679,6 +7048,41 @@ var quechuaProfile = {
6679
7048
  { form: "wan", role: "style", position: "postposition", required: false },
6680
7049
  { form: "hina", role: "method", position: "postposition", required: false }
6681
7050
  // "as/like"
7051
+ ],
7052
+ rules: [
7053
+ {
7054
+ name: "wait-oblique-verb-final",
7055
+ description: "Keep wait's from-phrase and or-run inside the clause, verb-final",
7056
+ priority: 90,
7057
+ match: {
7058
+ commands: ["wait", "suyay"],
7059
+ // Only `wait for X or Y from Z` strands: duration is missing from
7060
+ // canonicalOrder, so the or-run lands AFTER the verb and the next
7061
+ // trigger glues it into its event (behavior-sortable R3). See the
7062
+ // matching Turkish rule.
7063
+ requiredRoles: ["action", "duration", "source"],
7064
+ predicate: (parsed) => !parsed.roles.has("event")
7065
+ },
7066
+ transform: {
7067
+ // qillqa manta pointermove(clientY) utaq pointerup(clientY) suyay
7068
+ roleOrder: ["patient", "source", "duration", "action"],
7069
+ insertMarkers: true
7070
+ }
7071
+ },
7072
+ // the ruway ta kachay pi sayay chayqa validateForm() ta qayay
7073
+ sovHaltCallFusedRule({
7074
+ callVerb: "qayay",
7075
+ patientMarker: "ta",
7076
+ eventMarker: "pi",
7077
+ connective: "chayqa"
7078
+ }),
7079
+ // #note pa sanampa 0 kama 5 ta ñitiy pi akllay
7080
+ sovPickRangeRule({
7081
+ genitive: "pa",
7082
+ rangeSep: "kama",
7083
+ patientMarker: "ta",
7084
+ eventMarker: "pi"
7085
+ })
6682
7086
  ]
6683
7087
  };
6684
7088
  var swahiliProfile = {
@@ -6710,6 +7114,8 @@ var bengaliProfile = {
6710
7114
  direction: "ltr",
6711
7115
  // Bengali: Object comes before verb, postpositions follow nouns
6712
7116
  // "on click increment #count" → "#count কে ক্লিক এ বৃদ্ধি"
7117
+ // NOTE: roles absent from this order are safety-net-appended AFTER the verb
7118
+ // (see the Turkish profile note) — extend via per-command `rules`, not here.
6713
7119
  canonicalOrder: ["patient", "event", "action"],
6714
7120
  markers: [
6715
7121
  // Postpositions
@@ -6785,7 +7191,21 @@ var bengaliProfile = {
6785
7191
  roleOrder: ["patient", "destination", "action"],
6786
7192
  insertMarkers: true
6787
7193
  }
6788
- }
7194
+ },
7195
+ // the ঘটনা কে জমা এ থামুন তারপর validateForm() কে কল
7196
+ sovHaltCallFusedRule({
7197
+ callVerb: "\u0995\u09B2",
7198
+ patientMarker: "\u0995\u09C7",
7199
+ eventMarker: "\u098F",
7200
+ connective: "\u09A4\u09BE\u09B0\u09AA\u09B0"
7201
+ }),
7202
+ // #note র অক্ষর 0 থেকে 5 কে ক্লিক এ বাছুন
7203
+ sovPickRangeRule({
7204
+ genitive: "\u09B0",
7205
+ rangeSep: "\u09A5\u09C7\u0995\u09C7",
7206
+ patientMarker: "\u0995\u09C7",
7207
+ eventMarker: "\u098F"
7208
+ })
6789
7209
  ]
6790
7210
  };
6791
7211
  var italianProfile = {
@@ -6957,7 +7377,21 @@ var hindiProfile = {
6957
7377
  roleOrder: ["patient", "destination", "action"],
6958
7378
  insertMarkers: true
6959
7379
  }
6960
- }
7380
+ },
7381
+ // the घटना को जमा पर रोकें फिर validateForm() को कॉल
7382
+ sovHaltCallFusedRule({
7383
+ callVerb: "\u0915\u0949\u0932",
7384
+ patientMarker: "\u0915\u094B",
7385
+ eventMarker: "\u092A\u0930",
7386
+ connective: "\u092B\u093F\u0930"
7387
+ }),
7388
+ // #note का अक्षर 0 से 5 को क्लिक पर चुनें
7389
+ sovPickRangeRule({
7390
+ genitive: "\u0915\u093E",
7391
+ rangeSep: "\u0938\u0947",
7392
+ patientMarker: "\u0915\u094B",
7393
+ eventMarker: "\u092A\u0930"
7394
+ })
6961
7395
  ]
6962
7396
  };
6963
7397
  var tagalogProfile = {
@@ -8442,6 +8876,10 @@ var GrammarTransformer = class {
8442
8876
  if (block) {
8443
8877
  return this.transformBlock(block);
8444
8878
  }
8879
+ const strippedEnd = this.transformWithTrailingEnd(input);
8880
+ if (strippedEnd !== null) {
8881
+ return strippedEnd;
8882
+ }
8445
8883
  const setScope = this.transformSetWithScope(input);
8446
8884
  if (setScope !== null) {
8447
8885
  return setScope;
@@ -8469,6 +8907,35 @@ var GrammarTransformer = class {
8469
8907
  }
8470
8908
  return joinTokens(reordered.map((e) => e.translated || e.value));
8471
8909
  }
8910
+ /**
8911
+ * `<command …> end` fragments: transform the command without its stranded
8912
+ * terminator, then re-append the translated terminator as a standalone
8913
+ * trailing token. Fragments that open a block of their own (`if … end`,
8914
+ * `repeat … end`, `js … end`) bail — their terminator belongs to them and
8915
+ * their dedicated paths handle it.
8916
+ */
8917
+ transformWithTrailingEnd(input) {
8918
+ const src = this.sourceProfile.code;
8919
+ const tokens = input.trim().split(/\s+/);
8920
+ if (tokens.length < 2) {
8921
+ return null;
8922
+ }
8923
+ const sourceEnd = translateWord("end", "en", src).toLowerCase();
8924
+ if (tokens[tokens.length - 1].toLowerCase() !== sourceEnd) {
8925
+ return null;
8926
+ }
8927
+ const openers = new Set(
8928
+ ["if", "repeat", "unless", "while", "when", "live", "js"].map(
8929
+ (k) => translateWord(k, "en", src).toLowerCase()
8930
+ )
8931
+ );
8932
+ if (tokens.slice(0, -1).some((t) => openers.has(t.toLowerCase()))) {
8933
+ return null;
8934
+ }
8935
+ const inner = this.transformSingle(tokens.slice(0, -1).join(" "));
8936
+ const endT = translateWord(tokens[tokens.length - 1], src, this.targetProfile.code);
8937
+ return `${inner} ${endT}`;
8938
+ }
8472
8939
  /**
8473
8940
  * Detect and transform an inline JS block (`[on <event>] js <raw js> end`).
8474
8941
  *
@@ -8728,7 +9195,9 @@ var GrammarTransformer = class {
8728
9195
  const tailT = tail ? translateWord(tail, src, dst) : "";
8729
9196
  const clauseT = clause ? translateMultiWordValue(clause, src, dst) : "";
8730
9197
  const bodyT = this.transformConditionalBody(bodyTokens);
8731
- return [headT, clauseT, bodyT, tailT].filter((s) => s.length > 0).join(" ");
9198
+ const POSITIONAL_BRANCH_HEADS = /* @__PURE__ */ new Set(["first", "last", "next", "previous", "closest"]);
9199
+ const thenT = this.targetProfile.wordOrder === "SOV" && clauseT && POSITIONAL_BRANCH_HEADS.has(bodyTokens[1]?.toLowerCase()) && inner[bodyStart - 1]?.toLowerCase() !== "then" ? translateWord("then", src, dst) : "";
9200
+ return [headT, clauseT, thenT, bodyT, tailT].filter((s) => s.length > 0).join(" ");
8732
9201
  }
8733
9202
  /**
8734
9203
  * Transform an `if`/`unless` block body, splitting it at a top-level `else` into