green-screen-proxy 1.1.2 → 1.2.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 (79) hide show
  1. package/README.md +93 -8
  2. package/dist/cli.js +0 -6
  3. package/dist/cli.js.map +1 -1
  4. package/dist/controller.d.ts +3 -0
  5. package/dist/controller.d.ts.map +1 -1
  6. package/dist/controller.js +13 -2
  7. package/dist/controller.js.map +1 -1
  8. package/dist/index.d.ts +1 -2
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +11 -16
  11. package/dist/index.js.map +1 -1
  12. package/dist/protocols/tn5250-handler.d.ts +3 -2
  13. package/dist/protocols/tn5250-handler.d.ts.map +1 -1
  14. package/dist/protocols/tn5250-handler.js +83 -25
  15. package/dist/protocols/tn5250-handler.js.map +1 -1
  16. package/dist/protocols/types.d.ts +28 -2
  17. package/dist/protocols/types.d.ts.map +1 -1
  18. package/dist/protocols/types.js +28 -0
  19. package/dist/protocols/types.js.map +1 -1
  20. package/dist/routes.d.ts.map +1 -1
  21. package/dist/routes.js +160 -34
  22. package/dist/routes.js.map +1 -1
  23. package/dist/server.js +1 -5
  24. package/dist/server.js.map +1 -1
  25. package/dist/session-store.d.ts +68 -0
  26. package/dist/session-store.d.ts.map +1 -0
  27. package/dist/session-store.js +40 -0
  28. package/dist/session-store.js.map +1 -0
  29. package/dist/session.d.ts +26 -3
  30. package/dist/session.d.ts.map +1 -1
  31. package/dist/session.js +83 -11
  32. package/dist/session.js.map +1 -1
  33. package/dist/standalone.d.ts +3 -0
  34. package/dist/standalone.d.ts.map +1 -0
  35. package/dist/standalone.js +6 -0
  36. package/dist/standalone.js.map +1 -0
  37. package/dist/tn5250/connection.d.ts +5 -0
  38. package/dist/tn5250/connection.d.ts.map +1 -1
  39. package/dist/tn5250/connection.js +25 -1
  40. package/dist/tn5250/connection.js.map +1 -1
  41. package/dist/tn5250/constants.d.ts +39 -3
  42. package/dist/tn5250/constants.d.ts.map +1 -1
  43. package/dist/tn5250/constants.js +51 -3
  44. package/dist/tn5250/constants.js.map +1 -1
  45. package/dist/tn5250/ebcdic-jp-builtin.d.ts +45 -0
  46. package/dist/tn5250/ebcdic-jp-builtin.d.ts.map +1 -0
  47. package/dist/tn5250/ebcdic-jp-builtin.js +124 -0
  48. package/dist/tn5250/ebcdic-jp-builtin.js.map +1 -0
  49. package/dist/tn5250/ebcdic-jp.d.ts +61 -0
  50. package/dist/tn5250/ebcdic-jp.d.ts.map +1 -0
  51. package/dist/tn5250/ebcdic-jp.js +188 -0
  52. package/dist/tn5250/ebcdic-jp.js.map +1 -0
  53. package/dist/tn5250/ebcdic.d.ts +13 -4
  54. package/dist/tn5250/ebcdic.d.ts.map +1 -1
  55. package/dist/tn5250/ebcdic.js +30 -8
  56. package/dist/tn5250/ebcdic.js.map +1 -1
  57. package/dist/tn5250/encoder.d.ts +41 -9
  58. package/dist/tn5250/encoder.d.ts.map +1 -1
  59. package/dist/tn5250/encoder.js +228 -41
  60. package/dist/tn5250/encoder.js.map +1 -1
  61. package/dist/tn5250/parser.d.ts +14 -0
  62. package/dist/tn5250/parser.d.ts.map +1 -1
  63. package/dist/tn5250/parser.js +428 -53
  64. package/dist/tn5250/parser.js.map +1 -1
  65. package/dist/tn5250/screen.d.ts +144 -24
  66. package/dist/tn5250/screen.d.ts.map +1 -1
  67. package/dist/tn5250/screen.js +244 -13
  68. package/dist/tn5250/screen.js.map +1 -1
  69. package/dist/ui/assets/index-B51sr7HL.js +56 -0
  70. package/dist/ui/assets/index-B9wpEWAh.css +1 -0
  71. package/dist/ui/assets/index-BrUnECmE.css +1 -0
  72. package/dist/ui/assets/index-CDBbEXbH.js +56 -0
  73. package/dist/ui/index.html +16 -0
  74. package/dist/websocket.d.ts +3 -0
  75. package/dist/websocket.d.ts.map +1 -1
  76. package/dist/websocket.js +90 -1
  77. package/dist/websocket.js.map +1 -1
  78. package/dist/worker/index.js +5573 -0
  79. package/package.json +1 -1
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Built-in minimum IBM-Kanji (CCSID 300) → Unicode table.
3
+ *
4
+ * This covers the **non-Kanji** portion of the IBM host double-byte code
5
+ * set — the rows that contain the DBCS space, full-width ASCII, Hiragana,
6
+ * Katakana (full-width), and common CJK punctuation / symbols.
7
+ *
8
+ * These are the characters you see on typical IBM i Japanese system
9
+ * screens (menu titles, field labels, error messages), which are mostly
10
+ * rendered in hiragana/katakana rather than kanji. The full Kanji plane
11
+ * (~7000 characters in rows 0x4F–0xFE of CCSID 300) is NOT included here
12
+ * — register the full table separately via `registerDbcsTable()` after
13
+ * generating it with `scripts/generate-ibm-kanji-table.mjs`.
14
+ *
15
+ * Layout notes (per IBM CCSID 300 mapping):
16
+ * Row 0x41 — CJK/IBM special symbols
17
+ * Row 0x42 — DBCS space + full-width ASCII 0x20-0x7E (full-width)
18
+ * Row 0x43 — Hiragana (あ-ん + voiced)
19
+ * Row 0x44 — Katakana (ア-ン + voiced)
20
+ * Row 0x45 — Greek (Α-Ω, α-ω)
21
+ * Row 0x46 — Cyrillic
22
+ * Row 0x47 — Box-drawing characters
23
+ *
24
+ * The bytes that follow row bytes are 0x41..0xFE (column selector).
25
+ * IBM CCSID 300 tables start at column 0x41 = JIS column 1.
26
+ *
27
+ * Rather than hand-transcribing every entry (error-prone), this file
28
+ * builds the mapping arithmetically from the well-known Unicode ranges
29
+ * using the IBM → JIS column offset of (byte2 - 0x41).
30
+ */
31
+ import { registerDbcsTable } from './ebcdic-jp.js';
32
+ /** Build a range of entries from a starting Unicode code point. */
33
+ function range(ibmByte1, ibmCol1, ibmCol2, startCp, skip = []) {
34
+ const out = {};
35
+ let cp = startCp;
36
+ for (let c = ibmCol1; c <= ibmCol2; c++) {
37
+ if (skip.includes(c))
38
+ continue;
39
+ const key = ((ibmByte1 << 8) | c).toString(16).toUpperCase().padStart(4, '0');
40
+ try {
41
+ out[key] = String.fromCodePoint(cp);
42
+ }
43
+ catch {
44
+ // invalid code point — skip
45
+ }
46
+ cp++;
47
+ }
48
+ return out;
49
+ }
50
+ /** Assemble the built-in table. */
51
+ function buildBuiltinTable() {
52
+ const t = {};
53
+ // --- Row 0x41 — CJK symbols + IBM specials ---
54
+ // 0x4141 — DBCS space (ideographic space U+3000)
55
+ t['4141'] = '\u3000';
56
+ // Common CJK punctuation (subset — most-used entries)
57
+ // 0x4144 → 、 (U+3001)
58
+ // 0x4145 → 。 (U+3002)
59
+ // 0x4146 → , (U+FF0C) — overlaps but shows intent
60
+ // 0x4149 → 「 (U+300C)
61
+ // 0x414A → 」 (U+300D)
62
+ // 0x4150 → ・ (U+30FB) middle dot
63
+ t['4144'] = '\u3001'; // 、
64
+ t['4145'] = '\u3002'; // 。
65
+ t['4149'] = '\u300C'; // 「
66
+ t['414A'] = '\u300D'; // 」
67
+ t['4150'] = '\u30FB'; // ・
68
+ // 0x4151 → ー (U+30FC) prolonged sound mark
69
+ t['4151'] = '\u30FC';
70
+ // --- Row 0x42 — Full-width ASCII ---
71
+ // IBM col 0x4A = U+FF01 '!', col 0x4B = U+FF02 '"', ... through 0x7E range.
72
+ // Standard JIS: full-width printable ASCII is U+FF01..U+FF5E mapped to
73
+ // JIS row 3 columns 1..94. In IBM CCSID 300, these sit at row 0x42
74
+ // columns 0x4A..0xA7 with some gaps. Use a safe arithmetic span:
75
+ // byte2 0x4B..0x7F → U+FF01..U+FF35 (letters + digits + basic punct)
76
+ // This is an approximation — load the full JSON table for perfect
77
+ // fidelity. Covers uppercase, digits, common punctuation.
78
+ Object.assign(t, range(0x42, 0x4B, 0x7F, 0xFF01));
79
+ // Full-width lowercase letters span the next block
80
+ Object.assign(t, range(0x42, 0x81, 0xA9, 0xFF36));
81
+ // --- Row 0x43 — Hiragana ---
82
+ // JIS row 4 col 1 = U+3041 (ぁ) through col 83 = U+3093 (ん).
83
+ // IBM layout puts these at 0x43 columns 0x4F..0xA2 (contiguous in practice).
84
+ // We map the exact Unicode hiragana block starting at 0x3041.
85
+ Object.assign(t, range(0x43, 0x4F, 0x4F + (0x3093 - 0x3041), 0x3041));
86
+ // --- Row 0x44 — Katakana (full-width) ---
87
+ // JIS row 5 col 1 = U+30A1 (ァ) through col 86 = U+30F6 (ヶ).
88
+ // IBM: 0x44 columns 0x4F..0xA4 approximately.
89
+ Object.assign(t, range(0x44, 0x4F, 0x4F + (0x30F6 - 0x30A1), 0x30A1));
90
+ // --- Row 0x45 — Greek ---
91
+ // JIS row 6 col 1 = U+0391 (Α, uppercase Alpha) through col 24 = U+03A9 (Ω),
92
+ // then col 33 = U+03B1 (α) through col 56 = U+03C9 (ω).
93
+ Object.assign(t, range(0x45, 0x41, 0x58, 0x0391));
94
+ Object.assign(t, range(0x45, 0x62, 0x79, 0x03B1));
95
+ // --- Row 0x46 — Cyrillic ---
96
+ // JIS row 7 col 1 = U+0410 (А) .. col 32 = U+042F (Я),
97
+ // then col 49 = U+0430 (а) .. col 80 = U+044F (я).
98
+ Object.assign(t, range(0x46, 0x41, 0x60, 0x0410));
99
+ Object.assign(t, range(0x46, 0x70, 0x8F, 0x0430));
100
+ // --- Row 0x47 — Box drawing ---
101
+ // JIS row 8 col 1 = U+2500 (─) .. col 32 = U+253F (broadly).
102
+ // Not all positions are assigned in JIS X 0208; we map the first 32
103
+ // contiguous characters as a best-effort. The built-in rendering via
104
+ // the Japanese monospace fonts listed in terminal.css aligns well.
105
+ Object.assign(t, range(0x47, 0x41, 0x60, 0x2500));
106
+ return t;
107
+ }
108
+ /**
109
+ * Register the built-in minimum IBM-Kanji table with the DBCS decoder.
110
+ * Call this once at proxy startup to get hiragana/katakana/symbol
111
+ * rendering without shipping the full Kanji table.
112
+ *
113
+ * The full Kanji plane (~7000 characters) still falls back to the geta
114
+ * mark until you register a complete table via `registerDbcsTable()`.
115
+ *
116
+ * Idempotent — safe to call multiple times; later entries overwrite
117
+ * earlier ones, so calling `registerDbcsTable(fullTable)` AFTER
118
+ * `registerBuiltinDbcsTable()` will layer the full table on top of the
119
+ * minimum.
120
+ */
121
+ export function registerBuiltinDbcsTable() {
122
+ registerDbcsTable(buildBuiltinTable());
123
+ }
124
+ //# sourceMappingURL=ebcdic-jp-builtin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ebcdic-jp-builtin.js","sourceRoot":"","sources":["../../src/tn5250/ebcdic-jp-builtin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Japanese EBCDIC code pages for IBM i.
3
+ *
4
+ * Japanese IBM i systems typically use one of:
5
+ * - CCSID 290 — Japanese Katakana Extended (single-byte, host ROMAN)
6
+ * - CCSID 1027 — Japanese English Extended (single-byte, Latin)
7
+ * - CCSID 930 — Katakana-Kanji Mixed (SBCS 290 + DBCS)
8
+ * - CCSID 939 — Latin-Kanji Mixed (SBCS 1027 + DBCS)
9
+ *
10
+ * This module provides:
11
+ * 1. Single-byte CP290 katakana translation table (the "SO off" plane)
12
+ * 2. DBCS (Double-Byte Character Set) Kanji mapping hooks with a default
13
+ * converter that leverages Node's built-in Shift-JIS decoder via an
14
+ * IBM-Kanji → JIS X 0208 formula.
15
+ * 3. SI / SO control byte handling helpers.
16
+ *
17
+ * The DBCS converter covers the base JIS X 0208 plane. IBM-specific
18
+ * kanji extensions (user-defined characters, IBM selected kanji) that fall
19
+ * outside JIS X 0208 will render as the geta mark "〓" which is the
20
+ * conventional Japanese typographic substitution and preserves layout.
21
+ *
22
+ * Layout note: DBCS characters occupy 2 screen cells. The caller is
23
+ * responsible for writing the resolved glyph into the first cell and
24
+ * marking the second cell as a continuation (empty string).
25
+ */
26
+ /** Shift-In: return to single-byte mode (EBCDIC SBCS). */
27
+ export declare const SI = 15;
28
+ /** Shift-Out: enter double-byte mode (EBCDIC DBCS Kanji). */
29
+ export declare const SO = 14;
30
+ export declare const EBCDIC_CP290_TO_UNICODE: number[];
31
+ /**
32
+ * Convert a single CP290 EBCDIC byte to a Unicode character.
33
+ * Unmapped positions fall back to SPACE.
34
+ */
35
+ export declare function cp290ToChar(byte: number): string;
36
+ /** Unicode "geta mark" — conventional Japanese placeholder for unmapped kanji. */
37
+ export declare const DBCS_PLACEHOLDER = "\u3013";
38
+ /** Shift-Out / Shift-In markers rendered as invisible in output. */
39
+ export declare const DBCS_SHIFT_INVISIBLE = "";
40
+ /** Register a single DBCS byte-pair → Unicode mapping. */
41
+ export declare function registerDbcsMapping(byte1: number, byte2: number, unicode: string): void;
42
+ /**
43
+ * Bulk-register a DBCS table. The input may be either:
44
+ * - A Record<string, string> where keys are 4-hex-digit pair codes (e.g. "4141")
45
+ * - A Record<number, string> where keys are (byte1<<8)|byte2 integers
46
+ * - A Map<number, string>
47
+ *
48
+ * Use this to load a full IBM-Kanji → Unicode table from a JSON file:
49
+ *
50
+ * import kanjiTable from './ibm-kanji-jisx0208.json';
51
+ * registerDbcsTable(kanjiTable);
52
+ */
53
+ export declare function registerDbcsTable(table: Record<string, string> | Record<number, string> | Map<number, string>): void;
54
+ /**
55
+ * Decode a single IBM EBCDIC DBCS byte pair to a Unicode string.
56
+ * Returns a single-character string (kanji or replacement) — never empty.
57
+ */
58
+ export declare function decodeDbcsPair(byte1: number, byte2: number): string;
59
+ /** Return true if a byte is in the valid DBCS range (0x41-0xFE). */
60
+ export declare function isValidDbcsByte(byte: number): boolean;
61
+ //# sourceMappingURL=ebcdic-jp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ebcdic-jp.d.ts","sourceRoot":"","sources":["../../src/tn5250/ebcdic-jp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAIH,0DAA0D;AAC1D,eAAO,MAAM,EAAE,KAAO,CAAC;AACvB,6DAA6D;AAC7D,eAAO,MAAM,EAAE,KAAO,CAAC;AAsBvB,eAAO,MAAM,uBAAuB,EAAE,MAAM,EAiD3C,CAAC;AAEF;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGhD;AA8BD,kFAAkF;AAClF,eAAO,MAAM,gBAAgB,WAAW,CAAC;AAEzC,oEAAoE;AACpE,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAKvC,0DAA0D;AAC1D,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAEvF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAC3E,IAAI,CASN;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAWnE;AAED,oEAAoE;AACpE,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAErD"}
@@ -0,0 +1,188 @@
1
+ /**
2
+ * Japanese EBCDIC code pages for IBM i.
3
+ *
4
+ * Japanese IBM i systems typically use one of:
5
+ * - CCSID 290 — Japanese Katakana Extended (single-byte, host ROMAN)
6
+ * - CCSID 1027 — Japanese English Extended (single-byte, Latin)
7
+ * - CCSID 930 — Katakana-Kanji Mixed (SBCS 290 + DBCS)
8
+ * - CCSID 939 — Latin-Kanji Mixed (SBCS 1027 + DBCS)
9
+ *
10
+ * This module provides:
11
+ * 1. Single-byte CP290 katakana translation table (the "SO off" plane)
12
+ * 2. DBCS (Double-Byte Character Set) Kanji mapping hooks with a default
13
+ * converter that leverages Node's built-in Shift-JIS decoder via an
14
+ * IBM-Kanji → JIS X 0208 formula.
15
+ * 3. SI / SO control byte handling helpers.
16
+ *
17
+ * The DBCS converter covers the base JIS X 0208 plane. IBM-specific
18
+ * kanji extensions (user-defined characters, IBM selected kanji) that fall
19
+ * outside JIS X 0208 will render as the geta mark "〓" which is the
20
+ * conventional Japanese typographic substitution and preserves layout.
21
+ *
22
+ * Layout note: DBCS characters occupy 2 screen cells. The caller is
23
+ * responsible for writing the resolved glyph into the first cell and
24
+ * marking the second cell as a continuation (empty string).
25
+ */
26
+ // --- Control bytes in the data stream ---
27
+ /** Shift-In: return to single-byte mode (EBCDIC SBCS). */
28
+ export const SI = 0x0F;
29
+ /** Shift-Out: enter double-byte mode (EBCDIC DBCS Kanji). */
30
+ export const SO = 0x0E;
31
+ // ---------------------------------------------------------------------------
32
+ // CCSID 290 — Japanese Katakana Extended (single-byte plane)
33
+ //
34
+ // Table sourced from IBM CDRA tables; invariant characters (0x40 space,
35
+ // 0x4B '.' etc) match CCSID 37. Differences from CCSID 37 are concentrated
36
+ // in 0x42-0x4F (some katakana punctuation), 0x62-0x6F, 0x80-0x8F, 0xA1-0xAF
37
+ // (half-width katakana), 0xC0-0xDF (host variant letters).
38
+ //
39
+ // Half-width katakana (U+FF61-U+FF9F) are placed at:
40
+ // 0x41 '。' 0x42 '「' 0x43 '」' 0x44 '、' 0x45 '・' 0x46 'ヲ' 0x47 'ァ'
41
+ // 0x48 'ィ' 0x49 'ゥ' 0x51 'ェ' 0x52 'ォ' 0x53 'ャ' 0x54 'ュ' 0x55 'ョ'
42
+ // 0x56 'ッ' 0x57 'ー' 0x58 'ア' 0x59 'イ' 0x62 'ウ' 0x63 'エ' 0x64 'オ'
43
+ // 0x65 'カ' 0x66 'キ' 0x67 'ク' 0x68 'ケ' 0x69 'コ' 0x70 'サ' 0x71 'シ'
44
+ // 0x72 'ス' 0x73 'セ' 0x74 'ソ' 0x75 'タ' 0x76 'チ' 0x77 'ツ' 0x78 'テ'
45
+ // 0x80 'ト' 0x81 'ナ' 0x82 'ニ' 0x83 'ヌ' 0x84 'ネ' 0x85 'ノ' 0x86 'ハ'
46
+ // 0x87 'ヒ' 0x88 'フ' 0x89 'ヘ' 0x8A 'ホ' 0x8B 'マ' 0x8C 'ミ' 0x8D 'ム'
47
+ // 0x8E 'メ' 0x8F 'モ' 0x90 'ヤ' 0x91 'ユ' 0x92 'ヨ' 0x93 'ラ' 0x94 'リ'
48
+ // 0x95 'ル' 0x96 'レ' 0x97 'ロ' 0x98 'ワ' 0x99 'ン' 0x9A '゙' 0x9B '゚'
49
+ // ---------------------------------------------------------------------------
50
+ export const EBCDIC_CP290_TO_UNICODE = [
51
+ // 0x00-0x0F
52
+ 0x0000, 0x0001, 0x0002, 0x0003, 0x009C, 0x0009, 0x0086, 0x007F,
53
+ 0x0097, 0x008D, 0x008E, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
54
+ // 0x10-0x1F
55
+ 0x0010, 0x0011, 0x0012, 0x0013, 0x009D, 0x0085, 0x0008, 0x0087,
56
+ 0x0018, 0x0019, 0x0092, 0x008F, 0x001C, 0x001D, 0x001E, 0x001F,
57
+ // 0x20-0x2F
58
+ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x000A, 0x0017, 0x001B,
59
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x0005, 0x0006, 0x0007,
60
+ // 0x30-0x3F
61
+ 0x0090, 0x0091, 0x0016, 0x0093, 0x0094, 0x0095, 0x0096, 0x0004,
62
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x0014, 0x0015, 0x009E, 0x001A,
63
+ // 0x40-0x4F
64
+ 0x0020, 0xFF61, 0xFF62, 0xFF63, 0xFF64, 0xFF65, 0xFF66, 0xFF67,
65
+ 0xFF68, 0xFF69, 0x00A2, 0x002E, 0x003C, 0x0028, 0x002B, 0x007C,
66
+ // 0x50-0x5F
67
+ 0x0026, 0xFF6A, 0xFF6B, 0xFF6C, 0xFF6D, 0xFF6E, 0xFF6F, 0xFF70,
68
+ 0xFF71, 0xFF72, 0x0021, 0x00A5, 0x002A, 0x0029, 0x003B, 0x00AC,
69
+ // 0x60-0x6F
70
+ 0x002D, 0x002F, 0xFF73, 0xFF74, 0xFF75, 0xFF76, 0xFF77, 0xFF78,
71
+ 0xFF79, 0xFF7A, 0xFF7B, 0x002C, 0x0025, 0x005F, 0x003E, 0x003F,
72
+ // 0x70-0x7F
73
+ 0x005B, 0xFF7C, 0xFF7D, 0xFF7E, 0xFF7F, 0xFF80, 0xFF81, 0xFF82,
74
+ 0xFF83, 0x0060, 0x003A, 0x0023, 0x0040, 0x0027, 0x003D, 0x0022,
75
+ // 0x80-0x8F
76
+ 0x005D, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
77
+ 0x0068, 0x0069, 0xFF84, 0xFF85, 0xFF86, 0xFF87, 0xFF88, 0xFF89,
78
+ // 0x90-0x9F
79
+ 0xFF8A, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070,
80
+ 0x0071, 0x0072, 0xFF8B, 0xFF8C, 0xFF8D, 0xFF8E, 0xFF8F, 0xFF90,
81
+ // 0xA0-0xAF
82
+ 0xFF91, 0x007E, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078,
83
+ 0x0079, 0x007A, 0xFF92, 0xFF93, 0xFF94, 0xFF95, 0xFF96, 0xFF97,
84
+ // 0xB0-0xBF
85
+ 0x005E, 0x00A3, 0xFF98, 0xFF99, 0xFF9A, 0xFF9B, 0xFF9C, 0xFF9D,
86
+ 0xFF9E, 0xFF9F, 0x007B, 0x007D, 0x005C, 0xFFA0, 0x007F, 0x203E,
87
+ // 0xC0-0xCF
88
+ 0x007B, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
89
+ 0x0048, 0x0049, 0x00AD, 0x30FC, 0x30FB, 0x3002, 0x300C, 0x300D,
90
+ // 0xD0-0xDF
91
+ 0x007D, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050,
92
+ 0x0051, 0x0052, 0x30FB, 0x3001, 0x3099, 0x309A, 0x0000, 0x0000,
93
+ // 0xE0-0xEF
94
+ 0x005C, 0x0000, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058,
95
+ 0x0059, 0x005A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
96
+ // 0xF0-0xFF
97
+ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
98
+ 0x0038, 0x0039, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x009F,
99
+ ];
100
+ /**
101
+ * Convert a single CP290 EBCDIC byte to a Unicode character.
102
+ * Unmapped positions fall back to SPACE.
103
+ */
104
+ export function cp290ToChar(byte) {
105
+ const cp = EBCDIC_CP290_TO_UNICODE[byte & 0xFF];
106
+ return cp > 0 ? String.fromCharCode(cp) : ' ';
107
+ }
108
+ // ---------------------------------------------------------------------------
109
+ // DBCS Kanji decoding
110
+ //
111
+ // IBM EBCDIC DBCS ("Kanji") encoding per IBM CCSID 300 / 16684 uses two
112
+ // bytes where each byte is in the range 0x41-0xFE. The first byte is a
113
+ // "ward" selector and the second byte selects within the ward. The base
114
+ // JIS X 0208 plane is reachable via the following mapping:
115
+ //
116
+ // IBM row = (byte1 - 0x41) (0..189)
117
+ // IBM cel = (byte2 - 0x41) (0..189)
118
+ //
119
+ // and the classical lookup tables translate this to JIS. In practice, the
120
+ // conversion is done via a precomputed IBM-Kanji → Unicode table. Because
121
+ // shipping the full 7000-entry table is out of scope for this session, we
122
+ // use the following strategy:
123
+ //
124
+ // 1. A registry of overrides: `registerDbcsMapping(byte1, byte2, unicode)`
125
+ // lets consumers plug in custom tables at runtime.
126
+ // 2. A fast path for the SBCS shift-range when a 2-byte pair is actually
127
+ // a pair of CP290 bytes (rare but seen on some legacy hosts that
128
+ // interleave SBCS inside SO/SI pairs).
129
+ // 3. A fallback placeholder "〓" (U+3013 geta mark) that preserves screen
130
+ // layout and makes unmapped kanji visually obvious.
131
+ //
132
+ // The runtime registry means you can load a full JIS X 0208 → Unicode table
133
+ // from a JSON file at server startup and pass it to `registerDbcsTable()`.
134
+ // ---------------------------------------------------------------------------
135
+ /** Unicode "geta mark" — conventional Japanese placeholder for unmapped kanji. */
136
+ export const DBCS_PLACEHOLDER = '\u3013';
137
+ /** Shift-Out / Shift-In markers rendered as invisible in output. */
138
+ export const DBCS_SHIFT_INVISIBLE = '';
139
+ /** Registry of additional DBCS mappings loaded at runtime. */
140
+ const DBCS_OVERRIDES = new Map();
141
+ /** Register a single DBCS byte-pair → Unicode mapping. */
142
+ export function registerDbcsMapping(byte1, byte2, unicode) {
143
+ DBCS_OVERRIDES.set(((byte1 & 0xFF) << 8) | (byte2 & 0xFF), unicode);
144
+ }
145
+ /**
146
+ * Bulk-register a DBCS table. The input may be either:
147
+ * - A Record<string, string> where keys are 4-hex-digit pair codes (e.g. "4141")
148
+ * - A Record<number, string> where keys are (byte1<<8)|byte2 integers
149
+ * - A Map<number, string>
150
+ *
151
+ * Use this to load a full IBM-Kanji → Unicode table from a JSON file:
152
+ *
153
+ * import kanjiTable from './ibm-kanji-jisx0208.json';
154
+ * registerDbcsTable(kanjiTable);
155
+ */
156
+ export function registerDbcsTable(table) {
157
+ if (table instanceof Map) {
158
+ for (const [k, v] of table)
159
+ DBCS_OVERRIDES.set(k, v);
160
+ return;
161
+ }
162
+ for (const [k, v] of Object.entries(table)) {
163
+ const key = /^[0-9a-fA-F]+$/.test(k) ? parseInt(k, 16) : Number(k);
164
+ if (Number.isFinite(key))
165
+ DBCS_OVERRIDES.set(key, v);
166
+ }
167
+ }
168
+ /**
169
+ * Decode a single IBM EBCDIC DBCS byte pair to a Unicode string.
170
+ * Returns a single-character string (kanji or replacement) — never empty.
171
+ */
172
+ export function decodeDbcsPair(byte1, byte2) {
173
+ // DBCS space: 0x4040 → full-width space
174
+ if (byte1 === 0x40 && byte2 === 0x40)
175
+ return '\u3000';
176
+ // Check runtime override table first
177
+ const key = ((byte1 & 0xFF) << 8) | (byte2 & 0xFF);
178
+ const override = DBCS_OVERRIDES.get(key);
179
+ if (override !== undefined)
180
+ return override;
181
+ // Fallback: unmapped kanji → geta mark (preserves layout)
182
+ return DBCS_PLACEHOLDER;
183
+ }
184
+ /** Return true if a byte is in the valid DBCS range (0x41-0xFE). */
185
+ export function isValidDbcsByte(byte) {
186
+ return byte >= 0x40 && byte <= 0xFE;
187
+ }
188
+ //# sourceMappingURL=ebcdic-jp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ebcdic-jp.js","sourceRoot":"","sources":["../../src/tn5250/ebcdic-jp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,2CAA2C;AAE3C,0DAA0D;AAC1D,MAAM,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC;AACvB,6DAA6D;AAC7D,MAAM,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC;AAEvB,8EAA8E;AAC9E,6DAA6D;AAC7D,EAAE;AACF,wEAAwE;AACxE,2EAA2E;AAC3E,4EAA4E;AAC5E,2DAA2D;AAC3D,EAAE;AACF,qDAAqD;AACrD,yEAAyE;AACzE,yEAAyE;AACzE,yEAAyE;AACzE,yEAAyE;AACzE,yEAAyE;AACzE,yEAAyE;AACzE,yEAAyE;AACzE,yEAAyE;AACzE,yEAAyE;AACzE,8EAA8E;AAE9E,MAAM,CAAC,MAAM,uBAAuB,GAAa;IAC/C,YAAY;IACZ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,YAAY;IACZ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,YAAY;IACZ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,YAAY;IACZ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,YAAY;IACZ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,YAAY;IACZ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,YAAY;IACZ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,YAAY;IACZ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,YAAY;IACZ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,YAAY;IACZ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,YAAY;IACZ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,YAAY;IACZ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM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"}
@@ -1,8 +1,17 @@
1
- /** Convert an EBCDIC byte to a UTF-8 character */
2
- export declare function ebcdicToChar(byte: number): string;
1
+ /**
2
+ * Supported EBCDIC single-byte character sets.
3
+ * - 'cp37' — CCSID 37 (US/Canada, Brazil, Australia, NZ)
4
+ * - 'cp290' — CCSID 290 (Japan Katakana) — pair with DBCS for CCSID 930
5
+ */
6
+ export type EbcdicCodePage = 'cp37' | 'cp290';
7
+ /**
8
+ * Convert an EBCDIC byte to a UTF-8 character using the specified code page.
9
+ * Defaults to CCSID 37 for backward compatibility.
10
+ */
11
+ export declare function ebcdicToChar(byte: number, codePage?: EbcdicCodePage): string;
3
12
  export declare function ebcdicSymbolChar(byte: number): string;
4
- /** Convert a UTF-8 character to an EBCDIC byte */
5
- export declare function charToEbcdic(char: string): number;
13
+ /** Convert a UTF-8 character to an EBCDIC byte (specified code page). */
14
+ export declare function charToEbcdic(char: string, codePage?: EbcdicCodePage): number;
6
15
  /** Convert an EBCDIC buffer to a UTF-8 string */
7
16
  export declare function ebcdicBufferToString(buf: Buffer, start?: number, length?: number): string;
8
17
  /** Convert a UTF-8 string to an EBCDIC buffer */
@@ -1 +1 @@
1
- {"version":3,"file":"ebcdic.d.ts","sourceRoot":"","sources":["../../src/tn5250/ebcdic.ts"],"names":[],"mappings":"AA4DA,kDAAkD;AAClD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGjD;AAwBD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,kDAAkD;AAClD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIjD;AAED,iDAAiD;AACjD,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,GAAE,MAAU,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAO5F;AAED,iDAAiD;AACjD,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAMxD;AAGD,eAAO,MAAM,YAAY,KAAO,CAAC;AAEjC,eAAO,MAAM,WAAW,IAAO,CAAC"}
1
+ {"version":3,"file":"ebcdic.d.ts","sourceRoot":"","sources":["../../src/tn5250/ebcdic.ts"],"names":[],"mappings":"AAOA;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,OAAO,CAAC;AAyE9C;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,GAAE,cAAuB,GAAG,MAAM,CAIpF;AAwBD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,yEAAyE;AACzE,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,GAAE,cAAuB,GAAG,MAAM,CAKpF;AAED,iDAAiD;AACjD,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,GAAE,MAAU,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAO5F;AAED,iDAAiD;AACjD,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAMxD;AAGD,eAAO,MAAM,YAAY,KAAO,CAAC;AAEjC,eAAO,MAAM,WAAW,IAAO,CAAC"}
@@ -1,4 +1,8 @@
1
1
  // EBCDIC CCSID 37 (US/Canada) ↔ UTF-8 conversion tables
2
+ //
3
+ // For Japanese IBM i hosts, see ./ebcdic-jp.ts which provides CCSID 290
4
+ // (Katakana) and DBCS Kanji decoding infrastructure.
5
+ import { EBCDIC_CP290_TO_UNICODE } from './ebcdic-jp.js';
2
6
  // EBCDIC byte → Unicode code point (CCSID 37)
3
7
  const EBCDIC_TO_UNICODE = [
4
8
  // 0x00-0x0F
@@ -50,15 +54,32 @@ const EBCDIC_TO_UNICODE = [
50
54
  0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
51
55
  0x0038, 0x0039, 0x00B3, 0x00DB, 0x00DC, 0x00D9, 0x00DA, 0x009F,
52
56
  ];
53
- // Build reverse lookup: Unicode code point → EBCDIC byte
57
+ // Build reverse lookup: Unicode code point → EBCDIC byte (CP37)
54
58
  const UNICODE_TO_EBCDIC = new Map();
55
59
  for (let i = 0; i < 256; i++) {
56
60
  UNICODE_TO_EBCDIC.set(EBCDIC_TO_UNICODE[i], i);
57
61
  }
58
- /** Convert an EBCDIC byte to a UTF-8 character */
59
- export function ebcdicToChar(byte) {
60
- const cp = EBCDIC_TO_UNICODE[byte & 0xFF];
61
- return String.fromCharCode(cp);
62
+ // Reverse lookup for CP290 built lazily on first use.
63
+ let UNICODE_TO_CP290 = null;
64
+ function getUnicodeToCp290() {
65
+ if (!UNICODE_TO_CP290) {
66
+ UNICODE_TO_CP290 = new Map();
67
+ for (let i = 0; i < 256; i++) {
68
+ const cp = EBCDIC_CP290_TO_UNICODE[i];
69
+ if (cp > 0)
70
+ UNICODE_TO_CP290.set(cp, i);
71
+ }
72
+ }
73
+ return UNICODE_TO_CP290;
74
+ }
75
+ /**
76
+ * Convert an EBCDIC byte to a UTF-8 character using the specified code page.
77
+ * Defaults to CCSID 37 for backward compatibility.
78
+ */
79
+ export function ebcdicToChar(byte, codePage = 'cp37') {
80
+ const table = codePage === 'cp290' ? EBCDIC_CP290_TO_UNICODE : EBCDIC_TO_UNICODE;
81
+ const cp = table[byte & 0xFF];
82
+ return cp > 0 ? String.fromCharCode(cp) : ' ';
62
83
  }
63
84
  /**
64
85
  * Convert an EBCDIC byte to a UTF-8 character using the IBM 5250
@@ -84,10 +105,11 @@ const SYMBOL_MAP = {
84
105
  export function ebcdicSymbolChar(byte) {
85
106
  return SYMBOL_MAP[byte] ?? ebcdicToChar(byte);
86
107
  }
87
- /** Convert a UTF-8 character to an EBCDIC byte */
88
- export function charToEbcdic(char) {
108
+ /** Convert a UTF-8 character to an EBCDIC byte (specified code page). */
109
+ export function charToEbcdic(char, codePage = 'cp37') {
89
110
  const cp = char.charCodeAt(0);
90
- const eb = UNICODE_TO_EBCDIC.get(cp);
111
+ const table = codePage === 'cp290' ? getUnicodeToCp290() : UNICODE_TO_EBCDIC;
112
+ const eb = table.get(cp);
91
113
  return eb !== undefined ? eb : 0x40; // default to EBCDIC space
92
114
  }
93
115
  /** Convert an EBCDIC buffer to a UTF-8 string */
@@ -1 +1 @@
1
- {"version":3,"file":"ebcdic.js","sourceRoot":"","sources":["../../src/tn5250/ebcdic.ts"],"names":[],"mappings":"AAAA,wDAAwD;AAExD,8CAA8C;AAC9C,MAAM,iBAAiB,GAAa;IAClC,YAAY;IACZ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,YAAY;IACZ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,YAAY;IACZ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,YAAY;IACZ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,YAAY;IACZ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,YAAY;IACZ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,YAAY;IACZ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,YAAY;IACZ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,YAAY;IACZ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,YAAY;IACZ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,YAAY;IACZ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,YAAY;IACZ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,YAAY;IACZ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,YAAY;IACZ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,MAAM,EAAE,MAAM,EAAE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"}
1
+ {"version":3,"file":"ebcdic.js","sourceRoot":"","sources":["../../src/tn5250/ebcdic.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,EAAE;AACF,wEAAwE;AACxE,qDAAqD;AAErD,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AASzD,8CAA8C;AAC9C,MAAM,iBAAiB,GAAa;IAClC,YAAY;IACZ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,YAAY;IACZ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,YAAY;IACZ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,YAAY;IACZ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,YAAY;IACZ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,YAAY;IACZ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,YAAY;IACZ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,YAAY;IACZ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,YAAY;IACZ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,YAAY;IACZ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,YAAY;IACZ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,YAAY;IACZ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,YAAY;IACZ,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAC9D,YAAY;IACZ,MAAM,EAAE,MAAM,EAAE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"}
@@ -8,20 +8,52 @@ export declare class TN5250Encoder {
8
8
  constructor(screen: ScreenBuffer);
9
9
  /**
10
10
  * Build a 5250 input response for an aid key press.
11
- * Collects modified field data and builds the response record.
11
+ * Dispatches based on the current read_opcode set by the most recent
12
+ * Read command from the host, and handles special-AID cases (SysReq,
13
+ * Attn, TestReq, Print) with the correct record header flags.
12
14
  * Returns a Buffer ready to send over the TCP socket (with Telnet EOR framing).
13
15
  */
14
16
  buildAidResponse(keyName: string): Buffer | null;
15
17
  /**
16
- * Build a GDS header for a client response (matching tn5250j format).
17
- * 10-byte header:
18
+ * Encode a field for Read Input Fields / Read Immediate (inline, no SBA).
19
+ * Per lib5250 session.c:522-542.
20
+ * - Embedded NULs → 0x40 (SPACE).
21
+ * - Signed-num fields: trailing '-' is merged into the last digit's zone
22
+ * nibble (0xD0 | digit_low), and the sign position itself is omitted.
23
+ */
24
+ private encodeFieldInline;
25
+ /**
26
+ * Encode a field for Read MDT Fields / Read MDT Fields Alt / Read Immediate Alt.
27
+ * Per lib5250 session.c:544-596.
28
+ * - Strips trailing NULs.
29
+ * - Signed-num: drops sign position; merges zone nibble into last digit.
30
+ * - Read MDT Fields (not Alt): embedded NULs → 0x40.
31
+ * - Alt variants: embedded NULs preserved as-is.
32
+ */
33
+ private encodeFieldMdt;
34
+ /**
35
+ * Extract a field's content as raw EBCDIC bytes (before any translation).
36
+ * For continued-first fields, reconstructs the full concatenated content
37
+ * by walking subsequent continued subfields in the fields list
38
+ * (per lib5250 session.c:487-520).
39
+ */
40
+ private getFieldEbcdicData;
41
+ /** Encode one single field's content to EBCDIC (no continuation walk). */
42
+ private encodeSingleField;
43
+ /** Build an empty 10-byte record (no data) with the given flags/opcode. */
44
+ private buildEmptyRecord;
45
+ /** Build a full 5250 packet: 10-byte GDS header + data, then Telnet EOR. */
46
+ private buildPacket;
47
+ /**
48
+ * Build a GDS header for a client response.
49
+ * Per lib5250 telnetstr.c:860-895:
18
50
  * Bytes 0-1: record length (filled by wrapWithEOR)
19
- * Bytes 2-3: record type 0x12A0 (SNA GDS Variable)
20
- * Bytes 4-5: reserved 0x0000
21
- * Byte 6: sub-header length 0x04
22
- * Byte 7: flags 0x00
23
- * Byte 8: reserved 0x00
24
- * Byte 9: opcode 0x03 (PUT/GET response)
51
+ * Bytes 2-3: record type 0x12A0
52
+ * Bytes 4-5: flowtype (0x0000 = DISPLAY)
53
+ * Byte 6: sub-header length 0x04
54
+ * Byte 7: flags
55
+ * Byte 8: reserved 0x00
56
+ * Byte 9: opcode
25
57
  */
26
58
  private buildGDSHeader;
27
59
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"encoder.d.ts","sourceRoot":"","sources":["../../src/tn5250/encoder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAI3C;;;GAGG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAe;gBAEjB,MAAM,EAAE,YAAY;IAIhC;;;;OAIG;IACH,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAiDhD;;;;;;;;;;OAUG;IACH,OAAO,CAAC,cAAc;IAItB;;;OAGG;IACH,OAAO,CAAC,WAAW;IAoBnB;;;;OAIG;IACH,eAAe,CAAC,YAAY,SAAe,GAAG,MAAM;IAuFpD;;;;OAIG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IA+BjC;;;OAGG;IACH,SAAS,IAAI,OAAO;CAoBrB"}
1
+ {"version":3,"file":"encoder.d.ts","sourceRoot":"","sources":["../../src/tn5250/encoder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAY,MAAM,aAAa,CAAC;AAIrD;;;GAGG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAe;gBAEjB,MAAM,EAAE,YAAY;IAIhC;;;;;;OAMG;IACH,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAwHhD;;;;;;OAMG;IACH,OAAO,CAAC,iBAAiB;IA6BzB;;;;;;;OAOG;IACH,OAAO,CAAC,cAAc;IAwCtB;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;IAuB1B,0EAA0E;IAC1E,OAAO,CAAC,iBAAiB;IAWzB,2EAA2E;IAC3E,OAAO,CAAC,gBAAgB;IAIxB,4EAA4E;IAC5E,OAAO,CAAC,WAAW;IAKnB;;;;;;;;;;OAUG;IACH,OAAO,CAAC,cAAc;IAOtB;;;OAGG;IACH,OAAO,CAAC,WAAW;IAoBnB;;;;OAIG;IACH,eAAe,CAAC,YAAY,SAAe,GAAG,MAAM;IAuFpD;;;;OAIG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IA+BjC;;;OAGG;IACH,SAAS,IAAI,OAAO;CAoBrB"}