@ozdemirburak/morse-code-translator 5.0.4 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +39 -16
- package/dist/audio.d.ts +4 -0
- package/dist/audio.d.ts.map +1 -0
- package/dist/characters.d.ts +11 -0
- package/dist/characters.d.ts.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/morse-code-translator.es.js +609 -0
- package/dist/morse-code-translator.es.js.map +1 -0
- package/dist/morse-code-translator.umd.js +2 -0
- package/dist/morse-code-translator.umd.js.map +1 -0
- package/dist/options.d.ts +4 -0
- package/dist/options.d.ts.map +1 -0
- package/dist/types.d.ts +52 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +32 -28
- package/dist/morse-code-translator.min.js +0 -1
- package/src/audio.ts +0 -191
- package/src/characters.ts +0 -139
- package/src/index.d.ts +0 -26
- package/src/index.js +0 -353
- package/src/index.ts +0 -58
- package/src/options.ts +0 -24
package/src/characters.ts
DELETED
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
const baseCharacters: Characters = {
|
|
2
|
-
'1': { // Latin => https://en.wikipedia.org/wiki/Morse_code
|
|
3
|
-
'A': '01', 'B': '1000', 'C': '1010', 'D': '100', 'E': '0', 'F': '0010',
|
|
4
|
-
'G': '110', 'H': '0000', 'I': '00', 'J': '0111', 'K': '101', 'L': '0100',
|
|
5
|
-
'M': '11', 'N': '10', 'O': '111', 'P': '0110', 'Q': '1101', 'R': '010',
|
|
6
|
-
'S': '000', 'T': '1', 'U': '001', 'V': '0001', 'W': '011', 'X': '1001',
|
|
7
|
-
'Y': '1011', 'Z': '1100'
|
|
8
|
-
},
|
|
9
|
-
'2': { // Numbers
|
|
10
|
-
'0': '11111', '1': '01111', '2': '00111', '3': '00011', '4': '00001',
|
|
11
|
-
'5': '00000', '6': '10000', '7': '11000', '8': '11100', '9': '11110'
|
|
12
|
-
},
|
|
13
|
-
'3': { // Punctuation
|
|
14
|
-
'.': '010101', ',': '110011', '?': '001100', '\'': '011110', '!': '101011', '/': '10010',
|
|
15
|
-
'(': '10110', ')': '101101', '&': '01000', ':': '111000', ';': '101010', '=': '10001',
|
|
16
|
-
'+': '01010', '-': '100001', '_': '001101', '"': '010010', '$': '0001001', '@': '011010',
|
|
17
|
-
'¿': '00101', '¡': '110001'
|
|
18
|
-
},
|
|
19
|
-
'4': { // Latin Extended => https://ham.stackexchange.com/questions/1379/international-characters-in-morse-code
|
|
20
|
-
'Ã': '01101', 'Á': '01101', 'Å': '01101', 'À': '01101', 'Â': '01101', 'Ä': '0101',
|
|
21
|
-
'Ą': '0101', 'Æ': '0101', 'Ç': '10100', 'Ć': '10100', 'Ĉ': '10100', 'Č': '110',
|
|
22
|
-
'Ð': '00110', 'È': '01001', 'Ę': '00100', 'Ë': '00100', 'É': '00100',
|
|
23
|
-
'Ê': '10010', 'Ğ': '11010', 'Ĝ': '11010', 'Ĥ': '1111', 'İ': '01001', 'Ï': '10011',
|
|
24
|
-
'Ì': '01110', 'Ĵ': '01110', 'Ł': '01001', 'Ń': '11011', 'Ñ': '11011', 'Ó': '1110',
|
|
25
|
-
'Ò': '1110', 'Ö': '1110', 'Ô': '1110', 'Ø': '1110', 'Ś': '0001000', 'Ş': '01100',
|
|
26
|
-
'Ș': '1111', 'Š': '1111', 'Ŝ': '00010', 'ß': '000000', 'Þ': '01100', 'Ü': '0011',
|
|
27
|
-
'Ù': '0011', 'Ŭ': '0011', 'Ž': '11001', 'Ź': '110010', 'Ż': '11001'
|
|
28
|
-
},
|
|
29
|
-
'5': { // Cyrillic Alphabet => https://en.wikipedia.org/wiki/Russian_Morse_code
|
|
30
|
-
'А': '01', 'Б': '1000', 'В': '011', 'Г': '110', 'Д': '100', 'Е': '0',
|
|
31
|
-
'Ж': '0001', 'З': '1100', 'И': '00', 'Й': '0111', 'К': '101', 'Л': '0100',
|
|
32
|
-
'М': '11', 'Н': '10', 'О': '111', 'П': '0110', 'Р': '010', 'С': '000',
|
|
33
|
-
'Т': '1', 'У': '001', 'Ф': '0010', 'Х': '0000', 'Ц': '1010', 'Ч': '1110',
|
|
34
|
-
'Ш': '1111', 'Щ': '1101', 'Ъ': '11011', 'Ы': '1011', 'Ь': '1001', 'Э': '00100',
|
|
35
|
-
'Ю': '0011', 'Я': '0101', 'Ї': '01110', 'Є': '00100', 'І': '00', 'Ґ': '110'
|
|
36
|
-
},
|
|
37
|
-
'6': { // Greek Alphabet => https://en.wikipedia.org/wiki/Morse_code_for_non-Latin_alphabets
|
|
38
|
-
'Α': '01', 'Β': '1000', 'Γ': '110', 'Δ': '100', 'Ε': '0', 'Ζ': '1100',
|
|
39
|
-
'Η': '0000', 'Θ': '1010', 'Ι': '00', 'Κ': '101', 'Λ': '0100', 'Μ': '11',
|
|
40
|
-
'Ν': '10', 'Ξ': '1001', 'Ο': '111', 'Π': '0110', 'Ρ': '010', 'Σ': '000',
|
|
41
|
-
'Τ': '1', 'Υ': '1011', 'Φ': '0010', 'Χ': '1111', 'Ψ': '1101', 'Ω': '011'
|
|
42
|
-
},
|
|
43
|
-
'7': { // Hebrew Alphabet => https://en.wikipedia.org/wiki/Morse_code_for_non-Latin_alphabets
|
|
44
|
-
'א': '01', 'ב': '1000', 'ג': '110', 'ד': '100', 'ה': '111', 'ו': '0',
|
|
45
|
-
'ז': '1100', 'ח': '0000', 'ט': '001', 'י': '00', 'כ': '101', 'ל': '0100',
|
|
46
|
-
'מ': '11', 'נ': '10', 'ס': '1010', 'ע': '0111', 'פ': '0110', 'צ': '011',
|
|
47
|
-
'ק': '1101', 'ר': '010', 'ש': '000', 'ת': '1'
|
|
48
|
-
},
|
|
49
|
-
'8': { // Arabic Alphabet => https://en.wikipedia.org/wiki/Morse_code_for_non-Latin_alphabets
|
|
50
|
-
'ا': '01', 'ب': '1000', 'ت': '1', 'ث': '1010', 'ج': '0111', 'ح': '0000',
|
|
51
|
-
'خ': '111', 'د': '100', 'ذ': '1100', 'ر': '010', 'ز': '1110', 'س': '000',
|
|
52
|
-
'ش': '1111', 'ص': '1001', 'ض': '0001', 'ط': '001', 'ظ': '1011', 'ع': '0101',
|
|
53
|
-
'غ': '110', 'ف': '0010', 'ق': '1101', 'ك': '101', 'ل': '0100', 'م': '11',
|
|
54
|
-
'ن': '10', 'ه': '00100', 'و': '011', 'ي': '00', 'ﺀ': '0'
|
|
55
|
-
},
|
|
56
|
-
'9': { // Persian Alphabet => https://en.wikipedia.org/wiki/Morse_code_for_non-Latin_alphabets
|
|
57
|
-
'ا': '01', 'ب': '1000', 'پ': '0110', 'ت': '1', 'ث': '1010', 'ج': '0111',
|
|
58
|
-
'چ': '1110', 'ح': '0000', 'خ': '1001', 'د': '100', 'ذ': '0001', 'ر': '010',
|
|
59
|
-
'ز': '1100', 'ژ': '110', 'س': '000', 'ش': '1111', 'ص': '0101', 'ض': '00100',
|
|
60
|
-
'ط': '001', 'ظ': '1011', 'ع': '111', 'غ': '0011', 'ف': '0010', 'ق': '111000',
|
|
61
|
-
'ک': '101', 'گ': '1101', 'ل': '0100', 'م': '11', 'ن': '10', 'و': '011',
|
|
62
|
-
'ه': '0', 'ی': '00'
|
|
63
|
-
},
|
|
64
|
-
'10': { // Japanese Alphabet => https://ja.wikipedia.org/wiki/%E3%83%A2%E3%83%BC%E3%83%AB%E3%82%B9%E7%AC%A6%E5%8F%B7#%E5%92%8C%E6%96%87%E3%83%A2%E3%83%BC%E3%83%AB%E3%82%B9%E7%AC%A6%E5%8F%B7
|
|
65
|
-
'ア': '11011', 'カ': '0100', 'サ': '10101', 'タ': '10', 'ナ': '010', 'ハ': '1000',
|
|
66
|
-
'マ': '1001', 'ヤ': '011', 'ラ': '000', 'ワ': '101', 'イ': '01', 'キ': '10100',
|
|
67
|
-
'シ': '11010', 'チ': '0010', 'ニ': '1010', 'ヒ': '11001', 'ミ': '00101', 'リ': '110',
|
|
68
|
-
'ヰ': '01001', 'ウ': '001', 'ク': '0001', 'ス': '11101', 'ツ': '0110', 'ヌ': '0000',
|
|
69
|
-
'フ': '1100', 'ム': '1', 'ユ': '10011', 'ル': '10110', 'ン': '01010', 'エ': '10111',
|
|
70
|
-
'ケ': '1011', 'セ': '01110', 'テ': '01011', 'ネ': '1101', 'ヘ': '0', 'メ': '10001',
|
|
71
|
-
'レ': '111', 'ヱ': '01100', 'オ': '01000', 'コ': '1111', 'ソ': '1110', 'ト': '00100',
|
|
72
|
-
'ノ': '0011', 'ホ': '100', 'モ': '10010', 'ヨ': '11', 'ロ': '0101', 'ヲ': '0111',
|
|
73
|
-
'゛': '00', '゜': '00110', '。': '010100', 'ー': '01101', '、': '010101',
|
|
74
|
-
'(': '101101', ')': '010010'
|
|
75
|
-
},
|
|
76
|
-
'11': { // Korean Alphabet => https://ko.wikipedia.org/wiki/%EB%AA%A8%EC%8A%A4_%EB%B6%80%ED%98%B8
|
|
77
|
-
'ㄱ': '0100', 'ㄴ': '0010', 'ㄷ': '1000', 'ㄹ': '0001', 'ㅁ': '11', 'ㅂ': '011',
|
|
78
|
-
'ㅅ': '110', 'ㅇ': '101', 'ㅈ': '0110', 'ㅊ': '1010', 'ㅋ': '1001', 'ㅌ': '1100',
|
|
79
|
-
'ㅍ': '111', 'ㅎ': '0111', 'ㅏ': '0', 'ㅑ': '00', 'ㅓ': '1', 'ㅕ': '000',
|
|
80
|
-
'ㅗ': '01', 'ㅛ': '10', 'ㅜ': '0000', 'ㅠ': '010', 'ㅡ': '100', 'ㅣ': '001',
|
|
81
|
-
'ㅐ': '1101', 'ㅔ': '1011'
|
|
82
|
-
},
|
|
83
|
-
'12': { // Thai Alphabet => https://th.wikipedia.org/wiki/รหัสมอร์ส
|
|
84
|
-
'ก': '110', 'ข': '1010', 'ค': '101', 'ง': '10110', 'จ': '10010',
|
|
85
|
-
'ฉ': '1111', 'ช': '1001', 'ซ': '1100', 'ญ': '0111', 'ด': '100',
|
|
86
|
-
'ต': '1', 'ถ': '10100', 'ท': '10011', 'น': '10', 'บ': '1000',
|
|
87
|
-
'ป': '0110', 'ผ': '1101', 'ฝ': '10101', 'พ': '01100', 'ฟ': '0010',
|
|
88
|
-
'ม': '11', 'ย': '1011', 'ร': '010', 'ล': '0100', 'ว': '011',
|
|
89
|
-
'ส': '000', 'ห': '0000', 'อ': '10001', 'ฮ': '11011', 'ฤ': '01011',
|
|
90
|
-
'ะ': '01000', 'า': '01', 'ิ': '00100', 'ี': '00', 'ึ': '00110',
|
|
91
|
-
'ื': '0011', 'ุ': '00101', 'ู': '1110', 'เ': '0', 'แ': '0101',
|
|
92
|
-
'ไ': '01001', 'โ': '111', 'ำ': '00010', '่': '001', '้': '0001',
|
|
93
|
-
'๊': '11000', '๋': '01010', 'ั': '01101', '็': '11100', '์': '11001',
|
|
94
|
-
'ๆ': '10111', 'ฯ': '11010'
|
|
95
|
-
}
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
const getCharacters = (options: Options) => ({
|
|
99
|
-
...baseCharacters,
|
|
100
|
-
'0': baseCharacters[options.priority],
|
|
101
|
-
'1': {
|
|
102
|
-
...baseCharacters['1'],
|
|
103
|
-
[options.separator]: options.space
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
const getMappedCharacters = (options: Options, usePriority: boolean) => {
|
|
108
|
-
const mapped: Characters = {};
|
|
109
|
-
const characters = getCharacters(options);
|
|
110
|
-
for (const set in characters) {
|
|
111
|
-
mapped[set] = {};
|
|
112
|
-
for (const key in characters[set]) {
|
|
113
|
-
mapped[set][key] = characters[set][key].replace(/0/g, options.dot).replace(/1/g, options.dash);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
if (!usePriority) {
|
|
117
|
-
delete mapped['0'];
|
|
118
|
-
}
|
|
119
|
-
return mapped;
|
|
120
|
-
};
|
|
121
|
-
|
|
122
|
-
const swapCharacters = (options: Options) => {
|
|
123
|
-
const swapped: Record<string, string> = {};
|
|
124
|
-
const mappedCharacters = getMappedCharacters(options, true);
|
|
125
|
-
for (const set in mappedCharacters) {
|
|
126
|
-
for (const key in mappedCharacters[set]) {
|
|
127
|
-
if (typeof swapped[mappedCharacters[set][key]] === 'undefined') {
|
|
128
|
-
swapped[mappedCharacters[set][key]] = key;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
return swapped;
|
|
133
|
-
};
|
|
134
|
-
|
|
135
|
-
export {
|
|
136
|
-
getCharacters,
|
|
137
|
-
getMappedCharacters,
|
|
138
|
-
swapCharacters
|
|
139
|
-
};
|
package/src/index.d.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
interface Window {
|
|
2
|
-
webkitAudioContext: typeof AudioContext
|
|
3
|
-
webkitOfflineAudioContext: typeof OfflineAudioContext
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
type Characters = Record<string, Record<string, string>>
|
|
7
|
-
|
|
8
|
-
interface Oscillator {
|
|
9
|
-
type?: OscillatorType;
|
|
10
|
-
frequency?: number;
|
|
11
|
-
onended?: ((this: AudioScheduledSourceNode, ev: Event) => any) | null;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
interface Options {
|
|
15
|
-
dash: string;
|
|
16
|
-
dot: string;
|
|
17
|
-
space: string;
|
|
18
|
-
separator: string;
|
|
19
|
-
invalid: string;
|
|
20
|
-
priority: number;
|
|
21
|
-
wpm?: number;
|
|
22
|
-
unit: number;
|
|
23
|
-
fwUnit: number;
|
|
24
|
-
volume: number;
|
|
25
|
-
oscillator: Oscillator
|
|
26
|
-
}
|
package/src/index.js
DELETED
|
@@ -1,353 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const baseCharacters = {
|
|
4
|
-
'1': {
|
|
5
|
-
'A': '01', 'B': '1000', 'C': '1010', 'D': '100', 'E': '0', 'F': '0010',
|
|
6
|
-
'G': '110', 'H': '0000', 'I': '00', 'J': '0111', 'K': '101', 'L': '0100',
|
|
7
|
-
'M': '11', 'N': '10', 'O': '111', 'P': '0110', 'Q': '1101', 'R': '010',
|
|
8
|
-
'S': '000', 'T': '1', 'U': '001', 'V': '0001', 'W': '011', 'X': '1001',
|
|
9
|
-
'Y': '1011', 'Z': '1100'
|
|
10
|
-
},
|
|
11
|
-
'2': {
|
|
12
|
-
'0': '11111', '1': '01111', '2': '00111', '3': '00011', '4': '00001',
|
|
13
|
-
'5': '00000', '6': '10000', '7': '11000', '8': '11100', '9': '11110'
|
|
14
|
-
},
|
|
15
|
-
'3': {
|
|
16
|
-
'.': '010101', ',': '110011', '?': '001100', '\'': '011110', '!': '101011', '/': '10010',
|
|
17
|
-
'(': '10110', ')': '101101', '&': '01000', ':': '111000', ';': '101010', '=': '10001',
|
|
18
|
-
'+': '01010', '-': '100001', '_': '001101', '"': '010010', '$': '0001001', '@': '011010',
|
|
19
|
-
'¿': '00101', '¡': '110001'
|
|
20
|
-
},
|
|
21
|
-
'4': {
|
|
22
|
-
'Ã': '01101', 'Á': '01101', 'Å': '01101', 'À': '01101', 'Â': '01101', 'Ä': '0101',
|
|
23
|
-
'Ą': '0101', 'Æ': '0101', 'Ç': '10100', 'Ć': '10100', 'Ĉ': '10100', 'Č': '110',
|
|
24
|
-
'Ð': '00110', 'È': '01001', 'Ę': '00100', 'Ë': '00100', 'É': '00100',
|
|
25
|
-
'Ê': '10010', 'Ğ': '11010', 'Ĝ': '11010', 'Ĥ': '1111', 'İ': '01001', 'Ï': '10011',
|
|
26
|
-
'Ì': '01110', 'Ĵ': '01110', 'Ł': '01001', 'Ń': '11011', 'Ñ': '11011', 'Ó': '1110',
|
|
27
|
-
'Ò': '1110', 'Ö': '1110', 'Ô': '1110', 'Ø': '1110', 'Ś': '0001000', 'Ş': '01100',
|
|
28
|
-
'Ș': '1111', 'Š': '1111', 'Ŝ': '00010', 'ß': '000000', 'Þ': '01100', 'Ü': '0011',
|
|
29
|
-
'Ù': '0011', 'Ŭ': '0011', 'Ž': '11001', 'Ź': '110010', 'Ż': '11001'
|
|
30
|
-
},
|
|
31
|
-
'5': {
|
|
32
|
-
'А': '01', 'Б': '1000', 'В': '011', 'Г': '110', 'Д': '100', 'Е': '0',
|
|
33
|
-
'Ж': '0001', 'З': '1100', 'И': '00', 'Й': '0111', 'К': '101', 'Л': '0100',
|
|
34
|
-
'М': '11', 'Н': '10', 'О': '111', 'П': '0110', 'Р': '010', 'С': '000',
|
|
35
|
-
'Т': '1', 'У': '001', 'Ф': '0010', 'Х': '0000', 'Ц': '1010', 'Ч': '1110',
|
|
36
|
-
'Ш': '1111', 'Щ': '1101', 'Ъ': '11011', 'Ы': '1011', 'Ь': '1001', 'Э': '00100',
|
|
37
|
-
'Ю': '0011', 'Я': '0101', 'Ї': '01110', 'Є': '00100', 'І': '00', 'Ґ': '110'
|
|
38
|
-
},
|
|
39
|
-
'6': {
|
|
40
|
-
'Α': '01', 'Β': '1000', 'Γ': '110', 'Δ': '100', 'Ε': '0', 'Ζ': '1100',
|
|
41
|
-
'Η': '0000', 'Θ': '1010', 'Ι': '00', 'Κ': '101', 'Λ': '0100', 'Μ': '11',
|
|
42
|
-
'Ν': '10', 'Ξ': '1001', 'Ο': '111', 'Π': '0110', 'Ρ': '010', 'Σ': '000',
|
|
43
|
-
'Τ': '1', 'Υ': '1011', 'Φ': '0010', 'Χ': '1111', 'Ψ': '1101', 'Ω': '011'
|
|
44
|
-
},
|
|
45
|
-
'7': {
|
|
46
|
-
'א': '01', 'ב': '1000', 'ג': '110', 'ד': '100', 'ה': '111', 'ו': '0',
|
|
47
|
-
'ז': '1100', 'ח': '0000', 'ט': '001', 'י': '00', 'כ': '101', 'ל': '0100',
|
|
48
|
-
'מ': '11', 'נ': '10', 'ס': '1010', 'ע': '0111', 'פ': '0110', 'צ': '011',
|
|
49
|
-
'ק': '1101', 'ר': '010', 'ש': '000', 'ת': '1'
|
|
50
|
-
},
|
|
51
|
-
'8': {
|
|
52
|
-
'ا': '01', 'ب': '1000', 'ت': '1', 'ث': '1010', 'ج': '0111', 'ح': '0000',
|
|
53
|
-
'خ': '111', 'د': '100', 'ذ': '1100', 'ر': '010', 'ز': '1110', 'س': '000',
|
|
54
|
-
'ش': '1111', 'ص': '1001', 'ض': '0001', 'ط': '001', 'ظ': '1011', 'ع': '0101',
|
|
55
|
-
'غ': '110', 'ف': '0010', 'ق': '1101', 'ك': '101', 'ل': '0100', 'م': '11',
|
|
56
|
-
'ن': '10', 'ه': '00100', 'و': '011', 'ي': '00', 'ﺀ': '0'
|
|
57
|
-
},
|
|
58
|
-
'9': {
|
|
59
|
-
'ا': '01', 'ب': '1000', 'پ': '0110', 'ت': '1', 'ث': '1010', 'ج': '0111',
|
|
60
|
-
'چ': '1110', 'ح': '0000', 'خ': '1001', 'د': '100', 'ذ': '0001', 'ر': '010',
|
|
61
|
-
'ز': '1100', 'ژ': '110', 'س': '000', 'ش': '1111', 'ص': '0101', 'ض': '00100',
|
|
62
|
-
'ط': '001', 'ظ': '1011', 'ع': '111', 'غ': '0011', 'ف': '0010', 'ق': '111000',
|
|
63
|
-
'ک': '101', 'گ': '1101', 'ل': '0100', 'م': '11', 'ن': '10', 'و': '011',
|
|
64
|
-
'ه': '0', 'ی': '00'
|
|
65
|
-
},
|
|
66
|
-
'10': {
|
|
67
|
-
'ア': '11011', 'カ': '0100', 'サ': '10101', 'タ': '10', 'ナ': '010', 'ハ': '1000',
|
|
68
|
-
'マ': '1001', 'ヤ': '011', 'ラ': '000', 'ワ': '101', 'イ': '01', 'キ': '10100',
|
|
69
|
-
'シ': '11010', 'チ': '0010', 'ニ': '1010', 'ヒ': '11001', 'ミ': '00101', 'リ': '110',
|
|
70
|
-
'ヰ': '01001', 'ウ': '001', 'ク': '0001', 'ス': '11101', 'ツ': '0110', 'ヌ': '0000',
|
|
71
|
-
'フ': '1100', 'ム': '1', 'ユ': '10011', 'ル': '10110', 'ン': '01010', 'エ': '10111',
|
|
72
|
-
'ケ': '1011', 'セ': '01110', 'テ': '01011', 'ネ': '1101', 'ヘ': '0', 'メ': '10001',
|
|
73
|
-
'レ': '111', 'ヱ': '01100', 'オ': '01000', 'コ': '1111', 'ソ': '1110', 'ト': '00100',
|
|
74
|
-
'ノ': '0011', 'ホ': '100', 'モ': '10010', 'ヨ': '11', 'ロ': '0101', 'ヲ': '0111',
|
|
75
|
-
'゛': '00', '゜': '00110', '。': '010100', 'ー': '01101', '、': '010101',
|
|
76
|
-
'(': '101101', ')': '010010'
|
|
77
|
-
},
|
|
78
|
-
'11': {
|
|
79
|
-
'ㄱ': '0100', 'ㄴ': '0010', 'ㄷ': '1000', 'ㄹ': '0001', 'ㅁ': '11', 'ㅂ': '011',
|
|
80
|
-
'ㅅ': '110', 'ㅇ': '101', 'ㅈ': '0110', 'ㅊ': '1010', 'ㅋ': '1001', 'ㅌ': '1100',
|
|
81
|
-
'ㅍ': '111', 'ㅎ': '0111', 'ㅏ': '0', 'ㅑ': '00', 'ㅓ': '1', 'ㅕ': '000',
|
|
82
|
-
'ㅗ': '01', 'ㅛ': '10', 'ㅜ': '0000', 'ㅠ': '010', 'ㅡ': '100', 'ㅣ': '001',
|
|
83
|
-
'ㅐ': '1101', 'ㅔ': '1011'
|
|
84
|
-
},
|
|
85
|
-
'12': {
|
|
86
|
-
'ก': '110', 'ข': '1010', 'ค': '101', 'ง': '10110', 'จ': '10010',
|
|
87
|
-
'ฉ': '1111', 'ช': '1001', 'ซ': '1100', 'ญ': '0111', 'ด': '100',
|
|
88
|
-
'ต': '1', 'ถ': '10100', 'ท': '10011', 'น': '10', 'บ': '1000',
|
|
89
|
-
'ป': '0110', 'ผ': '1101', 'ฝ': '10101', 'พ': '01100', 'ฟ': '0010',
|
|
90
|
-
'ม': '11', 'ย': '1011', 'ร': '010', 'ล': '0100', 'ว': '011',
|
|
91
|
-
'ส': '000', 'ห': '0000', 'อ': '10001', 'ฮ': '11011', 'ฤ': '01011',
|
|
92
|
-
'ะ': '01000', 'า': '01', 'ิ': '00100', 'ี': '00', 'ึ': '00110',
|
|
93
|
-
'ื': '0011', 'ุ': '00101', 'ู': '1110', 'เ': '0', 'แ': '0101',
|
|
94
|
-
'ไ': '01001', 'โ': '111', 'ำ': '00010', '่': '001', '้': '0001',
|
|
95
|
-
'๊': '11000', '๋': '01010', 'ั': '01101', '็': '11100', '์': '11001',
|
|
96
|
-
'ๆ': '10111', 'ฯ': '11010'
|
|
97
|
-
}
|
|
98
|
-
};
|
|
99
|
-
const getCharacters = (options) => (Object.assign(Object.assign({}, baseCharacters), { '0': baseCharacters[options.priority], '1': Object.assign(Object.assign({}, baseCharacters['1']), { [options.separator]: options.space }) }));
|
|
100
|
-
const getMappedCharacters = (options, usePriority) => {
|
|
101
|
-
const mapped = {};
|
|
102
|
-
const characters = getCharacters(options);
|
|
103
|
-
for (const set in characters) {
|
|
104
|
-
mapped[set] = {};
|
|
105
|
-
for (const key in characters[set]) {
|
|
106
|
-
mapped[set][key] = characters[set][key].replace(/0/g, options.dot).replace(/1/g, options.dash);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
if (!usePriority) {
|
|
110
|
-
delete mapped['0'];
|
|
111
|
-
}
|
|
112
|
-
return mapped;
|
|
113
|
-
};
|
|
114
|
-
const swapCharacters = (options) => {
|
|
115
|
-
const swapped = {};
|
|
116
|
-
const mappedCharacters = getMappedCharacters(options, true);
|
|
117
|
-
for (const set in mappedCharacters) {
|
|
118
|
-
for (const key in mappedCharacters[set]) {
|
|
119
|
-
if (typeof swapped[mappedCharacters[set][key]] === 'undefined') {
|
|
120
|
-
swapped[mappedCharacters[set][key]] = key;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
return swapped;
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
const getOptions = (opts = {}) => {
|
|
128
|
-
var _a, _b, _c;
|
|
129
|
-
const options = Object.assign(Object.assign({}, opts), { dash: opts.dash || '-', dot: opts.dot || '.', space: opts.space || '/', separator: opts.separator || ' ', invalid: opts.invalid || '#', priority: opts.priority || 1, wpm: opts.wpm, unit: opts.unit || 0.08, fwUnit: opts.fwUnit || opts.unit || 0.08, volume: opts.volume || 100, oscillator: Object.assign(Object.assign({}, opts.oscillator), { type: ((_a = opts.oscillator) === null || _a === void 0 ? void 0 : _a.type) || 'sine', frequency: ((_b = opts.oscillator) === null || _b === void 0 ? void 0 : _b.frequency) || 500, onended: ((_c = opts.oscillator) === null || _c === void 0 ? void 0 : _c.onended) || null // event that fires when the tone has stopped playing
|
|
130
|
-
}) });
|
|
131
|
-
return options;
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
const getGainTimings = (morse, opts, currentTime = 0) => {
|
|
135
|
-
const timings = [];
|
|
136
|
-
let { unit, fwUnit } = opts;
|
|
137
|
-
let time = 0;
|
|
138
|
-
if (opts.wpm) {
|
|
139
|
-
// wpm mode uses standardised units
|
|
140
|
-
unit = fwUnit = 60 / (opts.wpm * 50);
|
|
141
|
-
}
|
|
142
|
-
timings.push([0, time]);
|
|
143
|
-
const tone = (i) => {
|
|
144
|
-
timings.push([1 * (opts.volume / 100.0), currentTime + time]);
|
|
145
|
-
time += i * unit;
|
|
146
|
-
};
|
|
147
|
-
const silence = (i) => {
|
|
148
|
-
timings.push([0, currentTime + time]);
|
|
149
|
-
time += i * unit;
|
|
150
|
-
};
|
|
151
|
-
const gap = (i) => {
|
|
152
|
-
timings.push([0, currentTime + time]);
|
|
153
|
-
time += i * fwUnit;
|
|
154
|
-
};
|
|
155
|
-
for (let i = 0, addSilence = false; i <= morse.length; i++) {
|
|
156
|
-
if (morse[i] === opts.space) {
|
|
157
|
-
gap(7);
|
|
158
|
-
addSilence = false;
|
|
159
|
-
}
|
|
160
|
-
else if (morse[i] === opts.dot) {
|
|
161
|
-
if (addSilence)
|
|
162
|
-
silence(1);
|
|
163
|
-
else
|
|
164
|
-
addSilence = true;
|
|
165
|
-
tone(1);
|
|
166
|
-
}
|
|
167
|
-
else if (morse[i] === opts.dash) {
|
|
168
|
-
if (addSilence)
|
|
169
|
-
silence(1);
|
|
170
|
-
else
|
|
171
|
-
addSilence = true;
|
|
172
|
-
tone(3);
|
|
173
|
-
}
|
|
174
|
-
else if ((typeof morse[i + 1] !== 'undefined' && morse[i + 1] !== opts.space) &&
|
|
175
|
-
(typeof morse[i - 1] !== 'undefined' && morse[i - 1] !== opts.space)) {
|
|
176
|
-
gap(3);
|
|
177
|
-
addSilence = false;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
return [timings, time];
|
|
181
|
-
};
|
|
182
|
-
// Source: https://github.com/mattdiamond/Recorderjs/blob/master/src/recorder.js#L155
|
|
183
|
-
const encodeWAV = (sampleRate, samples) => {
|
|
184
|
-
const buffer = new ArrayBuffer(44 + samples.length * 2);
|
|
185
|
-
const view = new DataView(buffer);
|
|
186
|
-
const writeString = (view, offset, string) => {
|
|
187
|
-
for (let i = 0; i < string.length; i++) {
|
|
188
|
-
view.setUint8(offset + i, string.charCodeAt(i));
|
|
189
|
-
}
|
|
190
|
-
};
|
|
191
|
-
// RIFF identifier
|
|
192
|
-
writeString(view, 0, 'RIFF');
|
|
193
|
-
// RIFF chunk length
|
|
194
|
-
view.setUint32(4, 36 + samples.length * 2, true);
|
|
195
|
-
// RIFF type
|
|
196
|
-
writeString(view, 8, 'WAVE');
|
|
197
|
-
// format chunk identifier
|
|
198
|
-
writeString(view, 12, 'fmt ');
|
|
199
|
-
// format chunk length
|
|
200
|
-
view.setUint32(16, 16, true);
|
|
201
|
-
// sample format (raw)
|
|
202
|
-
view.setUint16(20, 1, true);
|
|
203
|
-
// channel count
|
|
204
|
-
view.setUint16(22, 1, true);
|
|
205
|
-
// sample rate
|
|
206
|
-
view.setUint32(24, sampleRate, true);
|
|
207
|
-
// byte rate (sample rate * block align)
|
|
208
|
-
view.setUint32(28, sampleRate * 4, true);
|
|
209
|
-
// block align (channel count * bytes per sample)
|
|
210
|
-
view.setUint16(32, 2, true);
|
|
211
|
-
// bits per sample
|
|
212
|
-
view.setUint16(34, 16, true);
|
|
213
|
-
// data chunk identifier
|
|
214
|
-
writeString(view, 36, 'data');
|
|
215
|
-
// data chunk length
|
|
216
|
-
view.setUint32(40, samples.length * 2, true);
|
|
217
|
-
// to PCM
|
|
218
|
-
const floatTo16BitPCM = (output, offset, input) => {
|
|
219
|
-
for (let i = 0; i < input.length; i++, offset += 2) {
|
|
220
|
-
const s = Math.max(-1, Math.min(1, input[i]));
|
|
221
|
-
output.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true);
|
|
222
|
-
}
|
|
223
|
-
};
|
|
224
|
-
floatTo16BitPCM(view, 44, samples);
|
|
225
|
-
return view;
|
|
226
|
-
};
|
|
227
|
-
const audio = (morse, options) => {
|
|
228
|
-
let AudioContextClass = window.AudioContext || window.webkitAudioContext;
|
|
229
|
-
let OfflineAudioContextClass = window.OfflineAudioContext || window.webkitOfflineAudioContext;
|
|
230
|
-
if (!AudioContextClass || !OfflineAudioContextClass) {
|
|
231
|
-
throw new Error('Web Audio API is not supported in this browser');
|
|
232
|
-
}
|
|
233
|
-
const context = new AudioContextClass();
|
|
234
|
-
const [gainValues, totalTime] = getGainTimings(morse, options);
|
|
235
|
-
const offlineContext = new OfflineAudioContextClass(1, 44100 * totalTime, 44100);
|
|
236
|
-
const oscillator = offlineContext.createOscillator();
|
|
237
|
-
const gainNode = offlineContext.createGain();
|
|
238
|
-
oscillator.type = options.oscillator.type;
|
|
239
|
-
oscillator.frequency.value = options.oscillator.frequency;
|
|
240
|
-
gainValues.forEach(([value, time]) => gainNode.gain.setValueAtTime(value, time));
|
|
241
|
-
oscillator.connect(gainNode);
|
|
242
|
-
gainNode.connect(offlineContext.destination);
|
|
243
|
-
let source;
|
|
244
|
-
// Render the audio buffer
|
|
245
|
-
const render = new Promise((resolve, reject) => {
|
|
246
|
-
oscillator.start(0);
|
|
247
|
-
offlineContext.startRendering();
|
|
248
|
-
offlineContext.oncomplete = (e) => {
|
|
249
|
-
try {
|
|
250
|
-
source = context.createBufferSource();
|
|
251
|
-
source.buffer = e.renderedBuffer;
|
|
252
|
-
source.connect(context.destination);
|
|
253
|
-
source.onended = options.oscillator.onended;
|
|
254
|
-
resolve();
|
|
255
|
-
}
|
|
256
|
-
catch (err) {
|
|
257
|
-
reject(err);
|
|
258
|
-
}
|
|
259
|
-
};
|
|
260
|
-
offlineContext.onerror = (err) => {
|
|
261
|
-
reject(err);
|
|
262
|
-
};
|
|
263
|
-
});
|
|
264
|
-
let timeout;
|
|
265
|
-
const play = async () => {
|
|
266
|
-
await render;
|
|
267
|
-
if (context.state === 'suspended') {
|
|
268
|
-
await context.resume();
|
|
269
|
-
}
|
|
270
|
-
source.start(context.currentTime);
|
|
271
|
-
timeout = window.setTimeout(() => { stop(); }, totalTime * 1000);
|
|
272
|
-
};
|
|
273
|
-
const stop = () => {
|
|
274
|
-
clearTimeout(timeout);
|
|
275
|
-
if (source) {
|
|
276
|
-
source.stop(0);
|
|
277
|
-
}
|
|
278
|
-
};
|
|
279
|
-
const getWaveBlob = async () => {
|
|
280
|
-
await render;
|
|
281
|
-
const waveData = encodeWAV(offlineContext.sampleRate, source.buffer.getChannelData(0));
|
|
282
|
-
return new Blob([waveData], { type: 'audio/wav' });
|
|
283
|
-
};
|
|
284
|
-
const getWaveUrl = async () => {
|
|
285
|
-
const audioBlob = await getWaveBlob();
|
|
286
|
-
return URL.createObjectURL(audioBlob);
|
|
287
|
-
};
|
|
288
|
-
const exportWave = async (filename) => {
|
|
289
|
-
const waveUrl = await getWaveUrl();
|
|
290
|
-
const anchor = document.createElement('a');
|
|
291
|
-
anchor.href = waveUrl;
|
|
292
|
-
anchor.target = '_blank';
|
|
293
|
-
anchor.download = filename || 'morse.wav';
|
|
294
|
-
anchor.click();
|
|
295
|
-
};
|
|
296
|
-
return {
|
|
297
|
-
play,
|
|
298
|
-
stop,
|
|
299
|
-
getWaveBlob,
|
|
300
|
-
getWaveUrl,
|
|
301
|
-
exportWave,
|
|
302
|
-
context,
|
|
303
|
-
oscillator,
|
|
304
|
-
gainNode
|
|
305
|
-
};
|
|
306
|
-
};
|
|
307
|
-
|
|
308
|
-
(((name, root, factory) => {
|
|
309
|
-
if (typeof exports === 'object') {
|
|
310
|
-
module.exports = factory();
|
|
311
|
-
}
|
|
312
|
-
else if (typeof define === 'function' && define.amd) {
|
|
313
|
-
define(factory);
|
|
314
|
-
}
|
|
315
|
-
else if (root !== undefined) {
|
|
316
|
-
root[name] = factory();
|
|
317
|
-
}
|
|
318
|
-
})('morse-code-translator', globalThis, () => {
|
|
319
|
-
const encode = (text, opts) => {
|
|
320
|
-
const options = getOptions(opts);
|
|
321
|
-
const characters = getCharacters(options);
|
|
322
|
-
return [...text.replace(/\s+/g, options.separator).trim().toLocaleUpperCase()].map(function (character) {
|
|
323
|
-
for (const set in characters) {
|
|
324
|
-
if (typeof characters[set] !== 'undefined' && typeof characters[set][character] !== 'undefined') {
|
|
325
|
-
return characters[set][character];
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
return options.invalid;
|
|
329
|
-
}).join(options.separator).replace(/0/g, options.dot).replace(/1/g, options.dash);
|
|
330
|
-
};
|
|
331
|
-
const decode = (morse, opts) => {
|
|
332
|
-
const options = getOptions(opts);
|
|
333
|
-
const swapped = swapCharacters(options);
|
|
334
|
-
return morse.replace(/\s+/g, options.separator).trim().split(options.separator).map(function (characters) {
|
|
335
|
-
if (typeof swapped[characters] !== 'undefined') {
|
|
336
|
-
return swapped[characters];
|
|
337
|
-
}
|
|
338
|
-
return options.invalid;
|
|
339
|
-
}).join('');
|
|
340
|
-
};
|
|
341
|
-
const characters = (options, usePriority) => getMappedCharacters(getOptions(options), usePriority);
|
|
342
|
-
const audio$1 = (text, opts, morseString) => {
|
|
343
|
-
const morse = morseString || encode(text, opts);
|
|
344
|
-
const options = getOptions(opts);
|
|
345
|
-
return audio(morse, options);
|
|
346
|
-
};
|
|
347
|
-
return {
|
|
348
|
-
characters,
|
|
349
|
-
decode,
|
|
350
|
-
encode,
|
|
351
|
-
audio: audio$1
|
|
352
|
-
};
|
|
353
|
-
}));
|
package/src/index.ts
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { getCharacters, getMappedCharacters, swapCharacters } from './characters';
|
|
2
|
-
import getOptions from './options';
|
|
3
|
-
import getAudio from './audio';
|
|
4
|
-
|
|
5
|
-
declare let exports;
|
|
6
|
-
declare let module;
|
|
7
|
-
declare let define;
|
|
8
|
-
|
|
9
|
-
;(((name, root, factory) => {
|
|
10
|
-
if (typeof exports === 'object') {
|
|
11
|
-
module.exports = factory();
|
|
12
|
-
} else if (typeof define === 'function' && define.amd) {
|
|
13
|
-
define(factory);
|
|
14
|
-
} else if (root !== undefined) {
|
|
15
|
-
root[name] = factory();
|
|
16
|
-
}
|
|
17
|
-
})('morse-code-translator', globalThis, () => {
|
|
18
|
-
'use strict';
|
|
19
|
-
|
|
20
|
-
const encode = (text: string, opts: Options) => {
|
|
21
|
-
const options = getOptions(opts);
|
|
22
|
-
const characters = getCharacters(options);
|
|
23
|
-
return [...text.replace(/\s+/g, options.separator).trim().toLocaleUpperCase()].map(function (character) {
|
|
24
|
-
for (const set in characters) {
|
|
25
|
-
if (typeof characters[set] !== 'undefined' && typeof characters[set][character] !== 'undefined') {
|
|
26
|
-
return characters[set][character];
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
return options.invalid;
|
|
30
|
-
}).join(options.separator).replace(/0/g, options.dot).replace(/1/g, options.dash);
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
const decode = (morse: string, opts: Options) => {
|
|
34
|
-
const options = getOptions(opts);
|
|
35
|
-
const swapped = swapCharacters(options);
|
|
36
|
-
return morse.replace(/\s+/g, options.separator).trim().split(options.separator).map(function (characters) {
|
|
37
|
-
if (typeof swapped[characters] !== 'undefined') {
|
|
38
|
-
return swapped[characters];
|
|
39
|
-
}
|
|
40
|
-
return options.invalid;
|
|
41
|
-
}).join('');
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
const characters = (options, usePriority) => getMappedCharacters(getOptions(options), usePriority);
|
|
45
|
-
|
|
46
|
-
const audio = (text: string, opts: Options, morseString: string) => {
|
|
47
|
-
const morse = morseString || encode(text, opts);
|
|
48
|
-
const options = getOptions(opts);
|
|
49
|
-
return getAudio(morse, options);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return {
|
|
53
|
-
characters,
|
|
54
|
-
decode,
|
|
55
|
-
encode,
|
|
56
|
-
audio
|
|
57
|
-
};
|
|
58
|
-
}));
|
package/src/options.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
const getOptions = (opts: Partial<Options> = {}): Options => {
|
|
2
|
-
const options: Options = {
|
|
3
|
-
...opts,
|
|
4
|
-
dash: opts.dash || '-',
|
|
5
|
-
dot: opts.dot || '.',
|
|
6
|
-
space: opts.space || '/',
|
|
7
|
-
separator: opts.separator || ' ',
|
|
8
|
-
invalid: opts.invalid || '#',
|
|
9
|
-
priority: opts.priority || 1,
|
|
10
|
-
wpm: opts.wpm, // words per minute - PARIS method used in favour of unit/fwUnit options
|
|
11
|
-
unit: opts.unit || 0.08, // period of one unit, in seconds, 1.2 / c where c is speed of transmission, in words per minute
|
|
12
|
-
fwUnit: opts.fwUnit || opts.unit || 0.08, // Farnsworth unit to control intercharacter and interword gaps
|
|
13
|
-
volume: opts.volume || 100,
|
|
14
|
-
oscillator: {
|
|
15
|
-
...opts.oscillator,
|
|
16
|
-
type: opts.oscillator?.type || 'sine', // sine, square, sawtooth, triangle
|
|
17
|
-
frequency: opts.oscillator?.frequency || 500, // value in hertz
|
|
18
|
-
onended: opts.oscillator?.onended || null // event that fires when the tone has stopped playing
|
|
19
|
-
}
|
|
20
|
-
};
|
|
21
|
-
return options;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
export default getOptions;
|