@lokascript/i18n 2.9.3 → 2.10.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 (40) hide show
  1. package/dist/browser.cjs +74 -10
  2. package/dist/browser.cjs.map +1 -1
  3. package/dist/browser.d.cts +2 -2
  4. package/dist/browser.d.ts +2 -2
  5. package/dist/browser.js +74 -10
  6. package/dist/browser.js.map +1 -1
  7. package/dist/dictionaries/index.cjs +18 -10
  8. package/dist/dictionaries/index.cjs.map +1 -1
  9. package/dist/dictionaries/index.js +18 -10
  10. package/dist/dictionaries/index.js.map +1 -1
  11. package/dist/index.cjs +74 -10
  12. package/dist/index.cjs.map +1 -1
  13. package/dist/index.d.cts +1 -1
  14. package/dist/index.d.ts +1 -1
  15. package/dist/index.js +74 -10
  16. package/dist/index.js.map +1 -1
  17. package/dist/lokascript-i18n.min.js +1 -1
  18. package/dist/lokascript-i18n.min.js.map +1 -1
  19. package/dist/lokascript-i18n.mjs +110 -10
  20. package/dist/lokascript-i18n.mjs.map +1 -1
  21. package/dist/plugins/vite.cjs +18 -10
  22. package/dist/plugins/vite.cjs.map +1 -1
  23. package/dist/plugins/vite.js +18 -10
  24. package/dist/plugins/vite.js.map +1 -1
  25. package/dist/plugins/webpack.cjs +18 -10
  26. package/dist/plugins/webpack.cjs.map +1 -1
  27. package/dist/plugins/webpack.js +18 -10
  28. package/dist/plugins/webpack.js.map +1 -1
  29. package/dist/{transformer--W46PGaW.d.cts → transformer-CsOeqayN.d.cts} +18 -1
  30. package/dist/{transformer-FU06J6kG.d.ts → transformer-DWCTG1DQ.d.ts} +18 -1
  31. package/package.json +4 -4
  32. package/src/dictionaries/de.ts +3 -1
  33. package/src/dictionaries/es.ts +2 -2
  34. package/src/dictionaries/pl.ts +2 -1
  35. package/src/dictionaries/pt.ts +5 -2
  36. package/src/dictionaries/ru.ts +2 -2
  37. package/src/dictionaries/uk.ts +2 -2
  38. package/src/grammar/grammar.test.ts +87 -0
  39. package/src/grammar/transformer.ts +106 -0
  40. package/src/grammar/types.ts +4 -0
package/dist/index.cjs CHANGED
@@ -379,12 +379,12 @@ var es = {
379
379
  events: {
380
380
  click: "clic",
381
381
  dblclick: "dobleclic",
382
- mousedown: "rat\xF3nabajo",
383
- mouseup: "rat\xF3narriba",
384
382
  mouseenter: "rat\xF3nentrar",
385
383
  mouseleave: "rat\xF3nsalir",
386
384
  // V3 Batch 2: fused forms split to the S5b/tokenizer-known forms (the fused
387
385
  // spellings captured event=expression:undefined — broken listeners)
386
+ mousedown: "rat\xF3n abajo",
387
+ mouseup: "rat\xF3n arriba",
388
388
  mouseover: "rat\xF3n encima",
389
389
  mouseout: "rat\xF3n fuera",
390
390
  mousemove: "rat\xF3nmover",
@@ -1275,7 +1275,9 @@ var de = {
1275
1275
  reset: "zur\xFCcksetzen",
1276
1276
  load: "laden",
1277
1277
  unload: "entladen",
1278
- resize: "gr\xF6\xDFe\xE4ndern",
1278
+ // 'größeändern' was a malformed compound: German either separates the verb
1279
+ // phrase ('Größe ändern') or compounds with the linking -n- ('Größenänderung').
1280
+ resize: "gr\xF6\xDFen\xE4nderung",
1279
1281
  scroll: "scrollen",
1280
1282
  touchstart: "ber\xFChrungstart",
1281
1283
  touchend: "ber\xFChrungend",
@@ -2852,12 +2854,15 @@ var pt = {
2852
2854
  events: {
2853
2855
  click: "clique",
2854
2856
  dblclick: "duploClique",
2855
- mousedown: "mouseBaixo",
2856
- mouseup: "mouseCima",
2857
2857
  mouseenter: "mouseEntrar",
2858
2858
  mouseleave: "mouseSair",
2859
2859
  // V3 Batch 2: camelCase forms split to the S5b/tokenizer-known forms (the
2860
2860
  // fused spellings captured event=expression:undefined — broken listeners)
2861
+ // pt-BR idiom is "pressionado"/"solto", not the spatial baixo/cima calque —
2862
+ // cf. MDN pt-BR ("um botão ... é pressionado") and Scratch pt-BR
2863
+ // ("mouse pressionado?"). The calques stay as profile parse alternatives.
2864
+ mousedown: "mouse pressionado",
2865
+ mouseup: "mouse solto",
2861
2866
  mouseover: "mouse sobre",
2862
2867
  mouseout: "mouse fora",
2863
2868
  mousemove: "mouseMover",
@@ -3520,7 +3525,8 @@ var pl = {
3520
3525
  // Batch 3: resetuj captured on.event as expression (broken listener) — profile word round-trips
3521
3526
  load: "za\u0142aduj",
3522
3527
  unload: "wy\u0142aduj",
3523
- resize: "zmie\u0144rozmiar",
3528
+ // 'zmieńrozmiar' was a fused two-word phrase; Polish writes 'zmiana rozmiaru'.
3529
+ resize: "zmiana rozmiaru",
3524
3530
  scroll: "przewi\u0144",
3525
3531
  touchstart: "dotykstart",
3526
3532
  touchend: "dotykkoniec",
@@ -3679,7 +3685,7 @@ var russianDictionary = {
3679
3685
  morph: "\u0442\u0440\u0430\u043D\u0441\u0444\u043E\u0440\u043C\u0438\u0440\u043E\u0432\u0430\u0442\u044C",
3680
3686
  settle: "\u0441\u0442\u0430\u0431\u0438\u043B\u0438\u0437\u0438\u0440\u043E\u0432\u0430\u0442\u044C",
3681
3687
  append: "\u0434\u043E\u043F\u0438\u0441\u0430\u0442\u044C",
3682
- // profile alternative; the compound splits and добавить parses as add
3688
+ // matches the ru profile primary
3683
3689
  exit: "\u0432\u044B\u0439\u0442\u0438",
3684
3690
  else: "\u0438\u043D\u0430\u0447\u0435",
3685
3691
  install: "\u0438\u043D\u0441\u0442\u0430\u043B\u043B\u0438\u0440\u043E\u0432\u0430\u0442\u044C",
@@ -3689,7 +3695,8 @@ var russianDictionary = {
3689
3695
  focus: "\u0441\u0444\u043E\u043A\u0443\u0441\u0438\u0440\u043E\u0432\u0430\u0442\u044C",
3690
3696
  blur: "\u0440\u0430\u0437\u043C\u044B\u0442\u044C",
3691
3697
  clone: "\u043A\u043B\u043E\u043D\u0438\u0440\u043E\u0432\u0430\u0442\u044C",
3692
- prepend: "\u0434\u043E\u0431\u0430\u0432\u0438\u0442\u044C_\u0432_\u043D\u0430\u0447\u0430\u043B\u043E",
3698
+ prepend: "\u0434\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0432 \u043D\u0430\u0447\u0430\u043B\u043E",
3699
+ // natural form; the underscore compound was never natural Russian
3693
3700
  breakpoint: "\u0442\u043E\u0447\u043A\u0430-\u043E\u0441\u0442\u0430\u043D\u043E\u0432\u0430",
3694
3701
  clear: "\u043E\u0447\u0438\u0441\u0442\u0438\u0442\u044C",
3695
3702
  close: "\u0437\u0430\u043A\u0440\u044B\u0442\u044C",
@@ -3921,7 +3928,7 @@ var ukrainianDictionary = {
3921
3928
  morph: "\u0442\u0440\u0430\u043D\u0441\u0444\u043E\u0440\u043C\u0443\u0432\u0430\u0442\u0438",
3922
3929
  settle: "\u0441\u0442\u0430\u0431\u0456\u043B\u0456\u0437\u0443\u0432\u0430\u0442\u0438",
3923
3930
  append: "\u0434\u043E\u043F\u0438\u0441\u0430\u0442\u0438",
3924
- // profile alternative; the compound splits and додати parses as add
3931
+ // matches the uk profile primary
3925
3932
  exit: "\u0432\u0438\u0439\u0442\u0438",
3926
3933
  else: "\u0456\u043D\u0430\u043A\u0448\u0435",
3927
3934
  install: "\u0456\u043D\u0441\u0442\u0430\u043B\u044E\u0432\u0430\u0442\u0438",
@@ -3931,7 +3938,8 @@ var ukrainianDictionary = {
3931
3938
  focus: "\u0441\u0444\u043E\u043A\u0443\u0441\u0443\u0432\u0430\u0442\u0438",
3932
3939
  blur: "\u0440\u043E\u0437\u0444\u043E\u043A\u0443\u0441\u0443\u0432\u0430\u0442\u0438",
3933
3940
  clone: "\u043A\u043B\u043E\u043D\u0443\u0432\u0430\u0442\u0438",
3934
- prepend: "\u0434\u043E\u0434\u0430\u0442\u0438_\u043D\u0430_\u043F\u043E\u0447\u0430\u0442\u043E\u043A",
3941
+ prepend: "\u0434\u043E\u0434\u0430\u0442\u0438 \u043D\u0430 \u043F\u043E\u0447\u0430\u0442\u043E\u043A",
3942
+ // natural form; see ru.ts
3935
3943
  breakpoint: "\u0442\u043E\u0447\u043A\u0430-\u0437\u0443\u043F\u0438\u043D\u043A\u0438",
3936
3944
  clear: "\u043E\u0447\u0438\u0441\u0442\u0438\u0442\u0438",
3937
3945
  close: "\u0437\u0430\u043A\u0440\u0438\u0442\u0438",
@@ -15329,6 +15337,25 @@ function restoreCaretScopes(input, scopes) {
15329
15337
  (_m, n) => scopes[Number(n)] ?? ""
15330
15338
  );
15331
15339
  }
15340
+ var VIEW_TAIL_OPEN = "\uE002";
15341
+ var VIEW_TAIL_CLOSE = "\uE003";
15342
+ var VIEW_TAIL_RE = /\busing\s+view\b(?:\s+(?!then\b)[A-Za-z][\w-]*)?/gi;
15343
+ var VIEW_TAIL_TOKEN_RE = new RegExp(`^${VIEW_TAIL_OPEN}(\\d+)${VIEW_TAIL_CLOSE}$`);
15344
+ function maskViewTransitionTails(input) {
15345
+ const tails = [];
15346
+ const masked = input.replace(VIEW_TAIL_RE, (match) => {
15347
+ const idx = tails.length;
15348
+ tails.push(match);
15349
+ return `${VIEW_TAIL_OPEN}${idx}${VIEW_TAIL_CLOSE}`;
15350
+ });
15351
+ return tails.length > 0 ? { masked, tails } : null;
15352
+ }
15353
+ function restoreViewTransitionTails(input, tails) {
15354
+ return input.replace(
15355
+ new RegExp(`${VIEW_TAIL_OPEN}(\\d+)${VIEW_TAIL_CLOSE}`, "g"),
15356
+ (_m, n) => tails[Number(n)] ?? ""
15357
+ );
15358
+ }
15332
15359
  var GrammarTransformer = class {
15333
15360
  constructor(sourceLocale = "en", targetLocale) {
15334
15361
  const source = getProfile(sourceLocale);
@@ -15350,6 +15377,10 @@ var GrammarTransformer = class {
15350
15377
  return this.targetProfile.code === "he" ? repairHebrewFrontedAccusative(out) : out;
15351
15378
  }
15352
15379
  transformInternal(input) {
15380
+ const viewTails = maskViewTransitionTails(input);
15381
+ if (viewTails) {
15382
+ return restoreViewTransitionTails(this.transformInternal(viewTails.masked), viewTails.tails);
15383
+ }
15353
15384
  const caret = maskCaretScopes(input);
15354
15385
  if (caret) {
15355
15386
  return restoreCaretScopes(this.transform(caret.masked), caret.scopes);
@@ -15402,6 +15433,10 @@ var GrammarTransformer = class {
15402
15433
  if (setScope !== null) {
15403
15434
  return setScope;
15404
15435
  }
15436
+ const viewTail = this.transformWithViewTransitionTail(input);
15437
+ if (viewTail !== null) {
15438
+ return viewTail;
15439
+ }
15405
15440
  const parsed = parseStatement(input, this.sourceProfile.code);
15406
15441
  if (!parsed) {
15407
15442
  return input;
@@ -15425,6 +15460,35 @@ var GrammarTransformer = class {
15425
15460
  }
15426
15461
  return joinTokens(reordered.map((e) => e.translated || e.value));
15427
15462
  }
15463
+ /**
15464
+ * Clause carrying a masked `using view transition` tail: strip the opaque
15465
+ * token, transform the clause alone, and re-append the token at the very end.
15466
+ *
15467
+ * The tail is a clause-final modifier in every word order the corpus emits:
15468
+ * the semantic side matches it as the literal `using view` marker plus a value
15469
+ * word, and the SOV/VSO event-handler patterns admit it as an optional
15470
+ * TRAILING group (after the with-marked operand). So the target position is
15471
+ * "end of the transformed clause" for all 24 languages — no per-profile
15472
+ * placement decision, which is what makes this a passthrough rather than a
15473
+ * role.
15474
+ *
15475
+ * Returns null when the clause carries no masked tail, or when the token is
15476
+ * not clause-final (nothing to reposition — leaving it in place still restores
15477
+ * verbatim English).
15478
+ */
15479
+ transformWithViewTransitionTail(input) {
15480
+ const trimmed = input.trim();
15481
+ const tokens = trimmed.split(/\s+/);
15482
+ if (tokens.length < 2) {
15483
+ return null;
15484
+ }
15485
+ if (!VIEW_TAIL_TOKEN_RE.test(tokens[tokens.length - 1])) {
15486
+ return null;
15487
+ }
15488
+ const tail = tokens[tokens.length - 1];
15489
+ const head = tokens.slice(0, -1).join(" ");
15490
+ return `${this.transformSingle(head)} ${tail}`;
15491
+ }
15428
15492
  /**
15429
15493
  * `<command …> end` fragments: transform the command without its stranded
15430
15494
  * terminator, then re-append the translated terminator as a standalone